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 "include/core/SkBitmap.h"
9 #include "include/core/SkData.h"
10 #include "include/core/SkImage.h"
11 #include "include/core/SkImageGenerator.h"
12 #include "include/core/SkStream.h"
13 #include "include/core/SkTypeface.h"
14 #include "src/core/SkAutoMalloc.h"
15 #include "src/core/SkMakeUnique.h"
16 #include "src/core/SkMathPriv.h"
17 #include "src/core/SkMatrixPriv.h"
18 #include "src/core/SkReadBuffer.h"
19 #include "src/core/SkSafeMath.h"
20
21 #ifndef SK_DISABLE_READBUFFER
22
23 namespace {
24 // This generator intentionally should always fail on all attempts to get its pixels,
25 // simulating a bad or empty codec stream.
26 class EmptyImageGenerator final : public SkImageGenerator {
27 public:
EmptyImageGenerator(const SkImageInfo & info)28 EmptyImageGenerator(const SkImageInfo& info) : INHERITED(info) { }
29
30 private:
31 typedef SkImageGenerator INHERITED;
32 };
33
MakeEmptyImage(int width,int height)34 static sk_sp<SkImage> MakeEmptyImage(int width, int height) {
35 return SkImage::MakeFromGenerator(
36 skstd::make_unique<EmptyImageGenerator>(SkImageInfo::MakeN32Premul(width, height)));
37 }
38
39 } // anonymous namespace
40
41
SkReadBuffer()42 SkReadBuffer::SkReadBuffer() {
43 fVersion = 0;
44
45 fTFArray = nullptr;
46 fTFCount = 0;
47
48 fFactoryArray = nullptr;
49 fFactoryCount = 0;
50 }
51
SkReadBuffer(const void * data,size_t size)52 SkReadBuffer::SkReadBuffer(const void* data, size_t size) {
53 fVersion = 0;
54 this->setMemory(data, size);
55
56 fTFArray = nullptr;
57 fTFCount = 0;
58
59 fFactoryArray = nullptr;
60 fFactoryCount = 0;
61 }
62
setMemory(const void * data,size_t size)63 void SkReadBuffer::setMemory(const void* data, size_t size) {
64 this->validate(IsPtrAlign4(data) && (SkAlign4(size) == size));
65 if (!fError) {
66 fReader.setMemory(data, size);
67 }
68 }
setInvalid()69 void SkReadBuffer::setInvalid() {
70 if (!fError) {
71 // When an error is found, send the read cursor to the end of the stream
72 fReader.skip(fReader.available());
73 fError = true;
74 }
75 }
76
skip(size_t size)77 const void* SkReadBuffer::skip(size_t size) {
78 size_t inc = SkAlign4(size);
79 this->validate(inc >= size);
80 const void* addr = fReader.peek();
81 this->validate(IsPtrAlign4(addr) && fReader.isAvailable(inc));
82 if (fError) {
83 return nullptr;
84 }
85
86 fReader.skip(size);
87 return addr;
88 }
89
skip(size_t count,size_t size)90 const void* SkReadBuffer::skip(size_t count, size_t size) {
91 return this->skip(SkSafeMath::Mul(count, size));
92 }
93
setDeserialProcs(const SkDeserialProcs & procs)94 void SkReadBuffer::setDeserialProcs(const SkDeserialProcs& procs) {
95 fProcs = procs;
96 }
97
readBool()98 bool SkReadBuffer::readBool() {
99 uint32_t value = this->readUInt();
100 // Boolean value should be either 0 or 1
101 this->validate(!(value & ~1));
102 return value != 0;
103 }
104
readColor()105 SkColor SkReadBuffer::readColor() {
106 return this->readUInt();
107 }
108
readInt()109 int32_t SkReadBuffer::readInt() {
110 const size_t inc = sizeof(int32_t);
111 this->validate(IsPtrAlign4(fReader.peek()) && fReader.isAvailable(inc));
112 return fError ? 0 : fReader.readInt();
113 }
114
readScalar()115 SkScalar SkReadBuffer::readScalar() {
116 const size_t inc = sizeof(SkScalar);
117 this->validate(IsPtrAlign4(fReader.peek()) && fReader.isAvailable(inc));
118 return fError ? 0 : fReader.readScalar();
119 }
120
readUInt()121 uint32_t SkReadBuffer::readUInt() {
122 return this->readInt();
123 }
124
read32()125 int32_t SkReadBuffer::read32() {
126 return this->readInt();
127 }
128
peekByte()129 uint8_t SkReadBuffer::peekByte() {
130 if (fReader.available() <= 0) {
131 fError = true;
132 return 0;
133 }
134 return *((uint8_t*) fReader.peek());
135 }
136
readPad32(void * buffer,size_t bytes)137 bool SkReadBuffer::readPad32(void* buffer, size_t bytes) {
138 if (const void* src = this->skip(bytes)) {
139 memcpy(buffer, src, bytes);
140 return true;
141 }
142 return false;
143 }
144
readString(size_t * len)145 const char* SkReadBuffer::readString(size_t* len) {
146 *len = this->readUInt();
147
148 // The string is len characters and a terminating \0.
149 const char* c_str = this->skipT<char>(*len+1);
150
151 if (this->validate(c_str && c_str[*len] == '\0')) {
152 return c_str;
153 }
154 return nullptr;
155 }
156
readString(SkString * string)157 void SkReadBuffer::readString(SkString* string) {
158 size_t len;
159 if (const char* c_str = this->readString(&len)) {
160 string->set(c_str, len);
161 return;
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
readByteArrayAsData()263 sk_sp<SkData> SkReadBuffer::readByteArrayAsData() {
264 size_t numBytes = this->getArrayCount();
265 if (!this->validate(fReader.isAvailable(numBytes))) {
266 return nullptr;
267 }
268
269 SkAutoMalloc buffer(numBytes);
270 if (!this->readByteArray(buffer.get(), numBytes)) {
271 return nullptr;
272 }
273
274 return SkData::MakeFromMalloc(buffer.release(), numBytes);
275 }
276
getArrayCount()277 uint32_t SkReadBuffer::getArrayCount() {
278 const size_t inc = sizeof(uint32_t);
279 fError = fError || !IsPtrAlign4(fReader.peek()) || !fReader.isAvailable(inc);
280 return fError ? 0 : *(uint32_t*)fReader.peek();
281 }
282
283 /* Format:
284 * (subset) width, height
285 * (subset) origin x, y
286 * size (31bits)
287 * data [ encoded, with raw width/height ]
288 */
readImage()289 sk_sp<SkImage> SkReadBuffer::readImage() {
290 SkIRect bounds;
291 if (this->isVersionLT(SkPicturePriv::kStoreImageBounds_Version)) {
292 bounds.fLeft = bounds.fTop = 0;
293 bounds.fRight = this->read32();
294 bounds.fBottom = this->read32();
295 } else {
296 this->readIRect(&bounds);
297 }
298 const int width = bounds.width();
299 const int height = bounds.height();
300 if (width <= 0 || height <= 0) { // SkImage never has a zero dimension
301 this->validate(false);
302 return nullptr;
303 }
304
305 int32_t size = this->read32();
306 if (size == SK_NaN32) {
307 // 0x80000000 is never valid, since it cannot be passed to abs().
308 this->validate(false);
309 return nullptr;
310 }
311 if (size == 0) {
312 // The image could not be encoded at serialization time - return an empty placeholder.
313 return MakeEmptyImage(width, height);
314 }
315
316 // we used to negate the size for "custom" encoded images -- ignore that signal (Dec-2017)
317 size = SkAbs32(size);
318 if (size == 1) {
319 // legacy check (we stopped writing this for "raw" images Nov-2017)
320 this->validate(false);
321 return nullptr;
322 }
323
324 // Preflight check to make sure there's enough stuff in the buffer before
325 // we allocate the memory. This helps the fuzzer avoid OOM when it creates
326 // bad/corrupt input.
327 if (!this->validateCanReadN<uint8_t>(size)) {
328 return nullptr;
329 }
330
331 sk_sp<SkData> data = SkData::MakeUninitialized(size);
332 if (!this->readPad32(data->writable_data(), size)) {
333 this->validate(false);
334 return nullptr;
335 }
336 if (this->isVersionLT(SkPicturePriv::kDontNegateImageSize_Version)) {
337 (void)this->read32(); // originX
338 (void)this->read32(); // originY
339 }
340
341 sk_sp<SkImage> image;
342 if (fProcs.fImageProc) {
343 image = fProcs.fImageProc(data->data(), data->size(), fProcs.fImageCtx);
344 }
345 if (!image) {
346 image = SkImage::MakeFromEncoded(std::move(data));
347 }
348 if (image) {
349 if (bounds.x() || bounds.y() || width < image->width() || height < image->height()) {
350 image = image->makeSubset(bounds);
351 }
352 }
353 // Question: are we correct to return an "empty" image instead of nullptr, if the decoder
354 // failed for some reason?
355 return image ? image : MakeEmptyImage(width, height);
356 }
357
readTypeface()358 sk_sp<SkTypeface> SkReadBuffer::readTypeface() {
359 // Read 32 bits (signed)
360 // 0 -- return null (default font)
361 // >0 -- index
362 // <0 -- custom (serial procs) : negative size in bytes
363
364 int32_t index = this->read32();
365 if (index == 0) {
366 return nullptr;
367 } else if (index > 0) {
368 if (!this->validate(index <= fTFCount)) {
369 return nullptr;
370 }
371 return fTFArray[index - 1];
372 } else { // custom
373 size_t size = sk_negate_to_size_t(index);
374 const void* data = this->skip(size);
375 if (!this->validate(data != nullptr && fProcs.fTypefaceProc)) {
376 return nullptr;
377 }
378 return fProcs.fTypefaceProc(data, size, fProcs.fTypefaceCtx);
379 }
380 }
381
readFlattenable(SkFlattenable::Type ft)382 SkFlattenable* SkReadBuffer::readFlattenable(SkFlattenable::Type ft) {
383 SkFlattenable::Factory factory = nullptr;
384
385 if (fFactoryCount > 0) {
386 int32_t index = this->read32();
387 if (0 == index || !this->isValid()) {
388 return nullptr; // writer failed to give us the flattenable
389 }
390 index -= 1; // we stored the index-base-1
391 if ((unsigned)index >= (unsigned)fFactoryCount) {
392 this->validate(false);
393 return nullptr;
394 }
395 factory = fFactoryArray[index];
396 } else {
397 if (this->peekByte() != 0) {
398 // If the first byte is non-zero, the flattenable is specified by a string.
399 size_t ignored_length;
400 if (const char* name = this->readString(&ignored_length)) {
401 factory = SkFlattenable::NameToFactory(name);
402 fFlattenableDict.set(fFlattenableDict.count() + 1, factory);
403 }
404 } else {
405 // Read the index. We are guaranteed that the first byte
406 // is zeroed, so we must shift down a byte.
407 uint32_t index = this->readUInt() >> 8;
408 if (index == 0) {
409 return nullptr; // writer failed to give us the flattenable
410 }
411
412 if (SkFlattenable::Factory* found = fFlattenableDict.find(index)) {
413 factory = *found;
414 }
415 }
416
417 if (!this->validate(factory != nullptr)) {
418 return nullptr;
419 }
420 }
421
422 // if we get here, factory may still be null, but if that is the case, the
423 // failure was ours, not the writer.
424 sk_sp<SkFlattenable> obj;
425 uint32_t sizeRecorded = this->read32();
426 if (factory) {
427 size_t offset = fReader.offset();
428 obj = (*factory)(*this);
429 // check that we read the amount we expected
430 size_t sizeRead = fReader.offset() - offset;
431 if (sizeRecorded != sizeRead) {
432 this->validate(false);
433 return nullptr;
434 }
435 if (obj && obj->getFlattenableType() != ft) {
436 this->validate(false);
437 return nullptr;
438 }
439 } else {
440 // we must skip the remaining data
441 fReader.skip(sizeRecorded);
442 }
443 if (!this->isValid()) {
444 return nullptr;
445 }
446 return obj.release();
447 }
448
449 ///////////////////////////////////////////////////////////////////////////////////////////////////
450
checkInt(int32_t min,int32_t max)451 int32_t SkReadBuffer::checkInt(int32_t min, int32_t max) {
452 SkASSERT(min <= max);
453 int32_t value = this->read32();
454 if (value < min || value > max) {
455 this->validate(false);
456 value = min;
457 }
458 return value;
459 }
460
checkFilterQuality()461 SkFilterQuality SkReadBuffer::checkFilterQuality() {
462 return this->checkRange<SkFilterQuality>(kNone_SkFilterQuality, kLast_SkFilterQuality);
463 }
464
465 #endif // #ifndef SK_DISABLE_READBUFFER
466