From 94675cd8e38496c63dc033e015783c589d764193 Mon Sep 17 00:00:00 2001 From: "Erich E. Hoover" Date: Sat, 21 Dec 2019 17:53:57 -0700 Subject: [PATCH] ntdll: Drop support for floating point numbers in sscanf. Takes care of one more use of "long double". Signed-off-by: Erich E. Hoover Signed-off-by: Alexandre Julliard --- dlls/ntdll/string.c | 140 -------------------------------------- dlls/ntdll/tests/string.c | 47 +++++++++++++ 2 files changed, 47 insertions(+), 140 deletions(-) diff --git a/dlls/ntdll/string.c b/dlls/ntdll/string.c index 1d6af8558c0..709f0ebdbd4 100644 --- a/dlls/ntdll/string.c +++ b/dlls/ntdll/string.c @@ -848,7 +848,6 @@ static int NTDLL_vsscanf( const char *str, const char *format, __ms_va_list ap) int base; int h_prefix = 0; BOOLEAN l_prefix = FALSE; - BOOLEAN L_prefix = FALSE; BOOLEAN w_prefix = FALSE; BOOLEAN I64_prefix = FALSE; BOOLEAN prefix_finished = FALSE; @@ -881,7 +880,6 @@ static int NTDLL_vsscanf( const char *str, const char *format, __ms_va_list ap) l_prefix = TRUE; break; case 'w': w_prefix = TRUE; break; - case 'L': L_prefix = TRUE; break; case 'I': if (*(format + 1) == '6' && *(format + 2) == '4') @@ -990,144 +988,6 @@ static int NTDLL_vsscanf( const char *str, const char *format, __ms_va_list ap) } } break; - case 'e': - case 'E': - case 'f': - case 'g': - case 'G': - { /* read a float */ - long double cur = 1, expcnt = 10; - ULONGLONG d, hlp; - int exp = 0; - BOOLEAN negative = FALSE; - /*unsigned fpcontrol;*/ - BOOLEAN negexp; - - /* skip initial whitespace */ - while (nch != '\0' && isspace( nch )) - nch = (consumed++, *str++); - - /* get sign */ - if (nch == '-' || nch == '+') - { - negative = (nch == '-'); - if (width > 0) width--; - if (width == 0) break; - nch = (consumed++, *str++); - } - - /* get first digit */ - if ('.' != nch) - { - if (!isdigit( nch )) break; - d = nch - '0'; - nch = (consumed++, *str++); - if (width > 0) width--; - /* read until no more digits */ - while (width != 0 && nch != '\0' && isdigit( nch )) - { - hlp = d * 10 + nch - '0'; - nch = (consumed++, *str++); - if (width > 0) width--; - if(d > (ULONGLONG)-1/10 || hlp < d) - { - exp++; - break; - } - else - d = hlp; - } - while (width != 0 && nch != '\0' && isdigit( nch )) - { - exp++; - nch = (consumed++, *str++); - if (width > 0) width--; - } - } - else - d = 0; /* Fix: .8 -> 0.8 */ - - /* handle decimals */ - if (width != 0 && nch == '.') - { - nch = (consumed++, *str++); - if (width > 0) width--; - - while (width != 0 && nch != '\0' && isdigit( nch )) - { - hlp = d * 10 + nch - '0'; - nch = (consumed++, *str++); - if (width > 0) width--; - if(d > (ULONGLONG)-1/10 || hlp < d) - break; - - d = hlp; - exp--; - } - while (width != 0 && nch != '\0' && isdigit( nch )) - { - nch = (consumed++, *str++); - if (width > 0) width--; - } - } - - /* handle exponent */ - if (width != 0 && (nch == 'e' || nch == 'E')) - { - int sign = 1, e = 0; - - nch = (consumed++, *str++); - if (width > 0) width--; - if (width != 0 && (nch == '+' || nch == '-')) - { - if(nch == '-') - sign = -1; - nch = (consumed++, *str++); - if (width > 0) width--; - } - - /* exponent digits */ - while (width != 0 && nch != '\0' && isdigit( nch )) - { - if (e > INT_MAX/10 || (e = e * 10 + nch - '0') < 0) - e = INT_MAX; - nch = (consumed++, *str++); - if (width > 0) width--; - } - e *= sign; - - if(exp < 0 && e < 0 && e+exp > 0) exp = INT_MIN; - else if(exp > 0 && e > 0 && e+exp < 0) exp = INT_MAX; - else exp += e; - } - - /*fpcontrol = _control87(0, 0); - _control87(MSVCRT__EM_DENORMAL|MSVCRT__EM_INVALID|MSVCRT__EM_ZERODIVIDE - |MSVCRT__EM_OVERFLOW|MSVCRT__EM_UNDERFLOW|MSVCRT__EM_INEXACT, 0xffffffff);*/ - - negexp = (exp < 0); - if (negexp) - exp = -exp; - /* update 'cur' with this exponent. */ - while (exp) - { - if(exp & 1) - cur *= expcnt; - exp /= 2; - expcnt = expcnt*expcnt; - } - cur = (negexp ? d/cur : d*cur); - - /*_control87(fpcontrol, 0xffffffff);*/ - - st = 1; - if (!suppress) - { - if (L_prefix || l_prefix) _SET_NUMBER_( double ); - else _SET_NUMBER_( float ); - } - } - break; /* According to msdn, * 's' reads a character string in a call to fscanf * and 'S' a wide character string and vice versa in a diff --git a/dlls/ntdll/tests/string.c b/dlls/ntdll/tests/string.c index 5a2d8458c21..12027e88999 100644 --- a/dlls/ntdll/tests/string.c +++ b/dlls/ntdll/tests/string.c @@ -67,6 +67,8 @@ static int (__cdecl *p_tolower)(int); static int (__cdecl *p_toupper)(int); static int (__cdecl *p__strnicmp)(LPCSTR,LPCSTR,size_t); +static int (WINAPIV *p_sscanf)(const char *, const char *, ...); + static void InitFunctionPtrs(void) { hntdll = LoadLibraryA("ntdll.dll"); @@ -109,6 +111,8 @@ static void InitFunctionPtrs(void) p_tolower = (void *)GetProcAddress(hntdll, "tolower"); p_toupper = (void *)GetProcAddress(hntdll, "toupper"); p__strnicmp = (void *)GetProcAddress(hntdll, "_strnicmp"); + + p_sscanf = (void *)GetProcAddress(hntdll, "sscanf"); } /* if */ } @@ -1455,6 +1459,48 @@ static void test__strnicmp(void) ok(!ret, "_strnicmp returned %d\n", ret); } +static void test_sscanf(void) +{ + double d = 0.0; + float f = 0.0f; + int i = 0; + int ret; + + if (!p_sscanf) + { + win_skip("sscanf tests\n"); + return; + } + + ret = p_sscanf("10", "%d", &i); + ok(ret == 1, "ret = %d\n", ret); + ok(i == 10, "i = %d\n", i); + + ret = p_sscanf("10", "%f", &f); + ok(ret == 0 || broken(ret == 1) /* xp/2003 */, "ret = %d\n", ret); + ok(f == 0.0f, "f = %f\n", f); + + ret = p_sscanf("10", "%g", &f); + ok(ret == 0 || broken(ret == 1) /* xp/2003 */, "ret = %d\n", ret); + ok(f == 0.0f, "f = %f\n", f); + + ret = p_sscanf("10", "%e", &f); + ok(ret == 0 || broken(ret == 1) /* xp/2003 */, "ret = %d\n", ret); + ok(f == 0.0f, "f = %f\n", f); + + ret = p_sscanf("10", "%lf", &d); + ok(ret == 0 || broken(ret == 1) /* xp/2003 */, "ret = %d\n", ret); + ok(d == 0.0, "d = %lf\n", f); + + ret = p_sscanf("10", "%lg", &d); + ok(ret == 0 || broken(ret == 1) /* xp/2003 */, "ret = %d\n", ret); + ok(d == 0.0, "d = %lf\n", f); + + ret = p_sscanf("10", "%le", &d); + ok(ret == 0 || broken(ret == 1) /* xp/2003 */, "ret = %d\n", ret); + ok(d == 0.0, "d = %lf\n", f); +} + START_TEST(string) { InitFunctionPtrs(); @@ -1498,4 +1544,5 @@ START_TEST(string) test_tolower(); test_toupper(); test__strnicmp(); + test_sscanf(); }