| Index: net/disk_cache/simple/simple_synchronous_entry.cc
|
| diff --git a/net/disk_cache/simple/simple_synchronous_entry.cc b/net/disk_cache/simple/simple_synchronous_entry.cc
|
| index ea83472455e9170d7f0bb178fa6ee934bb09d6fd..1b5615da57e4045c3223a6e515435042651b1b52 100644
|
| --- a/net/disk_cache/simple/simple_synchronous_entry.cc
|
| +++ b/net/disk_cache/simple/simple_synchronous_entry.cc
|
| @@ -693,16 +693,25 @@ int SimpleSynchronousEntry::CheckEOFRecord(int index,
|
| const SimpleEntryStat& entry_stat,
|
| uint32_t expected_crc32) const {
|
| DCHECK(initialized_);
|
| +
|
| uint32_t crc32;
|
| bool has_crc32;
|
| - bool has_key_sha256;
|
| - int32_t stream_size;
|
| - int rv = GetEOFRecordData(index, entry_stat, &has_crc32, &has_key_sha256,
|
| - &crc32, &stream_size);
|
| - if (rv != net::OK) {
|
| - Doom();
|
| - return rv;
|
| + if (index == 1) {
|
| + DCHECK(read_stream1_crc32_);
|
| + crc32 = stream1_crc32_;
|
| + has_crc32 = has_stream1_crc32_;
|
| + } else {
|
| + DCHECK_EQ(2, index);
|
| + bool has_key_sha256;
|
| + int32_t stream_size;
|
| + int rv = GetEOFRecordData(index, entry_stat, &has_crc32, &has_key_sha256,
|
| + &crc32, &stream_size);
|
| + if (rv != net::OK) {
|
| + Doom();
|
| + return rv;
|
| + }
|
| }
|
| +
|
| if (has_crc32 && crc32 != expected_crc32) {
|
| DVLOG(1) << "EOF record had bad crc.";
|
| RecordCheckEOFResult(cache_type_, CHECK_EOF_RESULT_CRC_MISMATCH);
|
| @@ -822,7 +831,8 @@ SimpleSynchronousEntry::SimpleSynchronousEntry(net::CacheType cache_type,
|
| had_index_(had_index),
|
| key_(key),
|
| have_open_files_(false),
|
| - initialized_(false) {
|
| + initialized_(false),
|
| + read_stream1_crc32_(false) {
|
| for (int i = 0; i < kSimpleEntryFileCount; ++i)
|
| empty_file_omitted_[i] = false;
|
| }
|
| @@ -1232,18 +1242,47 @@ int SimpleSynchronousEntry::ReadAndValidateStream0(
|
| out_entry_stat->set_data_size(0, stream_0_size);
|
| out_entry_stat->set_data_size(1, total_size - stream_0_size);
|
|
|
| - // Put stream 0 data in memory.
|
| + // Put stream 0 data in memory, as well as sha256 for it and the footer
|
| + // of stream 1, so we can get its CRC conveniently in one go
|
| +
|
| *stream_0_data = new net::GrowableIOBuffer();
|
| - (*stream_0_data)->SetCapacity(stream_0_size + sizeof(net::SHA256HashValue));
|
| - int file_offset = out_entry_stat->GetOffsetInFile(key_.size(), 0, 0);
|
| - int read_size = stream_0_size;
|
| + (*stream_0_data)
|
| + ->SetCapacity(sizeof(SimpleFileEOF) + stream_0_size +
|
| + sizeof(net::SHA256HashValue));
|
| + int file_offset = out_entry_stat->GetOffsetInFile(key_.size(), 0, 0) -
|
| + sizeof(SimpleFileEOF);
|
| + if (file_offset < 0)
|
| + return net::ERR_FAILED;
|
| +
|
| + int read_size = stream_0_size + sizeof(SimpleFileEOF);
|
| if (has_key_sha256)
|
| read_size += sizeof(net::SHA256HashValue);
|
| if (files_[0].Read(file_offset, (*stream_0_data)->data(), read_size) !=
|
| read_size)
|
| return net::ERR_FAILED;
|
|
|
| - // Check the CRC32.
|
| + // Extract the EOF record for stream 1, and skip over it in the buffer.
|
| + SimpleFileEOF stream1_eof;
|
| + memcpy(&stream1_eof, (*stream_0_data)->data(), sizeof(SimpleFileEOF));
|
| + (*stream_0_data)->set_offset(sizeof(SimpleFileEOF));
|
| +
|
| + // Verify it, exract CRC.
|
| + // ### refactor this stuff to not be crude copy and paste
|
| + if (stream1_eof.final_magic_number != kSimpleFinalMagicNumber) {
|
| + RecordCheckEOFResult(cache_type_, CHECK_EOF_RESULT_MAGIC_NUMBER_MISMATCH);
|
| + DVLOG(1) << "EOF record had bad magic number.";
|
| + return net::ERR_CACHE_CHECKSUM_READ_FAILURE;
|
| + }
|
| +
|
| + if (!base::IsValueInRangeForNumericType<int32_t>(stream1_eof.stream_size))
|
| + return net::ERR_FAILED;
|
| +
|
| + read_stream1_crc32_ = true;
|
| + has_stream1_crc32_ = (stream1_eof.flags & SimpleFileEOF::FLAG_HAS_CRC32) ==
|
| + SimpleFileEOF::FLAG_HAS_CRC32;
|
| + stream1_crc32_ = stream1_eof.data_crc32;
|
| +
|
| + // Check the CRC32 for stream 0
|
| uint32_t expected_crc32 =
|
| stream_0_size == 0
|
| ? crc32(0, Z_NULL, 0)
|
|
|