Merge "Loosen resource file verification" into pi-dev

This commit is contained in:
TreeHugger Robot
2018-07-16 20:57:43 +00:00
committed by Android (Google) Code Review
3 changed files with 38 additions and 4 deletions

View File

@@ -32,11 +32,30 @@ Chunk ChunkIterator::Next() {
if (len_ != 0) { if (len_ != 0) {
// Prepare the next chunk. // Prepare the next chunk.
VerifyNextChunk(); if (VerifyNextChunkNonFatal()) {
VerifyNextChunk();
}
} }
return Chunk(this_chunk); return Chunk(this_chunk);
} }
// TODO(b/111401637) remove this and have full resource file verification
// Returns false if there was an error.
bool ChunkIterator::VerifyNextChunkNonFatal() {
if (len_ < sizeof(ResChunk_header)) {
last_error_ = "not enough space for header";
last_error_was_fatal_ = false;
return false;
}
const size_t size = dtohl(next_chunk_->size);
if (size > len_) {
last_error_ = "chunk size is bigger than given data";
last_error_was_fatal_ = false;
return false;
}
return true;
}
// Returns false if there was an error. // Returns false if there was an error.
bool ChunkIterator::VerifyNextChunk() { bool ChunkIterator::VerifyNextChunk() {
const uintptr_t header_start = reinterpret_cast<uintptr_t>(next_chunk_); const uintptr_t header_start = reinterpret_cast<uintptr_t>(next_chunk_);

View File

@@ -560,7 +560,9 @@ std::unique_ptr<const LoadedPackage> LoadedPackage::Load(const Chunk& chunk,
if (iter.HadError()) { if (iter.HadError()) {
LOG(ERROR) << iter.GetLastError(); LOG(ERROR) << iter.GetLastError();
return {}; if (iter.HadFatalError()) {
return {};
}
} }
// Flatten and construct the TypeSpecs. // Flatten and construct the TypeSpecs.
@@ -641,7 +643,9 @@ bool LoadedArsc::LoadTable(const Chunk& chunk, const LoadedIdmap* loaded_idmap,
if (iter.HadError()) { if (iter.HadError()) {
LOG(ERROR) << iter.GetLastError(); LOG(ERROR) << iter.GetLastError();
return false; if (iter.HadFatalError()) {
return false;
}
} }
return true; return true;
} }
@@ -673,7 +677,9 @@ std::unique_ptr<const LoadedArsc> LoadedArsc::Load(const StringPiece& data,
if (iter.HadError()) { if (iter.HadError()) {
LOG(ERROR) << iter.GetLastError(); LOG(ERROR) << iter.GetLastError();
return {}; if (iter.HadFatalError()) {
return {};
}
} }
// Need to force a move for mingw32. // Need to force a move for mingw32.

View File

@@ -94,18 +94,27 @@ class ChunkIterator {
Chunk Next(); Chunk Next();
inline bool HasNext() const { return !HadError() && len_ != 0; }; inline bool HasNext() const { return !HadError() && len_ != 0; };
// Returns whether there was an error and processing should stop
inline bool HadError() const { return last_error_ != nullptr; } inline bool HadError() const { return last_error_ != nullptr; }
inline std::string GetLastError() const { return last_error_; } inline std::string GetLastError() const { return last_error_; }
// Returns whether there was an error and processing should stop. For legacy purposes,
// some errors are considered "non fatal". Fatal errors stop processing new chunks and
// throw away any chunks already processed. Non fatal errors also stop processing new
// chunks, but, will retain and use any valid chunks already processed.
inline bool HadFatalError() const { return HadError() && last_error_was_fatal_; }
private: private:
DISALLOW_COPY_AND_ASSIGN(ChunkIterator); DISALLOW_COPY_AND_ASSIGN(ChunkIterator);
// Returns false if there was an error. // Returns false if there was an error.
bool VerifyNextChunk(); bool VerifyNextChunk();
// Returns false if there was an error. For legacy purposes.
bool VerifyNextChunkNonFatal();
const ResChunk_header* next_chunk_; const ResChunk_header* next_chunk_;
size_t len_; size_t len_;
const char* last_error_; const char* last_error_;
bool last_error_was_fatal_ = true;
}; };
} // namespace android } // namespace android