LCOV - code coverage report
Current view: top level - gfx/skia/skia/src/core - SkValidatingReadBuffer.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 178 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 33 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright 2013 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 "SkValidatingReadBuffer.h"
      10             : #include "SkStream.h"
      11             : #include "SkTypeface.h"
      12             : 
      13           0 : SkValidatingReadBuffer::SkValidatingReadBuffer(const void* data, size_t size) :
      14           0 :     fError(false) {
      15           0 :     this->setMemory(data, size);
      16           0 :     this->setFlags(SkReadBuffer::kValidation_Flag);
      17           0 : }
      18             : 
      19           0 : SkValidatingReadBuffer::~SkValidatingReadBuffer() {
      20           0 : }
      21             : 
      22           0 : bool SkValidatingReadBuffer::validate(bool isValid) {
      23           0 :     if (!fError && !isValid) {
      24             :         // When an error is found, send the read cursor to the end of the stream
      25           0 :         fReader.skip(fReader.available());
      26           0 :         fError = true;
      27             :     }
      28           0 :     return !fError;
      29             : }
      30             : 
      31           0 : bool SkValidatingReadBuffer::isValid() const {
      32           0 :     return !fError;
      33             : }
      34             : 
      35           0 : void SkValidatingReadBuffer::setMemory(const void* data, size_t size) {
      36           0 :     this->validate(IsPtrAlign4(data) && (SkAlign4(size) == size));
      37           0 :     if (!fError) {
      38           0 :         fReader.setMemory(data, size);
      39             :     }
      40           0 : }
      41             : 
      42           0 : const void* SkValidatingReadBuffer::skip(size_t size) {
      43           0 :     size_t inc = SkAlign4(size);
      44           0 :     this->validate(inc >= size);
      45           0 :     const void* addr = fReader.peek();
      46           0 :     this->validate(IsPtrAlign4(addr) && fReader.isAvailable(inc));
      47           0 :     if (fError) {
      48           0 :         return nullptr;
      49             :     }
      50             : 
      51           0 :     fReader.skip(size);
      52           0 :     return addr;
      53             : }
      54             : 
      55             : // All the methods in this file funnel down into either readInt(), readScalar() or skip(),
      56             : // followed by a memcpy. So we've got all our validation in readInt(), readScalar() and skip();
      57             : // if they fail they'll return a zero value or skip nothing, respectively, and set fError to
      58             : // true, which the caller should check to see if an error occurred during the read operation.
      59             : 
      60           0 : bool SkValidatingReadBuffer::readBool() {
      61           0 :     uint32_t value = this->readInt();
      62             :     // Boolean value should be either 0 or 1
      63           0 :     this->validate(!(value & ~1));
      64           0 :     return value != 0;
      65             : }
      66             : 
      67           0 : SkColor SkValidatingReadBuffer::readColor() {
      68           0 :     return this->readInt();
      69             : }
      70             : 
      71           0 : int32_t SkValidatingReadBuffer::readInt() {
      72           0 :     const size_t inc = sizeof(int32_t);
      73           0 :     this->validate(IsPtrAlign4(fReader.peek()) && fReader.isAvailable(inc));
      74           0 :     return fError ? 0 : fReader.readInt();
      75             : }
      76             : 
      77           0 : SkScalar SkValidatingReadBuffer::readScalar() {
      78           0 :     const size_t inc = sizeof(SkScalar);
      79           0 :     this->validate(IsPtrAlign4(fReader.peek()) && fReader.isAvailable(inc));
      80           0 :     return fError ? 0 : fReader.readScalar();
      81             : }
      82             : 
      83           0 : uint32_t SkValidatingReadBuffer::readUInt() {
      84           0 :     return this->readInt();
      85             : }
      86             : 
      87           0 : int32_t SkValidatingReadBuffer::read32() {
      88           0 :     return this->readInt();
      89             : }
      90             : 
      91           0 : uint8_t SkValidatingReadBuffer::peekByte() {
      92           0 :     if (fReader.available() <= 0) {
      93           0 :         fError = true;
      94           0 :         return 0;
      95             :     }
      96           0 :     return *((uint8_t*) fReader.peek());
      97             : }
      98             : 
      99           0 : void SkValidatingReadBuffer::readString(SkString* string) {
     100           0 :     const size_t len = this->readUInt();
     101           0 :     const void* ptr = fReader.peek();
     102           0 :     const char* cptr = (const char*)ptr;
     103             : 
     104             :     // skip over the string + '\0' and then pad to a multiple of 4
     105           0 :     const size_t alignedSize = SkAlign4(len + 1);
     106           0 :     this->skip(alignedSize);
     107           0 :     if (!fError) {
     108           0 :         this->validate(cptr[len] == '\0');
     109             :     }
     110           0 :     if (!fError) {
     111           0 :         string->set(cptr, len);
     112             :     }
     113           0 : }
     114             : 
     115           0 : void SkValidatingReadBuffer::readColor4f(SkColor4f* color) {
     116           0 :     const void* ptr = this->skip(sizeof(SkColor4f));
     117           0 :     if (!fError) {
     118           0 :         memcpy(color, ptr, sizeof(SkColor4f));
     119             :     }
     120           0 : }
     121             : 
     122           0 : void SkValidatingReadBuffer::readPoint(SkPoint* point) {
     123           0 :     point->fX = this->readScalar();
     124           0 :     point->fY = this->readScalar();
     125           0 : }
     126             : 
     127           0 : void SkValidatingReadBuffer::readMatrix(SkMatrix* matrix) {
     128           0 :     size_t size = 0;
     129           0 :     if (!fError) {
     130           0 :         size = matrix->readFromMemory(fReader.peek(), fReader.available());
     131           0 :         this->validate((SkAlign4(size) == size) && (0 != size));
     132             :     }
     133           0 :     if (!fError) {
     134           0 :         (void)this->skip(size);
     135             :     }
     136           0 : }
     137             : 
     138           0 : void SkValidatingReadBuffer::readIRect(SkIRect* rect) {
     139           0 :     const void* ptr = this->skip(sizeof(SkIRect));
     140           0 :     if (!fError) {
     141           0 :         memcpy(rect, ptr, sizeof(SkIRect));
     142             :     }
     143           0 : }
     144             : 
     145           0 : void SkValidatingReadBuffer::readRect(SkRect* rect) {
     146           0 :     const void* ptr = this->skip(sizeof(SkRect));
     147           0 :     if (!fError) {
     148           0 :         memcpy(rect, ptr, sizeof(SkRect));
     149             :     }
     150           0 : }
     151             : 
     152           0 : void SkValidatingReadBuffer::readRRect(SkRRect* rrect) {
     153           0 :     const void* ptr = this->skip(sizeof(SkRRect));
     154           0 :     if (!fError) {
     155           0 :         memcpy(rrect, ptr, sizeof(SkRRect));
     156           0 :         this->validate(rrect->isValid());
     157             :     }
     158             : 
     159           0 :     if (fError) {
     160           0 :         rrect->setEmpty();
     161             :     }
     162           0 : }
     163             : 
     164           0 : void SkValidatingReadBuffer::readRegion(SkRegion* region) {
     165           0 :     size_t size = 0;
     166           0 :     if (!fError) {
     167           0 :         size = region->readFromMemory(fReader.peek(), fReader.available());
     168           0 :         this->validate((SkAlign4(size) == size) && (0 != size));
     169             :     }
     170           0 :     if (!fError) {
     171           0 :         (void)this->skip(size);
     172             :     }
     173           0 : }
     174             : 
     175           0 : void SkValidatingReadBuffer::readPath(SkPath* path) {
     176           0 :     size_t size = 0;
     177           0 :     if (!fError) {
     178           0 :         size = path->readFromMemory(fReader.peek(), fReader.available());
     179           0 :         this->validate((SkAlign4(size) == size) && (0 != size));
     180             :     }
     181           0 :     if (!fError) {
     182           0 :         (void)this->skip(size);
     183             :     }
     184           0 : }
     185             : 
     186           0 : bool SkValidatingReadBuffer::readArray(void* value, size_t size, size_t elementSize) {
     187           0 :     const uint32_t count = this->getArrayCount();
     188           0 :     this->validate(size == count);
     189           0 :     (void)this->skip(sizeof(uint32_t)); // Skip array count
     190           0 :     const uint64_t byteLength64 = sk_64_mul(count, elementSize);
     191           0 :     const size_t byteLength = count * elementSize;
     192           0 :     this->validate(byteLength == byteLength64);
     193           0 :     const void* ptr = this->skip(SkAlign4(byteLength));
     194           0 :     if (!fError) {
     195           0 :         memcpy(value, ptr, byteLength);
     196           0 :         return true;
     197             :     }
     198           0 :     return false;
     199             : }
     200             : 
     201           0 : bool SkValidatingReadBuffer::readByteArray(void* value, size_t size) {
     202           0 :     return this->readArray(static_cast<unsigned char*>(value), size, sizeof(unsigned char));
     203             : }
     204             : 
     205           0 : bool SkValidatingReadBuffer::readColorArray(SkColor* colors, size_t size) {
     206           0 :     return this->readArray(colors, size, sizeof(SkColor));
     207             : }
     208             : 
     209           0 : bool SkValidatingReadBuffer::readColor4fArray(SkColor4f* colors, size_t size) {
     210           0 :     return this->readArray(colors, size, sizeof(SkColor4f));
     211             : }
     212             : 
     213           0 : bool SkValidatingReadBuffer::readIntArray(int32_t* values, size_t size) {
     214           0 :     return this->readArray(values, size, sizeof(int32_t));
     215             : }
     216             : 
     217           0 : bool SkValidatingReadBuffer::readPointArray(SkPoint* points, size_t size) {
     218           0 :     return this->readArray(points, size, sizeof(SkPoint));
     219             : }
     220             : 
     221           0 : bool SkValidatingReadBuffer::readScalarArray(SkScalar* values, size_t size) {
     222           0 :     return this->readArray(values, size, sizeof(SkScalar));
     223             : }
     224             : 
     225           0 : uint32_t SkValidatingReadBuffer::getArrayCount() {
     226           0 :     const size_t inc = sizeof(uint32_t);
     227           0 :     fError = fError || !IsPtrAlign4(fReader.peek()) || !fReader.isAvailable(inc);
     228           0 :     return fError ? 0 : *(uint32_t*)fReader.peek();
     229             : }
     230             : 
     231           0 : bool SkValidatingReadBuffer::validateAvailable(size_t size) {
     232           0 :     return this->validate((size <= SK_MaxU32) && fReader.isAvailable(static_cast<uint32_t>(size)));
     233             : }
     234             : 
     235           0 : SkFlattenable* SkValidatingReadBuffer::readFlattenable(SkFlattenable::Type type) {
     236             :     // The validating read buffer always uses strings and string-indices for unflattening.
     237           0 :     SkASSERT(0 == this->factoryCount());
     238             : 
     239           0 :     uint8_t firstByte = this->peekByte();
     240           0 :     if (fError) {
     241           0 :         return nullptr;
     242             :     }
     243             : 
     244           0 :     SkString name;
     245           0 :     if (firstByte) {
     246             :         // If the first byte is non-zero, the flattenable is specified by a string.
     247           0 :         this->readString(&name);
     248           0 :         if (fError) {
     249           0 :             return nullptr;
     250             :         }
     251             : 
     252             :         // Add the string to the dictionary.
     253           0 :         fFlattenableDict.set(fFlattenableDict.count() + 1, name);
     254             :     } else {
     255             :         // Read the index.  We are guaranteed that the first byte
     256             :         // is zeroed, so we must shift down a byte.
     257           0 :         uint32_t index = this->readUInt() >> 8;
     258           0 :         if (0 == index) {
     259           0 :             return nullptr; // writer failed to give us the flattenable
     260             :         }
     261             : 
     262           0 :         SkString* namePtr = fFlattenableDict.find(index);
     263           0 :         if (!namePtr) {
     264           0 :             return nullptr;
     265             :         }
     266           0 :         name = *namePtr;
     267             :     }
     268             : 
     269             :     // Is this the type we wanted ?
     270           0 :     const char* cname = name.c_str();
     271             :     SkFlattenable::Type baseType;
     272           0 :     if (!SkFlattenable::NameToType(cname, &baseType) || (baseType != type)) {
     273           0 :         return nullptr;
     274             :     }
     275             : 
     276             :     // Get the factory for this flattenable.
     277           0 :     SkFlattenable::Factory factory = this->getCustomFactory(name);
     278           0 :     if (!factory) {
     279           0 :         factory = SkFlattenable::NameToFactory(cname);
     280           0 :         if (!factory) {
     281           0 :             return nullptr; // writer failed to give us the flattenable
     282             :         }
     283             :     }
     284             : 
     285             :     // If we get here, the factory is non-null.
     286           0 :     sk_sp<SkFlattenable> obj;
     287           0 :     uint32_t sizeRecorded = this->readUInt();
     288           0 :     size_t offset = fReader.offset();
     289           0 :     obj = (*factory)(*this);
     290             :     // check that we read the amount we expected
     291           0 :     size_t sizeRead = fReader.offset() - offset;
     292           0 :     this->validate(sizeRecorded == sizeRead);
     293           0 :     if (fError) {
     294           0 :         obj = nullptr;
     295             :     }
     296           0 :     return obj.release();
     297             : }

Generated by: LCOV version 1.13