Index: src/core/SkSecureReader32.cpp |
diff --git a/src/core/SkSecureReader32.cpp b/src/core/SkSecureReader32.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..e630fcb37776aed2fc10cf2ead43ac62b6a3565c |
--- /dev/null |
+++ b/src/core/SkSecureReader32.cpp |
@@ -0,0 +1,136 @@ |
+/* |
+ * Copyright 2013 Google Inc. |
+ * |
+ * Use of this source code is governed by a BSD-style license that can be |
+ * found in the LICENSE file. |
+ */ |
+ |
+/////////////////////////////////////////////////////////////////////////////// |
+ |
+#include "SkSecureReader32.h" |
+#include "SkString.h" |
+ |
+SkSecureReader32::SkSecureReader32() : fCurr(NULL), fStop(NULL), fBase(NULL), fError(false) { |
+} |
+ |
+SkSecureReader32::SkSecureReader32(const void* data, size_t size) : fError(false) { |
+ this->setMemory(data, size); |
+} |
+ |
+void SkSecureReader32::setMemory(const void* data, size_t size) { |
+ fError |= (!ptr_align_4(data) || (SkAlign4(size) != size)); |
+ SkASSERT(!fError); |
+ |
+ fBase = fCurr = (const char*)data; |
+ fStop = (const char*)data + size; |
+} |
+ |
+uint32_t SkSecureReader32::size() const { |
+ return SkToU32(fStop - fBase); |
+} |
+ |
+uint32_t SkSecureReader32::offset() const { |
+ return SkToU32(fCurr - fBase); |
+} |
+ |
+bool SkSecureReader32::eof() const { |
+ return fCurr >= fStop; |
+} |
+ |
+const void* SkSecureReader32::base() const { |
+ return fBase; |
+} |
+ |
+const void* SkSecureReader32::peek() const { |
+ return fCurr; |
+} |
+ |
+bool SkSecureReader32::isAvailable(uint32_t size) const { |
+ return fCurr + size <= fStop; |
+} |
+ |
+bool SkSecureReader32::readBool() { |
+ return this->readInt() != 0; |
+} |
+ |
+int32_t SkSecureReader32::readInt() { |
+ int32_t value = 0; |
+ size_t inc = sizeof(value); |
+ fError |= !ptr_align_4(fCurr) || !this->isAvailable(inc); |
+ if (!fError) { |
+ value = *(const int32_t*)fCurr; |
+ fCurr += inc; |
+ } |
+ return value; |
+} |
+ |
+SkScalar SkSecureReader32::readScalar() { |
+ SkScalar value = 0; |
+ size_t inc = sizeof(value); |
+ fError |= !ptr_align_4(fCurr) || !this->isAvailable(inc); |
+ if (!fError) { |
+ value = *(const SkScalar*)fCurr; |
+ fCurr += inc; |
+ } |
+ return value; |
+} |
+ |
+const void* SkSecureReader32::skip(size_t size) { |
+ size_t inc = SkAlign4(size); |
+ fError |= !ptr_align_4(fCurr) || !this->isAvailable(inc); |
+ const void* addr = fCurr; |
+ if (!fError) { |
+ fCurr += inc; |
+ } |
+ return addr; |
+} |
+ |
+int32_t SkSecureReader32::readS32() { |
+ return this->readInt(); |
+} |
+ |
+uint32_t SkSecureReader32::readU32() { |
+ return this->readInt(); |
+} |
+ |
+void SkSecureReader32::readPath(SkPath* path) { |
+ size_t size = path->readFromMemory(this->peek()); |
+ fError |= (SkAlign4(size) != size); |
+ if (!fError) { |
+ (void)this->skip(size); |
+ } |
+} |
+ |
+void SkSecureReader32::readMatrix(SkMatrix* matrix) { |
+ size_t size = matrix->readFromMemory(this->peek()); |
+ fError |= (SkAlign4(size) != size); |
+ if (!fError) { |
+ (void)this->skip(size); |
+ } |
+} |
+ |
+void SkSecureReader32::readRegion(SkRegion* rgn) { |
+ size_t size = rgn->readFromMemory(this->peek()); |
+ fError |= (SkAlign4(size) != size); |
+ if (!fError) { |
+ (void)this->skip(size); |
+ } |
+} |
+ |
+/* |
+ * Strings are stored as: length[4-bytes] + string_data + '\0' + pad_to_mul_4 |
+ */ |
+ |
+const char* SkSecureReader32::readString(size_t* outLen) { |
+ size_t len = this->readInt(); |
+ const void* ptr = this->peek(); |
+ |
+ // skip over the string + '\0' and then pad to a multiple of 4 |
+ size_t alignedSize = SkAlign4(len + 1); |
+ this->skip(alignedSize); |
+ |
+ if (outLen) { |
+ *outLen = fError ? 0 : len; |
+ } |
+ return fError ? NULL : (const char*)ptr; |
+} |