From 0a89a699135802b083d142130d3b0ef618485478 Mon Sep 17 00:00:00 2001 From: "Erich E. Hoover" Date: Wed, 16 Oct 2019 16:09:16 -0600 Subject: [PATCH] msvcrt: Fix fscanf return when EOF is immediately after an end of line. Signed-off-by: Erich E. Hoover Signed-off-by: Piotr Caban Signed-off-by: Alexandre Julliard --- 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 0ba1f1a7b18..050699e4857 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 1058a7a911a..e2f216110d3 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 6d38e438c8c..5db9d439351 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(); -- 2.11.4.GIT