| 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..a2a335681a50fb72d5161ca2c72066628f49550d 100644
|
| --- a/chrome/utility/safe_browsing/mac/udif.cc
|
| +++ b/chrome/utility/safe_browsing/mac/udif.cc
|
| @@ -348,13 +348,57 @@ UDIFParser::UDIFParser(ReadStream* stream)
|
| : stream_(stream),
|
| partition_names_(),
|
| blocks_(),
|
| - block_size_(kSectorSize) {
|
| -}
|
| + block_size_(kSectorSize),
|
| + trailer_successfully_parsed_(false) {}
|
|
|
| UDIFParser::~UDIFParser() {}
|
|
|
| +bool UDIFParser::ParseTrailer() {
|
| + // Makes sure that trailer is only ever parsed single time during execution of
|
| + // constuctor, so position of ReadStream is not moved after constructor runs.
|
| + if (trailer_successfully_parsed_)
|
| + return true;
|
| +
|
| + 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";
|
| + return false;
|
| + }
|
| +
|
| + trailer_signature_ = trailer.signature;
|
| + plist_length_ = trailer.plist_length;
|
| + plist_offset_ = trailer.plist_offset;
|
| + return true;
|
| +}
|
| +
|
| bool UDIFParser::Parse() {
|
| - if (!ParseBlkx())
|
| + // First parses trailer and then parses blocks.
|
| + trailer_successfully_parsed_ = ParseTrailer();
|
| + if (!trailer_successfully_parsed_ || !ParseBlkx())
|
| return false;
|
|
|
| return true;
|
| @@ -407,41 +451,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)
|
| + if (!trailer_successfully_parsed_)
|
| 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";
|
| - return false;
|
| - }
|
| -
|
| - std::vector<uint8_t> plist_bytes(trailer.plist_length, 0);
|
| + std::vector<uint8_t> plist_bytes(plist_length_, 0);
|
|
|
| - if (stream_->Seek(trailer.plist_offset, SEEK_SET) == -1)
|
| + if (stream_->Seek(plist_offset_, SEEK_SET) == -1)
|
| return false;
|
|
|
| - if (!stream_->ReadExact(&plist_bytes[0], trailer.plist_length)) {
|
| + if (!stream_->ReadExact(&plist_bytes[0], plist_length_)) {
|
| DLOG(ERROR) << "Failed to read blkx plist data";
|
| return false;
|
| }
|
|
|