Dan Kegel : msvcrt: fread: Exhaust buffered data before using unbuffered data in ascii mode.

Alexandre Julliard julliard at winehq.org
Tue Dec 16 08:40:44 CST 2008


Module: wine
Branch: master
Commit: 72ffe1da676b673f6caa84f1859a601f6935dd99
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=72ffe1da676b673f6caa84f1859a601f6935dd99

Author: Dan Kegel <dank at kegel.com>
Date:   Mon Dec 15 21:47:56 2008 -0800

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(+), 0 deletions(-)

diff --git a/dlls/msvcrt/file.c b/dlls/msvcrt/file.c
index 76c4ea7..055ccac 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 9642d75..6f3fc85 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();




More information about the wine-cvs mailing list