Home | History | Annotate | Download | only in core
      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:
     25         EmptyImageGenerator(const SkImageInfo& info) : INHERITED(info) { }
     26 
     27     private:
     28         typedef SkImageGenerator INHERITED;
     29     };
     30 
     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 
     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 
     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 
     68 SkReadBuffer::~SkReadBuffer() {
     69     sk_free(fMemoryPtr);
     70 }
     71 
     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 }
     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 
     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 
     99 const void* SkReadBuffer::skip(size_t count, size_t size) {
    100     return this->skip(SkSafeMath::Mul(count, size));
    101 }
    102 
    103 void SkReadBuffer::setDeserialProcs(const SkDeserialProcs& procs) {
    104     fProcs = procs;
    105 }
    106 
    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 
    114 SkColor SkReadBuffer::readColor() {
    115     return this->readUInt();
    116 }
    117 
    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 
    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 
    130 uint32_t SkReadBuffer::readUInt() {
    131     return this->readInt();
    132 }
    133 
    134 int32_t SkReadBuffer::read32() {
    135     return this->readInt();
    136 }
    137 
    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 
    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 
    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 
    166 void SkReadBuffer::readColor4f(SkColor4f* color) {
    167     if (!this->readPad32(color, sizeof(SkColor4f))) {
    168         *color = {0, 0, 0, 0};
    169     }
    170 }
    171 
    172 void SkReadBuffer::readPoint(SkPoint* point) {
    173     point->fX = this->readScalar();
    174     point->fY = this->readScalar();
    175 }
    176 
    177 void SkReadBuffer::readPoint3(SkPoint3* point) {
    178     this->readPad32(point, sizeof(SkPoint3));
    179 }
    180 
    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 
    193 void SkReadBuffer::readIRect(SkIRect* rect) {
    194     if (!this->readPad32(rect, sizeof(SkIRect))) {
    195         rect->setEmpty();
    196     }
    197 }
    198 
    199 void SkReadBuffer::readRect(SkRect* rect) {
    200     if (!this->readPad32(rect, sizeof(SkRect))) {
    201         rect->setEmpty();
    202     }
    203 }
    204 
    205 void SkReadBuffer::readRRect(SkRRect* rrect) {
    206     if (!this->validate(fReader.readRRect(rrect))) {
    207         rrect->setEmpty();
    208     }
    209 }
    210 
    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 
    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 
    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 
    239 bool SkReadBuffer::readByteArray(void* value, size_t size) {
    240     return this->readArray(value, size, sizeof(uint8_t));
    241 }
    242 
    243 bool SkReadBuffer::readColorArray(SkColor* colors, size_t size) {
    244     return this->readArray(colors, size, sizeof(SkColor));
    245 }
    246 
    247 bool SkReadBuffer::readColor4fArray(SkColor4f* colors, size_t size) {
    248     return this->readArray(colors, size, sizeof(SkColor4f));
    249 }
    250 
    251 bool SkReadBuffer::readIntArray(int32_t* values, size_t size) {
    252     return this->readArray(values, size, sizeof(int32_t));
    253 }
    254 
    255 bool SkReadBuffer::readPointArray(SkPoint* points, size_t size) {
    256     return this->readArray(points, size, sizeof(SkPoint));
    257 }
    258 
    259 bool SkReadBuffer::readScalarArray(SkScalar* values, size_t size) {
    260     return this->readArray(values, size, sizeof(SkScalar));
    261 }
    262 
    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 
    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 
    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 
    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 
    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 
    444 SkFilterQuality SkReadBuffer::checkFilterQuality() {
    445     return this->checkRange<SkFilterQuality>(kNone_SkFilterQuality, kLast_SkFilterQuality);
    446 }
    447