13218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org/* 23218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org * Copyright 2013 Google Inc. 33218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org * 43218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org * Use of this source code is governed by a BSD-style license that can be 53218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org * found in the LICENSE file. 63218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org */ 73218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org 83218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org#include "SkBitmap.h" 93218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org#include "SkErrorInternals.h" 103218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org#include "SkValidatingReadBuffer.h" 113218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org#include "SkStream.h" 123218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org#include "SkTypeface.h" 133218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org 1424cb5def8c993a224c1d9af53e9cdbc28e3e5105commit-bot@chromium.orgSkValidatingReadBuffer::SkValidatingReadBuffer(const void* data, size_t size) : 1524cb5def8c993a224c1d9af53e9cdbc28e3e5105commit-bot@chromium.org fError(false) { 163218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org this->setMemory(data, size); 173218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org this->setFlags(SkFlattenableReadBuffer::kValidation_Flag); 183218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org} 193218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org 203218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.orgSkValidatingReadBuffer::~SkValidatingReadBuffer() { 213218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org} 223218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org 23ae553db4c7e96b5de88a78c8d195f34f8ea94d8ecommit-bot@chromium.orgbool SkValidatingReadBuffer::validate(bool isValid) { 24863cb3951e8da2d2eb8efd57c94d8f5ba069123ccommit-bot@chromium.org if (!fError && !isValid) { 25863cb3951e8da2d2eb8efd57c94d8f5ba069123ccommit-bot@chromium.org // When an error is found, send the read cursor to the end of the stream 26863cb3951e8da2d2eb8efd57c94d8f5ba069123ccommit-bot@chromium.org fReader.skip(fReader.available()); 27863cb3951e8da2d2eb8efd57c94d8f5ba069123ccommit-bot@chromium.org fError = true; 28863cb3951e8da2d2eb8efd57c94d8f5ba069123ccommit-bot@chromium.org } 29ae553db4c7e96b5de88a78c8d195f34f8ea94d8ecommit-bot@chromium.org return !fError; 30863cb3951e8da2d2eb8efd57c94d8f5ba069123ccommit-bot@chromium.org} 31863cb3951e8da2d2eb8efd57c94d8f5ba069123ccommit-bot@chromium.org 32ce9b6b24ac76aa0494ca27509a215d4abb5640e2commit-bot@chromium.orgbool SkValidatingReadBuffer::isValid() const { 33ce9b6b24ac76aa0494ca27509a215d4abb5640e2commit-bot@chromium.org return !fError; 34ce9b6b24ac76aa0494ca27509a215d4abb5640e2commit-bot@chromium.org} 35ce9b6b24ac76aa0494ca27509a215d4abb5640e2commit-bot@chromium.org 363218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.orgvoid SkValidatingReadBuffer::setMemory(const void* data, size_t size) { 37863cb3951e8da2d2eb8efd57c94d8f5ba069123ccommit-bot@chromium.org this->validate(IsPtrAlign4(data) && (SkAlign4(size) == size)); 383218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org if (!fError) { 393218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org fReader.setMemory(data, size); 403218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org } 413218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org} 423218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org 433218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.orgconst void* SkValidatingReadBuffer::skip(size_t size) { 443218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org size_t inc = SkAlign4(size); 453218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org const void* addr = fReader.peek(); 46863cb3951e8da2d2eb8efd57c94d8f5ba069123ccommit-bot@chromium.org this->validate(IsPtrAlign4(addr) && fReader.isAvailable(inc)); 473218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org if (!fError) { 483218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org fReader.skip(size); 493218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org } 503218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org return addr; 513218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org} 523218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org 533218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org// All the methods in this file funnel down into either readInt(), readScalar() or skip(), 543218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org// followed by a memcpy. So we've got all our validation in readInt(), readScalar() and skip(); 553218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org// if they fail they'll return a zero value or skip nothing, respectively, and set fError to 563218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org// true, which the caller should check to see if an error occurred during the read operation. 573218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org 583218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.orgbool SkValidatingReadBuffer::readBool() { 59e58089fa3c17cad3d8836256218ccb1e6020cf54commit-bot@chromium.org uint32_t value = this->readInt(); 60e58089fa3c17cad3d8836256218ccb1e6020cf54commit-bot@chromium.org // Boolean value should be either 0 or 1 61863cb3951e8da2d2eb8efd57c94d8f5ba069123ccommit-bot@chromium.org this->validate(!(value & ~1)); 62e58089fa3c17cad3d8836256218ccb1e6020cf54commit-bot@chromium.org return value != 0; 633218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org} 643218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org 653218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.orgSkColor SkValidatingReadBuffer::readColor() { 663218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org return this->readInt(); 673218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org} 683218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org 693218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.orgSkFixed SkValidatingReadBuffer::readFixed() { 703218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org return this->readInt(); 713218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org} 723218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org 733218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.orgint32_t SkValidatingReadBuffer::readInt() { 743218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org const size_t inc = sizeof(int32_t); 75863cb3951e8da2d2eb8efd57c94d8f5ba069123ccommit-bot@chromium.org this->validate(IsPtrAlign4(fReader.peek()) && fReader.isAvailable(inc)); 763218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org return fError ? 0 : fReader.readInt(); 773218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org} 783218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org 793218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.orgSkScalar SkValidatingReadBuffer::readScalar() { 803218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org const size_t inc = sizeof(SkScalar); 81863cb3951e8da2d2eb8efd57c94d8f5ba069123ccommit-bot@chromium.org this->validate(IsPtrAlign4(fReader.peek()) && fReader.isAvailable(inc)); 823218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org return fError ? 0 : fReader.readScalar(); 833218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org} 843218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org 853218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.orguint32_t SkValidatingReadBuffer::readUInt() { 863218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org return this->readInt(); 873218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org} 883218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org 893218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.orgint32_t SkValidatingReadBuffer::read32() { 903218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org return this->readInt(); 913218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org} 923218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org 933218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.orgvoid SkValidatingReadBuffer::readString(SkString* string) { 943218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org const size_t len = this->readInt(); 953218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org const void* ptr = fReader.peek(); 963218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org const char* cptr = (const char*)ptr; 973218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org 983218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org // skip over the string + '\0' and then pad to a multiple of 4 993218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org const size_t alignedSize = SkAlign4(len + 1); 1003218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org this->skip(alignedSize); 101c700a801bd1e134ad713064bbcc6da9a074e5ebdcommit-bot@chromium.org if (!fError) { 102c700a801bd1e134ad713064bbcc6da9a074e5ebdcommit-bot@chromium.org this->validate(cptr[len] == '\0'); 103c700a801bd1e134ad713064bbcc6da9a074e5ebdcommit-bot@chromium.org } 1043218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org if (!fError) { 1053218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org string->set(cptr, len); 1063218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org } 1073218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org} 1083218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org 1093218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.orgvoid* SkValidatingReadBuffer::readEncodedString(size_t* length, SkPaint::TextEncoding encoding) { 110c700a801bd1e134ad713064bbcc6da9a074e5ebdcommit-bot@chromium.org const int32_t encodingType = this->readInt(); 111863cb3951e8da2d2eb8efd57c94d8f5ba069123ccommit-bot@chromium.org this->validate(encodingType == encoding); 1123218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org *length = this->readInt(); 1133218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org const void* ptr = this->skip(SkAlign4(*length)); 1143218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org void* data = NULL; 1153218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org if (!fError) { 1163218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org data = sk_malloc_throw(*length); 1173218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org memcpy(data, ptr, *length); 1183218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org } 1193218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org return data; 1203218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org} 1213218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org 1223218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.orgvoid SkValidatingReadBuffer::readPoint(SkPoint* point) { 123c700a801bd1e134ad713064bbcc6da9a074e5ebdcommit-bot@chromium.org point->fX = this->readScalar(); 124c700a801bd1e134ad713064bbcc6da9a074e5ebdcommit-bot@chromium.org point->fY = this->readScalar(); 1253218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org} 1263218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org 1273218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.orgvoid SkValidatingReadBuffer::readMatrix(SkMatrix* matrix) { 1280c54a7b8945f1424f903279a94aef2280ec64aefcommit-bot@chromium.org size_t size = 0; 1290c54a7b8945f1424f903279a94aef2280ec64aefcommit-bot@chromium.org if (!fError) { 1300c54a7b8945f1424f903279a94aef2280ec64aefcommit-bot@chromium.org size = matrix->readFromMemory(fReader.peek(), fReader.available()); 131ae553db4c7e96b5de88a78c8d195f34f8ea94d8ecommit-bot@chromium.org this->validate((SkAlign4(size) == size) && (0 != size)); 1320c54a7b8945f1424f903279a94aef2280ec64aefcommit-bot@chromium.org } 1333218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org if (!fError) { 1343218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org (void)this->skip(size); 1353218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org } 1363218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org} 1373218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org 1383218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.orgvoid SkValidatingReadBuffer::readIRect(SkIRect* rect) { 1393218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org const void* ptr = this->skip(sizeof(SkIRect)); 1403218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org if (!fError) { 1413218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org memcpy(rect, ptr, sizeof(SkIRect)); 1423218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org } 1433218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org} 1443218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org 1453218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.orgvoid SkValidatingReadBuffer::readRect(SkRect* rect) { 1463218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org const void* ptr = this->skip(sizeof(SkRect)); 1473218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org if (!fError) { 1483218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org memcpy(rect, ptr, sizeof(SkRect)); 1493218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org } 1503218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org} 1513218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org 1523218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.orgvoid SkValidatingReadBuffer::readRegion(SkRegion* region) { 1530c54a7b8945f1424f903279a94aef2280ec64aefcommit-bot@chromium.org size_t size = 0; 1540c54a7b8945f1424f903279a94aef2280ec64aefcommit-bot@chromium.org if (!fError) { 1550c54a7b8945f1424f903279a94aef2280ec64aefcommit-bot@chromium.org size = region->readFromMemory(fReader.peek(), fReader.available()); 156ae553db4c7e96b5de88a78c8d195f34f8ea94d8ecommit-bot@chromium.org this->validate((SkAlign4(size) == size) && (0 != size)); 1570c54a7b8945f1424f903279a94aef2280ec64aefcommit-bot@chromium.org } 1583218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org if (!fError) { 1593218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org (void)this->skip(size); 1603218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org } 1613218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org} 1623218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org 1633218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.orgvoid SkValidatingReadBuffer::readPath(SkPath* path) { 1640c54a7b8945f1424f903279a94aef2280ec64aefcommit-bot@chromium.org size_t size = 0; 1650c54a7b8945f1424f903279a94aef2280ec64aefcommit-bot@chromium.org if (!fError) { 1660c54a7b8945f1424f903279a94aef2280ec64aefcommit-bot@chromium.org size = path->readFromMemory(fReader.peek(), fReader.available()); 167ae553db4c7e96b5de88a78c8d195f34f8ea94d8ecommit-bot@chromium.org this->validate((SkAlign4(size) == size) && (0 != size)); 1680c54a7b8945f1424f903279a94aef2280ec64aefcommit-bot@chromium.org } 1693218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org if (!fError) { 1703218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org (void)this->skip(size); 1713218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org } 1723218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org} 1733218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org 174863cb3951e8da2d2eb8efd57c94d8f5ba069123ccommit-bot@chromium.orgbool SkValidatingReadBuffer::readArray(void* value, size_t size, size_t elementSize) { 175863cb3951e8da2d2eb8efd57c94d8f5ba069123ccommit-bot@chromium.org const uint32_t count = this->getArrayCount(); 176863cb3951e8da2d2eb8efd57c94d8f5ba069123ccommit-bot@chromium.org this->validate(size == count); 177863cb3951e8da2d2eb8efd57c94d8f5ba069123ccommit-bot@chromium.org (void)this->skip(sizeof(uint32_t)); // Skip array count 178863cb3951e8da2d2eb8efd57c94d8f5ba069123ccommit-bot@chromium.org const size_t byteLength = count * elementSize; 179863cb3951e8da2d2eb8efd57c94d8f5ba069123ccommit-bot@chromium.org const void* ptr = this->skip(SkAlign4(byteLength)); 1803218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org if (!fError) { 181863cb3951e8da2d2eb8efd57c94d8f5ba069123ccommit-bot@chromium.org memcpy(value, ptr, byteLength); 182863cb3951e8da2d2eb8efd57c94d8f5ba069123ccommit-bot@chromium.org return true; 1833218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org } 184863cb3951e8da2d2eb8efd57c94d8f5ba069123ccommit-bot@chromium.org return false; 1853218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org} 1863218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org 187863cb3951e8da2d2eb8efd57c94d8f5ba069123ccommit-bot@chromium.orgbool SkValidatingReadBuffer::readByteArray(void* value, size_t size) { 188863cb3951e8da2d2eb8efd57c94d8f5ba069123ccommit-bot@chromium.org return readArray(static_cast<unsigned char*>(value), size, sizeof(unsigned char)); 1893218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org} 1903218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org 191863cb3951e8da2d2eb8efd57c94d8f5ba069123ccommit-bot@chromium.orgbool SkValidatingReadBuffer::readColorArray(SkColor* colors, size_t size) { 192863cb3951e8da2d2eb8efd57c94d8f5ba069123ccommit-bot@chromium.org return readArray(colors, size, sizeof(SkColor)); 1933218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org} 1943218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org 195863cb3951e8da2d2eb8efd57c94d8f5ba069123ccommit-bot@chromium.orgbool SkValidatingReadBuffer::readIntArray(int32_t* values, size_t size) { 196863cb3951e8da2d2eb8efd57c94d8f5ba069123ccommit-bot@chromium.org return readArray(values, size, sizeof(int32_t)); 1973218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org} 1983218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org 199863cb3951e8da2d2eb8efd57c94d8f5ba069123ccommit-bot@chromium.orgbool SkValidatingReadBuffer::readPointArray(SkPoint* points, size_t size) { 200863cb3951e8da2d2eb8efd57c94d8f5ba069123ccommit-bot@chromium.org return readArray(points, size, sizeof(SkPoint)); 201863cb3951e8da2d2eb8efd57c94d8f5ba069123ccommit-bot@chromium.org} 202863cb3951e8da2d2eb8efd57c94d8f5ba069123ccommit-bot@chromium.org 203863cb3951e8da2d2eb8efd57c94d8f5ba069123ccommit-bot@chromium.orgbool SkValidatingReadBuffer::readScalarArray(SkScalar* values, size_t size) { 204863cb3951e8da2d2eb8efd57c94d8f5ba069123ccommit-bot@chromium.org return readArray(values, size, sizeof(SkScalar)); 2053218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org} 2063218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org 2073218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.orguint32_t SkValidatingReadBuffer::getArrayCount() { 2080c54a7b8945f1424f903279a94aef2280ec64aefcommit-bot@chromium.org const size_t inc = sizeof(uint32_t); 2090c54a7b8945f1424f903279a94aef2280ec64aefcommit-bot@chromium.org fError = fError || !IsPtrAlign4(fReader.peek()) || !fReader.isAvailable(inc); 2108793ad7e7045baaeed4c9bd6dde482961b527c47rmistry@google.com return fError ? 0 : *(uint32_t*)fReader.peek(); 2113218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org} 2123218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org 2133218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.orgvoid SkValidatingReadBuffer::readBitmap(SkBitmap* bitmap) { 2143218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org const int width = this->readInt(); 2153218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org const int height = this->readInt(); 2163218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org const size_t length = this->readUInt(); 2173218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org // A size of zero means the SkBitmap was simply flattened. 218863cb3951e8da2d2eb8efd57c94d8f5ba069123ccommit-bot@chromium.org this->validate(length == 0); 2193218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org if (fError) { 2203218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org return; 2213218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org } 2223218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org bitmap->unflatten(*this); 223863cb3951e8da2d2eb8efd57c94d8f5ba069123ccommit-bot@chromium.org this->validate((bitmap->width() == width) && (bitmap->height() == height)); 224863cb3951e8da2d2eb8efd57c94d8f5ba069123ccommit-bot@chromium.org} 225863cb3951e8da2d2eb8efd57c94d8f5ba069123ccommit-bot@chromium.org 226863cb3951e8da2d2eb8efd57c94d8f5ba069123ccommit-bot@chromium.orgSkTypeface* SkValidatingReadBuffer::readTypeface() { 227863cb3951e8da2d2eb8efd57c94d8f5ba069123ccommit-bot@chromium.org // TODO: Implement this (securely) when needed 228863cb3951e8da2d2eb8efd57c94d8f5ba069123ccommit-bot@chromium.org return NULL; 2293218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org} 2303218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org 2313218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.orgSkFlattenable* SkValidatingReadBuffer::readFlattenable(SkFlattenable::Type type) { 2323218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org SkString name; 2333218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org this->readString(&name); 2343218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org if (fError) { 2353218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org return NULL; 2363218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org } 2373218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org 2383218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org // Is this the type we wanted ? 2393218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org const char* cname = name.c_str(); 2403218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org SkFlattenable::Type baseType; 2413218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org if (!SkFlattenable::NameToType(cname, &baseType) || (baseType != type)) { 2423218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org return NULL; 2433218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org } 2443218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org 2453218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org SkFlattenable::Factory factory = SkFlattenable::NameToFactory(cname); 2463218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org if (NULL == factory) { 2473218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org return NULL; // writer failed to give us the flattenable 2483218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org } 2493218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org 2503218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org // if we get here, factory may still be null, but if that is the case, the 2513218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org // failure was ours, not the writer. 2523218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org SkFlattenable* obj = NULL; 2533218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org uint32_t sizeRecorded = this->readUInt(); 2543218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org if (factory) { 2553218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org uint32_t offset = fReader.offset(); 2563218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org obj = (*factory)(*this); 2573218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org // check that we read the amount we expected 2583218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org uint32_t sizeRead = fReader.offset() - offset; 259863cb3951e8da2d2eb8efd57c94d8f5ba069123ccommit-bot@chromium.org this->validate(sizeRecorded == sizeRead); 2603218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org if (fError) { 2613218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org // we could try to fix up the offset... 2623218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org delete obj; 2633218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org obj = NULL; 2643218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org } 2653218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org } else { 2663218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org // we must skip the remaining data 2673218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org this->skip(sizeRecorded); 2683218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org SkASSERT(false); 2693218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org } 2703218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org return obj; 2713218b023674b5d0bfc3eca0a6bd6800e24660b8ecommit-bot@chromium.org} 272