skia2/include/core/SkFlattenableBuffers.h
commit-bot@chromium.org c0b7e10c6a Initial error handling code
I made it as simple as possible. The impact seems minimal and it should do what's necessary to make this code secure.

BUG=

Committed: http://code.google.com/p/skia/source/detail?r=11247

R=reed@google.com, scroggo@google.com, djsollen@google.com, sugoi@google.com, bsalomon@google.com, mtklein@google.com, senorblanco@google.com, senorblanco@chromium.org

Author: sugoi@chromium.org

Review URL: https://codereview.chromium.org/23021015

git-svn-id: http://skia.googlecode.com/svn/trunk@11922 2bbb7eff-a529-9590-31e7-b0007b416f81
2013-10-23 17:06:21 +00:00

221 lines
7.6 KiB
C++

/*
* Copyright 2012 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkFlattenableBuffers_DEFINED
#define SkFlattenableBuffers_DEFINED
#include "SkColor.h"
#include "SkData.h"
#include "SkPaint.h"
#include "SkPoint.h"
class SkBitmap;
class SkDrawLooper;
class SkFlattenable;
struct SkIRect;
class SkMatrix;
class SkOrderedReadBuffer;
class SkOrderedWriteBuffer;
class SkPath;
class SkPixelRef;
struct SkRect;
class SkRegion;
class SkStream;
class SkString;
class SkTypeface;
class SkUnitMapper;
class SkWStream;
class SkFlattenableReadBuffer {
public:
SkFlattenableReadBuffer();
virtual ~SkFlattenableReadBuffer();
bool isOrderedBinaryBuffer() { return NULL != getOrderedBinaryBuffer(); }
virtual SkOrderedReadBuffer* getOrderedBinaryBuffer() { return NULL; }
enum Flags {
kCrossProcess_Flag = 1 << 0,
kScalarIsFloat_Flag = 1 << 1,
kPtrIs64Bit_Flag = 1 << 2,
/** The kValidation_Flag is used to force stream validations (by making
* sure that no operation reads past the end of the stream, for example)
* and error handling if any reading operation yields an invalid value.
*/
kValidation_Flag = 1 << 3,
};
void setFlags(uint32_t flags) { fFlags = flags; }
uint32_t getFlags() const { return fFlags; }
bool isCrossProcess() const { return SkToBool(fFlags & (kCrossProcess_Flag | kValidation_Flag)); }
bool isScalarFloat() const { return SkToBool(fFlags & kScalarIsFloat_Flag); }
bool isPtr64Bit() const { return SkToBool(fFlags & kPtrIs64Bit_Flag); }
bool isValidating() const { return SkToBool(fFlags & kValidation_Flag); }
// primitives
virtual bool readBool() = 0;
virtual SkColor readColor() = 0;
virtual SkFixed readFixed() = 0;
virtual int32_t readInt() = 0;
virtual SkScalar readScalar() = 0;
virtual uint32_t readUInt() = 0;
virtual int32_t read32() = 0;
// strings -- the caller is responsible for freeing the string contents
virtual void readString(SkString* string) = 0;
virtual void* readEncodedString(size_t* length, SkPaint::TextEncoding encoding) = 0;
/**
@param type This parameter is only used when using SkValidatingReadBuffer. It will verify
that the object about to be deserialized is of the given type or early return
NULL otherwise. The type provided here is the type of the base class of the
object to deserialize.
*/
virtual SkFlattenable* readFlattenable(SkFlattenable::Type type) = 0;
SkColorFilter* readColorFilter();
SkDrawLooper* readDrawLooper();
SkImageFilter* readImageFilter();
SkMaskFilter* readMaskFilter();
SkPathEffect* readPathEffect();
SkPixelRef* readPixelRef();
SkRasterizer* readRasterizer();
SkShader* readShader();
SkUnitMapper* readUnitMapper();
SkXfermode* readXfermode();
// common data structures
virtual void readPoint(SkPoint* point) = 0;
virtual void readMatrix(SkMatrix* matrix) = 0;
virtual void readIRect(SkIRect* rect) = 0;
virtual void readRect(SkRect* rect) = 0;
virtual void readRegion(SkRegion* region) = 0;
virtual void readPath(SkPath* path) = 0;
// binary data and arrays
virtual uint32_t readByteArray(void* value) = 0;
virtual uint32_t readColorArray(SkColor* colors) = 0;
virtual uint32_t readIntArray(int32_t* values) = 0;
virtual uint32_t readPointArray(SkPoint* points) = 0;
virtual uint32_t readScalarArray(SkScalar* values) = 0;
/** This helper peeks into the buffer and reports back the length of the next array in
* the buffer but does not change the state of the buffer.
*/
virtual uint32_t getArrayCount() = 0;
// helper functions
virtual void* readFunctionPtr();
virtual void readPaint(SkPaint* paint);
virtual void readBitmap(SkBitmap* bitmap) = 0;
virtual SkTypeface* readTypeface() = 0;
// helper function for classes with const SkPoint members
SkPoint readPoint() {
SkPoint point;
this->readPoint(&point);
return point;
}
SkData* readByteArrayAsData() {
size_t len = this->getArrayCount();
void* buffer = sk_malloc_throw(len);
(void)this->readByteArray(buffer);
return SkData::NewFromMalloc(buffer, len);
}
virtual void validate(bool isValid) {}
private:
template <typename T> T* readFlattenableT();
uint32_t fFlags;
};
///////////////////////////////////////////////////////////////////////////////
class SkFlattenableWriteBuffer {
public:
SkFlattenableWriteBuffer();
virtual ~SkFlattenableWriteBuffer();
virtual bool isOrderedBinaryBuffer() { return false; }
virtual SkOrderedWriteBuffer* getOrderedBinaryBuffer() { sk_throw(); return NULL; }
// primitives
virtual void writeByteArray(const void* data, size_t size) = 0;
virtual void writeBool(bool value) = 0;
virtual void writeFixed(SkFixed value) = 0;
virtual void writeScalar(SkScalar value) = 0;
virtual void writeScalarArray(const SkScalar* value, uint32_t count) = 0;
virtual void writeInt(int32_t value) = 0;
virtual void writeIntArray(const int32_t* value, uint32_t count) = 0;
virtual void writeUInt(uint32_t value) = 0;
virtual void write32(int32_t value) = 0; // printf in hex
virtual void writeString(const char* value) = 0;
virtual void writeEncodedString(const void* value, size_t byteLength,
SkPaint::TextEncoding encoding) = 0;
// common data structures
virtual void writeFlattenable(const SkFlattenable* flattenable) = 0;
virtual void writeColor(const SkColor& color) = 0;
virtual void writeColorArray(const SkColor* color, uint32_t count) = 0;
virtual void writePoint(const SkPoint& point) = 0;
virtual void writePointArray(const SkPoint* points, uint32_t count) = 0;
virtual void writeMatrix(const SkMatrix& matrix) = 0;
virtual void writeIRect(const SkIRect& rect) = 0;
virtual void writeRect(const SkRect& rect) = 0;
virtual void writeRegion(const SkRegion& region) = 0;
virtual void writePath(const SkPath& path) = 0;
virtual size_t writeStream(SkStream* stream, size_t length) = 0;
// helper functions
virtual void writeFunctionPtr(void* ptr);
virtual void writePaint(const SkPaint& paint);
virtual void writeBitmap(const SkBitmap& bitmap) = 0;
virtual void writeTypeface(SkTypeface* typeface) = 0;
virtual bool writeToStream(SkWStream*) = 0;
enum Flags {
kCrossProcess_Flag = 0x01,
/** The kValidation_Flag is used here to make sure the write operation
* is symmetric with the read operation using the equivalent flag
* SkFlattenableReadBuffer::kValidation_Flag.
*/
kValidation_Flag = 0x02,
};
uint32_t getFlags() const { return fFlags; }
void setFlags(uint32_t flags) { fFlags = flags; }
bool isCrossProcess() const {
return SkToBool(fFlags & (kCrossProcess_Flag | kValidation_Flag));
}
bool isValidating() const {
return SkToBool(fFlags & kValidation_Flag);
}
bool persistTypeface() const { return (fFlags & kCrossProcess_Flag) != 0; }
void writeDataAsByteArray(SkData* data) {
this->writeByteArray(data->data(), data->size());
}
protected:
// A helper function so that each subclass does not have to be a friend of SkFlattenable
void flattenObject(const SkFlattenable* obj, SkFlattenableWriteBuffer& buffer);
uint32_t fFlags;
};
#endif