diff options
author | sugoi@google.com <sugoi@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-11-04 16:18:15 +0000 |
---|---|---|
committer | sugoi@google.com <sugoi@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-11-04 16:18:15 +0000 |
commit | 305f78e8c18a26b7ead11758d6a4fa0519932cca (patch) | |
tree | 84ce0e834d8c52393c0b52190fa0583168304ffd /include | |
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')
-rw-r--r-- | include/core/SkMatrix.h | 13 | ||||
-rw-r--r-- | include/core/SkPath.h | 15 | ||||
-rw-r--r-- | include/core/SkRRect.h | 16 | ||||
-rw-r--r-- | include/core/SkReader32.h | 32 | ||||
-rw-r--r-- | include/core/SkRegion.h | 13 |
5 files changed, 55 insertions, 34 deletions
diff --git a/include/core/SkMatrix.h b/include/core/SkMatrix.h index b6856d103c..dad5ff92f5 100644 --- a/include/core/SkMatrix.h +++ b/include/core/SkMatrix.h @@ -559,9 +559,16 @@ public: kMaxFlattenSize = 9 * sizeof(SkScalar) + sizeof(uint32_t) }; // return the number of bytes written, whether or not buffer is null - uint32_t writeToMemory(void* buffer) const; - // return the number of bytes read - uint32_t readFromMemory(const void* buffer); + size_t writeToMemory(void* buffer) const; + /** + * Reads data from the buffer parameter + * + * @param buffer Memory to read from + * @param length Amount of memory available in the buffer + * @return number of bytes read (must be a multiple of 4) or + * 0 if there was not enough memory available + */ + size_t readFromMemory(const void* buffer, size_t length); SkDEVCODE(void dump() const;) SkDEVCODE(void toString(SkString*) const;) diff --git a/include/core/SkPath.h b/include/core/SkPath.h index 785eb7793f..2b111fe505 100644 --- a/include/core/SkPath.h +++ b/include/core/SkPath.h @@ -899,16 +899,19 @@ public: void dump() const; /** - * Write the region to the buffer, and return the number of bytes written. + * Write the path to the buffer, and return the number of bytes written. * If buffer is NULL, it still returns the number of bytes. */ - uint32_t writeToMemory(void* buffer) const; - + size_t writeToMemory(void* buffer) const; /** - * Initialized the region from the buffer, returning the number - * of bytes actually read. + * Initializes the path from the buffer + * + * @param buffer Memory to read from + * @param length Amount of memory available in the buffer + * @return number of bytes read (must be a multiple of 4) or + * 0 if there was not enough memory available */ - uint32_t readFromMemory(const void* buffer); + size_t readFromMemory(const void* buffer, size_t length); /** Returns a non-zero, globally unique value corresponding to the set of verbs and points in the path (but not the fill type [except on Android skbug.com/1762]). diff --git a/include/core/SkRRect.h b/include/core/SkRRect.h index 402e6c6c4b..3c6386f1c6 100644 --- a/include/core/SkRRect.h +++ b/include/core/SkRRect.h @@ -244,14 +244,20 @@ public: * write kSizeInMemory bytes, and that value is guaranteed to always be * a multiple of 4. Return kSizeInMemory. */ - uint32_t writeToMemory(void* buffer) const; + size_t writeToMemory(void* buffer) const; /** - * Read the rrect from the specified buffer. This is guaranteed to always - * read kSizeInMemory bytes, and that value is guaranteed to always be - * a multiple of 4. Return kSizeInMemory. + * Reads the rrect from the specified buffer + * + * If the specified buffer is large enough, this will read kSizeInMemory bytes, + * and that value is guaranteed to always be a multiple of 4. + * + * @param buffer Memory to read from + * @param length Amount of memory available in the buffer + * @return number of bytes read (must be a multiple of 4) or + * 0 if there was not enough memory available */ - uint32_t readFromMemory(const void* buffer); + size_t readFromMemory(const void* buffer, size_t length); private: SkRect fRect; 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 diff --git a/include/core/SkRegion.h b/include/core/SkRegion.h index a088d54620..c9aa8daf88 100644 --- a/include/core/SkRegion.h +++ b/include/core/SkRegion.h @@ -361,13 +361,16 @@ public: * Write the region to the buffer, and return the number of bytes written. * If buffer is NULL, it still returns the number of bytes. */ - uint32_t writeToMemory(void* buffer) const; - + size_t writeToMemory(void* buffer) const; /** - * Initialized the region from the buffer, returning the number - * of bytes actually read. + * Initializes the region from the buffer + * + * @param buffer Memory to read from + * @param length Amount of memory available in the buffer + * @return number of bytes read (must be a multiple of 4) or + * 0 if there was not enough memory available */ - uint32_t readFromMemory(const void* buffer); + size_t readFromMemory(const void* buffer, size_t length); /** * Returns a reference to a global empty region. Just a convenience for |