From 72ffe1da676b673f6caa84f1859a601f6935dd99 Mon Sep 17 00:00:00 2001 From: Dan Kegel Date: Mon, 15 Dec 2008 21:47:56 -0800 Subject: [PATCH] msvcrt: fread: Exhaust buffered data before using unbuffered data in ascii mode. --- dlls/msvcrt/file.c | 2 ++ dlls/msvcrt/tests/file.c | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/dlls/msvcrt/file.c b/dlls/msvcrt/file.c index 76c4ea7bdff..055ccac7e46 100644 --- a/dlls/msvcrt/file.c +++ b/dlls/msvcrt/file.c @@ -2597,6 +2597,7 @@ MSVCRT_size_t CDECL MSVCRT_fread(void *ptr, MSVCRT_size_t size, MSVCRT_size_t nm /* first buffered data */ if(file->_cnt>0) { + while (file->_cnt>0 && rcnt > 0) { int pcnt= (rcnt>file->_cnt)? file->_cnt:rcnt; memcpy(ptr, file->_ptr, pcnt); file->_cnt -= pcnt; @@ -2606,6 +2607,7 @@ MSVCRT_size_t CDECL MSVCRT_fread(void *ptr, MSVCRT_size_t size, MSVCRT_size_t nm read += pcnt ; rcnt -= pcnt ; ptr = (char*)ptr + pcnt; + } } else if(!(file->_flag & MSVCRT__IOREAD )) { if(file->_flag & MSVCRT__IORW) { file->_flag |= MSVCRT__IOREAD; diff --git a/dlls/msvcrt/tests/file.c b/dlls/msvcrt/tests/file.c index 9642d755fcd..6f3fc857f1b 100644 --- a/dlls/msvcrt/tests/file.c +++ b/dlls/msvcrt/tests/file.c @@ -306,6 +306,44 @@ static void test_asciimode(void) unlink("ascii.tst"); } +static void test_asciimode2(void) +{ + /* Error sequence from one app was getchar followed by small fread + * with one \r removed had last byte of buffer filled with + * next byte of *unbuffered* data rather than next byte from buffer + * Test case is a short string of one byte followed by a newline + * followed by filler to fill out the sector, then a sector of + * some different byte. + */ + + FILE *fp; + char ibuf[4]; + int i; + static const char obuf[] = +"00\n\ +000000000000000000000000000000000000000000000000000000000000000000000000000000\n\ +000000000000000000000000000000000000000000000000000000000000000000000000000000\n\ +000000000000000000000000000000000000000000000000000000000000000000000000000000\n\ +000000000000000000000000000000000000000000000000000000000000000000000000000000\n\ +000000000000000000000000000000000000000000000000000000000000000000000000000000\n\ +000000000000000000000000000000000000000000000000000000000000000000000000000000\n\ +000000000000000000\n\ +1111111111111111111"; + + fp = fopen("ascii2.tst", "wt"); + fwrite(obuf, 1, sizeof(obuf), fp); + fclose(fp); + + fp = fopen("ascii2.tst", "rt"); + ok(getc(fp) == '0', "first char not 0"); + memset(ibuf, 0, sizeof(ibuf)); + i = fread(ibuf, 1, sizeof(ibuf), fp); + ok(i == sizeof(ibuf), "fread i %d != sizeof(ibuf) %d\n", i, sizeof(ibuf)); + ok(0 == strncmp(ibuf, obuf+1, sizeof(ibuf)), "ibuf != obuf\n"); + fclose(fp); + unlink("ascii2.tst"); +} + static WCHAR* AtoW( const char* p ) { WCHAR* buffer; @@ -1113,6 +1151,7 @@ START_TEST(file) test_fopen_fclose_fcloseall(); test_fileops(); test_asciimode(); + test_asciimode2(); test_readmode(FALSE); /* binary mode */ test_readmode(TRUE); /* ascii mode */ test_fgetc();