diff options
author | Alejandro Colomar <alx@kernel.org> | 2024-04-18 14:13:28 +0200 |
---|---|---|
committer | Alejandro Colomar <alx@kernel.org> | 2024-04-18 14:13:54 +0200 |
commit | 25fdce75ba7ef240b01c69af5b8dd26d0e648185 (patch) | |
tree | c40002649f27ef207f4a0ad888149ad9da712136 | |
parent | fb780435921038f6264fcbc74fe424e7d65b7de3 (diff) |
include/a2i/strtoi.h, lib/src/a2i/strtoi.c: Don't inline these functions
We've learnt from the xz backdoor that dependencies can be very
dangerous. By not inlining, we isolate the damage that our library
could cause. If a bug is ever found here, fixing the library should be
enough. If one wants to optimize, they still can use LTO.
Signed-off-by: Alejandro Colomar <alx@kernel.org>
-rw-r--r-- | include/a2i/strtoi.h | 101 | ||||
-rw-r--r-- | lib/src/a2i/strtoi.c | 92 |
2 files changed, 92 insertions, 101 deletions
diff --git a/include/a2i/strtoi.h b/include/a2i/strtoi.h index aa5d5b4..d202da3 100644 --- a/include/a2i/strtoi.h +++ b/include/a2i/strtoi.h @@ -6,62 +6,12 @@ #define INCLUDE_A2I_STRTOI_H_ -#include <errno.h> -#include <inttypes.h> -#include <stddef.h> #include <stdint.h> -#include <sys/param.h> #include <a2i/attr.h> -#include <a2i/inline.h> #include <a2i/qual.h> -#define a2i_strtoI(TYPE, s, endp, base, min, max, status) \ -({ \ - const char *s_ = s; \ - char **endp_ = endp; \ - int base_ = base; \ - TYPE min_ = min; \ - TYPE max_ = max; \ - int *status_ = status; \ - \ - int errno_saved_, st_; \ - char *e_; \ - TYPE n_; \ - \ - if (endp_ == NULL) \ - endp_ = &e_; \ - if (status_ == NULL) \ - status_ = &st_; \ - \ - if (base != 0 && (base_ < 2 || base_ > 36)) { \ - *status_ = EINVAL; \ - n_ = 0; \ - \ - } else { \ - errno_saved_ = errno; \ - errno = 0; \ - n_ = _Generic((TYPE) 0, \ - intmax_t: strtoimax, \ - uintmax_t: strtoumax \ - )(s_, endp_, base_); \ - \ - if (*endp_ == s_) \ - *status_ = ECANCELED; \ - else if (errno == ERANGE || n_ < min_ || n_ > max_) \ - *status_ = ERANGE; \ - else if (**endp_ != '\0') \ - *status_ = ENOTSUP; \ - else \ - *status_ = 0; \ - \ - errno = errno_saved_; \ - } \ - MAX(min_, MIN(max_, n_)); \ -}) - - #if defined(__clang__) # pragma clang assume_nonnull begin #endif @@ -69,57 +19,22 @@ A2I_ATTR_ACCESS(read_only, 1) A2I_ATTR_ACCESS(write_only, 2) A2I_ATTR_ACCESS(write_only, 6) A2I_ATTR_STRING(1) -a2i_inline intmax_t a2i_strtoi(const char *s, - char **a2i_nullable restrict endp, int base, - intmax_t min, intmax_t max, int *a2i_nullable restrict status); +intmax_t a2i_strtoi(const char *s, char **a2i_nullable restrict endp, + int base, intmax_t min, intmax_t max, int *a2i_nullable restrict status); + A2I_ATTR_ACCESS(read_only, 1) A2I_ATTR_ACCESS(write_only, 2) A2I_ATTR_ACCESS(write_only, 6) A2I_ATTR_STRING(1) -a2i_inline uintmax_t a2i_strtou(const char *s, - char **a2i_nullable restrict endp, int base, - uintmax_t min, uintmax_t max, int *a2i_nullable restrict status); +uintmax_t a2i_strtou(const char *s, char **a2i_nullable restrict endp, + int base, uintmax_t min, uintmax_t max, int *a2i_nullable restrict status); + A2I_ATTR_ACCESS(read_only, 1) A2I_ATTR_ACCESS(write_only, 2) A2I_ATTR_ACCESS(write_only, 6) A2I_ATTR_STRING(1) -a2i_inline uintmax_t a2i_strtou_noneg(const char *s, - char **a2i_nullable restrict endp, int base, - uintmax_t min, uintmax_t max, int *a2i_nullable restrict status); - - -a2i_inline intmax_t -a2i_strtoi(const char *s, - char **a2i_nullable restrict endp, int base, - intmax_t min, intmax_t max, int *a2i_nullable restrict status) -{ - return a2i_strtoI(intmax_t, s, endp, base, min, max, status); -} - - -a2i_inline uintmax_t -a2i_strtou(const char *s, - char **a2i_nullable restrict endp, int base, - uintmax_t min, uintmax_t max, int *a2i_nullable restrict status) -{ - return a2i_strtoI(uintmax_t, s, endp, base, min, max, status); -} - - -a2i_inline uintmax_t -a2i_strtou_noneg(const char *s, - char **a2i_nullable restrict endp, int base, - uintmax_t min, uintmax_t max, int *a2i_nullable restrict status) -{ - int st; - - if (status == NULL) - status = &st; - if (a2i_strtoi(s, endp, base, 0, 1, status) == 0 && *status == ERANGE) - return min; - - return a2i_strtou(s, endp, base, min, max, status); -} +uintmax_t a2i_strtou_noneg(const char *s, char **a2i_nullable restrict endp, + int base, uintmax_t min, uintmax_t max, int *a2i_nullable restrict status); #if defined(__clang__) # pragma clang assume_nonnull end #endif diff --git a/lib/src/a2i/strtoi.c b/lib/src/a2i/strtoi.c index d36ac93..75563f1 100644 --- a/lib/src/a2i/strtoi.c +++ b/lib/src/a2i/strtoi.c @@ -4,19 +4,95 @@ #include <a2i/strtoi.h> +#include <errno.h> +#include <inttypes.h> +#include <stddef.h> #include <stdint.h> +#include <sys/param.h> #include <a2i/qual.h> -#pragma clang assume_nonnull begin -extern inline intmax_t a2i_strtoi(const char *s, +#define a2i_strtoI(TYPE, s, endp, base, min, max, status) \ +({ \ + const char *s_ = s; \ + char **endp_ = endp; \ + int base_ = base; \ + TYPE min_ = min; \ + TYPE max_ = max; \ + int *status_ = status; \ + \ + int errno_saved_, st_; \ + char *e_; \ + TYPE n_; \ + \ + if (endp_ == NULL) \ + endp_ = &e_; \ + if (status_ == NULL) \ + status_ = &st_; \ + \ + if (base != 0 && (base_ < 2 || base_ > 36)) { \ + *status_ = EINVAL; \ + n_ = 0; \ + \ + } else { \ + errno_saved_ = errno; \ + errno = 0; \ + n_ = _Generic((TYPE) 0, \ + intmax_t: strtoimax, \ + uintmax_t: strtoumax \ + )(s_, endp_, base_); \ + \ + if (*endp_ == s_) \ + *status_ = ECANCELED; \ + else if (errno == ERANGE || n_ < min_ || n_ > max_) \ + *status_ = ERANGE; \ + else if (**endp_ != '\0') \ + *status_ = ENOTSUP; \ + else \ + *status_ = 0; \ + \ + errno = errno_saved_; \ + } \ + MAX(min_, MIN(max_, n_)); \ +}) + + +#if defined(__clang__) +# pragma clang assume_nonnull begin +#endif +intmax_t +a2i_strtoi(const char *s, char **a2i_nullable restrict endp, int base, - intmax_t min, intmax_t max, int *a2i_nullable restrict status); -extern inline uintmax_t a2i_strtou(const char *s, + intmax_t min, intmax_t max, int *a2i_nullable restrict status) +{ + return a2i_strtoI(intmax_t, s, endp, base, min, max, status); +} + + +uintmax_t +a2i_strtou(const char *s, char **a2i_nullable restrict endp, int base, - uintmax_t min, uintmax_t max, int *a2i_nullable restrict status); -extern inline uintmax_t a2i_strtou_noneg(const char *s, + uintmax_t min, uintmax_t max, int *a2i_nullable restrict status) +{ + return a2i_strtoI(uintmax_t, s, endp, base, min, max, status); +} + + +uintmax_t +a2i_strtou_noneg(const char *s, char **a2i_nullable restrict endp, int base, - uintmax_t min, uintmax_t max, int *a2i_nullable restrict status); -#pragma clang assume_nonnull end + uintmax_t min, uintmax_t max, int *a2i_nullable restrict status) +{ + int st; + + if (status == NULL) + status = &st; + if (a2i_strtoi(s, endp, base, 0, 1, status) == 0 && *status == ERANGE) + return min; + + return a2i_strtou(s, endp, base, min, max, status); +} +#if defined(__clang__) +# pragma clang assume_nonnull end +#endif |