From d5770d143b1d586930a5e6afab8c2d00b206ceeb Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Wed, 2 Apr 2014 09:15:40 -0600 Subject: sscanf: Use stroul() vs strol() for %u format. From kfrolov --- nuttx/ChangeLog | 4 ++++ nuttx/libc/stdio/lib_sscanf.c | 42 ++++++++++++++++++++++++++++-------------- 2 files changed, 32 insertions(+), 14 deletions(-) diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog index 54078ff61..3165033ec 100644 --- a/nuttx/ChangeLog +++ b/nuttx/ChangeLog @@ -7108,3 +7108,7 @@ DBGU (2014-4-1). * configs/sama5d3-xplained/nsh: Configurations now use the DBGU for the serial console (instead of USART1) (2014-4-1). + * libc/stdio/lib_sccanf.c: Use stroul() vs strol() with %u format + otherwise, range of values is restricted because of sign bit + from kfrolov (2014-4-2). + diff --git a/nuttx/libc/stdio/lib_sscanf.c b/nuttx/libc/stdio/lib_sscanf.c index 1bf9c1ed8..a4802b2c5 100644 --- a/nuttx/libc/stdio/lib_sscanf.c +++ b/nuttx/libc/stdio/lib_sscanf.c @@ -372,6 +372,7 @@ int vsscanf(FAR const char *buf, FAR const char *fmt, va_list ap) { FAR long *plong = NULL; FAR int *pint = NULL; + bool sign; lvdbg("vsscanf: Performing integer conversion\n"); @@ -415,24 +416,30 @@ int vsscanf(FAR const char *buf, FAR const char *fmt, va_list ap) * specific conversion specification. */ - if (*fmt == 'd' || *fmt == 'u') + sign = false; + switch (*fmt) { + default: + case 'd': + sign = true; + case 'u': base = 10; - } - else if (*fmt == 'x') - { + break; + + case 'x': base = 16; - } - else if (*fmt == 'o') - { + break; + + case 'o': base = 8; - } - else if (*fmt == 'b') - { + break; + + case 'b': base = 2; + break; } - /* Was a fieldwidth specified? */ + /* Was a field width specified? */ if (!width) { @@ -464,9 +471,16 @@ int vsscanf(FAR const char *buf, FAR const char *fmt, va_list ap) errsave = get_errno(); set_errno(0); - tmplong = strtol(tmp, &endptr, base); + if (sign) + { + tmplong = strtol(tmp, &endptr, base); + } + else + { + tmplong = strtoul(tmp, &endptr, base); + } - /* Number can't be converted */ + /* Check if the number was successfully converted */ if (tmp == endptr || get_errno() == ERANGE) { @@ -580,7 +594,7 @@ int vsscanf(FAR const char *buf, FAR const char *fmt, va_list ap) set_errno(0); dvalue = strtod(tmp, &endptr); - /* Number can't be converted */ + /* Check if the number was successfully converted */ if (tmp == endptr || get_errno() == ERANGE) { -- cgit v1.2.3