[PATCH] msvcrt: support I width modifier in *scanf* family

Eric Pouech eric.pouech at gmail.com
Tue Oct 19 11:55:27 CDT 2021


Despite what msdn states, I and I32 are supported width modifiers.

V2:
- better code structure
- added support and tests for I32

v3:
- fix 'test & copy & paste & don't test' error

Signed-off-by: Eric Pouech <eric.pouech at gmail.com>

---
 dlls/msvcrt/scanf.h       |   10 ++++++++--
 dlls/msvcrt/tests/scanf.c |   40 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 48 insertions(+), 2 deletions(-)

diff --git a/dlls/msvcrt/scanf.h b/dlls/msvcrt/scanf.h
index 3ab2efef13d..02284379854 100644
--- a/dlls/msvcrt/scanf.h
+++ b/dlls/msvcrt/scanf.h
@@ -279,13 +279,19 @@ _FUNCTION_ {
 			*(format + 2) == '4') {
 			I64_prefix = 1;
 			format += 2;
+			break;
 		    }
-		    break;
+		    else if (*(format + 1) == '3' &&
+			     *(format + 2) == '2') {
+			format += 2;
+			break;
+		    }
+		    /* fall through */
 #if _MSVCR_VER == 0 || _MSVCR_VER >= 140
                 case 'z':
+#endif
                     if (sizeof(void *) == sizeof(LONGLONG)) I64_prefix = 1;
                     break;
-#endif
 		default:
 		    prefix_finished = 1;
 		}
diff --git a/dlls/msvcrt/tests/scanf.c b/dlls/msvcrt/tests/scanf.c
index e175342796b..a87b3b3d59e 100644
--- a/dlls/msvcrt/tests/scanf.c
+++ b/dlls/msvcrt/tests/scanf.c
@@ -74,6 +74,7 @@ static void test_sscanf( void )
     int hour=21,min=59,sec=20;
     int  number,number_so_far;
     HMODULE hmod = GetModuleHandleA("msvcrt.dll");
+    DWORD_PTR result_ptr;
 
     p_sprintf = (void *)GetProcAddress( hmod, "sprintf" );
     p_sscanf = (void *)GetProcAddress( hmod, "sscanf" );
@@ -264,6 +265,45 @@ static void test_sscanf( void )
     if(ret == 14)
         ok(!strcmp(buffer, buffer1), "got %s, expected %s\n", buffer1, buffer);
 
+    strcpy(buffer,"12345678901234");
+    ret = p_sscanf(buffer, "%I64d", &result64);
+    ok(ret == 1, "Wrong number of arguments read: %d\n", ret);
+    ret = p_sprintf(buffer1, "%I64d", result64);
+    ok(ret==14 || broken(ret==10), "sprintf returned %d\n", ret);
+    if(ret == 14)
+        ok(!strcmp(buffer, buffer1), "got %s, expected %s\n", buffer1, buffer);
+
+    result = 0;
+    strcpy(buffer,"0x123456789");
+    ret = p_sscanf(buffer, "%I32x", &result);
+    ok(ret == 1, "Wrong number of arguments read: %d\n", ret);
+    ok(result == 0x23456789, "got %x, expected 0x23456789\n", result);
+
+    result_ptr = 0;
+    strcpy(buffer,"0x87654321");
+    ret = p_sscanf(buffer, "%Ix", &result_ptr);
+    ok(ret == 1, "Wrong number of arguments read: %d\n", ret);
+    ret = p_sprintf(buffer1, "%#Ix", result_ptr);
+    ok(ret==10, "sprintf returned %d\n", ret);
+    if(ret == 10)
+        ok(!strcmp(buffer, buffer1), "got %s, expected %s\n", buffer1, buffer);
+
+    result_ptr = 0;
+    strcpy(buffer,"0x123456789");
+    ret = p_sscanf(buffer, "%Ix", &result_ptr);
+    ok(ret == 1, "Wrong number of arguments read: %d\n", ret);
+    if (sizeof(void*) == sizeof(LONGLONG))
+    {
+        ret = p_sprintf(buffer1, "%#Ix", result_ptr);
+        ok(ret==11, "sprintf returned %d\n", ret);
+        if(ret == 11)
+            ok(!strcmp(buffer, buffer1), "got %s, expected %s\n", buffer1, buffer);
+    }
+    else
+    {
+        ok(result_ptr == 0x23456789, "got %x, expected 0x23456789\n", result);
+    }
+
     /* Check %i according to bug 1878 */
     strcpy(buffer,"123");
     ret = p_sscanf(buffer, "%i", &result);




More information about the wine-devel mailing list