diff options
author | 2013-11-04 20:28:23 +0000 | |
---|---|---|
committer | 2013-11-04 20:28:23 +0000 | |
commit | b48a59ae81a35642fe715a5cdd6fd758b652bff3 (patch) | |
tree | 4f901dda30343d1bf1ec06e97abeb8a3f384ed20 /include/core/SkReader32.h | |
parent | ac9d306a92e569e85a7611e9db00943b5b551f1e (diff) |
Checking structure sizes before reading them from memory to avoid overflowing the buffer's stream.
BUG=
R=reed@google.com
Committed: https://code.google.com/p/skia/source/detail?r=12114
Review URL: https://codereview.chromium.org/41253002
git-svn-id: http://skia.googlecode.com/svn/trunk@12119 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 |