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

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

Issue 23021015: Initial error handling code (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: New serialization method Created 7 years, 3 months 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
(Empty)
1 /*
2 * Copyright 2013 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #include "SkBitmap.h"
9 #include "SkErrorInternals.h"
10 #include "SkValidatingReadBuffer.h"
11 #include "SkStream.h"
12 #include "SkTypeface.h"
13
14 SkValidatingReadBuffer::SkValidatingReadBuffer() : INHERITED() {
15 fMemoryPtr = NULL;
16
17 fBitmapStorage = NULL;
18 fTFArray = NULL;
19 fTFCount = 0;
20
21 fFactoryTDArray = NULL;
22 fFactoryArray = NULL;
23 fFactoryCount = 0;
24 fBitmapDecoder = NULL;
25 #ifdef DEBUG_NON_DETERMINISTIC_ASSERT
26 fDecodedBitmapIndex = -1;
27 #endif // DEBUG_NON_DETERMINISTIC_ASSERT
28
29 setFlags(SkFlattenableReadBuffer::kValidation_Flag);
30 }
31
32 SkValidatingReadBuffer::SkValidatingReadBuffer(const void* data, size_t size) : INHERITED() {
33 this->setMemory(data, size);
34 fMemoryPtr = NULL;
35
36 fBitmapStorage = NULL;
37 fTFArray = NULL;
38 fTFCount = 0;
39
40 fFactoryTDArray = NULL;
41 fFactoryArray = NULL;
42 fFactoryCount = 0;
43 fBitmapDecoder = NULL;
44 #ifdef DEBUG_NON_DETERMINISTIC_ASSERT
45 fDecodedBitmapIndex = -1;
46 #endif // DEBUG_NON_DETERMINISTIC_ASSERT
47
48 setFlags(SkFlattenableReadBuffer::kValidation_Flag);
49 }
50
51 SkValidatingReadBuffer::SkValidatingReadBuffer(SkStream* stream) {
52 const size_t length = stream->getLength();
53 fMemoryPtr = sk_malloc_throw(length);
54 stream->read(fMemoryPtr, length);
55 this->setMemory(fMemoryPtr, length);
56
57 fBitmapStorage = NULL;
58 fTFArray = NULL;
59 fTFCount = 0;
60
61 fFactoryTDArray = NULL;
62 fFactoryArray = NULL;
63 fFactoryCount = 0;
64 fBitmapDecoder = NULL;
65 #ifdef DEBUG_NON_DETERMINISTIC_ASSERT
66 fDecodedBitmapIndex = -1;
67 #endif // DEBUG_NON_DETERMINISTIC_ASSERT
68
69 setFlags(SkFlattenableReadBuffer::kValidation_Flag);
70 }
71
72 SkValidatingReadBuffer::~SkValidatingReadBuffer() {
73 sk_free(fMemoryPtr);
74 SkSafeUnref(fBitmapStorage);
75 }
76
77 void SkValidatingReadBuffer::setMemory(const void* data, size_t size) {
78 fError |= (!ptr_align_4(data) || (SkAlign4(size) != size));
79 if (!fError) {
80 fReader.setMemory(data, size);
81 }
82 }
83
84 const void* SkValidatingReadBuffer::skip(size_t size) {
85 size_t inc = SkAlign4(size);
86 const void* addr = fReader.peek();
87 fError |= !ptr_align_4(addr) || !fReader.isAvailable(inc);
88 if (!fError) {
89 fReader.skip(size);
90 }
91 return addr;
92 }
mtklein 2013/09/24 22:52:18 Some comments in here about our validation strateg
sugoi1 2013/09/25 21:15:27 I've added the comment.
93
94 bool SkValidatingReadBuffer::readBool() {
95 return this->readInt() != 0;
96 }
97
98 SkColor SkValidatingReadBuffer::readColor() {
99 return this->readInt();
100 }
101
102 SkFixed SkValidatingReadBuffer::readFixed() {
103 return this->readInt();
104 }
105
106 int32_t SkValidatingReadBuffer::readInt() {
107 size_t inc = sizeof(int32_t);
108 fError |= !ptr_align_4(fReader.peek()) || !fReader.isAvailable(inc);
109 return fError ? 0 : fReader.readInt();
110 }
111
112 SkScalar SkValidatingReadBuffer::readScalar() {
113 size_t inc = sizeof(SkScalar);
114 fError |= !ptr_align_4(fReader.peek()) || !fReader.isAvailable(inc);
115 return fError ? 0 : fReader.readScalar();
116 }
117
118 uint32_t SkValidatingReadBuffer::readUInt() {
119 return this->readInt();
120 }
121
122 int32_t SkValidatingReadBuffer::read32() {
123 return this->readInt();
124 }
125
126 void SkValidatingReadBuffer::readString(SkString* string) {
127 size_t len = this->readInt();
128 const void* ptr = fReader.peek();
129
130 // skip over the string + '\0' and then pad to a multiple of 4
131 size_t alignedSize = SkAlign4(len + 1);
132 this->skip(alignedSize);
133 if (!fError) {
134 string->set((const char*)ptr, len);
135 }
136 }
137
138 void* SkValidatingReadBuffer::readEncodedString(size_t* length, SkPaint::TextEnc oding encoding) {
139 int32_t encodingType = fReader.readInt();
140 if (encodingType == encoding) {
141 fError = true;
142 }
143 *length = this->readInt();
144 const void* ptr = this->skip(SkAlign4(*length));
145 void* data = NULL;
146 if (!fError) {
147 data = sk_malloc_throw(*length);
148 memcpy(data, ptr, *length);
149 }
150 return data;
151 }
152
153 void SkValidatingReadBuffer::readPoint(SkPoint* point) {
154 point->fX = fReader.readScalar();
155 point->fY = fReader.readScalar();
156 }
157
158 void SkValidatingReadBuffer::readMatrix(SkMatrix* matrix) {
159 size_t size = matrix->readFromMemory(fReader.peek());
160 fError |= (SkAlign4(size) != size);
161 if (!fError) {
162 (void)this->skip(size);
163 }
164 }
165
166 void SkValidatingReadBuffer::readIRect(SkIRect* rect) {
167 memcpy(rect, this->skip(sizeof(SkIRect)), sizeof(SkIRect));
168 }
169
170 void SkValidatingReadBuffer::readRect(SkRect* rect) {
171 memcpy(rect, this->skip(sizeof(SkRect)), sizeof(SkRect));
172 }
173
174 void SkValidatingReadBuffer::readRegion(SkRegion* region) {
175 size_t size = region->readFromMemory(fReader.peek());
176 fError |= (SkAlign4(size) != size);
177 if (!fError) {
178 (void)this->skip(size);
179 }
180 }
181
182 void SkValidatingReadBuffer::readPath(SkPath* path) {
183 size_t size = path->readFromMemory(fReader.peek());
184 fError |= (SkAlign4(size) != size);
185 if (!fError) {
186 (void)this->skip(size);
187 }
188 }
189
190 uint32_t SkValidatingReadBuffer::readByteArray(void* value) {
191 const uint32_t length = this->readUInt();
192 memcpy(value, this->skip(SkAlign4(length)), length);
193 return fError ? 0 : length;
194 }
195
196 uint32_t SkValidatingReadBuffer::readColorArray(SkColor* colors) {
197 const uint32_t count = this->readUInt();
198 const uint32_t byteLength = count * sizeof(SkColor);
199 memcpy(colors, this->skip(SkAlign4(byteLength)), byteLength);
200 return fError ? 0 : count;
201 }
202
203 uint32_t SkValidatingReadBuffer::readIntArray(int32_t* values) {
204 const uint32_t count = this->readUInt();
205 const uint32_t byteLength = count * sizeof(int32_t);
206 memcpy(values, this->skip(SkAlign4(byteLength)), byteLength);
207 return fError ? 0 : count;
208 }
209
210 uint32_t SkValidatingReadBuffer::readPointArray(SkPoint* points) {
211 const uint32_t count = this->readUInt();
212 const uint32_t byteLength = count * sizeof(SkPoint);
213 memcpy(points, this->skip(SkAlign4(byteLength)), byteLength);
214 return fError ? 0 : count;
215 }
216
217 uint32_t SkValidatingReadBuffer::readScalarArray(SkScalar* values) {
218 const uint32_t count = this->readUInt();
219 const uint32_t byteLength = count * sizeof(SkScalar);
220 memcpy(values, this->skip(SkAlign4(byteLength)), byteLength);
221 return fError ? 0 : count;
222 }
223
224 uint32_t SkValidatingReadBuffer::getArrayCount() {
225 return *(uint32_t*)fReader.peek();
226 }
227
228 void SkValidatingReadBuffer::readBitmap(SkBitmap* bitmap) {
229 const int width = this->readInt();
230 const int height = this->readInt();
231 const size_t length = this->readUInt();
232 // A size of zero means the SkBitmap was simply flattened.
233 if (length != 0) {
234 fError = true;
235 }
236 if (fError) {
237 return;
238 }
239 bitmap->unflatten(*this);
240 if ((bitmap->width() != width) || (bitmap->height() != height)) {
241 fError = true;
242 }
243 }
244
245 SkTypeface* SkValidatingReadBuffer::readTypeface() {
246
247 uint32_t index = this->readUInt();
248 if (0 == index || index > (unsigned)fTFCount || fError) {
249 if (index) {
250 SkDebugf("====== typeface index %d\n", index);
251 }
252 return NULL;
253 } else {
254 SkASSERT(fTFArray);
255 return fTFArray[index - 1];
256 }
257 }
258
259 SkFlattenable* SkValidatingReadBuffer::readFlattenable(SkFlattenable::Type type) {
260 const SkFlattenable::Type flattenableType = static_cast<SkFlattenable::Type> (this->readInt());
261 // Is this the type we wanted ?
262 if (fError || !SkFlattenable::TypeIsA(flattenableType, type)) {
263 return NULL;
264 }
265
266 SkFlattenable::Factory factory = SkFlattenable::TypeToFactory(flattenableTyp e);
267 if (NULL == factory) {
268 return NULL; // writer failed to give us the flattenable
269 }
270
271 // if we get here, factory may still be null, but if that is the case, the
272 // failure was ours, not the writer.
mtklein 2013/09/24 22:52:18 SkASSERT it doesn't happen?
sugoi1 2013/09/25 21:15:27 Done.
273 SkFlattenable* obj = NULL;
274 uint32_t sizeRecorded = this->readUInt();
275 if (factory) {
276 uint32_t offset = fReader.offset();
277 obj = (*factory)(*this);
278 // check that we read the amount we expected
279 uint32_t sizeRead = fReader.offset() - offset;
280 if (sizeRecorded != sizeRead) {
281 // we could try to fix up the offset...
282 fError = true;
283 delete obj;
284 obj = NULL;
285 }
286 } else {
287 // we must skip the remaining data
288 this->skip(sizeRecorded);
289 }
290 return obj;
291 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698