• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 using System;
18 using Google.FlatBuffers;
19 
20 namespace Google.FlatBuffers.Test
21 {
22     [FlatBuffersTestClass]
23     public class FlatBuffersFuzzTests
24     {
25         private readonly Lcg _lcg = new Lcg();
26 
27         [FlatBuffersTestMethod]
TestObjects()28         public void TestObjects()
29         {
30             CheckObjects(11, 100);
31         }
32 
33         [FlatBuffersTestMethod]
TestNumbers()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]
TestNumbers64()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]
TestVector_1xUInt8()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]
TestVector_2xUint8()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]
TestVector_1xUInt16()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]
TestVector_2xUInt16()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]
TestCreateAsciiString()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]
TestCreateSharedAsciiString()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]
TestCreateArbitarytring()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]
TestEmptyVTable()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]
TestVTableWithOneBool()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]
TestVTableWithOneBool_DefaultValue()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]
TestVTableWithOneInt16()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]
TestVTableWithTwoInt16()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]
TestVTableWithInt16AndBool()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]
TestVTableWithEmptyVector()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]
TestVTableWithEmptyVectorAndScalars()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]
TestVTableWith_1xInt16_and_Vector_or_2xInt16()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]
TestVTableWithAStruct_of_int8_int16_int32()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]
TestVTableWithAVectorOf_2xStructOf_2xInt8()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]
TestVTableWithSomeElements()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]
TestVTableWithStrings()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]
TestVTableWithVectorOfStrings()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]
TestTwoFinishTable()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]
TestBunchOfBools()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]
TestBunchOfBoolsSizePrefixed()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]
TestWithFloat()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 
CheckObjects(int fieldCount, int objectCount)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 }
1053