1 /*
2 * Copyright 2012 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 "SkDeduper.h"
10 #include "SkImage.h"
11 #include "SkImageGenerator.h"
12 #include "SkMakeUnique.h"
13 #include "SkMathPriv.h"
14 #include "SkMatrixPriv.h"
15 #include "SkReadBuffer.h"
16 #include "SkSafeMath.h"
17 #include "SkStream.h"
18 #include "SkTypeface.h"
19
20 namespace {
21 // This generator intentionally should always fail on all attempts to get its pixels,
22 // simulating a bad or empty codec stream.
23 class EmptyImageGenerator final : public SkImageGenerator {
24 public:
EmptyImageGenerator(const SkImageInfo & info)25 EmptyImageGenerator(const SkImageInfo& info) : INHERITED(info) { }
26
27 private:
28 typedef SkImageGenerator INHERITED;
29 };
30
MakeEmptyImage(int width,int height)31 static sk_sp<SkImage> MakeEmptyImage(int width, int height) {
32 return SkImage::MakeFromGenerator(
33 skstd::make_unique<EmptyImageGenerator>(SkImageInfo::MakeN32Premul(width, height)));
34 }
35
36 } // anonymous namespace
37
38
SkReadBuffer()39 SkReadBuffer::SkReadBuffer() {
40 fVersion = 0;
41 fMemoryPtr = nullptr;
42
43 fTFArray = nullptr;
44 fTFCount = 0;
45
46 fFactoryArray = nullptr;
47 fFactoryCount = 0;
48 #ifdef DEBUG_NON_DETERMINISTIC_ASSERT
49 fDecodedBitmapIndex = -1;
50 #endif // DEBUG_NON_DETERMINISTIC_ASSERT
51 }
52
SkReadBuffer(const void * data,size_t size)53 SkReadBuffer::SkReadBuffer(const void* data, size_t size) {
54 fVersion = 0;
55 this->setMemory(data, size);
56 fMemoryPtr = nullptr;
57
58 fTFArray = nullptr;
59 fTFCount = 0;
60
61 fFactoryArray = nullptr;
62 fFactoryCount = 0;
63 #ifdef DEBUG_NON_DETERMINISTIC_ASSERT
64 fDecodedBitmapIndex = -1;
65 #endif // DEBUG_NON_DETERMINISTIC_ASSERT
66 }
67
~SkReadBuffer()68 SkReadBuffer::~SkReadBuffer() {
69 sk_free(fMemoryPtr);
70 }
71
setMemory(const void * data,size_t size)72 void SkReadBuffer::setMemory(const void* data, size_t size) {
73 this->validate(IsPtrAlign4(data) && (SkAlign4(size) == size));
74 if (!fError) {
75 fReader.setMemory(data, size);
76 }
77 }
setInvalid()78 void SkReadBuffer::setInvalid() {
79 if (!fError) {
80 // When an error is found, send the read cursor to the end of the stream
81 fReader.skip(fReader.available());
82 fError = true;
83 }
84 }
85
skip(size_t size)86 const void* SkReadBuffer::skip(size_t size) {
87 size_t inc = SkAlign4(size);
88 this->validate(inc >= size);
89 const void* addr = fReader.peek();
90 this->validate(IsPtrAlign4(addr) && fReader.isAvailable(inc));
91 if (fError) {
92 return nullptr;
93 }
94
95 fReader.skip(size);
96 return addr;
97 }
98
skip(size_t count,size_t size)99 const void* SkReadBuffer::skip(size_t count, size_t size) {
100 return this->skip(SkSafeMath::Mul(count, size));
101 }
102
setDeserialProcs(const SkDeserialProcs & procs)103 void SkReadBuffer::setDeserialProcs(const SkDeserialProcs& procs) {
104 fProcs = procs;
105 }
106
readBool()107 bool SkReadBuffer::readBool() {
108 uint32_t value = this->readUInt();
109 // Boolean value should be either 0 or 1
110 this->validate(!(value & ~1));
111 return value != 0;
112 }
113
readColor()114 SkColor SkReadBuffer::readColor() {
115 return this->readUInt();
116 }
117
readInt()118 int32_t SkReadBuffer::readInt() {
119 const size_t inc = sizeof(int32_t);
120 this->validate(IsPtrAlign4(fReader.peek()) && fReader.isAvailable(inc));
121 return fError ? 0 : fReader.readInt();
122 }
123
readScalar()124 SkScalar SkReadBuffer::readScalar() {
125 const size_t inc = sizeof(SkScalar);
126 this->validate(IsPtrAlign4(fReader.peek()) && fReader.isAvailable(inc));
127 return fError ? 0 : fReader.readScalar();
128 }
129
readUInt()130 uint32_t SkReadBuffer::readUInt() {
131 return this->readInt();
132 }
133
read32()134 int32_t SkReadBuffer::read32() {
135 return this->readInt();
136 }
137
peekByte()138 uint8_t SkReadBuffer::peekByte() {
139 if (fReader.available() <= 0) {
140 fError = true;
141 return 0;
142 }
143 return *((uint8_t*) fReader.peek());
144 }
145
readPad32(void * buffer,size_t bytes)146 bool SkReadBuffer::readPad32(void* buffer, size_t bytes) {
147 if (const void* src = this->skip(bytes)) {
148 memcpy(buffer, src, bytes);
149 return true;
150 }
151 return false;
152 }
153
readString(SkString * string)154 void SkReadBuffer::readString(SkString* string) {
155 const size_t len = this->readUInt();
156 // skip over the string + '\0'
157 if (const char* src = this->skipT<char>(len + 1)) {
158 if (this->validate(src[len] == 0)) {
159 string->set(src, len);
160 return;
161 }
162 }
163 string->reset();
164 }
165
readColor4f(SkColor4f * color)166 void SkReadBuffer::readColor4f(SkColor4f* color) {
167 if (!this->readPad32(color, sizeof(SkColor4f))) {
168 *color = {0, 0, 0, 0};
169 }
170 }
171
readPoint(SkPoint * point)172 void SkReadBuffer::readPoint(SkPoint* point) {
173 point->fX = this->readScalar();
174 point->fY = this->readScalar();
175 }
176
readPoint3(SkPoint3 * point)177 void SkReadBuffer::readPoint3(SkPoint3* point) {
178 this->readPad32(point, sizeof(SkPoint3));
179 }
180
readMatrix(SkMatrix * matrix)181 void SkReadBuffer::readMatrix(SkMatrix* matrix) {
182 size_t size = 0;
183 if (this->isValid()) {
184 size = SkMatrixPriv::ReadFromMemory(matrix, fReader.peek(), fReader.available());
185 (void)this->validate((SkAlign4(size) == size) && (0 != size));
186 }
187 if (!this->isValid()) {
188 matrix->reset();
189 }
190 (void)this->skip(size);
191 }
192
readIRect(SkIRect * rect)193 void SkReadBuffer::readIRect(SkIRect* rect) {
194 if (!this->readPad32(rect, sizeof(SkIRect))) {
195 rect->setEmpty();
196 }
197 }
198
readRect(SkRect * rect)199 void SkReadBuffer::readRect(SkRect* rect) {
200 if (!this->readPad32(rect, sizeof(SkRect))) {
201 rect->setEmpty();
202 }
203 }
204
readRRect(SkRRect * rrect)205 void SkReadBuffer::readRRect(SkRRect* rrect) {
206 if (!this->validate(fReader.readRRect(rrect))) {
207 rrect->setEmpty();
208 }
209 }
210
readRegion(SkRegion * region)211 void SkReadBuffer::readRegion(SkRegion* region) {
212 size_t size = 0;
213 if (!fError) {
214 size = region->readFromMemory(fReader.peek(), fReader.available());
215 if (!this->validate((SkAlign4(size) == size) && (0 != size))) {
216 region->setEmpty();
217 }
218 }
219 (void)this->skip(size);
220 }
221
readPath(SkPath * path)222 void SkReadBuffer::readPath(SkPath* path) {
223 size_t size = 0;
224 if (!fError) {
225 size = path->readFromMemory(fReader.peek(), fReader.available());
226 if (!this->validate((SkAlign4(size) == size) && (0 != size))) {
227 path->reset();
228 }
229 }
230 (void)this->skip(size);
231 }
232
readArray(void * value,size_t size,size_t elementSize)233 bool SkReadBuffer::readArray(void* value, size_t size, size_t elementSize) {
234 const uint32_t count = this->readUInt();
235 return this->validate(size == count) &&
236 this->readPad32(value, SkSafeMath::Mul(size, elementSize));
237 }
238
readByteArray(void * value,size_t size)239 bool SkReadBuffer::readByteArray(void* value, size_t size) {
240 return this->readArray(value, size, sizeof(uint8_t));
241 }
242
readColorArray(SkColor * colors,size_t size)243 bool SkReadBuffer::readColorArray(SkColor* colors, size_t size) {
244 return this->readArray(colors, size, sizeof(SkColor));
245 }
246
readColor4fArray(SkColor4f * colors,size_t size)247 bool SkReadBuffer::readColor4fArray(SkColor4f* colors, size_t size) {
248 return this->readArray(colors, size, sizeof(SkColor4f));
249 }
250
readIntArray(int32_t * values,size_t size)251 bool SkReadBuffer::readIntArray(int32_t* values, size_t size) {
252 return this->readArray(values, size, sizeof(int32_t));
253 }
254
readPointArray(SkPoint * points,size_t size)255 bool SkReadBuffer::readPointArray(SkPoint* points, size_t size) {
256 return this->readArray(points, size, sizeof(SkPoint));
257 }
258
readScalarArray(SkScalar * values,size_t size)259 bool SkReadBuffer::readScalarArray(SkScalar* values, size_t size) {
260 return this->readArray(values, size, sizeof(SkScalar));
261 }
262
getArrayCount()263 uint32_t SkReadBuffer::getArrayCount() {
264 const size_t inc = sizeof(uint32_t);
265 fError = fError || !IsPtrAlign4(fReader.peek()) || !fReader.isAvailable(inc);
266 return fError ? 0 : *(uint32_t*)fReader.peek();
267 }
268
readImage()269 sk_sp<SkImage> SkReadBuffer::readImage() {
270 if (fInflator) {
271 SkImage* img = fInflator->getImage(this->read32());
272 return img ? sk_ref_sp(img) : nullptr;
273 }
274
275 int width = this->read32();
276 int height = this->read32();
277 if (width <= 0 || height <= 0) { // SkImage never has a zero dimension
278 this->validate(false);
279 return nullptr;
280 }
281
282 /*
283 * What follows is a 32bit encoded size.
284 * 0 : failure, nothing else to do
285 * <0 : negative (int32_t) of a custom encoded blob using SerialProcs
286 * >0 : standard encoded blob size (use MakeFromEncoded)
287 */
288
289 int32_t encoded_size = this->read32();
290 if (encoded_size == 0) {
291 // The image could not be encoded at serialization time - return an empty placeholder.
292 return MakeEmptyImage(width, height);
293 }
294 if (encoded_size == 1) {
295 // legacy check (we stopped writing this for "raw" images Nov-2017)
296 this->validate(false);
297 return nullptr;
298 }
299
300 size_t size = SkAbs32(encoded_size);
301 sk_sp<SkData> data = SkData::MakeUninitialized(size);
302 if (!this->readPad32(data->writable_data(), size)) {
303 this->validate(false);
304 return nullptr;
305 }
306 int32_t originX = this->read32();
307 int32_t originY = this->read32();
308 if (originX < 0 || originY < 0) {
309 this->validate(false);
310 return nullptr;
311 }
312
313 sk_sp<SkImage> image;
314 if (encoded_size < 0) { // custom encoded, need serial proc
315 if (fProcs.fImageProc) {
316 image = fProcs.fImageProc(data->data(), data->size(), fProcs.fImageCtx);
317 } else {
318 // Nothing to do (no client proc), but since we've already "read" the custom data,
319 // wee just leave image as nullptr.
320 }
321 } else {
322 SkIRect subset = SkIRect::MakeXYWH(originX, originY, width, height);
323 image = SkImage::MakeFromEncoded(std::move(data), &subset);
324 }
325 // Question: are we correct to return an "empty" image instead of nullptr, if the decoder
326 // failed for some reason?
327 return image ? image : MakeEmptyImage(width, height);
328 }
329
readTypeface()330 sk_sp<SkTypeface> SkReadBuffer::readTypeface() {
331 if (fInflator) {
332 return sk_ref_sp(fInflator->getTypeface(this->read32()));
333 }
334
335 // Read 32 bits (signed)
336 // 0 -- return null (default font)
337 // >0 -- index
338 // <0 -- custom (serial procs) : negative size in bytes
339
340 int32_t index = this->read32();
341 if (index == 0) {
342 return nullptr;
343 } else if (index > 0) {
344 if (!this->validate(index <= fTFCount)) {
345 return nullptr;
346 }
347 return sk_ref_sp(fTFArray[index - 1]);
348 } else { // custom
349 size_t size = sk_negate_to_size_t(index);
350 const void* data = this->skip(size);
351 if (!this->validate(data != nullptr && fProcs.fTypefaceProc)) {
352 return nullptr;
353 }
354 return fProcs.fTypefaceProc(data, size, fProcs.fTypefaceCtx);
355 }
356 }
357
readFlattenable(SkFlattenable::Type ft)358 SkFlattenable* SkReadBuffer::readFlattenable(SkFlattenable::Type ft) {
359 SkFlattenable::Factory factory = nullptr;
360
361 if (fInflator) {
362 factory = fInflator->getFactory(this->read32());
363 if (!factory) {
364 return nullptr;
365 }
366 } else if (fFactoryCount > 0) {
367 int32_t index = this->read32();
368 if (0 == index || !this->isValid()) {
369 return nullptr; // writer failed to give us the flattenable
370 }
371 index -= 1; // we stored the index-base-1
372 if ((unsigned)index >= (unsigned)fFactoryCount) {
373 this->validate(false);
374 return nullptr;
375 }
376 factory = fFactoryArray[index];
377 } else {
378 SkString name;
379 if (this->peekByte()) {
380 // If the first byte is non-zero, the flattenable is specified by a string.
381 this->readString(&name);
382
383 // Add the string to the dictionary.
384 fFlattenableDict.set(fFlattenableDict.count() + 1, name);
385 } else {
386 // Read the index. We are guaranteed that the first byte
387 // is zeroed, so we must shift down a byte.
388 uint32_t index = this->readUInt() >> 8;
389 if (index == 0) {
390 return nullptr; // writer failed to give us the flattenable
391 }
392 SkString* namePtr = fFlattenableDict.find(index);
393 if (!this->validate(namePtr != nullptr)) {
394 return nullptr;
395 }
396 name = *namePtr;
397 }
398
399 // Check if a custom Factory has been specified for this flattenable.
400 if (!(factory = this->getCustomFactory(name))) {
401 // If there is no custom Factory, check for a default.
402 if (!(factory = SkFlattenable::NameToFactory(name.c_str()))) {
403 return nullptr; // writer failed to give us the flattenable
404 }
405 }
406 }
407
408 // if we get here, factory may still be null, but if that is the case, the
409 // failure was ours, not the writer.
410 sk_sp<SkFlattenable> obj;
411 uint32_t sizeRecorded = this->read32();
412 if (factory) {
413 size_t offset = fReader.offset();
414 obj = (*factory)(*this);
415 // check that we read the amount we expected
416 size_t sizeRead = fReader.offset() - offset;
417 if (sizeRecorded != sizeRead) {
418 this->validate(false);
419 return nullptr;
420 }
421 if (obj && obj->getFlattenableType() != ft) {
422 this->validate(false);
423 return nullptr;
424 }
425 } else {
426 // we must skip the remaining data
427 fReader.skip(sizeRecorded);
428 }
429 return obj.release();
430 }
431
432 ///////////////////////////////////////////////////////////////////////////////////////////////////
433
checkInt(int32_t min,int32_t max)434 int32_t SkReadBuffer::checkInt(int32_t min, int32_t max) {
435 SkASSERT(min <= max);
436 int32_t value = this->read32();
437 if (value < min || value > max) {
438 this->validate(false);
439 value = min;
440 }
441 return value;
442 }
443
checkFilterQuality()444 SkFilterQuality SkReadBuffer::checkFilterQuality() {
445 return this->checkRange<SkFilterQuality>(kNone_SkFilterQuality, kLast_SkFilterQuality);
446 }
447