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