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

This commit is contained in:
Dan Kegel 2008-12-15 21:47:56 -08:00 committed by Alexandre Julliard
parent 902443579f
commit 72ffe1da67
2 changed files with 41 additions and 0 deletions

View File

@ -2597,6 +2597,7 @@ MSVCRT_size_t CDECL MSVCRT_fread(void *ptr, MSVCRT_size_t size, MSVCRT_size_t nm
/* first buffered data */ /* first buffered data */
if(file->_cnt>0) { if(file->_cnt>0) {
while (file->_cnt>0 && rcnt > 0) {
int pcnt= (rcnt>file->_cnt)? file->_cnt:rcnt; int pcnt= (rcnt>file->_cnt)? file->_cnt:rcnt;
memcpy(ptr, file->_ptr, pcnt); memcpy(ptr, file->_ptr, pcnt);
file->_cnt -= 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 ; read += pcnt ;
rcnt -= pcnt ; rcnt -= pcnt ;
ptr = (char*)ptr + pcnt; ptr = (char*)ptr + pcnt;
}
} else if(!(file->_flag & MSVCRT__IOREAD )) { } else if(!(file->_flag & MSVCRT__IOREAD )) {
if(file->_flag & MSVCRT__IORW) { if(file->_flag & MSVCRT__IORW) {
file->_flag |= MSVCRT__IOREAD; file->_flag |= MSVCRT__IOREAD;

View File

@ -306,6 +306,44 @@ static void test_asciimode(void)
unlink("ascii.tst"); 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 ) static WCHAR* AtoW( const char* p )
{ {
WCHAR* buffer; WCHAR* buffer;
@ -1113,6 +1151,7 @@ START_TEST(file)
test_fopen_fclose_fcloseall(); test_fopen_fclose_fcloseall();
test_fileops(); test_fileops();
test_asciimode(); test_asciimode();
test_asciimode2();
test_readmode(FALSE); /* binary mode */ test_readmode(FALSE); /* binary mode */
test_readmode(TRUE); /* ascii mode */ test_readmode(TRUE); /* ascii mode */
test_fgetc(); test_fgetc();