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