diff options
| author | Anton Kling <anton@kling.gg> | 2024-11-22 23:00:55 +0100 | 
|---|---|---|
| committer | Anton Kling <anton@kling.gg> | 2024-11-22 23:00:55 +0100 | 
| commit | 2dce92236b9fe0a9398287ac7c62f2f4e67d53b6 (patch) | |
| tree | 2e03ae3d27fabd7004cb396c23debfc74e64e3b7 | |
| parent | 597ac49280e8ab59e779c5d33ad266b477208293 (diff) | |
libc: Fix bugs in strto(u)l(l)
| -rw-r--r-- | userland/libc/stdlib/strtol.c | 5 | ||||
| -rw-r--r-- | userland/libc/stdlib/strtoll.c | 5 | ||||
| -rw-r--r-- | userland/libc/stdlib/strtoul.c | 30 | 
3 files changed, 24 insertions, 16 deletions
diff --git a/userland/libc/stdlib/strtol.c b/userland/libc/stdlib/strtol.c index 4a1e189..460dedd 100644 --- a/userland/libc/stdlib/strtol.c +++ b/userland/libc/stdlib/strtol.c @@ -44,12 +44,15 @@ long strtol(const char *str, char **restrict endptr, int base) {    if (2 <= base && 36 >= base) {      for (; *str; str++) { +      int val = get_value(*str, base); +      if (-1 == val) { +        break; +      }        if (ret_value > LONG_MAX / base) {          errno = ERANGE;          return LONG_MAX;        }        ret_value *= base; -      int val = get_value(*str, base);        if (ret_value > LONG_MAX - val) {          errno = ERANGE;          return LONG_MAX; diff --git a/userland/libc/stdlib/strtoll.c b/userland/libc/stdlib/strtoll.c index d1eacde..0e397ff 100644 --- a/userland/libc/stdlib/strtoll.c +++ b/userland/libc/stdlib/strtoll.c @@ -44,12 +44,15 @@ long long strtoll(const char *str, char **restrict endptr, int base) {    if (2 <= base && 36 >= base) {      for (; *str; str++) { +      int val = get_value(*str, base); +      if(-1 == val) { +        break; +      }        if (ret_value > LLONG_MAX / base) {          errno = ERANGE;          return LLONG_MAX;        }        ret_value *= base; -      int val = get_value(*str, base);        if (ret_value > LLONG_MAX - val) {          errno = ERANGE;          return LLONG_MAX; diff --git a/userland/libc/stdlib/strtoul.c b/userland/libc/stdlib/strtoul.c index f286a77..39dc8eb 100644 --- a/userland/libc/stdlib/strtoul.c +++ b/userland/libc/stdlib/strtoul.c @@ -7,16 +7,17 @@  extern int errno;  int get_value(char c, long base) {    int r; -  if (c >= '0' && c <= '9') -    r = c - '0'; -  else if (c >= 'A' && c <= 'Z') -    r = c - 'A'; -  else if (c >= 'a' && c <= 'z') -    r = c - 'a'; -  else +  int l = tolower(c); +  if (l >= '0' && l <= '9') { +    r = l - '0'; +  } else if (l >= 'a' && l <= 'z') { +    r = (l - 'a') + 10; +  } else {      return -1; -  if (r >= base) +  } +  if (r >= base) {      return -1; +  }    return r;  } @@ -59,13 +60,14 @@ unsigned long strtoul(const char *restrict str, char **restrict endptr,    if (2 <= base && 36 >= base) {      for (; *str; str++) { -      ret_value *= base;        int val = get_value(*str, base); -      /*        if (-1 == val) { -        errno = ERANGE; -        return 0; -      }*/ +        break; +      } +      if (-1 == val) { +        break; +      } +      ret_value *= base;        if (ret_value > ULONG_MAX - val) {          errno = ERANGE;          return 0; @@ -78,6 +80,6 @@ unsigned long strtoul(const char *restrict str, char **restrict endptr,      return 0;    }    if (endptr) -    *endptr = (char*)str; +    *endptr = (char *)str;    return ret_value;  }  |