OLD | NEW |
---|---|
(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 } | |
OLD | NEW |