Chromium Code Reviews| Index: chrome/utility/safe_browsing/mac/udif.cc |
| diff --git a/chrome/utility/safe_browsing/mac/udif.cc b/chrome/utility/safe_browsing/mac/udif.cc |
| index 0c4be3fa310747ef84226969a5ea536f630e8b6c..acf751fda0afc1df8b4b374be8f7b5af033e148f 100644 |
| --- a/chrome/utility/safe_browsing/mac/udif.cc |
| +++ b/chrome/utility/safe_browsing/mac/udif.cc |
| @@ -348,18 +348,58 @@ UDIFParser::UDIFParser(ReadStream* stream) |
| : stream_(stream), |
| partition_names_(), |
| blocks_(), |
| - block_size_(kSectorSize) { |
| -} |
| + block_size_(kSectorSize), |
| + trailer_(new UDIFResourceFile), |
| + trailer_successfully_parsed_(false) {} |
| UDIFParser::~UDIFParser() {} |
| -bool UDIFParser::Parse() { |
| - if (!ParseBlkx()) |
| +bool UDIFParser::ParseTrailer() { |
| + // Makes sure that trailer is only ever parsed single time during execution of |
| + // constuctor, so position of ReadStream is not moved while parsing blocks. |
| + if (trailer_successfully_parsed_) |
| + return true; |
| + |
| + if (trailer_.get() == nullptr) |
|
Robert Sesek
2017/06/12 20:52:34
This will never happen (Chromium terminates on OOM
mortonm
2017/06/12 21:39:49
I removed the null pointer check, but unless anyon
|
| return false; |
| + off_t trailer_start = stream_->Seek(-sizeof(*trailer_), SEEK_END); |
| + if (trailer_start == -1) |
| + return false; |
| + |
| + if (!stream_->ReadType(trailer_.get())) { |
| + DLOG(ERROR) << "Failed to read UDIFResourceFile"; |
| + return false; |
| + } |
| + ConvertBigEndian(trailer_.get()); |
| + |
| + if (trailer_->signature != trailer_->kSignature) { |
| + DLOG(ERROR) << "blkx signature does not match, is 0x" << std::hex |
| + << trailer_->signature; |
| + return false; |
| + } |
| + if (trailer_->version != trailer_->kVersion) { |
| + DLOG(ERROR) << "blkx version does not match, is " << trailer_->version; |
| + return false; |
| + } |
| + |
| + auto plist_end = base::CheckedNumeric<size_t>(trailer_->plist_offset) + |
| + trailer_->plist_length; |
| + if (!plist_end.IsValid() || |
| + plist_end.ValueOrDie() > base::checked_cast<size_t>(trailer_start)) { |
| + DLOG(ERROR) << "blkx plist extends past UDIF trailer"; |
| + return false; |
| + } |
| + |
| return true; |
| } |
| +bool UDIFParser::Parse() { |
| + // First parses trailer and then parses blocks. |
| + trailer_successfully_parsed_ = ParseTrailer(); |
| + return trailer_successfully_parsed_ && ParseBlkx(); |
| +} |
| + |
| size_t UDIFParser::GetNumberOfPartitions() { |
| return blocks_.size(); |
| } |
| @@ -407,41 +447,15 @@ std::unique_ptr<ReadStream> UDIFParser::GetPartitionReadStream( |
| } |
| bool UDIFParser::ParseBlkx() { |
| - UDIFResourceFile trailer; |
| - off_t trailer_start = stream_->Seek(-sizeof(trailer), SEEK_END); |
| - if (trailer_start == -1) |
| - return false; |
| - |
| - if (!stream_->ReadType(&trailer)) { |
| - DLOG(ERROR) << "Failed to read UDIFResourceFile"; |
| - return false; |
| - } |
| - ConvertBigEndian(&trailer); |
| - |
| - if (trailer.signature != trailer.kSignature) { |
| - DLOG(ERROR) << "blkx signature does not match, is 0x" |
| - << std::hex << trailer.signature; |
| - return false; |
| - } |
| - if (trailer.version != trailer.kVersion) { |
| - DLOG(ERROR) << "blkx version does not match, is " << trailer.version; |
| - return false; |
| - } |
| - |
| - auto plist_end = base::CheckedNumeric<size_t>(trailer.plist_offset) + |
| - trailer.plist_length; |
| - if (!plist_end.IsValid() || |
| - plist_end.ValueOrDie() > base::checked_cast<size_t>(trailer_start)) { |
| - DLOG(ERROR) << "blkx plist extends past UDIF trailer"; |
| + if (!trailer_successfully_parsed_) |
| return false; |
| - } |
| - std::vector<uint8_t> plist_bytes(trailer.plist_length, 0); |
| + std::vector<uint8_t> plist_bytes(trailer_->plist_length, 0); |
| - if (stream_->Seek(trailer.plist_offset, SEEK_SET) == -1) |
| + if (stream_->Seek(trailer_->plist_offset, SEEK_SET) == -1) |
| return false; |
| - if (!stream_->ReadExact(&plist_bytes[0], trailer.plist_length)) { |
| + if (!stream_->ReadExact(&plist_bytes[0], trailer_->plist_length)) { |
| DLOG(ERROR) << "Failed to read blkx plist data"; |
| return false; |
| } |