Commit 8c29b7dc authored by H. Verbeet's avatar H. Verbeet Committed by Alexandre Julliard

msvcrt: Fix reading of signed numbers with unsigned read types in scanf.

parent 19a08820
...@@ -114,7 +114,7 @@ _FUNCTION_ { ...@@ -114,7 +114,7 @@ _FUNCTION_ {
* the form %[*][width][{h | l | I64 | L}]type */ * the form %[*][width][{h | l | I64 | L}]type */
else if (*format == '%') { else if (*format == '%') {
int st = 0; int suppress = 0; int width = 0; int st = 0; int suppress = 0; int width = 0;
int base, number_signed; int base;
int h_prefix = 0; int h_prefix = 0;
int l_prefix = 0; int l_prefix = 0;
int L_prefix = 0; int L_prefix = 0;
...@@ -157,19 +157,19 @@ _FUNCTION_ { ...@@ -157,19 +157,19 @@ _FUNCTION_ {
switch(*format) { switch(*format) {
case 'x': case 'x':
case 'X': /* hexadecimal integer. */ case 'X': /* hexadecimal integer. */
base = 16; number_signed = 0; base = 16;
goto number; goto number;
case 'o': /* octal integer */ case 'o': /* octal integer */
base = 8; number_signed = 0; base = 8;
goto number; goto number;
case 'u': /* unsigned decimal integer */ case 'u': /* unsigned decimal integer */
base = 10; number_signed = 0; base = 10;
goto number; goto number;
case 'd': /* signed decimal integer */ case 'd': /* signed decimal integer */
base = 10; number_signed = 1; base = 10;
goto number; goto number;
case 'i': /* generic integer */ case 'i': /* generic integer */
base = 10; number_signed = 1; base = 10;
number: { number: {
/* read an integer */ /* read an integer */
ULONGLONG cur = 0; ULONGLONG cur = 0;
...@@ -179,8 +179,7 @@ _FUNCTION_ { ...@@ -179,8 +179,7 @@ _FUNCTION_ {
while ((nch!=_EOF_) && _ISSPACE_(nch)) while ((nch!=_EOF_) && _ISSPACE_(nch))
nch = _GETC_(file); nch = _GETC_(file);
/* get sign */ /* get sign */
if (number_signed && (nch == '-' || if (nch == '-' || nch == '+') {
nch == '+')) {
negative = (nch=='-'); negative = (nch=='-');
nch = _GETC_(file); nch = _GETC_(file);
if (width>0) width--; if (width>0) width--;
...@@ -225,22 +224,10 @@ _FUNCTION_ { ...@@ -225,22 +224,10 @@ _FUNCTION_ {
st = 1; st = 1;
if (!suppress) { if (!suppress) {
#define _SET_NUMBER_(type) *va_arg(ap, type*) = negative ? -cur : cur #define _SET_NUMBER_(type) *va_arg(ap, type*) = negative ? -cur : cur
if (number_signed) {
if (I64_prefix) _SET_NUMBER_(LONGLONG); if (I64_prefix) _SET_NUMBER_(LONGLONG);
else if (l_prefix) _SET_NUMBER_(long int); else if (l_prefix) _SET_NUMBER_(long int);
else if (h_prefix) _SET_NUMBER_(short int); else if (h_prefix) _SET_NUMBER_(short int);
else _SET_NUMBER_(int); else _SET_NUMBER_(int);
} else {
if (negative) {
WARN("Dropping sign in reading a negative number into an unsigned value");
negative = 0;
}
if (I64_prefix) _SET_NUMBER_(ULONGLONG);
else if (l_prefix) _SET_NUMBER_(unsigned long int);
else if (h_prefix)
_SET_NUMBER_(unsigned short int);
else _SET_NUMBER_(unsigned int);
}
} }
} }
break; break;
......
...@@ -52,6 +52,11 @@ static void test_sscanf( void ) ...@@ -52,6 +52,11 @@ static void test_sscanf( void )
ok( sscanf(buffer, "%x", &result) == 1, "sscanf failed\n" ); ok( sscanf(buffer, "%x", &result) == 1, "sscanf failed\n" );
ok( result == 0x51, "sscanf reads %x instead of %x\n", result, 0x51 ); ok( result == 0x51, "sscanf reads %x instead of %x\n", result, 0x51 );
result = 0;
ret = sscanf("-1", "%x", &result);
ok(ret == 1, "Wrong number of arguments read: %d (expected 1)\n", ret);
ok(result == -1, "Read %d, expected -1\n", result);
/* check % followed by any char */ /* check % followed by any char */
strcpy(buffer,"\"%12@"); strcpy(buffer,"\"%12@");
strcpy(format,"%\"%%%d%@"); /* work around gcc format check */ strcpy(format,"%\"%%%d%@"); /* work around gcc format check */
...@@ -93,9 +98,29 @@ static void test_sscanf( void ) ...@@ -93,9 +98,29 @@ static void test_sscanf( void )
ret = sscanf(buffer, "%i", &result); ret = sscanf(buffer, "%i", &result);
ok(ret == 1, "Wrong number of arguments read: %d\n", ret); ok(ret == 1, "Wrong number of arguments read: %d\n", ret);
ok(result == 123, "Wrong number read\n"); ok(result == 123, "Wrong number read\n");
result = 0;
ret = sscanf("-1", "%i", &result);
ok(ret == 1, "Wrong number of arguments read: %d (expected 1)\n", ret);
ok(result == -1, "Read %d, expected -1\n", result);
ret = sscanf(buffer, "%d", &result); ret = sscanf(buffer, "%d", &result);
ok(ret == 1, "Wrong number of arguments read: %d\n", ret); ok(ret == 1, "Wrong number of arguments read: %d\n", ret);
ok(result == 123, "Wrong number read\n"); ok(result == 123, "Wrong number read\n");
result = 0;
ret = sscanf("-1", "%d", &result);
ok(ret == 1, "Wrong number of arguments read: %d (expected 1)\n", ret);
ok(result == -1, "Read %d, expected -1\n", result);
/* %o */
result = 0;
ret = sscanf("-1", "%o", &result);
ok(ret == 1, "Wrong number of arguments read: %d (expected 1)\n", ret);
ok(result == -1, "Read %d, expected -1\n", result);
/* %u */
result = 0;
ret = sscanf("-1", "%u", &result);
ok(ret == 1, "Wrong number of arguments read: %d (expected 1)\n", ret);
ok(result == -1, "Read %d, expected -1\n", result);
/* Check %c */ /* Check %c */
strcpy(buffer,"a"); strcpy(buffer,"a");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment