diff options
Diffstat (limited to 'libbb/safe_strtol.c')
-rw-r--r-- | libbb/safe_strtol.c | 102 |
1 files changed, 77 insertions, 25 deletions
diff --git a/libbb/safe_strtol.c b/libbb/safe_strtol.c index 027fc1e..a7f012f 100644 --- a/libbb/safe_strtol.c +++ b/libbb/safe_strtol.c @@ -7,21 +7,10 @@ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. */ -#include <stdlib.h> -#include <errno.h> #include <assert.h> #include "libbb.h" -int safe_strtoi(char *arg, int* value) -{ - int error; - long lvalue = *value; - error = safe_strtol(arg, &lvalue); - *value = (int) lvalue; - return error; -} - -int safe_strtod(char *arg, double* value) +int safe_strtod(const char *arg, double* value) { char *endptr; int errno_save = errno; @@ -29,69 +18,132 @@ int safe_strtod(char *arg, double* value) assert(arg!=NULL); errno = 0; *value = strtod(arg, &endptr); - if (errno != 0 || *endptr!='\0' || endptr==arg) { + if (errno != 0 || *endptr != '\0' || endptr == arg) { return 1; } errno = errno_save; return 0; } -int safe_strtol(char *arg, long* value) +int safe_strtoull(const char *arg, unsigned long long* value) { char *endptr; int errno_save = errno; assert(arg!=NULL); + if (!isdigit(arg[0])) /* strtouXX takes minus signs w/o error! :( */ + return 1; errno = 0; - *value = strtol(arg, &endptr, 0); - if (errno != 0 || *endptr!='\0' || endptr==arg) { + *value = strtoull(arg, &endptr, 0); + if (errno != 0 || *endptr != '\0' || endptr == arg) { return 1; } errno = errno_save; return 0; } -int safe_strtoul(char *arg, unsigned long* value) +int safe_strtoll(const char *arg, long long* value) { char *endptr; int errno_save = errno; assert(arg!=NULL); errno = 0; - *value = strtoul(arg, &endptr, 0); - if (errno != 0 || *endptr!='\0' || endptr==arg) { + *value = strtoll(arg, &endptr, 0); + if (errno != 0 || *endptr != '\0' || endptr == arg) { return 1; } errno = errno_save; return 0; } -int safe_strtoll(char *arg, long long* value) +int safe_strtoul(const char *arg, unsigned long* value) { char *endptr; int errno_save = errno; assert(arg!=NULL); + if (!isdigit(arg[0])) /* strtouXX takes minus signs w/o error! :( */ + return 1; errno = 0; - *value = strtoll(arg, &endptr, 0); - if (errno != 0 || *endptr!='\0' || endptr==arg) { + *value = strtoul(arg, &endptr, 0); + if (errno != 0 || *endptr != '\0' || endptr == arg) { return 1; } errno = errno_save; return 0; } -int safe_strtoull(char *arg, unsigned long long* value) +int safe_strtol(const char *arg, long* value) { char *endptr; int errno_save = errno; assert(arg!=NULL); errno = 0; - *value = strtoull(arg, &endptr, 0); - if (errno != 0 || *endptr!='\0' || endptr==arg) { + *value = strtol(arg, &endptr, 0); + if (errno != 0 || *endptr != '\0' || endptr == arg) { return 1; } errno = errno_save; return 0; } + +/* TODO: This is what uclibc is doing. Try to do the same? */ + +#if 0 +#if defined __HAVE_ELF__ + +# define strong_alias(name, aliasname) _strong_alias(name, aliasname) +# define _strong_alias(name, aliasname) \ + extern __typeof (name) aliasname __attribute__ ((alias (#name))); + +#else /* !defined __HAVE_ELF__ */ + +# define strong_alias(name, aliasname) _strong_alias (name, aliasname) +# define _strong_alias(name, aliasname) \ + __asm__(".global " __C_SYMBOL_PREFIX__ #aliasname "\n" \ + ".set " __C_SYMBOL_PREFIX__ #aliasname "," __C_SYMBOL_PREFIX__ #name); + +#endif +#endif + +int safe_strtoi(const char *arg, int* value) +{ + if (sizeof(long) == sizeof(int)) { + return safe_strtol(arg, (long*)value); + } else { + int error; + long lvalue = *value; + error = safe_strtol(arg, &lvalue); + if (lvalue < INT_MIN || lvalue > INT_MAX) + return 1; + *value = (int) lvalue; + return error; + } +} + +int safe_strtou(const char *arg, unsigned* value) +{ + if (sizeof(unsigned long) == sizeof(unsigned)) { + return safe_strtoul(arg, (unsigned long*)value); + } else { + int error; + unsigned long lvalue = *value; + error = safe_strtoul(arg, &lvalue); + if (lvalue > UINT_MAX) + return 1; + *value = (unsigned) lvalue; + return error; + } +} + +int BUG_safe_strtou32_unimplemented(void); +int safe_strtou32(const char *arg, uint32_t* value) +{ + if (sizeof(uint32_t) == sizeof(unsigned)) + return safe_strtou(arg, (unsigned*)value); + if (sizeof(uint32_t) == sizeof(unsigned long)) + return safe_strtoul(arg, (unsigned long*)value); + return BUG_safe_strtou32_unimplemented(); +} |