Merge "Fix fread returning bad data."

This commit is contained in:
Christopher Ferris 2015-02-28 18:31:00 +00:00 committed by Gerrit Code Review
commit 2ae7c1e336
2 changed files with 44 additions and 0 deletions

View file

@ -102,6 +102,12 @@ fread(void *buf, size_t size, size_t count, FILE *fp)
* avoid copying it through the buffer?
*/
if (total > (size_t) fp->_bf._size) {
/*
* Make sure that fseek doesn't think it can
* reuse the buffer since we are going to read
* directly from the file descriptor.
*/
fp->_flags |= __SMOD;
break;
}

View file

@ -965,3 +965,41 @@ TEST(stdio, fwrite_after_fread_slow_path) {
TEST(stdio, fwrite_after_fread_fast_path) {
test_fwrite_after_fread(64*1024);
}
// http://b/19172514
TEST(stdio, fread_after_fseek) {
TemporaryFile tf;
FILE* fp = fopen(tf.filename, "w+");
ASSERT_TRUE(fp != nullptr);
char file_data[12288];
for (size_t i = 0; i < 12288; i++) {
file_data[i] = i;
}
ASSERT_EQ(12288U, fwrite(file_data, 1, 12288, fp));
fclose(fp);
fp = fopen(tf.filename, "r");
ASSERT_TRUE(fp != nullptr);
char buffer[8192];
size_t cur_location = 0;
// Small read to populate internal buffer.
ASSERT_EQ(100U, fread(buffer, 1, 100, fp));
ASSERT_EQ(memcmp(file_data, buffer, 100), 0);
cur_location = static_cast<size_t>(ftell(fp));
// Large read to force reading into the user supplied buffer and bypassing
// the internal buffer.
ASSERT_EQ(8192U, fread(buffer, 1, 8192, fp));
ASSERT_EQ(memcmp(file_data+cur_location, buffer, 8192), 0);
// Small backwards seek to verify fseek does not reuse the internal buffer.
ASSERT_EQ(0, fseek(fp, -22, SEEK_CUR));
cur_location = static_cast<size_t>(ftell(fp));
ASSERT_EQ(22U, fread(buffer, 1, 22, fp));
ASSERT_EQ(memcmp(file_data+cur_location, buffer, 22), 0);
fclose(fp);
}