Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(86)

Side by Side Diff: src/core/SkValidatingReadBuffer.cpp

Issue 37803002: Adding size parameter to read array functions (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Cleanup Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright 2013 Google Inc. 2 * Copyright 2013 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkBitmap.h" 8 #include "SkBitmap.h"
9 #include "SkErrorInternals.h" 9 #include "SkErrorInternals.h"
10 #include "SkValidatingReadBuffer.h" 10 #include "SkValidatingReadBuffer.h"
11 #include "SkStream.h" 11 #include "SkStream.h"
12 #include "SkTypeface.h" 12 #include "SkTypeface.h"
13 13
14 SkValidatingReadBuffer::SkValidatingReadBuffer(const void* data, size_t size) : 14 SkValidatingReadBuffer::SkValidatingReadBuffer(const void* data, size_t size) :
15 fError(false) { 15 fError(false) {
16 this->setMemory(data, size); 16 this->setMemory(data, size);
17 this->setFlags(SkFlattenableReadBuffer::kValidation_Flag); 17 this->setFlags(SkFlattenableReadBuffer::kValidation_Flag);
18 } 18 }
19 19
20 SkValidatingReadBuffer::~SkValidatingReadBuffer() { 20 SkValidatingReadBuffer::~SkValidatingReadBuffer() {
21 } 21 }
22 22
23 void SkValidatingReadBuffer::setMemory(const void* data, size_t size) { 23 void SkValidatingReadBuffer::setMemory(const void* data, size_t size) {
24 fError = fError || !IsPtrAlign4(data) || (SkAlign4(size) != size); 24 this->validate(IsPtrAlign4(data) && (SkAlign4(size) == size));
25 if (!fError) { 25 if (!fError) {
26 fReader.setMemory(data, size); 26 fReader.setMemory(data, size);
27 } 27 }
28 } 28 }
29 29
30 const void* SkValidatingReadBuffer::skip(size_t size) { 30 const void* SkValidatingReadBuffer::skip(size_t size) {
31 size_t inc = SkAlign4(size); 31 size_t inc = SkAlign4(size);
32 const void* addr = fReader.peek(); 32 const void* addr = fReader.peek();
33 fError = fError || !IsPtrAlign4(addr) || !fReader.isAvailable(inc); 33 this->validate(IsPtrAlign4(addr) && fReader.isAvailable(inc));
34 if (!fError) { 34 if (!fError) {
35 fReader.skip(size); 35 fReader.skip(size);
36 } 36 }
37 return addr; 37 return addr;
38 } 38 }
39 39
40 // All the methods in this file funnel down into either readInt(), readScalar() or skip(), 40 // All the methods in this file funnel down into either readInt(), readScalar() or skip(),
41 // followed by a memcpy. So we've got all our validation in readInt(), readScala r() and skip(); 41 // followed by a memcpy. So we've got all our validation in readInt(), readScala r() and skip();
42 // if they fail they'll return a zero value or skip nothing, respectively, and s et fError to 42 // if they fail they'll return a zero value or skip nothing, respectively, and s et fError to
43 // true, which the caller should check to see if an error occurred during the re ad operation. 43 // true, which the caller should check to see if an error occurred during the re ad operation.
44 44
45 bool SkValidatingReadBuffer::readBool() { 45 bool SkValidatingReadBuffer::readBool() {
46 uint32_t value = this->readInt(); 46 uint32_t value = this->readInt();
47 // Boolean value should be either 0 or 1 47 // Boolean value should be either 0 or 1
48 if (value & ~1) { 48 this->validate(!(value & ~1));
49 fError = true;
50 }
51 return value != 0; 49 return value != 0;
52 } 50 }
53 51
54 SkColor SkValidatingReadBuffer::readColor() { 52 SkColor SkValidatingReadBuffer::readColor() {
55 return this->readInt(); 53 return this->readInt();
56 } 54 }
57 55
58 SkFixed SkValidatingReadBuffer::readFixed() { 56 SkFixed SkValidatingReadBuffer::readFixed() {
59 return this->readInt(); 57 return this->readInt();
60 } 58 }
61 59
62 int32_t SkValidatingReadBuffer::readInt() { 60 int32_t SkValidatingReadBuffer::readInt() {
63 const size_t inc = sizeof(int32_t); 61 const size_t inc = sizeof(int32_t);
64 fError = fError || !IsPtrAlign4(fReader.peek()) || !fReader.isAvailable(inc) ; 62 this->validate(IsPtrAlign4(fReader.peek()) && fReader.isAvailable(inc));
65 return fError ? 0 : fReader.readInt(); 63 return fError ? 0 : fReader.readInt();
66 } 64 }
67 65
68 SkScalar SkValidatingReadBuffer::readScalar() { 66 SkScalar SkValidatingReadBuffer::readScalar() {
69 const size_t inc = sizeof(SkScalar); 67 const size_t inc = sizeof(SkScalar);
70 fError = fError || !IsPtrAlign4(fReader.peek()) || !fReader.isAvailable(inc) ; 68 this->validate(IsPtrAlign4(fReader.peek()) && fReader.isAvailable(inc));
71 return fError ? 0 : fReader.readScalar(); 69 return fError ? 0 : fReader.readScalar();
72 } 70 }
73 71
74 uint32_t SkValidatingReadBuffer::readUInt() { 72 uint32_t SkValidatingReadBuffer::readUInt() {
75 return this->readInt(); 73 return this->readInt();
76 } 74 }
77 75
78 int32_t SkValidatingReadBuffer::read32() { 76 int32_t SkValidatingReadBuffer::read32() {
79 return this->readInt(); 77 return this->readInt();
80 } 78 }
81 79
82 void SkValidatingReadBuffer::readString(SkString* string) { 80 void SkValidatingReadBuffer::readString(SkString* string) {
83 const size_t len = this->readInt(); 81 const size_t len = this->readInt();
84 const void* ptr = fReader.peek(); 82 const void* ptr = fReader.peek();
85 const char* cptr = (const char*)ptr; 83 const char* cptr = (const char*)ptr;
86 84
87 // skip over the string + '\0' and then pad to a multiple of 4 85 // skip over the string + '\0' and then pad to a multiple of 4
88 const size_t alignedSize = SkAlign4(len + 1); 86 const size_t alignedSize = SkAlign4(len + 1);
89 this->skip(alignedSize); 87 this->skip(alignedSize);
90 fError = fError || (cptr[len] != '\0'); 88 this->validate(cptr[len] == '\0');
91 if (!fError) { 89 if (!fError) {
92 string->set(cptr, len); 90 string->set(cptr, len);
93 } 91 }
94 } 92 }
95 93
96 void* SkValidatingReadBuffer::readEncodedString(size_t* length, SkPaint::TextEnc oding encoding) { 94 void* SkValidatingReadBuffer::readEncodedString(size_t* length, SkPaint::TextEnc oding encoding) {
97 const int32_t encodingType = fReader.readInt(); 95 const int32_t encodingType = fReader.readInt();
98 fError = fError || (encodingType != encoding); 96 this->validate(encodingType == encoding);
99 *length = this->readInt(); 97 *length = this->readInt();
100 const void* ptr = this->skip(SkAlign4(*length)); 98 const void* ptr = this->skip(SkAlign4(*length));
101 void* data = NULL; 99 void* data = NULL;
102 if (!fError) { 100 if (!fError) {
103 data = sk_malloc_throw(*length); 101 data = sk_malloc_throw(*length);
104 memcpy(data, ptr, *length); 102 memcpy(data, ptr, *length);
105 } 103 }
106 return data; 104 return data;
107 } 105 }
108 106
109 void SkValidatingReadBuffer::readPoint(SkPoint* point) { 107 void SkValidatingReadBuffer::readPoint(SkPoint* point) {
110 point->fX = fReader.readScalar(); 108 point->fX = fReader.readScalar();
111 point->fY = fReader.readScalar(); 109 point->fY = fReader.readScalar();
112 } 110 }
113 111
114 void SkValidatingReadBuffer::readMatrix(SkMatrix* matrix) { 112 void SkValidatingReadBuffer::readMatrix(SkMatrix* matrix) {
115 const size_t size = matrix->readFromMemory(fReader.peek()); 113 const size_t size = matrix->readFromMemory(fReader.peek());
116 fError = fError || (SkAlign4(size) != size); 114 this->validate(SkAlign4(size) == size);
117 if (!fError) { 115 if (!fError) {
118 (void)this->skip(size); 116 (void)this->skip(size);
119 } 117 }
120 } 118 }
121 119
122 void SkValidatingReadBuffer::readIRect(SkIRect* rect) { 120 void SkValidatingReadBuffer::readIRect(SkIRect* rect) {
123 const void* ptr = this->skip(sizeof(SkIRect)); 121 const void* ptr = this->skip(sizeof(SkIRect));
124 if (!fError) { 122 if (!fError) {
125 memcpy(rect, ptr, sizeof(SkIRect)); 123 memcpy(rect, ptr, sizeof(SkIRect));
126 } 124 }
127 } 125 }
128 126
129 void SkValidatingReadBuffer::readRect(SkRect* rect) { 127 void SkValidatingReadBuffer::readRect(SkRect* rect) {
130 const void* ptr = this->skip(sizeof(SkRect)); 128 const void* ptr = this->skip(sizeof(SkRect));
131 if (!fError) { 129 if (!fError) {
132 memcpy(rect, ptr, sizeof(SkRect)); 130 memcpy(rect, ptr, sizeof(SkRect));
133 } 131 }
134 } 132 }
135 133
136 void SkValidatingReadBuffer::readRegion(SkRegion* region) { 134 void SkValidatingReadBuffer::readRegion(SkRegion* region) {
137 const size_t size = region->readFromMemory(fReader.peek()); 135 const size_t size = region->readFromMemory(fReader.peek());
138 fError = fError || (SkAlign4(size) != size); 136 this->validate(SkAlign4(size) == size);
139 if (!fError) { 137 if (!fError) {
140 (void)this->skip(size); 138 (void)this->skip(size);
141 } 139 }
142 } 140 }
143 141
144 void SkValidatingReadBuffer::readPath(SkPath* path) { 142 void SkValidatingReadBuffer::readPath(SkPath* path) {
145 const size_t size = path->readFromMemory(fReader.peek()); 143 const size_t size = path->readFromMemory(fReader.peek());
146 fError = fError || (SkAlign4(size) != size); 144 this->validate(SkAlign4(size) == size);
147 if (!fError) { 145 if (!fError) {
148 (void)this->skip(size); 146 (void)this->skip(size);
149 } 147 }
150 } 148 }
151 149
152 uint32_t SkValidatingReadBuffer::readByteArray(void* value) { 150 template <typename T> bool SkValidatingReadBuffer::readArray(T* value, size_t si ze) {
153 const uint32_t length = this->readUInt(); 151 const uint32_t count = this->getArrayCount();
154 const void* ptr = this->skip(SkAlign4(length)); 152 const size_t byteLength = count * sizeof(T);
153 this->validate(size == byteLength);
154 (void)this->skip(sizeof(uint32_t)); // Skip array count
155 const void* ptr = this->skip(SkAlign4(byteLength));
155 if (!fError) { 156 if (!fError) {
156 memcpy(value, ptr, length); 157 memcpy(value, ptr, byteLength);
157 return length; 158 return true;
158 } 159 }
159 return 0; 160 return false;
160 } 161 }
161 162
162 uint32_t SkValidatingReadBuffer::readColorArray(SkColor* colors) { 163 bool SkValidatingReadBuffer::readByteArray(void* value, size_t size) {
163 const uint32_t count = this->readUInt(); 164 return readArray(static_cast<unsigned char*>(value), size);
164 const uint32_t byteLength = count * sizeof(SkColor);
165 const void* ptr = this->skip(SkAlign4(byteLength));
166 if (!fError) {
167 memcpy(colors, ptr, byteLength);
168 return count;
169 }
170 return 0;
171 } 165 }
172 166
173 uint32_t SkValidatingReadBuffer::readIntArray(int32_t* values) { 167 bool SkValidatingReadBuffer::readColorArray(SkColor* colors, size_t size) {
174 const uint32_t count = this->readUInt(); 168 return readArray(colors, size);
175 const uint32_t byteLength = count * sizeof(int32_t);
176 const void* ptr = this->skip(SkAlign4(byteLength));
177 if (!fError) {
178 memcpy(values, ptr, byteLength);
179 return count;
180 }
181 return 0;
182 } 169 }
183 170
184 uint32_t SkValidatingReadBuffer::readPointArray(SkPoint* points) { 171 bool SkValidatingReadBuffer::readIntArray(int32_t* values, size_t size) {
185 const uint32_t count = this->readUInt(); 172 return readArray(values, size);
186 const uint32_t byteLength = count * sizeof(SkPoint);
187 const void* ptr = this->skip(SkAlign4(byteLength));
188 if (!fError) {
189 memcpy(points, ptr, byteLength);
190 return count;
191 }
192 return 0;
193 } 173 }
194 174
195 uint32_t SkValidatingReadBuffer::readScalarArray(SkScalar* values) { 175 bool SkValidatingReadBuffer::readPointArray(SkPoint* points, size_t size) {
196 const uint32_t count = this->readUInt(); 176 return readArray(points, size);
197 const uint32_t byteLength = count * sizeof(SkScalar); 177 }
198 const void* ptr = this->skip(SkAlign4(byteLength)); 178
199 if (!fError) { 179 bool SkValidatingReadBuffer::readScalarArray(SkScalar* values, size_t size) {
200 memcpy(values, ptr, byteLength); 180 return readArray(values, size);
201 return count;
202 }
203 return 0;
204 } 181 }
205 182
206 uint32_t SkValidatingReadBuffer::getArrayCount() { 183 uint32_t SkValidatingReadBuffer::getArrayCount() {
207 return *(uint32_t*)fReader.peek(); 184 return *(uint32_t*)fReader.peek();
208 } 185 }
209 186
210 void SkValidatingReadBuffer::readBitmap(SkBitmap* bitmap) { 187 void SkValidatingReadBuffer::readBitmap(SkBitmap* bitmap) {
211 const int width = this->readInt(); 188 const int width = this->readInt();
212 const int height = this->readInt(); 189 const int height = this->readInt();
213 const size_t length = this->readUInt(); 190 const size_t length = this->readUInt();
214 // A size of zero means the SkBitmap was simply flattened. 191 // A size of zero means the SkBitmap was simply flattened.
215 fError = fError || (length != 0); 192 this->validate(length == 0);
216 if (fError) { 193 if (fError) {
217 return; 194 return;
218 } 195 }
219 bitmap->unflatten(*this); 196 bitmap->unflatten(*this);
220 fError = fError || (bitmap->width() != width) || (bitmap->height() != height ); 197 this->validate((bitmap->width() == width) && (bitmap->height() == height));
221 } 198 }
222 199
223 SkFlattenable* SkValidatingReadBuffer::readFlattenable(SkFlattenable::Type type) { 200 SkFlattenable* SkValidatingReadBuffer::readFlattenable(SkFlattenable::Type type) {
224 SkString name; 201 SkString name;
225 this->readString(&name); 202 this->readString(&name);
226 if (fError) { 203 if (fError) {
227 return NULL; 204 return NULL;
228 } 205 }
229 206
230 // Is this the type we wanted ? 207 // Is this the type we wanted ?
(...skipping 10 matching lines...) Expand all
241 218
242 // if we get here, factory may still be null, but if that is the case, the 219 // if we get here, factory may still be null, but if that is the case, the
243 // failure was ours, not the writer. 220 // failure was ours, not the writer.
244 SkFlattenable* obj = NULL; 221 SkFlattenable* obj = NULL;
245 uint32_t sizeRecorded = this->readUInt(); 222 uint32_t sizeRecorded = this->readUInt();
246 if (factory) { 223 if (factory) {
247 uint32_t offset = fReader.offset(); 224 uint32_t offset = fReader.offset();
248 obj = (*factory)(*this); 225 obj = (*factory)(*this);
249 // check that we read the amount we expected 226 // check that we read the amount we expected
250 uint32_t sizeRead = fReader.offset() - offset; 227 uint32_t sizeRead = fReader.offset() - offset;
251 fError = fError || (sizeRecorded != sizeRead); 228 this->validate(sizeRecorded == sizeRead);
252 if (fError) { 229 if (fError) {
253 // we could try to fix up the offset... 230 // we could try to fix up the offset...
254 delete obj; 231 delete obj;
255 obj = NULL; 232 obj = NULL;
256 } 233 }
257 } else { 234 } else {
258 // we must skip the remaining data 235 // we must skip the remaining data
259 this->skip(sizeRecorded); 236 this->skip(sizeRecorded);
260 SkASSERT(false); 237 SkASSERT(false);
261 } 238 }
262 return obj; 239 return obj;
263 } 240 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698