H. Verbeet : msvcrt:
Fix reading of signed numbers with unsigned read types in scanf.
Alexandre Julliard
julliard at wine.codeweavers.com
Mon Mar 27 05:29:02 CST 2006
Module: wine
Branch: refs/heads/master
Commit: 8c29b7dc8ba584fb72cc12d9f405a1920aea95e8
URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=8c29b7dc8ba584fb72cc12d9f405a1920aea95e8
Author: H. Verbeet <hverbeet at gmail.com>
Date: Sun Mar 26 04:10:28 2006 +0200
msvcrt: Fix reading of signed numbers with unsigned read types in scanf.
---
dlls/msvcrt/scanf.h | 35 +++++++++++------------------------
dlls/msvcrt/tests/scanf.c | 25 +++++++++++++++++++++++++
2 files changed, 36 insertions(+), 24 deletions(-)
diff --git a/dlls/msvcrt/scanf.h b/dlls/msvcrt/scanf.h
index 4c27c68..ad3245d 100644
--- a/dlls/msvcrt/scanf.h
+++ b/dlls/msvcrt/scanf.h
@@ -114,7 +114,7 @@ _FUNCTION_ {
* the form %[*][width][{h | l | I64 | L}]type */
else if (*format == '%') {
int st = 0; int suppress = 0; int width = 0;
- int base, number_signed;
+ int base;
int h_prefix = 0;
int l_prefix = 0;
int L_prefix = 0;
@@ -157,19 +157,19 @@ _FUNCTION_ {
switch(*format) {
case 'x':
case 'X': /* hexadecimal integer. */
- base = 16; number_signed = 0;
+ base = 16;
goto number;
case 'o': /* octal integer */
- base = 8; number_signed = 0;
+ base = 8;
goto number;
case 'u': /* unsigned decimal integer */
- base = 10; number_signed = 0;
+ base = 10;
goto number;
case 'd': /* signed decimal integer */
- base = 10; number_signed = 1;
+ base = 10;
goto number;
case 'i': /* generic integer */
- base = 10; number_signed = 1;
+ base = 10;
number: {
/* read an integer */
ULONGLONG cur = 0;
@@ -179,8 +179,7 @@ _FUNCTION_ {
while ((nch!=_EOF_) && _ISSPACE_(nch))
nch = _GETC_(file);
/* get sign */
- if (number_signed && (nch == '-' ||
- nch == '+')) {
+ if (nch == '-' || nch == '+') {
negative = (nch=='-');
nch = _GETC_(file);
if (width>0) width--;
@@ -225,22 +224,10 @@ _FUNCTION_ {
st = 1;
if (!suppress) {
#define _SET_NUMBER_(type) *va_arg(ap, type*) = negative ? -cur : cur
- if (number_signed) {
- if (I64_prefix) _SET_NUMBER_(LONGLONG);
- else if (l_prefix) _SET_NUMBER_(long int);
- else if (h_prefix) _SET_NUMBER_(short 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);
- }
+ if (I64_prefix) _SET_NUMBER_(LONGLONG);
+ else if (l_prefix) _SET_NUMBER_(long int);
+ else if (h_prefix) _SET_NUMBER_(short int);
+ else _SET_NUMBER_(int);
}
}
break;
diff --git a/dlls/msvcrt/tests/scanf.c b/dlls/msvcrt/tests/scanf.c
index 2482825..d90a3bd 100644
--- a/dlls/msvcrt/tests/scanf.c
+++ b/dlls/msvcrt/tests/scanf.c
@@ -52,6 +52,11 @@ static void test_sscanf( void )
ok( sscanf(buffer, "%x", &result) == 1, "sscanf failed\n" );
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 */
strcpy(buffer,"\"%12@");
strcpy(format,"%\"%%%d%@"); /* work around gcc format check */
@@ -93,9 +98,29 @@ static void test_sscanf( void )
ret = sscanf(buffer, "%i", &result);
ok(ret == 1, "Wrong number of arguments read: %d\n", ret);
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);
ok(ret == 1, "Wrong number of arguments read: %d\n", ret);
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 */
strcpy(buffer,"a");
More information about the wine-cvs
mailing list