• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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