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

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: Fixed comments 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::validate(bool isValid) {
24 if (!fError && !isValid) {
25 // When an error is found, send the read cursor to the end of the stream
26 fReader.skip(fReader.available());
27 fError = true;
28 }
29 }
30
23 void SkValidatingReadBuffer::setMemory(const void* data, size_t size) { 31 void SkValidatingReadBuffer::setMemory(const void* data, size_t size) {
24 fError = fError || !IsPtrAlign4(data) || (SkAlign4(size) != size); 32 this->validate(IsPtrAlign4(data) && (SkAlign4(size) == size));
25 if (!fError) { 33 if (!fError) {
26 fReader.setMemory(data, size); 34 fReader.setMemory(data, size);
27 } 35 }
28 } 36 }
29 37
30 const void* SkValidatingReadBuffer::skip(size_t size) { 38 const void* SkValidatingReadBuffer::skip(size_t size) {
31 size_t inc = SkAlign4(size); 39 size_t inc = SkAlign4(size);
32 const void* addr = fReader.peek(); 40 const void* addr = fReader.peek();
33 fError = fError || !IsPtrAlign4(addr) || !fReader.isAvailable(inc); 41 this->validate(IsPtrAlign4(addr) && fReader.isAvailable(inc));
34 if (!fError) { 42 if (!fError) {
35 fReader.skip(size); 43 fReader.skip(size);
36 } 44 }
37 return addr; 45 return addr;
38 } 46 }
39 47
40 // All the methods in this file funnel down into either readInt(), readScalar() or skip(), 48 // 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(); 49 // 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 50 // 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. 51 // true, which the caller should check to see if an error occurred during the re ad operation.
44 52
45 bool SkValidatingReadBuffer::readBool() { 53 bool SkValidatingReadBuffer::readBool() {
46 uint32_t value = this->readInt(); 54 uint32_t value = this->readInt();
47 // Boolean value should be either 0 or 1 55 // Boolean value should be either 0 or 1
48 if (value & ~1) { 56 this->validate(!(value & ~1));
49 fError = true;
50 }
51 return value != 0; 57 return value != 0;
52 } 58 }
53 59
54 SkColor SkValidatingReadBuffer::readColor() { 60 SkColor SkValidatingReadBuffer::readColor() {
55 return this->readInt(); 61 return this->readInt();
56 } 62 }
57 63
58 SkFixed SkValidatingReadBuffer::readFixed() { 64 SkFixed SkValidatingReadBuffer::readFixed() {
59 return this->readInt(); 65 return this->readInt();
60 } 66 }
61 67
62 int32_t SkValidatingReadBuffer::readInt() { 68 int32_t SkValidatingReadBuffer::readInt() {
63 const size_t inc = sizeof(int32_t); 69 const size_t inc = sizeof(int32_t);
64 fError = fError || !IsPtrAlign4(fReader.peek()) || !fReader.isAvailable(inc) ; 70 this->validate(IsPtrAlign4(fReader.peek()) && fReader.isAvailable(inc));
65 return fError ? 0 : fReader.readInt(); 71 return fError ? 0 : fReader.readInt();
66 } 72 }
67 73
68 SkScalar SkValidatingReadBuffer::readScalar() { 74 SkScalar SkValidatingReadBuffer::readScalar() {
69 const size_t inc = sizeof(SkScalar); 75 const size_t inc = sizeof(SkScalar);
70 fError = fError || !IsPtrAlign4(fReader.peek()) || !fReader.isAvailable(inc) ; 76 this->validate(IsPtrAlign4(fReader.peek()) && fReader.isAvailable(inc));
71 return fError ? 0 : fReader.readScalar(); 77 return fError ? 0 : fReader.readScalar();
72 } 78 }
73 79
74 uint32_t SkValidatingReadBuffer::readUInt() { 80 uint32_t SkValidatingReadBuffer::readUInt() {
75 return this->readInt(); 81 return this->readInt();
76 } 82 }
77 83
78 int32_t SkValidatingReadBuffer::read32() { 84 int32_t SkValidatingReadBuffer::read32() {
79 return this->readInt(); 85 return this->readInt();
80 } 86 }
81 87
82 void SkValidatingReadBuffer::readString(SkString* string) { 88 void SkValidatingReadBuffer::readString(SkString* string) {
83 const size_t len = this->readInt(); 89 const size_t len = this->readInt();
84 const void* ptr = fReader.peek(); 90 const void* ptr = fReader.peek();
85 const char* cptr = (const char*)ptr; 91 const char* cptr = (const char*)ptr;
86 92
87 // skip over the string + '\0' and then pad to a multiple of 4 93 // skip over the string + '\0' and then pad to a multiple of 4
88 const size_t alignedSize = SkAlign4(len + 1); 94 const size_t alignedSize = SkAlign4(len + 1);
89 this->skip(alignedSize); 95 this->skip(alignedSize);
90 fError = fError || (cptr[len] != '\0'); 96 this->validate(cptr[len] == '\0');
91 if (!fError) { 97 if (!fError) {
92 string->set(cptr, len); 98 string->set(cptr, len);
93 } 99 }
94 } 100 }
95 101
96 void* SkValidatingReadBuffer::readEncodedString(size_t* length, SkPaint::TextEnc oding encoding) { 102 void* SkValidatingReadBuffer::readEncodedString(size_t* length, SkPaint::TextEnc oding encoding) {
97 const int32_t encodingType = fReader.readInt(); 103 const int32_t encodingType = fReader.readInt();
98 fError = fError || (encodingType != encoding); 104 this->validate(encodingType == encoding);
99 *length = this->readInt(); 105 *length = this->readInt();
100 const void* ptr = this->skip(SkAlign4(*length)); 106 const void* ptr = this->skip(SkAlign4(*length));
101 void* data = NULL; 107 void* data = NULL;
102 if (!fError) { 108 if (!fError) {
103 data = sk_malloc_throw(*length); 109 data = sk_malloc_throw(*length);
104 memcpy(data, ptr, *length); 110 memcpy(data, ptr, *length);
105 } 111 }
106 return data; 112 return data;
107 } 113 }
108 114
109 void SkValidatingReadBuffer::readPoint(SkPoint* point) { 115 void SkValidatingReadBuffer::readPoint(SkPoint* point) {
110 point->fX = fReader.readScalar(); 116 point->fX = fReader.readScalar();
111 point->fY = fReader.readScalar(); 117 point->fY = fReader.readScalar();
112 } 118 }
113 119
114 void SkValidatingReadBuffer::readMatrix(SkMatrix* matrix) { 120 void SkValidatingReadBuffer::readMatrix(SkMatrix* matrix) {
115 const size_t size = matrix->readFromMemory(fReader.peek()); 121 const size_t size = matrix->readFromMemory(fReader.peek());
116 fError = fError || (SkAlign4(size) != size); 122 this->validate(SkAlign4(size) == size);
117 if (!fError) { 123 if (!fError) {
118 (void)this->skip(size); 124 (void)this->skip(size);
119 } 125 }
120 } 126 }
121 127
122 void SkValidatingReadBuffer::readIRect(SkIRect* rect) { 128 void SkValidatingReadBuffer::readIRect(SkIRect* rect) {
123 const void* ptr = this->skip(sizeof(SkIRect)); 129 const void* ptr = this->skip(sizeof(SkIRect));
124 if (!fError) { 130 if (!fError) {
125 memcpy(rect, ptr, sizeof(SkIRect)); 131 memcpy(rect, ptr, sizeof(SkIRect));
126 } 132 }
127 } 133 }
128 134
129 void SkValidatingReadBuffer::readRect(SkRect* rect) { 135 void SkValidatingReadBuffer::readRect(SkRect* rect) {
130 const void* ptr = this->skip(sizeof(SkRect)); 136 const void* ptr = this->skip(sizeof(SkRect));
131 if (!fError) { 137 if (!fError) {
132 memcpy(rect, ptr, sizeof(SkRect)); 138 memcpy(rect, ptr, sizeof(SkRect));
133 } 139 }
134 } 140 }
135 141
136 void SkValidatingReadBuffer::readRegion(SkRegion* region) { 142 void SkValidatingReadBuffer::readRegion(SkRegion* region) {
137 const size_t size = region->readFromMemory(fReader.peek()); 143 const size_t size = region->readFromMemory(fReader.peek());
138 fError = fError || (SkAlign4(size) != size); 144 this->validate(SkAlign4(size) == size);
139 if (!fError) { 145 if (!fError) {
140 (void)this->skip(size); 146 (void)this->skip(size);
141 } 147 }
142 } 148 }
143 149
144 void SkValidatingReadBuffer::readPath(SkPath* path) { 150 void SkValidatingReadBuffer::readPath(SkPath* path) {
145 const size_t size = path->readFromMemory(fReader.peek()); 151 const size_t size = path->readFromMemory(fReader.peek());
146 fError = fError || (SkAlign4(size) != size); 152 this->validate(SkAlign4(size) == size);
147 if (!fError) { 153 if (!fError) {
148 (void)this->skip(size); 154 (void)this->skip(size);
149 } 155 }
150 } 156 }
151 157
152 uint32_t SkValidatingReadBuffer::readByteArray(void* value) { 158 bool SkValidatingReadBuffer::readArray(void* value, size_t size, size_t elementS ize) {
153 const uint32_t length = this->readUInt(); 159 const uint32_t count = this->getArrayCount();
154 const void* ptr = this->skip(SkAlign4(length)); 160 this->validate(size == count);
161 (void)this->skip(sizeof(uint32_t)); // Skip array count
162 const size_t byteLength = count * elementSize;
163 const void* ptr = this->skip(SkAlign4(byteLength));
155 if (!fError) { 164 if (!fError) {
156 memcpy(value, ptr, length); 165 memcpy(value, ptr, byteLength);
157 return length; 166 return true;
158 } 167 }
159 return 0; 168 return false;
160 } 169 }
161 170
162 uint32_t SkValidatingReadBuffer::readColorArray(SkColor* colors) { 171 bool SkValidatingReadBuffer::readByteArray(void* value, size_t size) {
163 const uint32_t count = this->readUInt(); 172 return readArray(static_cast<unsigned char*>(value), size, sizeof(unsigned c har));
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 } 173 }
172 174
173 uint32_t SkValidatingReadBuffer::readIntArray(int32_t* values) { 175 bool SkValidatingReadBuffer::readColorArray(SkColor* colors, size_t size) {
174 const uint32_t count = this->readUInt(); 176 return readArray(colors, size, sizeof(SkColor));
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 } 177 }
183 178
184 uint32_t SkValidatingReadBuffer::readPointArray(SkPoint* points) { 179 bool SkValidatingReadBuffer::readIntArray(int32_t* values, size_t size) {
185 const uint32_t count = this->readUInt(); 180 return readArray(values, size, sizeof(int32_t));
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 } 181 }
194 182
195 uint32_t SkValidatingReadBuffer::readScalarArray(SkScalar* values) { 183 bool SkValidatingReadBuffer::readPointArray(SkPoint* points, size_t size) {
196 const uint32_t count = this->readUInt(); 184 return readArray(points, size, sizeof(SkPoint));
197 const uint32_t byteLength = count * sizeof(SkScalar); 185 }
198 const void* ptr = this->skip(SkAlign4(byteLength)); 186
199 if (!fError) { 187 bool SkValidatingReadBuffer::readScalarArray(SkScalar* values, size_t size) {
200 memcpy(values, ptr, byteLength); 188 return readArray(values, size, sizeof(SkScalar));
201 return count;
202 }
203 return 0;
204 } 189 }
205 190
206 uint32_t SkValidatingReadBuffer::getArrayCount() { 191 uint32_t SkValidatingReadBuffer::getArrayCount() {
207 return *(uint32_t*)fReader.peek(); 192 return *(uint32_t*)fReader.peek();
208 } 193 }
209 194
210 void SkValidatingReadBuffer::readBitmap(SkBitmap* bitmap) { 195 void SkValidatingReadBuffer::readBitmap(SkBitmap* bitmap) {
211 const int width = this->readInt(); 196 const int width = this->readInt();
212 const int height = this->readInt(); 197 const int height = this->readInt();
213 const size_t length = this->readUInt(); 198 const size_t length = this->readUInt();
214 // A size of zero means the SkBitmap was simply flattened. 199 // A size of zero means the SkBitmap was simply flattened.
215 fError = fError || (length != 0); 200 this->validate(length == 0);
216 if (fError) { 201 if (fError) {
217 return; 202 return;
218 } 203 }
219 bitmap->unflatten(*this); 204 bitmap->unflatten(*this);
220 fError = fError || (bitmap->width() != width) || (bitmap->height() != height ); 205 this->validate((bitmap->width() == width) && (bitmap->height() == height));
206 }
207
208 SkTypeface* SkValidatingReadBuffer::readTypeface() {
209 // TODO: Implement this (securely) when needed
210 return NULL;
221 } 211 }
222 212
223 SkFlattenable* SkValidatingReadBuffer::readFlattenable(SkFlattenable::Type type) { 213 SkFlattenable* SkValidatingReadBuffer::readFlattenable(SkFlattenable::Type type) {
224 SkString name; 214 SkString name;
225 this->readString(&name); 215 this->readString(&name);
226 if (fError) { 216 if (fError) {
227 return NULL; 217 return NULL;
228 } 218 }
229 219
230 // Is this the type we wanted ? 220 // Is this the type we wanted ?
(...skipping 10 matching lines...) Expand all
241 231
242 // if we get here, factory may still be null, but if that is the case, the 232 // if we get here, factory may still be null, but if that is the case, the
243 // failure was ours, not the writer. 233 // failure was ours, not the writer.
244 SkFlattenable* obj = NULL; 234 SkFlattenable* obj = NULL;
245 uint32_t sizeRecorded = this->readUInt(); 235 uint32_t sizeRecorded = this->readUInt();
246 if (factory) { 236 if (factory) {
247 uint32_t offset = fReader.offset(); 237 uint32_t offset = fReader.offset();
248 obj = (*factory)(*this); 238 obj = (*factory)(*this);
249 // check that we read the amount we expected 239 // check that we read the amount we expected
250 uint32_t sizeRead = fReader.offset() - offset; 240 uint32_t sizeRead = fReader.offset() - offset;
251 fError = fError || (sizeRecorded != sizeRead); 241 this->validate(sizeRecorded == sizeRead);
252 if (fError) { 242 if (fError) {
253 // we could try to fix up the offset... 243 // we could try to fix up the offset...
254 delete obj; 244 delete obj;
255 obj = NULL; 245 obj = NULL;
256 } 246 }
257 } else { 247 } else {
258 // we must skip the remaining data 248 // we must skip the remaining data
259 this->skip(sizeRecorded); 249 this->skip(sizeRecorded);
260 SkASSERT(false); 250 SkASSERT(false);
261 } 251 }
262 return obj; 252 return obj;
263 } 253 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698