summaryrefslogtreecommitdiff
path: root/libs/androidfw
diff options
context:
space:
mode:
author Bill Yi <byi@google.com> 2018-10-19 21:19:30 +0000
committer Gerrit Code Review <noreply-gerritcodereview@google.com> 2018-10-19 21:19:30 +0000
commit04d53e26115e6747c4a7f7313d227f2e1839ca3f (patch)
treeb12ca81510b840e0c6982f4e24324e802dc8f2fe /libs/androidfw
parent7fff7e5eff2640fac3729ff4f955f8e37cebf75f (diff)
parent0b537c73f71ef7f7b42ced71c75ec055c0940b11 (diff)
Merge "Merge pi-dr1-dev to aosp-master"
Diffstat (limited to 'libs/androidfw')
-rw-r--r--libs/androidfw/ChunkIterator.cpp21
-rw-r--r--libs/androidfw/LoadedArsc.cpp12
-rw-r--r--libs/androidfw/include/androidfw/Chunk.h9
3 files changed, 38 insertions, 4 deletions
diff --git a/libs/androidfw/ChunkIterator.cpp b/libs/androidfw/ChunkIterator.cpp
index d8adbe5ac85d..8fc321968055 100644
--- a/libs/androidfw/ChunkIterator.cpp
+++ b/libs/androidfw/ChunkIterator.cpp
@@ -32,11 +32,30 @@ Chunk ChunkIterator::Next() {
if (len_ != 0) {
// Prepare the next chunk.
- VerifyNextChunk();
+ if (VerifyNextChunkNonFatal()) {
+ VerifyNextChunk();
+ }
}
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.
bool ChunkIterator::VerifyNextChunk() {
const uintptr_t header_start = reinterpret_cast<uintptr_t>(next_chunk_);
diff --git a/libs/androidfw/LoadedArsc.cpp b/libs/androidfw/LoadedArsc.cpp
index 21f023dc0f05..68d216d286cf 100644
--- a/libs/androidfw/LoadedArsc.cpp
+++ b/libs/androidfw/LoadedArsc.cpp
@@ -594,7 +594,9 @@ std::unique_ptr<const LoadedPackage> LoadedPackage::Load(const Chunk& chunk,
if (iter.HadError()) {
LOG(ERROR) << iter.GetLastError();
- return {};
+ if (iter.HadFatalError()) {
+ return {};
+ }
}
// Flatten and construct the TypeSpecs.
@@ -675,7 +677,9 @@ bool LoadedArsc::LoadTable(const Chunk& chunk, const LoadedIdmap* loaded_idmap,
if (iter.HadError()) {
LOG(ERROR) << iter.GetLastError();
- return false;
+ if (iter.HadFatalError()) {
+ return false;
+ }
}
return true;
}
@@ -707,7 +711,9 @@ std::unique_ptr<const LoadedArsc> LoadedArsc::Load(const StringPiece& data,
if (iter.HadError()) {
LOG(ERROR) << iter.GetLastError();
- return {};
+ if (iter.HadFatalError()) {
+ return {};
+ }
}
// Need to force a move for mingw32.
diff --git a/libs/androidfw/include/androidfw/Chunk.h b/libs/androidfw/include/androidfw/Chunk.h
index 89b588e2b2e9..99a52dc9244e 100644
--- a/libs/androidfw/include/androidfw/Chunk.h
+++ b/libs/androidfw/include/androidfw/Chunk.h
@@ -94,18 +94,27 @@ class ChunkIterator {
Chunk Next();
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 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:
DISALLOW_COPY_AND_ASSIGN(ChunkIterator);
// Returns false if there was an error.
bool VerifyNextChunk();
+ // Returns false if there was an error. For legacy purposes.
+ bool VerifyNextChunkNonFatal();
const ResChunk_header* next_chunk_;
size_t len_;
const char* last_error_;
+ bool last_error_was_fatal_ = true;
};
} // namespace android