skia2/tests/SerializationTest.cpp
bungeman@google.com a9a4b04a98 Fix Valgrind reports of test branching on uninitialized data.
Fixes reports like:
[07:10:01.235147] [ 71/188] (9) Serialization
[07:10:01.235186] ==20052== Thread 3:
[07:10:01.235223] ==20052== Conditional jump or move depends on uninitialised value(s)
[07:10:01.235259] ==20052==    at 0x546632: SkRRect::setRectRadii(SkRect const&, SkPoint const*) (SkRect.h:426)
[07:10:01.735876] ==20052==    by 0x546FB7: SkRRect::readFromMemory(void const*, unsigned long) (SkRRect.cpp:362)
[07:10:01.735965] ==20052==    by 0x47F87F: Tests(skiatest::Reporter*) (SerializationTest.cpp:20)
[07:10:01.736007] ==20052==    by 0x480367: skiatest::SerializationClass::onRun(skiatest::Reporter*) (SerializationTest.cpp:212)
[07:10:01.736048] ==20052==    by 0x4881DA: skiatest::Test::run() (Test.cpp:109)
[07:10:01.736086] ==20052==    by 0x482516: SkTestRunnable::run() (skia_test.cpp:155)
[07:10:01.736122] ==20052==    by 0x6236E5: SkThreadPool::Loop(void*) (SkThreadPool.cpp:97)
[07:10:01.736158] ==20052==    by 0x62DDB2: thread_start(void*) (SkThreadUtils_pthread.cpp:66)
[07:10:01.736192] ==20052==    by 0x4E39E99: start_thread (pthread_create.c:308)
[07:10:01.736228] ==20052==    by 0x6A5BCCC: clone (clone.S:112)
[07:10:01.736262] ==20052==  Uninitialised value was created by a stack allocation
[07:10:01.736296] ==20052==    at 0x47EC6A: Tests(skiatest::Reporter*) (SerializationTest.cpp:155)



git-svn-id: http://skia.googlecode.com/svn/trunk@12419 2bbb7eff-a529-9590-31e7-b0007b416f81
2013-11-27 17:00:12 +00:00

219 lines
7.5 KiB
C++

/*
* Copyright 2013 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "SkOrderedWriteBuffer.h"
#include "SkValidatingReadBuffer.h"
#include "Test.h"
static const uint32_t kArraySize = 64;
template<typename T>
static void TestAlignment(T* testObj, skiatest::Reporter* reporter) {
// Test memory read/write functions directly
unsigned char dataWritten[1024];
size_t bytesWrittenToMemory = testObj->writeToMemory(dataWritten);
REPORTER_ASSERT(reporter, SkAlign4(bytesWrittenToMemory) == bytesWrittenToMemory);
size_t bytesReadFromMemory = testObj->readFromMemory(dataWritten, bytesWrittenToMemory);
REPORTER_ASSERT(reporter, SkAlign4(bytesReadFromMemory) == bytesReadFromMemory);
}
template<typename T> struct SerializationUtils {
};
template<> struct SerializationUtils<SkMatrix> {
static void Write(SkOrderedWriteBuffer& writer, const SkMatrix* matrix) {
writer.writeMatrix(*matrix);
}
static void Read(SkValidatingReadBuffer& reader, SkMatrix* matrix) {
reader.readMatrix(matrix);
}
};
template<> struct SerializationUtils<SkPath> {
static void Write(SkOrderedWriteBuffer& writer, const SkPath* path) {
writer.writePath(*path);
}
static void Read(SkValidatingReadBuffer& reader, SkPath* path) {
reader.readPath(path);
}
};
template<> struct SerializationUtils<SkRegion> {
static void Write(SkOrderedWriteBuffer& writer, const SkRegion* region) {
writer.writeRegion(*region);
}
static void Read(SkValidatingReadBuffer& reader, SkRegion* region) {
reader.readRegion(region);
}
};
template<> struct SerializationUtils<unsigned char> {
static void Write(SkOrderedWriteBuffer& writer, unsigned char* data, uint32_t arraySize) {
writer.writeByteArray(data, arraySize);
}
static bool Read(SkValidatingReadBuffer& reader, unsigned char* data, uint32_t arraySize) {
return reader.readByteArray(data, arraySize);
}
};
template<> struct SerializationUtils<SkColor> {
static void Write(SkOrderedWriteBuffer& writer, SkColor* data, uint32_t arraySize) {
writer.writeColorArray(data, arraySize);
}
static bool Read(SkValidatingReadBuffer& reader, SkColor* data, uint32_t arraySize) {
return reader.readColorArray(data, arraySize);
}
};
template<> struct SerializationUtils<int32_t> {
static void Write(SkOrderedWriteBuffer& writer, int32_t* data, uint32_t arraySize) {
writer.writeIntArray(data, arraySize);
}
static bool Read(SkValidatingReadBuffer& reader, int32_t* data, uint32_t arraySize) {
return reader.readIntArray(data, arraySize);
}
};
template<> struct SerializationUtils<SkPoint> {
static void Write(SkOrderedWriteBuffer& writer, SkPoint* data, uint32_t arraySize) {
writer.writePointArray(data, arraySize);
}
static bool Read(SkValidatingReadBuffer& reader, SkPoint* data, uint32_t arraySize) {
return reader.readPointArray(data, arraySize);
}
};
template<> struct SerializationUtils<SkScalar> {
static void Write(SkOrderedWriteBuffer& writer, SkScalar* data, uint32_t arraySize) {
writer.writeScalarArray(data, arraySize);
}
static bool Read(SkValidatingReadBuffer& reader, SkScalar* data, uint32_t arraySize) {
return reader.readScalarArray(data, arraySize);
}
};
template<typename T>
static void TestObjectSerialization(T* testObj, skiatest::Reporter* reporter) {
SkOrderedWriteBuffer writer(1024);
writer.setFlags(SkOrderedWriteBuffer::kValidation_Flag);
SerializationUtils<T>::Write(writer, testObj);
size_t bytesWritten = writer.bytesWritten();
REPORTER_ASSERT(reporter, SkAlign4(bytesWritten) == bytesWritten);
unsigned char dataWritten[1024];
writer.writeToMemory(dataWritten);
// Make sure this fails when it should (test with smaller size, but still multiple of 4)
SkValidatingReadBuffer buffer(dataWritten, bytesWritten - 4);
T obj;
SerializationUtils<T>::Read(buffer, &obj);
REPORTER_ASSERT(reporter, !buffer.validate(true));
// Make sure this succeeds when it should
SkValidatingReadBuffer buffer2(dataWritten, bytesWritten);
const unsigned char* peekBefore = static_cast<const unsigned char*>(buffer2.skip(0));
T obj2;
SerializationUtils<T>::Read(buffer2, &obj2);
const unsigned char* peekAfter = static_cast<const unsigned char*>(buffer2.skip(0));
// This should have succeeded, since there are enough bytes to read this
REPORTER_ASSERT(reporter, buffer2.validate(true));
REPORTER_ASSERT(reporter, static_cast<size_t>(peekAfter - peekBefore) == bytesWritten);
TestAlignment(testObj, reporter);
}
template<typename T>
static void TestArraySerialization(T* data, skiatest::Reporter* reporter) {
SkOrderedWriteBuffer writer(1024);
writer.setFlags(SkOrderedWriteBuffer::kValidation_Flag);
SerializationUtils<T>::Write(writer, data, kArraySize);
size_t bytesWritten = writer.bytesWritten();
// This should write the length (in 4 bytes) and the array
REPORTER_ASSERT(reporter, (4 + kArraySize * sizeof(T)) == bytesWritten);
unsigned char dataWritten[1024];
writer.writeToMemory(dataWritten);
// Make sure this fails when it should
SkValidatingReadBuffer buffer(dataWritten, bytesWritten);
T dataRead[kArraySize];
bool success = SerializationUtils<T>::Read(buffer, dataRead, kArraySize / 2);
// This should have failed, since the provided size was too small
REPORTER_ASSERT(reporter, !success);
// Make sure this succeeds when it should
SkValidatingReadBuffer buffer2(dataWritten, bytesWritten);
success = SerializationUtils<T>::Read(buffer2, dataRead, kArraySize);
// This should have succeeded, since there are enough bytes to read this
REPORTER_ASSERT(reporter, success);
}
static void Tests(skiatest::Reporter* reporter) {
// Test matrix serialization
{
SkMatrix matrix = SkMatrix::I();
TestObjectSerialization(&matrix, reporter);
}
// Test path serialization
{
SkPath path;
TestObjectSerialization(&path, reporter);
}
// Test region serialization
{
SkRegion region;
TestObjectSerialization(&region, reporter);
}
// Test rrect serialization
{
// SkRRect does not initialize anything.
// An uninitialized SkRRect can be serialized,
// but will branch on uninitialized data when deserialized.
SkRRect rrect;
SkRect rect = SkRect::MakeXYWH(1, 2, 20, 30);
SkVector corners[4] = { {1, 2}, {2, 3}, {3,4}, {4,5} };
rrect.setRectRadii(rect, corners);
TestAlignment(&rrect, reporter);
}
// Test readByteArray
{
unsigned char data[kArraySize] = { 1, 2, 3 };
TestArraySerialization(data, reporter);
}
// Test readColorArray
{
SkColor data[kArraySize] = { SK_ColorBLACK, SK_ColorWHITE, SK_ColorRED };
TestArraySerialization(data, reporter);
}
// Test readIntArray
{
int32_t data[kArraySize] = { 1, 2, 4, 8 };
TestArraySerialization(data, reporter);
}
// Test readPointArray
{
SkPoint data[kArraySize] = { {6, 7}, {42, 128} };
TestArraySerialization(data, reporter);
}
// Test readScalarArray
{
SkScalar data[kArraySize] = { SK_Scalar1, SK_ScalarHalf, SK_ScalarMax };
TestArraySerialization(data, reporter);
}
}
#include "TestClassDef.h"
DEFINE_TESTCLASS("Serialization", SerializationClass, Tests)