1/*
2 * Copyright 2015 Google Inc. All rights reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17using System;
18using Google.FlatBuffers;
19
20namespace Google.FlatBuffers.Test
21{
22 [FlatBuffersTestClass]
23 public class FlatBuffersFuzzTests
24 {
25 private readonly Lcg _lcg = new Lcg();
26
27 [FlatBuffersTestMethod]
28 public void TestObjects()
29 {
30 CheckObjects(11, 100);
31 }
32
33 [FlatBuffersTestMethod]
34 public void TestNumbers()
35 {
36 var builder = new FlatBufferBuilder(1);
37 Assert.ArrayEqual(new byte[] { 0 }, builder.DataBuffer.ToFullArray());
38 builder.AddBool(true);
39 Assert.ArrayEqual(new byte[] { 1 }, builder.DataBuffer.ToFullArray());
40 builder.AddSbyte(-127);
41 Assert.ArrayEqual(new byte[] { 129, 1 }, builder.DataBuffer.ToFullArray());
42 builder.AddByte(255);
43 Assert.ArrayEqual(new byte[] { 0, 255, 129, 1 }, builder.DataBuffer.ToFullArray()); // First pad
44 builder.AddShort(-32222);
45 Assert.ArrayEqual(new byte[] { 0, 0, 0x22, 0x82, 0, 255, 129, 1 }, builder.DataBuffer.ToFullArray()); // Second pad
46 builder.AddUshort(0xFEEE);
47 Assert.ArrayEqual(new byte[] { 0xEE, 0xFE, 0x22, 0x82, 0, 255, 129, 1 }, builder.DataBuffer.ToFullArray()); // no pad
48 builder.AddInt(-53687092);
49 Assert.ArrayEqual(new byte[] { 0, 0, 0, 0, 204, 204, 204, 252, 0xEE, 0xFE, 0x22, 0x82, 0, 255, 129, 1 }, builder.DataBuffer.ToFullArray()); // third pad
50 builder.AddUint(0x98765432);
51 Assert.ArrayEqual(new byte[] { 0x32, 0x54, 0x76, 0x98, 204, 204, 204, 252, 0xEE, 0xFE, 0x22, 0x82, 0, 255, 129, 1 }, builder.DataBuffer.ToFullArray()); // no pad
52 }
53
54 [FlatBuffersTestMethod]
55 public void TestNumbers64()
56 {
57 var builder = new FlatBufferBuilder(1);
58 builder.AddUlong(0x1122334455667788);
59 Assert.ArrayEqual(new byte[] { 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11 }, builder.DataBuffer.ToFullArray());
60
61 builder = new FlatBufferBuilder(1);
62 builder.AddLong(0x1122334455667788);
63 Assert.ArrayEqual(new byte[] { 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11 }, builder.DataBuffer.ToFullArray());
64 }
65
66 [FlatBuffersTestMethod]
67 public void TestVector_1xUInt8()
68 {
69 var builder = new FlatBufferBuilder(1);
70 builder.StartVector(sizeof(byte), 1, 1);
71 Assert.ArrayEqual(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 }, builder.DataBuffer.ToFullArray());
72 builder.AddByte(1);
73 Assert.ArrayEqual(new byte[] { 0, 0, 0, 0, 1, 0, 0, 0 }, builder.DataBuffer.ToFullArray());
74 builder.EndVector();
75 Assert.ArrayEqual(new byte[] { 1, 0, 0, 0, 1, 0, 0, 0 }, builder.DataBuffer.ToFullArray());
76 }
77
78 [FlatBuffersTestMethod]
79 public void TestVector_2xUint8()
80 {
81 var builder = new FlatBufferBuilder(1);
82 builder.StartVector(sizeof(byte), 2, 1);
83 Assert.ArrayEqual(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 }, builder.DataBuffer.ToFullArray());
84 builder.AddByte(1);
85 Assert.ArrayEqual(new byte[] { 0, 0, 0, 0, 0, 1, 0, 0 }, builder.DataBuffer.ToFullArray());
86 builder.AddByte(2);
87 Assert.ArrayEqual(new byte[] { 0, 0, 0, 0, 2, 1, 0, 0 }, builder.DataBuffer.ToFullArray());
88 builder.EndVector();
89 Assert.ArrayEqual(new byte[] { 2, 0, 0, 0, 2, 1, 0, 0 }, builder.DataBuffer.ToFullArray());
90 }
91
92 [FlatBuffersTestMethod]
93 public void TestVector_1xUInt16()
94 {
95 var builder = new FlatBufferBuilder(1);
96 builder.StartVector(sizeof(ushort), 1, 1);
97 Assert.ArrayEqual(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 }, builder.DataBuffer.ToFullArray());
98 builder.AddUshort(1);
99 Assert.ArrayEqual(new byte[] { 0, 0, 0, 0, 1, 0, 0, 0 }, builder.DataBuffer.ToFullArray());
100 builder.EndVector();
101 Assert.ArrayEqual(new byte[] { 1, 0, 0, 0, 1, 0, 0, 0 }, builder.DataBuffer.ToFullArray());
102 }
103
104 [FlatBuffersTestMethod]
105 public void TestVector_2xUInt16()
106 {
107 var builder = new FlatBufferBuilder(1);
108 builder.StartVector(sizeof(ushort), 2, 1);
109 Assert.ArrayEqual(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 }, builder.DataBuffer.ToFullArray());
110 builder.AddUshort(0xABCD);
111 Assert.ArrayEqual(new byte[] { 0, 0, 0, 0, 0, 0, 0xCD, 0xAB }, builder.DataBuffer.ToFullArray());
112 builder.AddUshort(0xDCBA);
113 Assert.ArrayEqual(new byte[] { 0, 0, 0, 0, 0xBA, 0xDC, 0xCD, 0xAB }, builder.DataBuffer.ToFullArray());
114 builder.EndVector();
115 Assert.ArrayEqual(new byte[] { 2, 0, 0, 0, 0xBA, 0xDC, 0xCD, 0xAB }, builder.DataBuffer.ToFullArray());
116 }
117
118 [FlatBuffersTestMethod]
119 public void TestCreateAsciiString()
120 {
121 var builder = new FlatBufferBuilder(1);
122 builder.CreateString("foo");
123 Assert.ArrayEqual(new byte[] { 3, 0, 0, 0, (byte)'f', (byte)'o', (byte)'o', 0 }, builder.DataBuffer.ToFullArray());
124
125 builder.CreateString("moop");
126 Assert.ArrayEqual(new byte[]
127 {
128 0, 0, 0, 0,
129 0, 0, 0, 0,
130 0, 0, 0, 0, // Padding to 32 bytes
131 4, 0, 0, 0,
132 (byte)'m', (byte)'o', (byte)'o', (byte)'p',
133 0, 0, 0, 0, // zero terminator with 3 byte pad
134 3, 0, 0, 0,
135 (byte)'f', (byte)'o', (byte)'o', 0
136 }, builder.DataBuffer.ToFullArray());
137 }
138
139 [FlatBuffersTestMethod]
140 public void TestCreateSharedAsciiString()
141 {
142 var builder = new FlatBufferBuilder(1);
143 builder.CreateSharedString("foo");
144 Assert.ArrayEqual(new byte[] { 3, 0, 0, 0, (byte)'f', (byte)'o', (byte)'o', 0 }, builder.DataBuffer.ToFullArray());
145
146 builder.CreateSharedString("foo");
147 Assert.ArrayEqual(new byte[] { 3, 0, 0, 0, (byte)'f', (byte)'o', (byte)'o', 0 }, builder.DataBuffer.ToFullArray());
148 }
149
150 [FlatBuffersTestMethod]
151 public void TestCreateArbitarytring()
152 {
153 var builder = new FlatBufferBuilder(1);
154 builder.CreateString("\x01\x02\x03");
155 Assert.ArrayEqual(new byte[]
156 {
157 3, 0, 0, 0,
158 0x01, 0x02, 0x03, 0
159 }, builder.DataBuffer.ToFullArray()); // No padding
160 builder.CreateString("\x04\x05\x06\x07");
161 Assert.ArrayEqual(new byte[]
162 {
163 0, 0, 0, 0,
164 0, 0, 0, 0,
165 0, 0, 0, 0, // Padding to 32 bytes
166 4, 0, 0, 0,
167 0x04, 0x05, 0x06, 0x07,
168 0, 0, 0, 0, // zero terminator with 3 byte pad
169 3, 0, 0, 0,
170 0x01, 0x02, 0x03, 0
171 }, builder.DataBuffer.ToFullArray()); // No padding
172 }
173
174 [FlatBuffersTestMethod]
175 public void TestEmptyVTable()
176 {
177 var builder = new FlatBufferBuilder(1);
178 builder.StartTable(0);
179 Assert.ArrayEqual(new byte[] { 0 }, builder.DataBuffer.ToFullArray());
180 builder.EndTable();
181 Assert.ArrayEqual(new byte[]
182 {
183 4, 0, 4, 0,
184 4, 0, 0, 0
185 },
186 builder.DataBuffer.ToFullArray());
187 }
188
189 [FlatBuffersTestMethod]
190 public void TestVTableWithOneBool()
191 {
192 var builder = new FlatBufferBuilder(1);
193 builder.StartTable(1);
194 Assert.ArrayEqual(new byte[] { 0 }, builder.DataBuffer.ToFullArray());
195 builder.AddBool(0, true, false);
196 builder.EndTable();
197 Assert.ArrayEqual(new byte[]
198 {
199 0, 0, // padding to 16 bytes
200 6, 0, // vtable bytes
201 8, 0, // object length inc vtable offset
202 7, 0, // start of bool value
203 6, 0, 0, 0, // int32 offset for start of vtable
204 0, 0, 0, // padding
205 1, // value 0
206 },
207 builder.DataBuffer.ToFullArray());
208 var verifier = new Verifier(builder.DataBuffer);
209 var offset = 8;
210 // table must be ok
211 Assert.IsTrue(verifier.VerifyTableStart((uint)offset));
212 // First field must be bool
213 Assert.IsTrue(verifier.VerifyField((uint)offset, 4, 1, 1, true));
214 // Check Error: Second field
215 Assert.IsFalse(verifier.VerifyField((uint)offset, 6, 1, 1, true));
216 // Check Error: First field too big alignment
217 Assert.IsFalse(verifier.VerifyField((uint)offset, 4, 1, 2, true));
218 // Check Error: First size to big
219 Assert.IsFalse(verifier.VerifyField((uint)offset, 4, 2, 1, true));
220 }
221
222 [FlatBuffersTestMethod]
223 public void TestVTableWithOneBool_DefaultValue()
224 {
225 var builder = new FlatBufferBuilder(1);
226 builder.StartTable(1);
227 Assert.ArrayEqual(new byte[] { 0 }, builder.DataBuffer.ToFullArray());
228 builder.AddBool(0, false, false);
229 builder.EndTable();
230 Assert.ArrayEqual(new byte[]
231 {
232 // No padding.
233 4, 0, // vtable bytes
234 4, 0, // end of object from here
235 // entry 0 is not stored (trimmed end of vtable)
236 4, 0, 0, 0, // int32 offset for start of vtable
237 },
238 builder.DataBuffer.ToFullArray());
239 var verifier = new Verifier(builder.DataBuffer);
240 var offset = 4;
241 // table must be ok
242 Assert.IsTrue(verifier.VerifyTableStart((uint)offset));
243 // First field must be bool
244 Assert.IsTrue(verifier.VerifyField((uint)offset, 4, 1, 1, false));
245 // Error Check: First field not present
246 Assert.IsFalse(verifier.VerifyField((uint)offset, 4, 1, 1, true));
247 }
248
249 [FlatBuffersTestMethod]
250 public void TestVTableWithOneInt16()
251 {
252 var builder = new FlatBufferBuilder(1);
253 builder.StartTable(1);
254 Assert.ArrayEqual(new byte[] { 0 }, builder.DataBuffer.ToFullArray());
255 builder.AddShort(0, 0x789A, 0);
256 int offset = builder.EndTable();
257 Assert.ArrayEqual(new byte[]
258 {
259 0, 0, // padding to 16 bytes
260 6, 0, // vtable bytes
261 8, 0, // object length inc vtable offset
262 6, 0, // start of int16 value
263 6, 0, 0, 0, // int32 offset for start of vtable
264 0, 0, // padding
265 0x9A, 0x78, //value 0
266 },
267 builder.DataBuffer.ToFullArray());
268 var verifier = new Verifier(builder.DataBuffer);
269 offset += builder.DataBuffer.Position;
270 // table must be ok
271 Assert.IsTrue(verifier.VerifyTableStart((uint)offset));
272 // First field must be ushort
273 Assert.IsTrue(verifier.VerifyField((uint)offset, 4, 2, 2, true));
274 // Check Error: Second field
275 Assert.IsFalse(verifier.VerifyField((uint)offset, 6, 2, 2, true));
276 // Check Error: First field too big alignment
277 Assert.IsFalse(verifier.VerifyField((uint)offset, 4, 4, 2, true));
278 // Check Error: First field size to big
279 Assert.IsFalse(verifier.VerifyField((uint)offset, 4, 2, 4, true));
280 }
281
282 [FlatBuffersTestMethod]
283 public void TestVTableWithTwoInt16()
284 {
285 var builder = new FlatBufferBuilder(1);
286 builder.StartTable(2);
287 Assert.ArrayEqual(new byte[] { 0 }, builder.DataBuffer.ToFullArray());
288 builder.AddShort(0, 0x3456, 0);
289 builder.AddShort(1, 0x789A, 0);
290 int offset = builder.EndTable();
291 Assert.ArrayEqual(new byte[]
292 {
293 8, 0, // vtable bytes
294 8, 0, // object length inc vtable offset
295 6, 0, // start of int16 value 0
296 4, 0, // start of int16 value 1
297 8, 0, 0, 0, // int32 offset for start of vtable
298 0x9A, 0x78, // value 1
299 0x56, 0x34, // value 0
300 },
301 builder.DataBuffer.ToFullArray());
302 var verifier = new Verifier(builder.DataBuffer);
303 offset += builder.DataBuffer.Position;
304 // table must be ok
305 Assert.IsTrue(verifier.VerifyTableStart((uint)offset));
306 // First field must be ushort
307 Assert.IsTrue(verifier.VerifyField((uint)offset, 4, 2, 2, true));
308 // Check Error: Second field
309 Assert.IsTrue(verifier.VerifyField((uint)offset, 6, 2, 2, true));
310 // Check Error: Second field too big alignment
311 Assert.IsFalse(verifier.VerifyField((uint)offset, 4, 4, 2, true));
312 // Check Error: Second field size to big
313 Assert.IsFalse(verifier.VerifyField((uint)offset, 4, 2, 4, true));
314 }
315
316 [FlatBuffersTestMethod]
317 public void TestVTableWithInt16AndBool()
318 {
319 var builder = new FlatBufferBuilder(1);
320 builder.StartTable(2);
321 Assert.ArrayEqual(new byte[] { 0 }, builder.DataBuffer.ToFullArray());
322 builder.AddShort(0, 0x3456, 0);
323 builder.AddBool(1, true, false);
324 int offset = builder.EndTable();
325 Assert.ArrayEqual(new byte[]
326 {
327 8, 0, // vtable bytes
328 8, 0, // object length inc vtable offset
329 6, 0, // start of int16 value 0
330 5, 0, // start of bool value 1
331 8, 0, 0, 0, // int32 offset for start of vtable
332 0, 1, // padding + value 1
333 0x56, 0x34, // value 0
334 },
335 builder.DataBuffer.ToFullArray());
336 var verifier = new Verifier(builder.DataBuffer);
337 offset += builder.DataBuffer.Position;
338 // table must be ok
339 Assert.IsTrue(verifier.VerifyTableStart((uint)offset));
340 // First field must be ushort
341 Assert.IsTrue(verifier.VerifyField((uint)offset, 4, 2, 2, true));
342 // Check Error: Second field must be bool
343 Assert.IsTrue(verifier.VerifyField((uint)offset, 6, 1, 1, true));
344 // Check Error: Second field too big alignment
345 Assert.IsFalse(verifier.VerifyField((uint)offset, 4, 4, 2, true));
346 // Check Error: Second field size to big
347 Assert.IsFalse(verifier.VerifyField((uint)offset, 4, 2, 4, true));
348 }
349
350 [FlatBuffersTestMethod]
351 public void TestVTableWithEmptyVector()
352 {
353 var builder = new FlatBufferBuilder(1);
354 builder.StartVector(sizeof(byte), 0, 1);
355 var vecEnd = builder.EndVector();
356
357 builder.StartTable(1);
358
359 builder.AddOffset(0, vecEnd.Value, 0);
360 builder.EndTable();
361 Assert.ArrayEqual(new byte[]
362 {
363 0, 0, 0, 0,
364 0, 0, 0, 0,
365 0, 0, 0, 0,
366 0, 0, // Padding to 32 bytes
367 6, 0, // vtable bytes
368 8, 0, // object length inc vtable offset
369 4, 0, // start of vector offset value 0
370 6, 0, 0, 0, // int32 offset for start of vtable
371 4, 0, 0, 0,
372 0, 0, 0, 0,
373 },
374 builder.DataBuffer.ToFullArray());
375 var verifier = new Verifier(builder.DataBuffer);
376 uint checkOffset = 20;
377 // table must be ok
378 Assert.IsTrue(verifier.VerifyTableStart(checkOffset));
379 // First field must be vector with element size 1
380 Assert.IsTrue(verifier.VerifyVectorOfData(checkOffset, 4, 1, true));
381 }
382
383 [FlatBuffersTestMethod]
384 public void TestVTableWithEmptyVectorAndScalars()
385 {
386 var builder = new FlatBufferBuilder(1);
387 builder.StartVector(sizeof(byte), 0, 1);
388 var vecEnd = builder.EndVector();
389
390 builder.StartTable(2);
391 builder.AddShort(0, 55, 0);
392 builder.AddOffset(1, vecEnd.Value, 0);
393 builder.EndTable();
394 Assert.ArrayEqual(new byte[]
395 {
396 0, 0, 0, 0,
397 0, 0, 0, 0, // Padding to 32 bytes
398 8, 0, // vtable bytes
399 12, 0, // object length inc vtable offset
400 10, 0, // offset to int16 value 0
401 4, 0, // start of vector offset value 1
402 8, 0, 0, 0, // int32 offset for start of vtable
403 8, 0, 0, 0, // value 1
404 0, 0, 55, 0, // value 0
405 0, 0, 0, 0, // length of vector (not in sctruc)
406 },
407 builder.DataBuffer.ToFullArray());
408 var verifier = new Verifier(builder.DataBuffer);
409 uint checkOffset = 16;
410 // table must be ok
411 Assert.IsTrue(verifier.VerifyTableStart(checkOffset));
412 // First field must be short
413 Assert.IsTrue(verifier.VerifyField(checkOffset, 4, 2, 2, true));
414 // Second field must be vector with element size 1
415 Assert.IsTrue(verifier.VerifyVectorOfData(checkOffset, 6, 2, true));
416 }
417
418
419 [FlatBuffersTestMethod]
420 public void TestVTableWith_1xInt16_and_Vector_or_2xInt16()
421 {
422 var builder = new FlatBufferBuilder(1);
423 builder.StartVector(sizeof(short), 2, 1);
424 builder.AddShort(0x1234);
425 builder.AddShort(0x5678);
426 var vecEnd = builder.EndVector();
427
428 builder.StartTable(2);
429 builder.AddOffset(1, vecEnd.Value, 0);
430 builder.AddShort(0, 55, 0);
431 builder.EndTable();
432 Assert.ArrayEqual(new byte[]
433 {
434 0, 0, 0, 0, // Padding to 32 bytes
435 8, 0, // vtable bytes
436 12, 0, // object length
437 6, 0, // start of value 0 from end of vtable
438 8, 0, // start of value 1 from end of buffer
439 8, 0, 0, 0, // int32 offset for start of vtable
440 0, 0, 55, 0, // padding + value 0
441 4, 0, 0, 0, // position of vector from here
442 2, 0, 0, 0, // length of vector
443 0x78, 0x56, // vector value 0
444 0x34, 0x12, // vector value 1
445 },
446 builder.DataBuffer.ToFullArray());
447 var verifier = new Verifier(builder.DataBuffer);
448 uint checkOffset = 12;
449 // table must be ok
450 Assert.IsTrue(verifier.VerifyTableStart(checkOffset));
451 // Second field must be vector with element size 2
452 Assert.IsTrue(verifier.VerifyVectorOfData(checkOffset, 6, 2, true));
453 // Check Error: Second field with too big size
454 Assert.IsFalse(verifier.VerifyVectorOfData(checkOffset, 6, 4, true));
455 // First field must be short
456 Assert.IsTrue(verifier.VerifyField(checkOffset, 4, 2, 2, true));
457 }
458
459 [FlatBuffersTestMethod]
460 public void TestVTableWithAStruct_of_int8_int16_int32()
461 {
462 var builder = new FlatBufferBuilder(1);
463 builder.StartTable(1);
464 builder.Prep(4+4+4, 0);
465 builder.AddSbyte(55);
466 builder.Pad(3);
467 builder.AddShort(0x1234);
468 builder.Pad(2);
469 builder.AddInt(0x12345678);
470 var structStart = builder.Offset;
471 builder.AddStruct(0, structStart, 0);
472 builder.EndTable();
473 Assert.ArrayEqual(new byte[]
474 {
475 0, 0, 0, 0,
476 0, 0, 0, 0,
477 0, 0, // Padding to 32 bytes
478 6, 0, // vtable bytes
479 16, 0, // object length
480 4, 0, // start of struct from here
481 6, 0, 0, 0, // int32 offset for start of vtable
482 0x78, 0x56, 0x34, 0x12, // struct value 2
483 0x00, 0x00, 0x34, 0x12, // struct value 1
484 0x00, 0x00, 0x00, 55, // struct value 0
485 },
486 builder.DataBuffer.ToFullArray());
487 var verifier = new Verifier(builder.DataBuffer);
488 uint checkOffset = 16;
489 // table must be ok
490 Assert.IsTrue(verifier.VerifyTableStart(checkOffset));
491 // First field must be a struct with 12 bytes
492 Assert.IsTrue(verifier.VerifyField(checkOffset, 4, 12, 4, true));
493 // Check Error: First field with more than 12 bytes
494 Assert.IsFalse(verifier.VerifyField(checkOffset, 4, 16, 4, true));
495 }
496
497
498 [FlatBuffersTestMethod]
499 public void TestVTableWithAVectorOf_2xStructOf_2xInt8()
500 {
501 var builder = new FlatBufferBuilder(1);
502 builder.StartVector(sizeof(byte)*2, 2, 1);
503 builder.AddByte(33);
504 builder.AddByte(44);
505 builder.AddByte(55);
506 builder.AddByte(66);
507 var vecEnd = builder.EndVector();
508
509 builder.StartTable(1);
510 builder.AddOffset(0, vecEnd.Value, 0);
511 builder.EndTable();
512
513 Assert.ArrayEqual(new byte[]
514 {
515 0, 0, 0, 0,
516 0, 0, 0, 0,
517 0, 0, // Padding to 32 bytes
518 6, 0, // vtable bytes
519 8, 0, // object length
520 4, 0, // offset of vector offset
521 6, 0, 0, 0, // int32 offset for start of vtable
522 4, 0, 0, 0, // Vector start offset
523 2, 0, 0, 0, // Vector len
524 66, // vector 1, 1
525 55, // vector 1, 0
526 44, // vector 0, 1
527 33, // vector 0, 0
528 },
529 builder.DataBuffer.ToFullArray());
530 var verifier = new Verifier(builder.DataBuffer);
531 uint checkOffset = 16;
532 // table must be ok
533 Assert.IsTrue(verifier.VerifyTableStart(checkOffset));
534 // First field must be vector with element size 2
535 Assert.IsTrue(verifier.VerifyVectorOfData(checkOffset, 4, 2, true));
536 }
537
538 [FlatBuffersTestMethod]
539 public void TestVTableWithSomeElements()
540 {
541 var builder = new FlatBufferBuilder(1);
542 builder.StartTable(2);
543 builder.AddByte(0, 33, 0);
544 builder.AddShort(1, 66, 0);
545 var off = builder.EndTable();
546 builder.Finish(off);
547
548 byte[] padded = new byte[]
549 {
550 0, 0, 0, 0,
551 0, 0, 0, 0,
552 0, 0, 0, 0, //Padding to 32 bytes
553 12, 0, 0, 0, // root of table, pointing to vtable offset
554 8, 0, // vtable bytes
555 8, 0, // object length
556 7, 0, // start of value 0
557 4, 0, // start of value 1
558 8, 0, 0, 0, // int32 offset for start of vtable
559 66, 0, // value 1
560 0, 33, // value 0
561
562 };
563 Assert.ArrayEqual(padded, builder.DataBuffer.ToFullArray());
564
565 // no padding in sized array
566 byte[] unpadded = new byte[padded.Length - 12];
567 Buffer.BlockCopy(padded, 12, unpadded, 0, unpadded.Length);
568 Assert.ArrayEqual(unpadded, builder.DataBuffer.ToSizedArray());
569
570 var verifier = new Verifier(builder.DataBuffer);
571 uint checkOffset = builder.DataBuffer.GetUint(builder.DataBuffer.Position) + (uint)builder.DataBuffer.Position;
572 // table must be ok
573 Assert.IsTrue(verifier.VerifyTableStart(checkOffset));
574 // First field must be a struct with 12 bytes
575 Assert.IsTrue(verifier.VerifyField(checkOffset, 4, 1, 1, true));
576 // Second field must be a struct with 12 bytes
577 Assert.IsTrue(verifier.VerifyField(checkOffset, 6, 2, 2, true));
578 }
579
580 [FlatBuffersTestMethod]
581 public void TestVTableWithStrings()
582 {
583 var builder = new FlatBufferBuilder(64);
584 var str1 = builder.CreateString("foo");
585 var str2 = builder.CreateString("foobar");
586 builder.StartTable(2);
587 builder.AddOffset(0, str1.Value, 0);
588 builder.AddOffset(1, str2.Value, 0);
589 var off = builder.EndTable();
590 builder.Finish(off);
591
592 byte[] padded = new byte[]
593 {
594 0, 0, 0, 0,
595 0, 0, 0, 0,
596 0, 0, 0, 0,
597 0, 0, 0, 0,
598 0, 0, 0, 0, //Padding to 32 bytes
599 12, 0, 0, 0, // root of table, pointing to vtable offset
600 8, 0, // vtable bytes
601 12, 0, // object length
602 8, 0, // start of value 0
603 4, 0, // start of value 1
604 8, 0, 0, 0, // int32 offset for start of vtable
605 8, 0, 0, 0, // pointer to string
606 16, 0, 0, 0, // pointer to string
607 6, 0, 0, 0, // length of string
608 102, 111, 111, 98, 97, 114, 0, 0, // "foobar" + padding
609 3, 0, 0, 0, // length of string
610 102, 111, 111, 0 // "bar"
611 };
612 Assert.ArrayEqual(padded, builder.DataBuffer.ToFullArray());
613
614 var verifier = new Verifier(builder.DataBuffer);
615 uint checkOffset = builder.DataBuffer.GetUint(builder.DataBuffer.Position) + (uint)builder.DataBuffer.Position;
616 // table must be ok
617 Assert.IsTrue(verifier.VerifyTableStart(checkOffset));
618 // First field string check
619 Assert.IsTrue(verifier.VerifyString(checkOffset, 4, true));
620 // Second field string check
621 Assert.IsTrue(verifier.VerifyString(checkOffset, 6, true));
622 }
623
624 [FlatBuffersTestMethod]
625 public void TestVTableWithVectorOfStrings()
626 {
627 var builder = new FlatBufferBuilder(64);
628 var str1 = builder.CreateString("foo");
629 var str2 = builder.CreateString("foobar");
630 builder.StartVector(sizeof(int), 2, 1);
631 builder.AddOffset(str1.Value);
632 builder.AddOffset(str2.Value);
633 var vec = builder.EndVector();
634 builder.StartTable(1);
635 builder.AddOffset(0, vec.Value, 0);
636 var off = builder.EndTable();
637 builder.Finish(off);
638
639 byte[] padded = new byte[]
640 {
641 0, 0, 0, 0,
642 0, 0, 0, 0,
643 0, 0, 0, 0, //Padding to 32 bytes
644 12, 0, 0, 0, // root of table, pointing to vtable offset
645 0, 0, // padding
646 6, 0, // vtable bytes
647 8, 0, // object length
648 4, 0, // start of value 0
649 6, 0, 0, 0, // int32 offset for start of vtable
650 4, 0, 0, 0, // pointer to vector
651 2, 0, 0, 0, // length of vector
652 8, 0, 0, 0, // int32 offset to string 1
653 16, 0, 0, 0, // int32 offset to string 2
654 6, 0, 0, 0, // length of string
655 102, 111, 111, 98, 97, 114, 0, 0, // "foobar" + padding
656 3, 0, 0, 0, // length of string
657 102, 111, 111, 0 // "bar"
658 };
659 Assert.ArrayEqual(padded, builder.DataBuffer.ToFullArray());
660
661 var verifier = new Verifier(builder.DataBuffer);
662 uint checkOffset = builder.DataBuffer.GetUint(builder.DataBuffer.Position) + (uint)builder.DataBuffer.Position;
663 // table must be ok
664 Assert.IsTrue(verifier.VerifyTableStart(checkOffset));
665 // First field string check
666 Assert.IsTrue(verifier.VerifyVectorOfStrings(checkOffset, 4, true));
667 }
668
669 [FlatBuffersTestMethod]
670 public void TestTwoFinishTable()
671 {
672 var builder = new FlatBufferBuilder(1);
673 builder.StartTable(2);
674 builder.AddByte(0, 33, 0);
675 builder.AddByte(1, 44, 0);
676 var off0 = builder.EndTable();
677 builder.Finish(off0);
678
679 builder.StartTable(3);
680 builder.AddByte(0, 55, 0);
681 builder.AddByte(1, 66, 0);
682 builder.AddByte(2, 77, 0);
683 var off1 = builder.EndTable();
684 builder.Finish(off1);
685
686 Assert.ArrayEqual(new byte[]
687 {
688 0, 0, 0, 0,
689 0, 0, 0, 0,
690 0, 0, 0, 0,
691 0, 0, 0, 0,
692 0, 0, 0, 0, // padding to 64 bytes
693 16, 0, 0, 0, // root of table, pointing to vtable offset (obj1)
694 0, 0, // padding
695
696 10, 0, // vtable bytes
697 8, 0, // object length
698 7, 0, // start of value 0
699 6, 0, // start of value 1
700 5, 0, // start of value 2
701 10, 0, 0, 0, // int32 offset for start of vtable
702 0, // pad
703 77, // values 2, 1, 0
704 66,
705 55,
706
707 12, 0, 0, 0, // root of table, pointing to vtable offset (obj0)
708 8, 0, // vtable bytes
709 8, 0, // object length
710 7, 0, // start of value 0
711 6, 0, // start of value 1
712 8, 0, 0, 0, // int32 offset for start of vtable
713 0, 0, // pad
714 44, // value 1, 0
715 33,
716 },
717 builder.DataBuffer.ToFullArray());
718
719 // check obj1
720 var verifier = new Verifier(builder.DataBuffer);
721 uint checkOffset = builder.DataBuffer.GetUint(builder.DataBuffer.Position) + (uint)builder.DataBuffer.Position;
722 // table must be ok
723 Assert.IsTrue(verifier.VerifyTableStart(checkOffset));
724 // First field must be a struct with 12 bytes
725 Assert.IsTrue(verifier.VerifyField(checkOffset, 4, 1, 1, true));
726 // Second field must be a struct with 12 bytes
727 Assert.IsTrue(verifier.VerifyField(checkOffset, 6, 1, 1, true));
728 // Third field must be a struct with 12 bytes
729 Assert.IsTrue(verifier.VerifyField(checkOffset, 8, 1, 1, true));
730 // Check Error: 4. field did not exist
731 Assert.IsFalse(verifier.VerifyField(checkOffset, 10, 1, 1, true));
732
733 // check obj0
734 checkOffset = 56;
735 // table must be ok
736 Assert.IsTrue(verifier.VerifyTableStart(checkOffset));
737 // First field must be a struct with 12 bytes
738 Assert.IsTrue(verifier.VerifyField(checkOffset, 4, 1, 1, true));
739 // Second field must be a struct with 12 bytes
740 Assert.IsTrue(verifier.VerifyField(checkOffset, 6, 1, 1, true));
741 // Check Error: 3. field did not exist
742 Assert.IsFalse(verifier.VerifyField(checkOffset, 8, 1, 1, true));
743 // Check Error: 4. field did not exist
744 Assert.IsFalse(verifier.VerifyField(checkOffset, 10, 1, 1, true));
745 }
746
747 [FlatBuffersTestMethod]
748 public void TestBunchOfBools()
749 {
750 var builder = new FlatBufferBuilder(1);
751 builder.StartTable(8);
752 for (var i = 0; i < 8; i++)
753 {
754 builder.AddBool(i, true, false);
755 }
756 var off = builder.EndTable();
757 builder.Finish(off);
758
759 byte[] padded = new byte[]
760 {
761 0, 0, 0, 0,
762 0, 0, 0, 0,
763 0, 0, 0, 0,
764 0, 0, 0, 0,
765 0, 0, 0, 0,
766 0, 0, 0, 0,
767 0, 0, 0, 0, // padding to 64 bytes
768
769 24, 0, 0, 0, // root of table, pointing to vtable offset (obj0)
770 20, 0, // vtable bytes
771 12, 0, // object length
772 11, 0, // start of value 0
773 10, 0, // start of value 1
774 9, 0, // start of value 2
775 8, 0, // start of value 3
776 7, 0, // start of value 4
777 6, 0, // start of value 5
778 5, 0, // start of value 6
779 4, 0, // start of value 7
780
781 20, 0, 0, 0, // int32 offset for start of vtable
782
783 1, 1, 1, 1, // values
784 1, 1, 1, 1,
785
786 };
787 Assert.ArrayEqual(padded, builder.DataBuffer.ToFullArray());
788
789 // no padding in sized array
790 byte[] unpadded = new byte[padded.Length - 28];
791 Buffer.BlockCopy(padded, 28, unpadded, 0, unpadded.Length);
792 Assert.ArrayEqual(unpadded, builder.DataBuffer.ToSizedArray());
793
794 var verifier = new Verifier(builder.DataBuffer);
795 uint checkOffset = builder.DataBuffer.GetUint(builder.DataBuffer.Position) + (uint)builder.DataBuffer.Position;
796 // table must be ok
797 Assert.IsTrue(verifier.VerifyTableStart(checkOffset));
798 for (var i = 0; i < 8; i++)
799 {
800 Assert.IsTrue(verifier.VerifyField(checkOffset, (short)(4 + i * 2), 1, 1, true));
801 }
802 Assert.IsFalse(verifier.VerifyField(checkOffset, (short)(4 + 8 * 2), 1, 1, true));
803 }
804
805 [FlatBuffersTestMethod]
806 public void TestBunchOfBoolsSizePrefixed()
807 {
808 var builder = new FlatBufferBuilder(1);
809 builder.StartTable(8);
810 for (var i = 0; i < 8; i++)
811 {
812 builder.AddBool(i, true, false);
813 }
814 var off = builder.EndTable();
815 builder.FinishSizePrefixed(off);
816
817 byte[] padded = new byte[]
818 {
819 0, 0, 0, 0,
820 0, 0, 0, 0,
821 0, 0, 0, 0,
822 0, 0, 0, 0,
823 0, 0, 0, 0,
824 0, 0, 0, 0, // padding to 64 bytes
825
826 36, 0, 0, 0, // size prefix
827 24, 0, 0, 0, // root of table, pointing to vtable offset (obj0)
828 20, 0, // vtable bytes
829 12, 0, // object length
830 11, 0, // start of value 0
831 10, 0, // start of value 1
832 9, 0, // start of value 2
833 8, 0, // start of value 3
834 7, 0, // start of value 4
835 6, 0, // start of value 5
836 5, 0, // start of value 6
837 4, 0, // start of value 7
838
839 20, 0, 0, 0, // int32 offset for start of vtable
840
841 1, 1, 1, 1, // values
842 1, 1, 1, 1,
843
844 };
845 Assert.ArrayEqual(padded, builder.DataBuffer.ToFullArray());
846
847 // no padding in sized array
848 byte[] unpadded = new byte[padded.Length - 24];
849 Buffer.BlockCopy(padded, 24, unpadded, 0, unpadded.Length);
850 Assert.ArrayEqual(unpadded, builder.DataBuffer.ToSizedArray());
851 }
852
853 [FlatBuffersTestMethod]
854 public void TestWithFloat()
855 {
856 var builder = new FlatBufferBuilder(1);
857 builder.StartTable(1);
858 builder.AddFloat(0, 1, 0);
859 builder.EndTable();
860
861
862 Assert.ArrayEqual(new byte[]
863 {
864 0, 0,
865 6, 0, // vtable bytes
866 8, 0, // object length
867 4, 0, // start of value 0
868 6, 0, 0, 0, // int32 offset for start of vtable
869 0, 0, 128, 63, // value
870
871 },
872 builder.DataBuffer.ToFullArray());
873 var verifier = new Verifier(builder.DataBuffer);
874 uint checkOffset = 8;
875 // table must be ok
876 Assert.IsTrue(verifier.VerifyTableStart(checkOffset));
877 // First Field must be float
878 Assert.IsTrue(verifier.VerifyField(checkOffset, 4, 4, 4, true));
879 // Check Error: First Field with to big size
880 Assert.IsFalse(verifier.VerifyField(checkOffset, 4, 8, 4, true));
881 // Check Error: First Field with to big padding
882 Assert.IsFalse(verifier.VerifyField(checkOffset, 4, 4, 8, true));
883 }
884
885 private void CheckObjects(int fieldCount, int objectCount)
886 {
887 _lcg.Reset();
888
889 const int testValuesMax = 11;
890
891 var builder = new FlatBufferBuilder(1);
892
893 var objects = new int[objectCount];
894
895 for (var i = 0; i < objectCount; ++i)
896 {
897 builder.StartTable(fieldCount);
898
899 for (var j = 0; j < fieldCount; ++j)
900 {
901 var fieldType = _lcg.Next()%testValuesMax;
902
903 switch (fieldType)
904 {
905 case 0:
906 {
907 builder.AddBool(j, FuzzTestData.BoolValue, false);
908 break;
909 }
910 case 1:
911 {
912 builder.AddSbyte(j, FuzzTestData.Int8Value, 0);
913 break;
914 }
915 case 2:
916 {
917 builder.AddByte(j, FuzzTestData.UInt8Value, 0);
918 break;
919 }
920 case 3:
921 {
922 builder.AddShort(j, FuzzTestData.Int16Value, 0);
923 break;
924 }
925 case 4:
926 {
927 builder.AddUshort(j, FuzzTestData.UInt16Value, 0);
928 break;
929 }
930 case 5:
931 {
932 builder.AddInt(j, FuzzTestData.Int32Value, 0);
933 break;
934 }
935 case 6:
936 {
937 builder.AddUint(j, FuzzTestData.UInt32Value, 0);
938 break;
939 }
940 case 7:
941 {
942 builder.AddLong(j, FuzzTestData.Int64Value, 0);
943 break;
944 }
945 case 8:
946 {
947 builder.AddUlong(j, FuzzTestData.UInt64Value, 0);
948 break;
949 }
950 case 9:
951 {
952 builder.AddFloat(j, FuzzTestData.Float32Value, 0);
953 break;
954 }
955 case 10:
956 {
957 builder.AddDouble(j, FuzzTestData.Float64Value, 0);
958 break;
959 }
960 default:
961 throw new Exception("Unreachable");
962 }
963
964 }
965
966 var offset = builder.EndTable();
967
968 // Store the object offset
969 objects[i] = offset;
970 }
971
972 _lcg.Reset();
973
974 // Test all objects are readable and return expected values...
975 for (var i = 0; i < objectCount; ++i)
976 {
977 var table = new TestTable(builder.DataBuffer, builder.DataBuffer.Length - objects[i]);
978
979 for (var j = 0; j < fieldCount; ++j)
980 {
981 var fieldType = _lcg.Next() % testValuesMax;
982 var fc = 2 + j; // 2 == VtableMetadataFields
983 var f = fc * 2;
984
985 switch (fieldType)
986 {
987 case 0:
988 {
989 Assert.AreEqual(FuzzTestData.BoolValue, table.GetSlot(f, false));
990 break;
991 }
992 case 1:
993 {
994 Assert.AreEqual(FuzzTestData.Int8Value, table.GetSlot(f, (sbyte)0));
995 break;
996 }
997 case 2:
998 {
999 Assert.AreEqual(FuzzTestData.UInt8Value, table.GetSlot(f, (byte)0));
1000 break;
1001 }
1002 case 3:
1003 {
1004 Assert.AreEqual(FuzzTestData.Int16Value, table.GetSlot(f, (short)0));
1005 break;
1006 }
1007 case 4:
1008 {
1009 Assert.AreEqual(FuzzTestData.UInt16Value, table.GetSlot(f, (ushort)0));
1010 break;
1011 }
1012 case 5:
1013 {
1014 Assert.AreEqual(FuzzTestData.Int32Value, table.GetSlot(f, (int)0));
1015 break;
1016 }
1017 case 6:
1018 {
1019 Assert.AreEqual(FuzzTestData.UInt32Value, table.GetSlot(f, (uint)0));
1020 break;
1021 }
1022 case 7:
1023 {
1024 Assert.AreEqual(FuzzTestData.Int64Value, table.GetSlot(f, (long)0));
1025 break;
1026 }
1027 case 8:
1028 {
1029 Assert.AreEqual(FuzzTestData.UInt64Value, table.GetSlot(f, (ulong)0));
1030 break;
1031 }
1032 case 9:
1033 {
1034 Assert.AreEqual(FuzzTestData.Float32Value, table.GetSlot(f, (float)0));
1035 break;
1036 }
1037 case 10:
1038 {
1039 Assert.AreEqual(FuzzTestData.Float64Value, table.GetSlot(f, (double)0));
1040 break;
1041 }
1042 default:
1043 throw new Exception("Unreachable");
1044 }
1045
1046 }
1047
1048 }
1049
1050 }
1051 }
1052}
View as plain text