File: Serialize.cpp

package info (click to toggle)
storm-lang 0.7.5-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 52,028 kB
  • sloc: ansic: 261,471; cpp: 140,432; sh: 14,891; perl: 9,846; python: 2,525; lisp: 2,504; asm: 860; makefile: 678; pascal: 70; java: 52; xml: 37; awk: 12
file content (135 lines) | stat: -rw-r--r-- 5,113 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#include "stdafx.h"
#include "Fn.h"
#include "Core/Io/Buffer.h"
#include "Core/Io/Serialization.h"
#include "Core/Io/MemStream.h"

BEGIN_TEST(Serialize, BS) {

	// Simple serialization.
	CHECK(runFn<Bool>(S("tests.bs.simpleSerialization")));

	// Multiple times in the same stream.
	CHECK(runFn<Bool>(S("tests.bs.multipleSerialization")));

	// Shuffled output (simulating altering the order of members from when serialization was made).
	CHECK(runFn<Bool>(S("tests.bs.shuffledSerialization")));
	CHECK_EQ(::toS(runFn<Str *>(S("tests.bs.shuffledSerialization2"))), L"Custom A, Custom B, ");

	// Extra data in the stream.
	CHECK_EQ(::toS(runFn<Str *>(S("tests.bs.extraSerialization"))), L"Custom A, Custom B, ");

	// Missing data in the stream, but default values are available.
	CHECK_EQ(::toS(runFn<Str *>(S("tests.bs.missingSerialization"))), L"Def A, Custom B, ");

	// Primitives.
	CHECK(runFn<Bool>(S("tests.bs.primitiveSerialization")));

	// Reading/writing different formal types.
	CHECK(runFn<Bool>(S("tests.bs.typeDiffSerialization")));

	// Serialization of containers.
	CHECK(runFn<Bool>(S("tests.bs.arraySerialization")));
	CHECK(runFn<Bool>(S("tests.bs.mapSerialization")));
	CHECK(runFn<Bool>(S("tests.bs.setSerialization")));
	CHECK(runFn<Bool>(S("tests.bs.maybeSerialization")));

	// Custom serialization.
	CHECK(runFn<Bool>(S("tests.bs.customSerialization")));

	// Serialization of Url.
	CHECK(runFn<Bool>(S("tests.bs.urlSerialization")));

	// Serialization of Version.
	CHECK(runFn<Bool>(S("tests.bs.versionSerialization")));

} END_TEST

static ObjIStream *createStream(Buffer b) {
	return new (gEngine()) ObjIStream(new (gEngine()) MemIStream(b));
}

BEGIN_TEST(SerializeLimits, BS) {
	Buffer b = runFn<Buffer>(S("tests.bs.createLargeObject"));
	Type *type = runFn<Type *>(S("tests.bs.largeObjectType"));

	// Check so that it works with decent limits.
	{
		ObjIStream *input = createStream(b);
		input->maxTypeDescSize(1024);
		input->maxReadSize = 10000; // This data blob is about 8k.
		input->maxArraySize = 1000;
		CHECK(input->readClass(type) != NULL);
	}

	// Check so that type descriptions limit works.
	{
		ObjIStream *input = createStream(b);
		input->maxTypeDescSize(512);
		CHECK_ERROR(input->readClass(type), SizeLimitReached);
	}

	// Check so that total object size works.
	{
		ObjIStream *input = createStream(b);
		input->maxReadSize = 1024;
		CHECK_ERROR(input->readClass(type), SizeLimitReached);
	}

	// Check so that array size works.
	{
		ObjIStream *input = createStream(b);
		input->maxArraySize = 300; // Arrays are 4 byte large and contain 100 elements.
		CHECK_ERROR(input->readClass(type), SizeLimitReached);
	}

} END_TEST

static void deserializeBuffer(byte *data, size_t size) {
	Buffer b = buffer(gEngine(), Nat(size));
	for (Nat i = 0; i < size; i++)
		b[i] = data[i];
	b.filled(Nat(size));

	runFn<void>(S("tests.bs.deserializeBuffer"), b);
}

// Randomly generated, causes a crash.
static byte bad1[] = {
	0xCD, 0xFE, 0x25, 0x4B, 0xE1, 0x39, 0x9C, 0x06, 0x7B, 0x81, 0x4D, 0x40, 0x13, 0xE3, 0xFE, 0x93,
	0xF9, 0x28, 0x05, 0x1A, 0xF9, 0xEE, 0xCD, 0x98, 0xC8, 0x36, 0x51, 0x01, 0x84, 0xCD, 0xCF, 0x66,
	0x5A, 0x03, 0x45, 0xA3, 0x92, 0xDB, 0x82, 0x19, 0x5E, 0x36, 0x25, 0x4E, 0x66, 0xC1, 0x59, 0x92,
	0x32, 0x13, 0x5D, 0xDC, 0xCE, 0xAC, 0x11, 0x92, 0xCF, 0xA4, 0x64, 0x9F, 0xC6, 0x78, 0x0C, 0xD0,
	0xC1, 0xD5, 0x6D, 0x9F, 0xCB, 0x14, 0x11, 0x71, 0xCB, 0xD7, 0xCC, 0xB5, 0x81, 0xA8, 0xA7, 0x38,
	0x0F, 0x78, 0x88, 0x41, 0xD1, 0xEC, 0xCE, 0xCA, 0xD0, 0x58, 0x04, 0x97, 0x0B, 0xBE, 0xB7, 0x12,
	0x14, 0x7C, 0x9C, 0x5F, 0x63, 0x26, 0x71, 0x4C, 0xC8, 0x2A, 0x99, 0xF6, 0x56, 0xD0, 0x26, 0xB6,
	0xBD, 0xE5, 0x68, 0xB1, 0xDB, 0x36, 0x2E, 0xE4, 0xED, 0x15, 0xAF, 0x01, 0x35, 0x63, 0x45, 0x00,
};

static byte bad2[] = {
	0x2F, 0x34, 0x15, 0x0F, 0x7A, 0x40, 0x5C, 0x90, 0xD8, 0x08, 0x55, 0x28, 0x83, 0x94, 0x9C, 0x10,
	0x07, 0x97, 0xD9, 0x2D, 0x2C, 0x76, 0xAD, 0xB8, 0x21, 0x50, 0xA3, 0x76, 0xDF, 0xA7, 0x80, 0x98,
	0xDD, 0x95, 0xBB, 0x0B, 0x08, 0x22, 0x2D, 0x61, 0x71, 0xF7, 0x9C, 0xC6, 0x77, 0x74, 0xB2, 0x57,
	0x66, 0x27, 0x57, 0x61, 0xD6, 0x41, 0x3B, 0x2A, 0x84, 0x90, 0xC6, 0x44, 0x10, 0x12, 0x69, 0x77,
	0x99, 0xC3, 0x66, 0x36, 0xDA, 0x6D, 0xE8, 0x94, 0x09, 0x8D, 0x36, 0xC2, 0xF0, 0x7F, 0x26, 0x98,
	0x7C, 0x92, 0x69, 0x48, 0x76, 0x83, 0x10, 0xA5, 0x71, 0xB8, 0xB2, 0xD6, 0x48, 0x1C, 0x33, 0x02,
	0xCC, 0x97, 0xAF, 0xE8, 0x46, 0x8C, 0xBB, 0xB9, 0x52, 0x75, 0x79, 0x36, 0x74, 0xFD, 0x49, 0x2C,
	0xE2, 0xFE, 0xD8, 0xBD, 0x38, 0x9A, 0x3F, 0x55, 0xAC, 0xDC, 0xC7, 0x82, 0x48, 0x06, 0x58, 0xDA,
};

BEGIN_TESTX(SerializeMalformed, BS) {
	// These degrade performance quite badly on 32-bit systems, so we don't run them by
	// default. This is probably because the large allocations (~1G) will likely get pinned by some
	// value on the stack and not be collected.
	CHECK_RUNS(deserializeBuffer(bad1, sizeof(bad1)));
	CHECK_RUNS(deserializeBuffer(bad2, sizeof(bad2)));
} END_TEST


BEGIN_TESTX(SerializeFuzz, BS) {
	runFn<void>(S("tests.bs.deserializeFuzz"));
} END_TEST

BEGIN_TESTX(SerializePerf, BS) {
	runFn<void>(S("tests.bs.serializationPerf"));
} END_TEST