Erich E. Hoover : msvcrt: Fix fscanf return when EOF is immediately after an end of line.

Alexandre Julliard julliard at winehq.org
Tue Oct 22 16:57:01 CDT 2019


Module: wine
Branch: master
Commit: 0a89a699135802b083d142130d3b0ef618485478
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=0a89a699135802b083d142130d3b0ef618485478

Author: Erich E. Hoover <erich.e.hoover at gmail.com>
Date:   Wed Oct 16 16:09:16 2019 -0600

msvcrt: Fix fscanf return when EOF is immediately after an end of line.

Signed-off-by: Erich E. Hoover <erich.e.hoover at gmail.com>
Signed-off-by: Piotr Caban <piotr at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/msvcr90/tests/msvcr90.c | 14 +++++++++++++
 dlls/msvcrt/scanf.h          | 10 +++++++++
 dlls/msvcrt/tests/scanf.c    | 50 +++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 73 insertions(+), 1 deletion(-)

diff --git a/dlls/msvcr90/tests/msvcr90.c b/dlls/msvcr90/tests/msvcr90.c
index 0ba1f1a7b1..050699e485 100644
--- a/dlls/msvcr90/tests/msvcr90.c
+++ b/dlls/msvcr90/tests/msvcr90.c
@@ -135,6 +135,7 @@ static int (__cdecl *p__memicmp)(const char*, const char*, size_t);
 static int (__cdecl *p__memicmp_l)(const char*, const char*, size_t, _locale_t);
 static int (__cdecl *p__vsnwprintf)(wchar_t *buffer,size_t count, const wchar_t *format, __ms_va_list valist);
 static size_t (__cdecl *p___strncnt)(const char *str, size_t count);
+static int (__cdecl *p_swscanf)(const wchar_t *str, const wchar_t* format, ...);
 
 /* make sure we use the correct errno */
 #undef errno
@@ -405,6 +406,7 @@ static BOOL init(void)
     SET(p__memicmp_l, "_memicmp_l");
     SET(p__vsnwprintf, "_vsnwprintf");
     SET(p___strncnt, "__strncnt");
+    SET(p_swscanf, "swscanf");
 
     if (sizeof(void *) == 8)
     {
@@ -1925,6 +1927,17 @@ static void test___strncnt(void)
     }
 }
 
+static void test_swscanf(void)
+{
+
+    wchar_t buffer[100];
+    int ret;
+
+    /* check WEOF */
+    ret = p_swscanf(L" \t\n\n", L"%s", buffer);
+    ok( ret == (short)WEOF, "ret = %d\n", ret );
+}
+
 START_TEST(msvcr90)
 {
     if(!init())
@@ -1963,4 +1976,5 @@ START_TEST(msvcr90)
     test__fpieee_flt();
 #endif
     test___strncnt();
+    test_swscanf();
 }
diff --git a/dlls/msvcrt/scanf.h b/dlls/msvcrt/scanf.h
index 1058a7a911..e2f216110d 100644
--- a/dlls/msvcrt/scanf.h
+++ b/dlls/msvcrt/scanf.h
@@ -487,6 +487,10 @@ _FUNCTION_ {
                         nch = _GETC_(file);
 			if (width>0) width--;
                     }
+                    /* if we have reached the EOF and output nothing then report EOF */
+                    if (nch==_EOF_ && rd==0 && st==0) {
+                        return _EOF_RET;
+                    }
                     /* terminate */
                     if (st && !suppress) *sptr = 0;
                 }
@@ -517,6 +521,12 @@ _FUNCTION_ {
                         nch = _GETC_(file);
 			if (width>0) width--;
                     }
+#if _MSVCR_VER >= 80
+                    /* if we have reached the EOF and output nothing then report EOF */
+                    if (nch==_EOF_ && rd==0 && st==0) {
+                        return _EOF_RET;
+                    }
+#endif
                     /* terminate */
                     if (st && !suppress) *sptr = 0;
                 }
diff --git a/dlls/msvcrt/tests/scanf.c b/dlls/msvcrt/tests/scanf.c
index 6d38e438c8..5db9d43935 100644
--- a/dlls/msvcrt/tests/scanf.c
+++ b/dlls/msvcrt/tests/scanf.c
@@ -22,6 +22,41 @@
 
 #include "wine/test.h"
 
+static void test_fscanf( void )
+{
+    static const char file_name[] = "fscanf.tst";
+    static const char contents[] =
+        "line1\n"
+        "line2 "
+    ;
+    char buf[1024];
+    FILE *fp;
+    int ret;
+
+    fp = fopen(file_name, "wb");
+    ok(fp != NULL, "fp = %p\n", fp);
+    if(!fp) {
+        skip("failed to create temporary test file\n");
+        return;
+    }
+
+    ret = fprintf(fp, contents);
+    fclose(fp);
+
+    fp = fopen(file_name, "rb");
+    ret = fscanf(fp, "%s", buf);
+    ok(ret == 1, "ret = %d\n", ret);
+    ok(strcmp(buf, "line1") == 0, "buf = %s\n", buf);
+    ret = fscanf(fp, "%s", buf);
+    ok(ret == 1, "ret = %d\n", ret);
+    ok(strcmp(buf, "line2") == 0, "buf = %s\n", buf);
+    ret = fscanf(fp, "%s", buf);
+    ok(ret == EOF, "ret = %d\n", ret);
+    fclose(fp);
+
+    unlink(file_name);
+}
+
 static void test_sscanf( void )
 {
     /* use function pointers to bypass gcc builtin */
@@ -48,6 +83,14 @@ static void test_sscanf( void )
     ret = p_sscanf(buffer, "%d", &result);
     ok( ret == EOF,"sscanf returns %x instead of %x\n", ret, EOF );
 
+    ret = p_sscanf(" \t\n\n", "%s", buffer);
+    ok( ret == EOF, "ret = %d\n", ret );
+
+    buffer1[0] = 'a';
+    ret = p_sscanf("test\n", "%s%c", buffer, buffer1);
+    ok( ret == 2, "ret = %d\n", ret );
+    ok( buffer1[0] == '\n', "buffer1[0] = %d\n", buffer1[0] );
+
     /* check %p */
     ok( p_sscanf("000000000046F170", "%p", &ptr) == 1, "sscanf failed\n"  );
     ok( ptr == (void *)0x46F170,"sscanf reads %p instead of %x\n", ptr, 0x46F170 );
@@ -313,7 +356,7 @@ static void test_sscanf_s(void)
 
 static void test_swscanf( void )
 {
-    wchar_t buffer[100];
+    wchar_t buffer[100], results[100];
     int result, ret;
     static const WCHAR formatd[] = {'%','d',0};
     const WCHAR format2[] = {'a',0x1234,'%',0x1234,'%','c',0};
@@ -328,6 +371,10 @@ static void test_swscanf( void )
     ok( ret == (short)WEOF || broken(ret == 0),
         "swscanf returns %x instead of %x\n", ret, WEOF );
 
+    ret = swscanf(L" \t\n\n", L"%s", results);
+    /* sscanf returns EOF under this case, but swscanf does not return WEOF */
+    ok( ret == 0, "ret = %d\n", ret );
+
     buffer[0] = 'a';
     buffer[1] = 0x1234;
     buffer[2] = 0x1234;
@@ -372,6 +419,7 @@ static void test_swscanf_s(void)
 
 START_TEST(scanf)
 {
+    test_fscanf();
     test_sscanf();
     test_sscanf_s();
     test_swscanf();




More information about the wine-cvs mailing list