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 if (!this->validate((SkAlign4(size) == size) && (0 != size))) { 186 matrix->reset(); 187 } 188 } 189 (void)this->skip(size); 190 } 191 192 void SkReadBuffer::readIRect(SkIRect* rect) { 193 if (!this->readPad32(rect, sizeof(SkIRect))) { 194 rect->setEmpty(); 195 } 196 } 197 198 void SkReadBuffer::readRect(SkRect* rect) { 199 if (!this->readPad32(rect, sizeof(SkRect))) { 200 rect->setEmpty(); 201 } 202 } 203 204 void SkReadBuffer::readRRect(SkRRect* rrect) { 205 if (!this->validate(fReader.readRRect(rrect))) { 206 rrect->setEmpty(); 207 } 208 } 209 210 void SkReadBuffer::readRegion(SkRegion* region) { 211 size_t size = 0; 212 if (!fError) { 213 size = region->readFromMemory(fReader.peek(), fReader.available()); 214 if (!this->validate((SkAlign4(size) == size) && (0 != size))) { 215 region->setEmpty(); 216 } 217 } 218 (void)this->skip(size); 219 } 220 221 void SkReadBuffer::readPath(SkPath* path) { 222 size_t size = 0; 223 if (!fError) { 224 size = path->readFromMemory(fReader.peek(), fReader.available()); 225 if (!this->validate((SkAlign4(size) == size) && (0 != size))) { 226 path->reset(); 227 } 228 } 229 (void)this->skip(size); 230 } 231 232 bool SkReadBuffer::readArray(void* value, size_t size, size_t elementSize) { 233 const uint32_t count = this->readUInt(); 234 return this->validate(size == count) && 235 this->readPad32(value, SkSafeMath::Mul(size, elementSize)); 236 } 237 238 bool SkReadBuffer::readByteArray(void* value, size_t size) { 239 return this->readArray(value, size, sizeof(uint8_t)); 240 } 241 242 bool SkReadBuffer::readColorArray(SkColor* colors, size_t size) { 243 return this->readArray(colors, size, sizeof(SkColor)); 244 } 245 246 bool SkReadBuffer::readColor4fArray(SkColor4f* colors, size_t size) { 247 return this->readArray(colors, size, sizeof(SkColor4f)); 248 } 249 250 bool SkReadBuffer::readIntArray(int32_t* values, size_t size) { 251 return this->readArray(values, size, sizeof(int32_t)); 252 } 253 254 bool SkReadBuffer::readPointArray(SkPoint* points, size_t size) { 255 return this->readArray(points, size, sizeof(SkPoint)); 256 } 257 258 bool SkReadBuffer::readScalarArray(SkScalar* values, size_t size) { 259 return this->readArray(values, size, sizeof(SkScalar)); 260 } 261 262 uint32_t SkReadBuffer::getArrayCount() { 263 const size_t inc = sizeof(uint32_t); 264 fError = fError || !IsPtrAlign4(fReader.peek()) || !fReader.isAvailable(inc); 265 return fError ? 0 : *(uint32_t*)fReader.peek(); 266 } 267 268 sk_sp<SkImage> SkReadBuffer::readImage() { 269 if (fInflator) { 270 SkImage* img = fInflator->getImage(this->read32()); 271 return img ? sk_ref_sp(img) : nullptr; 272 } 273 274 int width = this->read32(); 275 int height = this->read32(); 276 if (width <= 0 || height <= 0) { // SkImage never has a zero dimension 277 this->validate(false); 278 return nullptr; 279 } 280 281 /* 282 * What follows is a 32bit encoded size. 283 * 0 : failure, nothing else to do 284 * <0 : negative (int32_t) of a custom encoded blob using SerialProcs 285 * >0 : standard encoded blob size (use MakeFromEncoded) 286 */ 287 288 int32_t encoded_size = this->read32(); 289 if (encoded_size == 0) { 290 // The image could not be encoded at serialization time - return an empty placeholder. 291 return MakeEmptyImage(width, height); 292 } 293 if (encoded_size == 1) { 294 // legacy check (we stopped writing this for "raw" images Nov-2017) 295 this->validate(false); 296 return nullptr; 297 } 298 299 size_t size = SkAbs32(encoded_size); 300 sk_sp<SkData> data = SkData::MakeUninitialized(size); 301 if (!this->readPad32(data->writable_data(), size)) { 302 this->validate(false); 303 return nullptr; 304 } 305 int32_t originX = this->read32(); 306 int32_t originY = this->read32(); 307 if (originX < 0 || originY < 0) { 308 this->validate(false); 309 return nullptr; 310 } 311 312 sk_sp<SkImage> image; 313 if (encoded_size < 0) { // custom encoded, need serial proc 314 if (fProcs.fImageProc) { 315 image = fProcs.fImageProc(data->data(), data->size(), fProcs.fImageCtx); 316 } else { 317 // Nothing to do (no client proc), but since we've already "read" the custom data, 318 // wee just leave image as nullptr. 319 } 320 } else { 321 SkIRect subset = SkIRect::MakeXYWH(originX, originY, width, height); 322 image = SkImage::MakeFromEncoded(std::move(data), &subset); 323 } 324 // Question: are we correct to return an "empty" image instead of nullptr, if the decoder 325 // failed for some reason? 326 return image ? image : MakeEmptyImage(width, height); 327 } 328 329 sk_sp<SkTypeface> SkReadBuffer::readTypeface() { 330 if (fInflator) { 331 return sk_ref_sp(fInflator->getTypeface(this->read32())); 332 } 333 334 // Read 32 bits (signed) 335 // 0 -- return null (default font) 336 // >0 -- index 337 // <0 -- custom (serial procs) : negative size in bytes 338 339 int32_t index = this->read32(); 340 if (index == 0) { 341 return nullptr; 342 } else if (index > 0) { 343 if (!this->validate(index <= fTFCount)) { 344 return nullptr; 345 } 346 return sk_ref_sp(fTFArray[index - 1]); 347 } else { // custom 348 size_t size = sk_negate_to_size_t(index); 349 const void* data = this->skip(size); 350 if (!this->validate(data != nullptr && fProcs.fTypefaceProc)) { 351 return nullptr; 352 } 353 return fProcs.fTypefaceProc(data, size, fProcs.fTypefaceCtx); 354 } 355 } 356 357 SkFlattenable* SkReadBuffer::readFlattenable(SkFlattenable::Type ft) { 358 SkFlattenable::Factory factory = nullptr; 359 360 if (fInflator) { 361 factory = fInflator->getFactory(this->read32()); 362 if (!factory) { 363 return nullptr; 364 } 365 } else if (fFactoryCount > 0) { 366 int32_t index = this->read32(); 367 if (0 == index || !this->isValid()) { 368 return nullptr; // writer failed to give us the flattenable 369 } 370 index -= 1; // we stored the index-base-1 371 if ((unsigned)index >= (unsigned)fFactoryCount) { 372 this->validate(false); 373 return nullptr; 374 } 375 factory = fFactoryArray[index]; 376 } else { 377 SkString name; 378 if (this->peekByte()) { 379 // If the first byte is non-zero, the flattenable is specified by a string. 380 this->readString(&name); 381 382 // Add the string to the dictionary. 383 fFlattenableDict.set(fFlattenableDict.count() + 1, name); 384 } else { 385 // Read the index. We are guaranteed that the first byte 386 // is zeroed, so we must shift down a byte. 387 uint32_t index = this->readUInt() >> 8; 388 if (index == 0) { 389 return nullptr; // writer failed to give us the flattenable 390 } 391 SkString* namePtr = fFlattenableDict.find(index); 392 if (!this->validate(namePtr != nullptr)) { 393 return nullptr; 394 } 395 name = *namePtr; 396 } 397 398 // Check if a custom Factory has been specified for this flattenable. 399 if (!(factory = this->getCustomFactory(name))) { 400 // If there is no custom Factory, check for a default. 401 if (!(factory = SkFlattenable::NameToFactory(name.c_str()))) { 402 return nullptr; // writer failed to give us the flattenable 403 } 404 } 405 } 406 407 // if we get here, factory may still be null, but if that is the case, the 408 // failure was ours, not the writer. 409 sk_sp<SkFlattenable> obj; 410 uint32_t sizeRecorded = this->read32(); 411 if (factory) { 412 size_t offset = fReader.offset(); 413 obj = (*factory)(*this); 414 // check that we read the amount we expected 415 size_t sizeRead = fReader.offset() - offset; 416 if (sizeRecorded != sizeRead) { 417 this->validate(false); 418 return nullptr; 419 } 420 if (obj && obj->getFlattenableType() != ft) { 421 this->validate(false); 422 return nullptr; 423 } 424 } else { 425 // we must skip the remaining data 426 fReader.skip(sizeRecorded); 427 } 428 return obj.release(); 429 } 430 431 /////////////////////////////////////////////////////////////////////////////////////////////////// 432 433 int32_t SkReadBuffer::checkInt(int32_t min, int32_t max) { 434 SkASSERT(min <= max); 435 int32_t value = this->read32(); 436 if (value < min || value > max) { 437 this->validate(false); 438 value = min; 439 } 440 return value; 441 } 442 443 SkFilterQuality SkReadBuffer::checkFilterQuality() { 444 return this->checkRange<SkFilterQuality>(kNone_SkFilterQuality, kLast_SkFilterQuality); 445 } 446