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