diff options
author | 2013-11-04 16:18:15 +0000 | |
---|---|---|
committer | 2013-11-04 16:18:15 +0000 | |
commit | 305f78e8c18a26b7ead11758d6a4fa0519932cca (patch) | |
tree | 84ce0e834d8c52393c0b52190fa0583168304ffd /include/core/SkReader32.h | |
parent | fe2faa8b16e2a607543c5b30637e7da54012e169 (diff) |
Checking structure sizes before reading them from memory to avoid overflowing the buffer's stream.
BUG=
R=reed@google.com
Review URL: https://codereview.chromium.org/41253002
git-svn-id: http://skia.googlecode.com/svn/trunk@12114 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'include/core/SkReader32.h')
-rw-r--r-- | include/core/SkReader32.h | 32 |
1 files changed, 17 insertions, 15 deletions
diff --git a/include/core/SkReader32.h b/include/core/SkReader32.h index 7a8d22a80c..40ae12ce23 100644 --- a/include/core/SkReader32.h +++ b/include/core/SkReader32.h @@ -106,27 +106,20 @@ public: int32_t readS32() { return this->readInt(); } uint32_t readU32() { return this->readInt(); } - void readPath(SkPath* path) { - size_t size = path->readFromMemory(this->peek()); - SkASSERT(SkAlign4(size) == size); - (void)this->skip(size); + bool readPath(SkPath* path) { + return readObjectFromMemory(path); } - void readMatrix(SkMatrix* matrix) { - size_t size = matrix->readFromMemory(this->peek()); - SkASSERT(SkAlign4(size) == size); - (void)this->skip(size); + bool readMatrix(SkMatrix* matrix) { + return readObjectFromMemory(matrix); } - SkRRect* readRRect(SkRRect* rrect) { - rrect->readFromMemory(this->skip(SkRRect::kSizeInMemory)); - return rrect; + bool readRRect(SkRRect* rrect) { + return readObjectFromMemory(rrect); } - void readRegion(SkRegion* rgn) { - size_t size = rgn->readFromMemory(this->peek()); - SkASSERT(SkAlign4(size) == size); - (void)this->skip(size); + bool readRegion(SkRegion* rgn) { + return readObjectFromMemory(rgn); } /** @@ -143,6 +136,15 @@ public: size_t readIntoString(SkString* copy); private: + template <typename T> bool readObjectFromMemory(T* obj) { + size_t size = obj->readFromMemory(this->peek(), this->available()); + // If readFromMemory() fails (which means that available() was too small), it returns 0 + bool success = (size > 0) && (size <= this->available()) && (SkAlign4(size) == size); + // In case of failure, we want to skip to the end + (void)this->skip(success ? size : this->available()); + return success; + } + // these are always 4-byte aligned const char* fCurr; // current position within buffer const char* fStop; // end of buffer |