summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortira-misu <gunter.burchardt@boschrexroth.de>2023-04-06 00:29:14 +0200
committerGitHub <noreply@github.com>2023-04-06 00:29:14 +0200
commit876a64aae138be5d9eb9245348719a18161d8e09 (patch)
tree14940818e1a6506eeb180150d610e41a06735732
parent2803983c708ff6f4861c324597fd8e5f74660f67 (diff)
downloadflatbuffers-876a64aae138be5d9eb9245348719a18161d8e09.tar.gz
flatbuffers-876a64aae138be5d9eb9245348719a18161d8e09.tar.bz2
flatbuffers-876a64aae138be5d9eb9245348719a18161d8e09.zip
[CS] Verifier (#7850)
* Fix C/C++ Create<Type>Direct with sorted vectors If a struct has a key the vector has to be sorted. To sort the vector you can't use "const". * Changes due to code review * Improve code readability * Add generate of JSON schema to string to lib * option indent_step is supported * Remove unused variables * Fix break in test * Fix style to be consistent with rest of the code * [TS] Fix reserved words as arguments (#6955) * [TS] Fix generation of reserved words in object api (#7106) * [TS] Fix generation of object api * [TS] Fix MakeCamel -> ConvertCase * [C#] Fix collision of field name and type name * [TS] Add test for struct of struct of struct * Update generated files * Add missing files * [TS] Fix query of null/undefined fields in object api * Add .Net verfier * Add some fuzz tests for .Net * Remove additional files * Fix .net test * Changes due to PR * Fix generated files --------- Co-authored-by: Derek Bailey <derekbailey@google.com>
-rw-r--r--docs/source/CsharpUsage.md41
-rw-r--r--docs/source/doxyfile3
-rw-r--r--net/FlatBuffers/FlatBufferVerify.cs822
-rw-r--r--net/FlatBuffers/FlatBuffers.net35.csproj2
-rw-r--r--src/idl_gen_csharp.cpp244
-rw-r--r--tests/FlatBuffers.Test/FlatBuffers.Core.Test.csproj3
-rw-r--r--tests/FlatBuffers.Test/FlatBuffersExampleTests.cs5
-rw-r--r--tests/FlatBuffers.Test/FlatBuffersFuzzTests.cs253
-rw-r--r--tests/KeywordTest/KeywordsInTable.cs13
-rw-r--r--tests/KeywordTest/KeywordsInUnion.cs22
-rw-r--r--tests/KeywordTest/Table2.cs11
-rw-r--r--tests/MyGame/Example/Any.cs25
-rw-r--r--tests/MyGame/Example/AnyAmbiguousAliases.cs25
-rw-r--r--tests/MyGame/Example/AnyUniqueAliases.cs25
-rw-r--r--tests/MyGame/Example/ArrayTable.cs11
-rw-r--r--tests/MyGame/Example/Monster.cs71
-rw-r--r--tests/MyGame/Example/Referrable.cs10
-rw-r--r--tests/MyGame/Example/Stat.cs12
-rw-r--r--tests/MyGame/Example/TestSimpleTableWithEnum.cs10
-rw-r--r--tests/MyGame/Example/TypeAliases.cs21
-rw-r--r--tests/MyGame/Example2/Monster.cs9
-rw-r--r--tests/MyGame/InParentNamespace.cs9
-rw-r--r--tests/MyGame/MonsterExtra.cs20
-rw-r--r--tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.cs10
-rw-r--r--tests/namespace_test/NamespaceA/NamespaceB/UnionInNestedNS.cs19
-rw-r--r--tests/namespace_test/NamespaceA/SecondTableInA.cs10
-rw-r--r--tests/namespace_test/NamespaceA/TableInFirstNS.cs14
-rw-r--r--tests/namespace_test/NamespaceC/TableInC.cs11
-rw-r--r--tests/nested_namespace_test/nested_namespace_test3_generated.cs10
-rw-r--r--tests/optional_scalars/ScalarStuff.cs46
-rw-r--r--tests/type_field_collsion/Collision.cs11
-rw-r--r--tests/union_value_collsion/union_value_collision_generated.cs74
-rw-r--r--tests/union_vector/Attacker.cs10
-rw-r--r--tests/union_vector/Character.cs34
-rw-r--r--tests/union_vector/Gadget.cs22
-rw-r--r--tests/union_vector/HandFan.cs10
-rw-r--r--tests/union_vector/Movie.cs13
37 files changed, 1952 insertions, 9 deletions
diff --git a/docs/source/CsharpUsage.md b/docs/source/CsharpUsage.md
index da36fa8b..b0acc77d 100644
--- a/docs/source/CsharpUsage.md
+++ b/docs/source/CsharpUsage.md
@@ -142,6 +142,47 @@ To use it:
`ByKey` only works if the vector has been sorted, it will
likely not find elements if it hasn't been sorted.
+## Buffer verification
+
+As mentioned in [C++ Usage](@ref flatbuffers_guide_use_cpp) buffer
+accessor functions do not verify buffer offsets at run-time.
+If it is necessary, you can optionally use a buffer verifier before you
+access the data. This verifier will check all offsets, all sizes of
+fields, and null termination of strings to ensure that when a buffer
+is accessed, all reads will end up inside the buffer.
+
+Each root type will have a verification function generated for it,
+e.g. `Monster.VerifyMonster`. This can be called as shown:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cs}
+ var ok = Monster.VerifyMonster(buf);
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+if `ok` is true, the buffer is safe to read.
+
+For a more detailed control of verification `MonsterVerify.Verify`
+for `Monster` type can be used:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cs}
+ # Sequence of calls
+ FlatBuffers.Verifier verifier = new FlatBuffers.Verifier(buf);
+ var ok = verifier.VerifyBuffer("MONS", false, MonsterVerify.Verify);
+
+ # Or single line call
+ var ok = new FlatBuffers.Verifier(bb).setStringCheck(true).\
+ VerifyBuffer("MONS", false, MonsterVerify.Verify);
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+if `ok` is true, the buffer is safe to read.
+
+A second parameter of `verifyBuffer` specifies whether buffer content is
+size prefixed or not. In the example above, the buffer is assumed to not include
+size prefix (`false`).
+
+Verifier supports options that can be set using appropriate fluent methods:
+* SetMaxDepth - limit the nesting depth. Default: 1000000
+* SetMaxTables - total amount of tables the verifier may encounter. Default: 64
+* SetAlignmentCheck - check content alignment. Default: True
+* SetStringCheck - check if strings contain termination '0' character. Default: true
+
+
## Text parsing
There currently is no support for parsing text (Schema's and JSON) directly
diff --git a/docs/source/doxyfile b/docs/source/doxyfile
index 8cf9000d..9541aaff 100644
--- a/docs/source/doxyfile
+++ b/docs/source/doxyfile
@@ -779,7 +779,8 @@ INPUT = "FlatBuffers.md" \
"../../python/flatbuffers/builder.py" \
"../../js/flatbuffers.js" \
"../../php/FlatbufferBuilder.php" \
- "../../net/FlatBuffers/FlatBufferBuilder.cs" \
+ "../../net/FlatBuffers/FlatBufferBuilder.cs"
+ "../../net/FlatBuffers/FlatBufferVerify.cs" \
"../../include/flatbuffers/flatbuffers.h" \
"../../go/builder.go" \
"../../rust/flatbuffers/src/builder.rs"
diff --git a/net/FlatBuffers/FlatBufferVerify.cs b/net/FlatBuffers/FlatBufferVerify.cs
new file mode 100644
index 00000000..15064e8a
--- /dev/null
+++ b/net/FlatBuffers/FlatBufferVerify.cs
@@ -0,0 +1,822 @@
+/*
+ * Copyright 2014 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+using System;
+using System.Reflection;using System.Collections.Generic;
+using System.IO;
+
+namespace Google.FlatBuffers
+{
+
+ /// <summary>
+ /// The Class of the Verifier Options
+ /// </summary>
+ public class Options
+ {
+ public const int DEFAULT_MAX_DEPTH = 64;
+ public const int DEFAULT_MAX_TABLES = 1000000;
+
+ private int max_depth = 0;
+ private int max_tables = 0;
+ private bool string_end_check = false;
+ private bool alignment_check = false;
+
+ public Options()
+ {
+ max_depth = DEFAULT_MAX_DEPTH;
+ max_tables = DEFAULT_MAX_TABLES;
+ string_end_check = true;
+ alignment_check = true;
+ }
+
+ public Options(int maxDepth, int maxTables, bool stringEndCheck, bool alignmentCheck)
+ {
+ max_depth = maxDepth;
+ max_tables = maxTables;
+ string_end_check = stringEndCheck;
+ alignment_check = alignmentCheck;
+ }
+ /// <summary> Maximum depth of nested tables allowed in a valid flatbuffer. </summary>
+ public int maxDepth
+ {
+ get { return max_depth; }
+ set { max_depth = value; }
+ }
+ /// <summary> Maximum number of tables allowed in a valid flatbuffer. </summary>
+ public int maxTables
+ {
+ get { return max_tables; }
+ set { max_tables = value; }
+ }
+ /// <summary> Check that string contains its null terminator </summary>
+ public bool stringEndCheck
+ {
+ get { return string_end_check; }
+ set { string_end_check = value; }
+ }
+ /// <summary> Check alignment of elements </summary>
+ public bool alignmentCheck
+ {
+ get { return alignment_check; }
+ set { alignment_check = value; }
+ }
+ }
+
+ public struct checkElementStruct
+ {
+ public bool elementValid;
+ public uint elementOffset;
+ }
+
+ public delegate bool VerifyTableAction(Verifier verifier, uint tablePos);
+ public delegate bool VerifyUnionAction(Verifier verifier, byte typeId, uint tablePos);
+
+ /// <summary>
+ /// The Main Class of the FlatBuffer Verifier
+ /// </summary>
+ public class Verifier
+ {
+ private ByteBuffer verifier_buffer = null;
+ private Options verifier_options = null;
+ private int depth_cnt = 0;
+ private int num_tables_cnt = 0;
+
+ public const int SIZE_BYTE = 1;
+ public const int SIZE_INT = 4;
+ public const int SIZE_U_OFFSET = 4;
+ public const int SIZE_S_OFFSET = 4;
+ public const int SIZE_V_OFFSET = 2;
+ public const int SIZE_PREFIX_LENGTH = FlatBufferConstants.SizePrefixLength; // default size = 4
+ public const int FLATBUFFERS_MAX_BUFFER_SIZE = System.Int32.MaxValue; // default size = 2147483647
+ public const int FILE_IDENTIFIER_LENGTH = FlatBufferConstants.FileIdentifierLength; // default size = 4
+
+ /// <summary> The Base Constructor of the Verifier object </summary>
+ public Verifier()
+ {
+ // Verifier buffer
+ verifier_buffer = null;
+ // Verifier settings
+ verifier_options = null;
+ // Depth counter
+ depth_cnt = 0;
+ // Tables counter
+ num_tables_cnt = 0;
+ }
+
+ /// <summary> The Constructor of the Verifier object with input parameters: ByteBuffer and/or Options </summary>
+ /// <param name="buf"> Input flat byte buffer defined as ByteBuffer type</param>
+ /// <param name="options"> Options object with settings for the coniguration the Verifier </param>
+ public Verifier(ByteBuffer buf, Options options = null)
+ {
+ verifier_buffer = buf;
+ verifier_options = options ?? new Options();
+ depth_cnt = 0;
+ num_tables_cnt = 0;
+ }
+
+ /// <summary> Bytes Buffer for Verify</summary>
+ public ByteBuffer Buf
+ {
+ get { return verifier_buffer; }
+ set { verifier_buffer = value; }
+ }
+ /// <summary> Options of the Verifier </summary>
+ public Options options
+ {
+ get { return verifier_options; }
+ set { verifier_options = value; }
+ }
+ /// <summary> Counter of tables depth in a tested flatbuffer </summary>
+ public int depth
+ {
+ get { return depth_cnt; }
+ set { depth_cnt = value; }
+ }
+ /// <summary> Counter of tables in a tested flatbuffer </summary>
+ public int numTables
+ {
+ get { return num_tables_cnt; }
+ set { num_tables_cnt = value; }
+ }
+
+
+ /// <summary> Method set maximum tables depth of valid structure</summary>
+ /// <param name="value"> Specify Value of the maximum depth of the structure</param>
+ public Verifier SetMaxDepth(int value)
+ {
+ verifier_options.maxDepth = value;
+ return this;
+ }
+ /// <summary> Specify maximum number of tables in structure </summary>
+ /// <param name="value"> Specify Value of the maximum number of the tables in the structure</param>
+ public Verifier SetMaxTables(int value)
+ {
+ verifier_options.maxTables = value;
+ return this;
+ }
+ /// <summary> Enable/disable buffer content alignment check </summary>
+ /// <param name="value"> Value of the State for buffer content alignment check (Enable = true) </param>
+ public Verifier SetAlignmentCheck(bool value)
+ {
+ verifier_options.alignmentCheck = value;
+ return this;
+ }
+ /// <summary> Enable/disable checking of string termination '0' character </summary>
+ /// <param name="value"> Value of the option for string termination '0' character check (Enable = true)</param>
+ public Verifier SetStringCheck(bool value)
+ {
+ verifier_options.stringEndCheck = value;
+ return this;
+ }
+
+ /// <summary> Check if there is identifier in buffer </summary>
+ /// <param name="buf"> Input flat byte buffer defined as ByteBuffer type </param>
+ /// <param name="startPos">Start position of data in the Byte Buffer</param>
+ /// <param name="identifier"> Identifier for the Byte Buffer</param>
+ /// <returns> Return True when the Byte Buffer Identifier is present</returns>
+ private bool BufferHasIdentifier(ByteBuffer buf, uint startPos, string identifier)
+ {
+ if (identifier.Length != FILE_IDENTIFIER_LENGTH)
+ {
+ throw new ArgumentException("FlatBuffers: file identifier must be length" + Convert.ToString(FILE_IDENTIFIER_LENGTH));
+ }
+ for (int i = 0; i < FILE_IDENTIFIER_LENGTH; i++)
+ {
+ if ((sbyte)identifier[i] != verifier_buffer.GetSbyte(Convert.ToInt32(SIZE_S_OFFSET + i + startPos)))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /// <summary> Get UOffsetT from buffer at given position - it must be verified before read </summary>
+ /// <param name="buf"> Input flat byte buffer defined as ByteBuffer type </param>
+ /// <param name="pos"> Position of data in the Byte Buffer</param>
+ /// <returns> Return the UOffset Value (Unsigned Integer type - 4 bytes) in pos </returns>
+ private uint ReadUOffsetT(ByteBuffer buf, uint pos)
+ {
+ return buf.GetUint(Convert.ToInt32(pos));
+ }
+ /// <summary> Get SOffsetT from buffer at given position - it must be verified before read </summary>
+ /// <param name="buf"> Input flat byte buffer defined as ByteBuffer type </param>
+ /// <param name="pos"> Position of data in the Byte Buffer</param>
+ /// <returns> Return the SOffset Value (Signed Integer type - 4 bytes) in pos </returns>
+ private int ReadSOffsetT(ByteBuffer buf, int pos)
+ {
+ return buf.GetInt(pos);
+ }
+ /// <summary> Get VOffsetT from buffer at given position - it must be verified before read </summary>
+ /// <param name="buf"> Input flat byte buffer defined as ByteBuffer type </param>
+ /// <param name="pos"> Position of data in the Byte Buffer</param>
+ /// <returns> Return the VOffset Value (Short type - 2 bytes) in pos </returns>
+ private short ReadVOffsetT(ByteBuffer buf, int pos)
+ {
+ return buf.GetShort(pos);
+ }
+
+ /// <summary> Get table data area relative offset from vtable. Result is relative to table start
+ /// Fields which are deprecated are ignored by checking against the vtable's length. </summary>
+ /// <param name="pos"> Position of data in the Byte Buffer </param>
+ /// <param name="vtableOffset"> offset of value in the Table</param>
+ /// <returns> Return the relative VOffset Value (Short type - 2 bytes) in calculated offset </returns>
+ private short GetVRelOffset(int pos, short vtableOffset)
+ {
+ short VOffset = 0;
+ // Used try/catch because pos typa as int 32bit
+ try
+ {
+ // First, get vtable offset
+ short vtable = Convert.ToInt16(pos - ReadSOffsetT(verifier_buffer, pos));
+ // Check that offset points to vtable area (is smaller than vtable size)
+ if (vtableOffset < ReadVOffsetT(verifier_buffer, vtable))
+ {
+ // Now, we can read offset value - TODO check this value against size of table data
+ VOffset = ReadVOffsetT(verifier_buffer, vtable + vtableOffset);
+ }
+ else
+ {
+ VOffset = 0;
+ }
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("Exception: {0}", e);
+ return VOffset;
+ }
+ return VOffset;
+
+ }
+ /// <summary> Get table data area absolute offset from vtable. Result is the absolute buffer offset.
+ /// The result value offset cannot be '0' (pointing to itself) so after validation this method returnes '0'
+ /// value as a marker for missing optional entry </summary>
+ /// <param name="tablePos"> Table Position value in the Byte Buffer </param>
+ /// <param name="vtableOffset"> offset value in the Table</param>
+ /// <returns> Return the absolute UOffset Value </returns>
+ private uint GetVOffset(uint tablePos, short vtableOffset)
+ {
+ uint UOffset = 0;
+ // First, get vtable relative offset
+ short relPos = GetVRelOffset(Convert.ToInt32(tablePos), vtableOffset);
+ if (relPos != 0)
+ {
+ // Calculate offset based on table postion
+ UOffset = Convert.ToUInt32(tablePos + relPos);
+ }
+ else
+ {
+ UOffset = 0;
+ }
+ return UOffset;
+ }
+
+ /// <summary> Check flatbuffer complexity (tables depth, elements counter and so on) </summary>
+ /// <returns> If complexity is too high function returns false as verification error </returns>
+ private bool CheckComplexity()
+ {
+ return ((depth <= options.maxDepth) && (numTables <= options.maxTables));
+ }
+
+ /// <summary> Check alignment of element. </summary>
+ /// <returns> Return True when alignment of the element is correct</returns>
+ private bool CheckAlignment(uint element, ulong align)
+ {
+ return (((element & (align - 1)) == 0) || (!options.alignmentCheck));
+ }
+
+ /// <summary> Check if element is valid in buffer area. </summary>
+ /// <param name="pos"> Value defines the offset/position to element</param>
+ /// <param name="elementSize"> Size of element</param>
+ /// <returns> Return True when Element is correct </returns>
+ private bool CheckElement(uint pos, ulong elementSize)
+ {
+ return ((elementSize < Convert.ToUInt64(verifier_buffer.Length)) && (pos <= (Convert.ToUInt32(verifier_buffer.Length) - elementSize)));
+ }
+ /// <summary> Check if element is a valid scalar. </summary>
+ /// <param name="pos"> Value defines the offset to scalar</param>
+ /// <param name="elementSize"> Size of element</param>
+ /// <returns> Return True when Scalar Element is correct </returns>
+ private bool CheckScalar(uint pos, ulong elementSize)
+ {
+ return ((CheckAlignment(pos, elementSize)) && (CheckElement(pos, elementSize)));
+ }
+ /// <summary> Check offset. It is a scalar with size of UOffsetT. </summary>
+ private bool CheckOffset(uint offset)
+ {
+ return (CheckScalar(offset, SIZE_U_OFFSET));
+ }
+
+ private checkElementStruct CheckVectorOrString(uint pos, ulong elementSize)
+ {
+ var result = new checkElementStruct
+ {
+ elementValid = false,
+ elementOffset = 0
+ };
+
+ uint vectorPos = pos;
+ // Check we can read the vector/string size field (it is of uoffset size)
+ if (!CheckScalar(vectorPos, SIZE_U_OFFSET))
+ {
+ // result.elementValid = false; result.elementOffset = 0;
+ return result;
+ }
+ // Check the whole array. If this is a string, the byte past the array
+ // must be 0.
+ uint size = ReadUOffsetT(verifier_buffer, vectorPos);
+ ulong max_elements = (FLATBUFFERS_MAX_BUFFER_SIZE / elementSize);
+ if (size >= max_elements)
+ {
+ // Protect against byte_size overflowing.
+ // result.elementValid = false; result.elementOffset = 0;
+ return result;
+ }
+
+ uint bytes_size = SIZE_U_OFFSET + (Convert.ToUInt32(elementSize) * size);
+ uint buffer_end_pos = vectorPos + bytes_size;
+ result.elementValid = CheckElement(vectorPos, bytes_size);
+ result.elementOffset = buffer_end_pos;
+ return (result);
+ }
+
+ /// <summary>Verify a string at given position.</summary>
+ private bool CheckString(uint pos)
+ {
+ var result = CheckVectorOrString(pos, SIZE_BYTE);
+ if (options.stringEndCheck)
+ {
+ result.elementValid = result.elementValid && CheckScalar(result.elementOffset, 1); // Must have terminator
+ result.elementValid = result.elementValid && (verifier_buffer.GetSbyte(Convert.ToInt32(result.elementOffset)) == 0); // Terminating byte must be 0.
+ }
+ return result.elementValid;
+ }
+
+ /// <summary> Verify the vector of elements of given size </summary>
+ private bool CheckVector(uint pos, ulong elementSize)
+ {
+ var result = CheckVectorOrString(pos, elementSize);
+ return result.elementValid;
+ }
+ /// <summary> Verify table content using structure dependent generated function </summary>
+ private bool CheckTable(uint tablePos, VerifyTableAction verifyAction)
+ {
+ return verifyAction(this, tablePos);
+ }
+
+ /// <summary> String check wrapper function to be used in vector of strings check </summary>
+ private bool CheckStringFunc(Verifier verifier, uint pos)
+ {
+ return verifier.CheckString(pos);
+ }
+
+ /// <summary> Check vector of objects. Use generated object verification function </summary>
+ private bool CheckVectorOfObjects(uint pos, VerifyTableAction verifyAction)
+ {
+ if (!CheckVector(pos, SIZE_U_OFFSET))
+ {
+ return false;
+ }
+ uint size = ReadUOffsetT(verifier_buffer, pos);
+ // Vector data starts just after vector size/length
+ uint vecStart = pos + SIZE_U_OFFSET;
+ uint vecOff = 0;
+ // Iterate offsets and verify referenced objects
+ for (uint i = 0; i < size; i++)
+ {
+ vecOff = vecStart + (i * SIZE_U_OFFSET);
+ if (!CheckIndirectOffset(vecOff))
+ {
+ return false;
+ }
+ uint objOffset = GetIndirectOffset(vecOff);
+ if (!verifyAction(this, objOffset))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /// <summary> Check if the offset referenced by offsetPos is the valid offset pointing to buffer</summary>
+ // offsetPos - offset to offset data
+ private bool CheckIndirectOffset(uint pos)
+ {
+ // Check the input offset is valid
+ if(!CheckScalar(pos, SIZE_U_OFFSET))
+ {
+ return false;
+ }
+ // Get indirect offset
+ uint offset = ReadUOffsetT(verifier_buffer, pos);
+ // May not point to itself neither wrap around (buffers are max 2GB)
+ if ((offset == 0) || (offset >= FLATBUFFERS_MAX_BUFFER_SIZE))
+ {
+ return false;
+ }
+ // Must be inside the buffer
+ return CheckElement(pos + offset, 1);
+ }
+
+ /// <summary> Check flatbuffer content using generated object verification function </summary>
+ private bool CheckBufferFromStart(string identifier, uint startPos, VerifyTableAction verifyAction)
+ {
+ if ((identifier != null) &&
+ (identifier.Length == 0) &&
+ ((verifier_buffer.Length < (SIZE_U_OFFSET + FILE_IDENTIFIER_LENGTH)) || (!BufferHasIdentifier(verifier_buffer, startPos, identifier))))
+ {
+ return false;
+ }
+ if(!CheckIndirectOffset(startPos))
+ {
+ return false;
+ }
+ uint offset = GetIndirectOffset(startPos);
+ return CheckTable(offset, verifyAction); // && GetComputedSize()
+ }
+
+ /// <summary> Get indirect offset. It is an offset referenced by offset Pos </summary>
+ private uint GetIndirectOffset(uint pos)
+ {
+ // Get indirect offset referenced by offsetPos
+ uint offset = pos + ReadUOffsetT(verifier_buffer, pos);
+ return offset;
+ }
+
+ /// <summary> Verify beginning of table </summary>
+ /// <param name="tablePos"> Position in the Table </param>
+ /// <returns> Return True when the verification of the beginning of the table is passed</returns>
+ // (this method is used internally by generated verification functions)
+ public bool VerifyTableStart(uint tablePos)
+ {
+ // Starting new table verification increases complexity of structure
+ depth_cnt++;
+ num_tables_cnt++;
+
+ if (!CheckScalar(tablePos, SIZE_S_OFFSET))
+ {
+ return false;
+ }
+ uint vtable = (uint)(tablePos - ReadSOffsetT(verifier_buffer, Convert.ToInt32(tablePos)));
+ return ((CheckComplexity()) && (CheckScalar(vtable, SIZE_V_OFFSET)) && (CheckAlignment(Convert.ToUInt32(ReadVOffsetT(verifier_buffer, Convert.ToInt32(vtable))), SIZE_V_OFFSET)) && (CheckElement(vtable, Convert.ToUInt64(ReadVOffsetT(verifier_buffer, Convert.ToInt32(vtable))))));
+ }
+
+ /// <summary> Verify end of table. In practice, this function does not check buffer but handles
+ /// verification statistics update </summary>
+ // (this method is used internally by generated verification functions)
+ public bool VerifyTableEnd(uint tablePos)
+ {
+ depth--;
+ return true;
+ }
+
+ /// <summary> Verifiy static/inlined data area field </summary>
+ /// <param name="tablePos"> Position in the Table</param>
+ /// <param name="offsetId"> Offset to the static/inlined data element </param>
+ /// <param name="elementSize"> Size of the element </param>
+ /// <param name="align"> Alignment bool value </param>
+ /// <param name="required"> Required Value when the offset == 0 </param>
+ /// <returns>Return True when the verification of the static/inlined data element is passed</returns>
+ // (this method is used internally by generated verification functions)
+ public bool VerifyField(uint tablePos, short offsetId, ulong elementSize, ulong align, bool required)
+ {
+ uint offset = GetVOffset(tablePos, offsetId);
+ if (offset != 0)
+ {
+ return ((CheckAlignment(offset, align)) && (CheckElement(offset, elementSize)));
+ }
+ return !required; // it is OK if field is not required
+ }
+
+ /// <summary> Verify string </summary>
+ /// <param name="tablePos"> Position in the Table</param>
+ /// <param name="vOffset"> Offset to the String element </param>
+ /// <param name="required"> Required Value when the offset == 0 </param>
+ /// <returns>Return True when the verification of the String is passed</returns>
+ // (this method is used internally by generated verification functions)
+ public bool VerifyString(uint tablePos, short vOffset, bool required)
+ {
+ var offset = GetVOffset(tablePos, vOffset);
+ if (offset == 0)
+ {
+ return !required;
+ }
+ if (!CheckIndirectOffset(offset))
+ {
+ return false;
+ }
+ var strOffset = GetIndirectOffset(offset);
+ return CheckString(strOffset);
+ }
+
+ /// <summary> Verify vector of fixed size structures and scalars </summary>
+ /// <param name="tablePos"> Position in the Table</param>
+ /// <param name="vOffset"> Offset to the Vector of Data </param>
+ /// <param name="elementSize"> Size of the element</param>
+ /// <param name="required"> Required Value when the offset == 0 </param>
+ /// <returns>Return True when the verification of the Vector of Data passed</returns>
+ // (this method is used internally by generated verification functions)
+ public bool VerifyVectorOfData(uint tablePos, short vOffset, ulong elementSize, bool required)
+ {
+ var offset = GetVOffset(tablePos, vOffset);
+ if (offset == 0)
+ {
+ return !required;
+ }
+ if (!CheckIndirectOffset(offset))
+ {
+ return false;
+ }
+ var vecOffset = GetIndirectOffset(offset);
+ return CheckVector(vecOffset, elementSize);
+ }
+
+ /// <summary> Verify array of strings </summary>
+ /// <param name="tablePos"> Position in the Table</param>
+ /// <param name="offsetId"> Offset to the Vector of String </param>
+ /// <param name="required"> Required Value when the offset == 0 </param>
+ /// <returns>Return True when the verification of the Vector of String passed</returns>
+ // (this method is used internally by generated verification functions)
+ public bool VerifyVectorOfStrings(uint tablePos, short offsetId, bool required)
+ {
+ var offset = GetVOffset(tablePos, offsetId);
+ if (offset == 0)
+ {
+ return !required;
+ }
+ if (!CheckIndirectOffset(offset))
+ {
+ return false;
+ }
+ var vecOffset = GetIndirectOffset(offset);
+ return CheckVectorOfObjects(vecOffset, CheckStringFunc);
+ }
+
+ /// <summary> Verify vector of tables (objects). Tables are verified using generated verifyObjFunc </summary>
+ /// <param name="tablePos"> Position in the Table</param>
+ /// <param name="offsetId"> Offset to the Vector of Table </param>
+ /// <param name="verifyAction"> Method used to the verification Table </param>
+ /// <param name="required"> Required Value when the offset == 0 </param>
+ /// <returns>Return True when the verification of the Vector of Table passed</returns>
+ // (this method is used internally by generated verification functions)
+ public bool VerifyVectorOfTables(uint tablePos, short offsetId, VerifyTableAction verifyAction, bool required)
+ {
+ var offset = GetVOffset(tablePos, offsetId);
+ if (offset == 0)
+ {
+ return !required;
+ }
+ if (!CheckIndirectOffset(offset))
+ {
+ return false;
+ }
+ var vecOffset = GetIndirectOffset(offset);
+ return CheckVectorOfObjects(vecOffset, verifyAction);
+ }
+
+ /// <summary> Verify table object using generated verification function. </summary>
+ /// <param name="tablePos"> Position in the Table</param>
+ /// <param name="offsetId"> Offset to the Table </param>
+ /// <param name="verifyAction"> Method used to the verification Table </param>
+ /// <param name="required"> Required Value when the offset == 0 </param>
+ /// <returns>Return True when the verification of the Table passed</returns>
+ // (this method is used internally by generated verification functions)
+ public bool VerifyTable(uint tablePos, short offsetId, VerifyTableAction verifyAction, bool required)
+ {
+ var offset = GetVOffset(tablePos, offsetId);
+ if (offset == 0)
+ {
+ return !required;
+ }
+ if (!CheckIndirectOffset(offset))
+ {
+ return false;
+ }
+ var tabOffset = GetIndirectOffset(offset);
+ return CheckTable(tabOffset, verifyAction);
+ }
+
+ /// <summary> Verify nested buffer object. When verifyObjFunc is provided, it is used to verify object structure. </summary>
+ /// <param name="tablePos"> Position in the Table </param>
+ /// <param name="offsetId"> Offset to the Table </param>
+ /// <param name="verifyAction"> Method used to the verification Table </param>
+ /// <param name="required"> Required Value when the offset == 0 </param>
+ // (this method is used internally by generated verification functions)
+ public bool VerifyNestedBuffer(uint tablePos, short offsetId, VerifyTableAction verifyAction, bool required)
+ {
+ var offset = GetVOffset(tablePos, offsetId);
+ if (offset == 0)
+ {
+ return !required;
+ }
+ uint vecOffset = GetIndirectOffset(offset);
+ if (!CheckVector(vecOffset, SIZE_BYTE))
+ {
+ return false;
+ }
+ if (verifyAction != null)
+ {
+ var vecLength = ReadUOffsetT(verifier_buffer, vecOffset);
+ // Buffer begins after vector length
+ var vecStart = vecOffset + SIZE_U_OFFSET;
+ // Create and Copy nested buffer bytes from part of Verify Buffer
+ var nestedByteBuffer = new ByteBuffer(verifier_buffer.ToArray(Convert.ToInt32(vecStart), Convert.ToInt32(vecLength)));
+ var nestedVerifyier = new Verifier(nestedByteBuffer, options);
+ // There is no internal identifier - use empty one
+ if (!nestedVerifyier.CheckBufferFromStart("", 0, verifyAction))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /// <summary> Verifiy static/inlined data area at absolute offset </summary>
+ /// <param name="pos"> Position of static/inlined data area in the Byte Buffer</param>
+ /// <param name="elementSize"> Size of the union data</param>
+ /// <param name="align"> Alignment bool value </param>
+ /// <returns>Return True when the verification of the Union Data is passed</returns>
+ // (this method is used internally by generated verification functions)
+ public bool VerifyUnionData(uint pos, ulong elementSize, ulong align)
+ {
+ bool result = ((CheckAlignment(pos, align)) && (CheckElement(pos, elementSize)));
+ return result;
+ }
+
+ /// <summary> Verify string referenced by absolute offset value </summary>
+ /// <param name="pos"> Position of Union String in the Byte Buffer</param>
+ /// <returns>Return True when the verification of the Union String is passed</returns>
+ // (this method is used internally by generated verification functions)
+ public bool VerifyUnionString(uint pos)
+ {
+ bool result = CheckString(pos);
+ return result;
+ }
+
+ /// <summary> Method verifies union object using generated verification function </summary>
+ /// <param name="tablePos"> Position in the Table</param>
+ /// <param name="typeIdVOffset"> Offset in the Table</param>
+ /// <param name="valueVOffset"> Offset to Element</param>
+ /// <param name="verifyAction"> Verification Method used for Union</param>
+ /// <param name="required"> Required Value when the offset == 0 </param>
+ // (this method is used internally by generated verification functions)
+ public bool VerifyUnion(uint tablePos, short typeIdVOffset, short valueVOffset, VerifyUnionAction verifyAction, bool required)
+ {
+ // Check the union type index
+ var offset = GetVOffset(tablePos, typeIdVOffset);
+ if (offset == 0)
+ {
+ return !required;
+ }
+ if (!((CheckAlignment(offset, SIZE_BYTE)) && (CheckElement(offset, SIZE_BYTE))))
+ {
+ return false;
+ }
+ // Check union data
+ offset = GetVOffset(tablePos, valueVOffset);
+ // Take type id
+ var typeId = verifier_buffer.Get(Convert.ToInt32(offset));
+ if (offset == 0)
+ {
+ // When value data is not present, allow union verification function to deal with illegal offset
+ return verifyAction(this, typeId, Convert.ToUInt32(verifier_buffer.Length));
+ }
+ if (!CheckIndirectOffset(offset))
+ {
+ return false;
+ }
+ // Take value offset and validate union structure
+ uint unionOffset = GetIndirectOffset(offset);
+ return verifyAction(this, typeId, unionOffset);
+ }
+
+ /// <summary> Verify vector of unions (objects). Unions are verified using generated verifyObjFunc </summary>
+ /// <param name="tablePos"> Position of the Table</param>
+ /// <param name="typeOffsetId"> Offset in the Table (Union type id)</param>
+ /// <param name="offsetId"> Offset to vector of Data Stucture offset</param>
+ /// <param name="verifyAction"> Verification Method used for Union</param>
+ /// <param name="required"> Required Value when the offset == 0 </param>
+ /// <returns>Return True when the verification of the Vector of Unions passed</returns>
+ // (this method is used internally by generated verification functions)
+ public bool VerifyVectorOfUnion(uint tablePos, short typeOffsetId, short offsetId, VerifyUnionAction verifyAction, bool required)
+ {
+ // type id offset must be valid
+ var offset = GetVOffset(tablePos, typeOffsetId);
+ if (offset == 0)
+ {
+ return !required;
+ }
+ if (!CheckIndirectOffset(offset))
+ {
+ return false;
+ }
+ // Get type id table absolute offset
+ var typeIdVectorOffset = GetIndirectOffset(offset);
+ // values offset must be valid
+ offset = GetVOffset(tablePos, offsetId);
+ if (!CheckIndirectOffset(offset))
+ {
+ return false;
+ }
+ var valueVectorOffset = GetIndirectOffset(offset);
+ // validate referenced vectors
+ if(!CheckVector(typeIdVectorOffset, SIZE_BYTE) ||
+ !CheckVector(valueVectorOffset, SIZE_U_OFFSET))
+ {
+ return false;
+ }
+ // Both vectors should have the same length
+ var typeIdVectorLength = ReadUOffsetT(verifier_buffer, typeIdVectorOffset);
+ var valueVectorLength = ReadUOffsetT(verifier_buffer, valueVectorOffset);
+ if (typeIdVectorLength != valueVectorLength)
+ {
+ return false;
+ }
+ // Verify each union from vectors
+ var typeIdStart = typeIdVectorOffset + SIZE_U_OFFSET;
+ var valueStart = valueVectorOffset + SIZE_U_OFFSET;
+ for (uint i = 0; i < typeIdVectorLength; i++)
+ {
+ // Get type id
+ byte typeId = verifier_buffer.Get(Convert.ToInt32(typeIdStart + i * SIZE_U_OFFSET));
+ // get offset to vector item
+ uint off = valueStart + i * SIZE_U_OFFSET;
+ // Check the vector item has a proper offset
+ if (!CheckIndirectOffset(off))
+ {
+ return false;
+ }
+ uint valueOffset = GetIndirectOffset(off);
+ // Verify object
+ if (!verifyAction(this, typeId, valueOffset))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ // Method verifies flatbuffer data using generated Table verification function.
+ // The data buffer is already provided when creating [Verifier] object (see [NewVerifier])
+ //
+ // - identifier - the expected identifier of buffer data.
+ // When empty identifier is provided the identifier validation is skipped.
+ // - sizePrefixed - this flag should be true when buffer is prefixed with content size
+ // - verifyObjFunc - function to be used for verification. This function is generated by compiler and included in each table definition file with name "<Tablename>Verify"
+ //
+ // Example:
+ //
+ // /* Verify Monster table. Ignore buffer name and assume buffer does not contain data length prefix */
+ // isValid = verifier.verifyBuffer(bb, false, MonsterVerify)
+ //
+ // /* Verify Monster table. Buffer name is 'MONS' and contains data length prefix */
+ // isValid = verifier.verifyBuffer("MONS", true, MonsterVerify)
+ /// <summary> Method verifies flatbuffer data using generated Table verification function </summary>
+ ///
+ /// <param name="identifier"> The expected identifier of buffer data</param>
+ /// <param name="sizePrefixed"> Flag should be true when buffer is prefixed with content size</param>
+ /// <param name="verifyAction"> Function to be used for verification. This function is generated by compiler and included in each table definition file</param>
+ /// <returns> Return True when verification of FlatBuffer passed</returns>
+ /// <example>
+ /// Example 1. Verify Monster table. Ignore buffer name and assume buffer does not contain data length prefix
+ /// <code> isValid = verifier.VerifyBuffer(bb, false, MonsterVerify)</code>
+ /// Example 2. Verify Monster table. Buffer name is 'MONS' and contains data length prefix
+ /// <code> isValid = verifier.VerifyBuffer("MONS", true, MonsterVerify)</code>
+ /// </example>
+ public bool VerifyBuffer(string identifier, bool sizePrefixed, VerifyTableAction verifyAction)
+ {
+ // Reset counters - starting verification from beginning
+ depth = 0;
+ numTables = 0;
+
+ var start = (uint)(verifier_buffer.Position);
+ if (sizePrefixed)
+ {
+ start = (uint)(verifier_buffer.Position) + SIZE_PREFIX_LENGTH;
+ if(!CheckScalar((uint)(verifier_buffer.Position), SIZE_PREFIX_LENGTH))
+ {
+ return false;
+ }
+ uint size = ReadUOffsetT(verifier_buffer, (uint)(verifier_buffer.Position));
+ if (size != ((uint)(verifier_buffer.Length) - start))
+ {
+ return false;
+ }
+ }
+ return CheckBufferFromStart(identifier, start, verifyAction);
+ }
+ }
+
+}
diff --git a/net/FlatBuffers/FlatBuffers.net35.csproj b/net/FlatBuffers/FlatBuffers.net35.csproj
index 574580e3..9c64d006 100644
--- a/net/FlatBuffers/FlatBuffers.net35.csproj
+++ b/net/FlatBuffers/FlatBuffers.net35.csproj
@@ -40,9 +40,9 @@
<Compile Include="ByteBufferUtil.cs" />
<Compile Include="FlatBufferBuilder.cs" />
<Compile Include="FlatBufferConstants.cs" />
+ <Compile Include="FlatBufferVerify.cs" />
<Compile Include="IFlatbufferObject.cs" />
<Compile Include="Offset.cs" />
- <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Struct.cs" />
<Compile Include="Table.cs" />
</ItemGroup>
diff --git a/src/idl_gen_csharp.cpp b/src/idl_gen_csharp.cpp
index a2dc5611..8b1fafdf 100644
--- a/src/idl_gen_csharp.cpp
+++ b/src/idl_gen_csharp.cpp
@@ -169,6 +169,7 @@ class CSharpGenerator : public BaseGenerator {
if (!parser_.opts.one_file)
cur_name_space_ = struct_def.defined_namespace;
GenStruct(struct_def, &declcode, parser_.opts);
+ GenStructVerifier(struct_def, &declcode);
if (parser_.opts.one_file) {
one_file_code += declcode;
} else {
@@ -623,6 +624,173 @@ class CSharpGenerator : public BaseGenerator {
")";
}
+ // Get the value of a table verification function start
+ void GetStartOfTableVerifier(const StructDef &struct_def, std::string *code_ptr) {
+ std::string &code = *code_ptr;
+ code += "\n";
+ code += "static public class " + struct_def.name + "Verify\n";
+ code += "{\n";
+ code += " static public bool Verify";
+ code += "(Google.FlatBuffers.Verifier verifier, uint tablePos)\n";
+ code += " {\n";
+ code += " return verifier.VerifyTableStart(tablePos)\n";
+ }
+
+ // Get the value of a table verification function end
+ void GetEndOfTableVerifier(std::string *code_ptr) {
+ std::string &code = *code_ptr;
+ code += " && verifier.VerifyTableEnd(tablePos);\n";
+ code += " }\n";
+ code += "}\n";
+ }
+
+ std::string GetNestedFlatBufferName(const FieldDef &field) {
+ std::string name;
+ if (field.nested_flatbuffer) {
+ name = NamespacedName(*field.nested_flatbuffer);
+ } else {
+ name = "";
+ }
+ return name ;
+ }
+
+ // Generate the code to call the appropriate Verify function(s) for a field.
+ void GenVerifyCall(CodeWriter &code_, const FieldDef &field, const char *prefix) {
+ code_.SetValue("PRE", prefix);
+ code_.SetValue("NAME", ConvertCase(field.name, Case::kUpperCamel));
+ code_.SetValue("REQUIRED", field.IsRequired() ? "Required" : "");
+ code_.SetValue("REQUIRED_FLAG", field.IsRequired() ? "true" : "false");
+ code_.SetValue("TYPE", GenTypeGet(field.value.type));
+ code_.SetValue("INLINESIZE", NumToString(InlineSize(field.value.type)));
+ code_.SetValue("OFFSET", NumToString(field.value.offset));
+
+ if (IsScalar(field.value.type.base_type) || IsStruct(field.value.type)) {
+ code_.SetValue("ALIGN", NumToString(InlineAlignment(field.value.type)));
+ code_ +=
+ "{{PRE}} && verifier.VerifyField(tablePos, "
+ "{{OFFSET}} /*{{NAME}}*/, {{INLINESIZE}} /*{{TYPE}}*/, {{ALIGN}}, {{REQUIRED_FLAG}})";
+ } else {
+ // TODO - probably code below should go to this 'else' - code_ += "{{PRE}}VerifyOffset{{REQUIRED}}(verifier, {{OFFSET}})\\";
+ }
+
+ switch (field.value.type.base_type) {
+ case BASE_TYPE_UNION: {
+ auto union_name = NamespacedName(*field.value.type.enum_def);
+ code_.SetValue("ENUM_NAME1", field.value.type.enum_def->name);
+ code_.SetValue("ENUM_NAME", union_name);
+ code_.SetValue("SUFFIX", UnionTypeFieldSuffix());
+ // Caution: This construction assumes, that UNION type id element has been created just before union data and
+ // its offset precedes union. Such assumption is common in flatbuffer implementation
+ code_.SetValue("TYPE_ID_OFFSET", NumToString(field.value.offset - sizeof(voffset_t)));
+ code_ += "{{PRE}} && verifier.VerifyUnion(tablePos, {{TYPE_ID_OFFSET}}, "
+ "{{OFFSET}} /*{{NAME}}*/, {{ENUM_NAME}}Verify.Verify, {{REQUIRED_FLAG}})";
+ break;
+ }
+ case BASE_TYPE_STRUCT: {
+ if (!field.value.type.struct_def->fixed) {
+ code_ += "{{PRE}} && verifier.VerifyTable(tablePos, "
+ "{{OFFSET}} /*{{NAME}}*/, {{TYPE}}Verify.Verify, {{REQUIRED_FLAG}})";
+ }
+ break;
+ }
+ case BASE_TYPE_STRING: {
+ code_ += "{{PRE}} && verifier.VerifyString(tablePos, "
+ "{{OFFSET}} /*{{NAME}}*/, {{REQUIRED_FLAG}})";
+ break;
+ }
+ case BASE_TYPE_VECTOR: {
+
+ switch (field.value.type.element) {
+ case BASE_TYPE_STRING: {
+ code_ += "{{PRE}} && verifier.VerifyVectorOfStrings(tablePos, "
+ "{{OFFSET}} /*{{NAME}}*/, {{REQUIRED_FLAG}})";
+ break;
+ }
+ case BASE_TYPE_STRUCT: {
+ if (!field.value.type.struct_def->fixed) {
+ code_ += "{{PRE}} && verifier.VerifyVectorOfTables(tablePos, "
+ "{{OFFSET}} /*{{NAME}}*/, {{TYPE}}Verify.Verify, {{REQUIRED_FLAG}})";
+ } else {
+ code_.SetValue(
+ "VECTOR_ELEM_INLINESIZE",
+ NumToString(InlineSize(field.value.type.VectorType())));
+ code_ +=
+ "{{PRE}} && "
+ "verifier.VerifyVectorOfData(tablePos, "
+ "{{OFFSET}} /*{{NAME}}*/, {{VECTOR_ELEM_INLINESIZE}} "
+ "/*{{TYPE}}*/, {{REQUIRED_FLAG}})";
+ }
+ break;
+ }
+ case BASE_TYPE_UNION: {
+ // Vectors of unions are not yet supported for go
+ break;
+ }
+ default:
+ // Generate verifier for vector of data.
+ // It may be either nested flatbuffer of just vector of bytes
+ auto nfn = GetNestedFlatBufferName(field);
+ if (!nfn.empty()) {
+ code_.SetValue("CPP_NAME", nfn);
+ // FIXME: file_identifier.
+ code_ += "{{PRE}} && verifier.VerifyNestedBuffer(tablePos, "
+ "{{OFFSET}} /*{{NAME}}*/, {{CPP_NAME}}Verify.Verify, {{REQUIRED_FLAG}})";
+ } else if (field.flexbuffer) {
+ code_ += "{{PRE}} && verifier.VerifyNestedBuffer(tablePos, "
+ "{{OFFSET}} /*{{NAME}}*/, null, {{REQUIRED_FLAG}})";
+ } else {
+ code_.SetValue("VECTOR_ELEM_INLINESIZE", NumToString(InlineSize(field.value.type.VectorType())));
+ code_ +=
+ "{{PRE}} && verifier.VerifyVectorOfData(tablePos, "
+ "{{OFFSET}} /*{{NAME}}*/, {{VECTOR_ELEM_INLINESIZE}} /*{{TYPE}}*/, {{REQUIRED_FLAG}})";
+ }
+ break;
+ }
+
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ }
+
+ // Generate table constructors, conditioned on its members' types.
+ void GenTableVerifier(const StructDef &struct_def, std::string *code_ptr) {
+ CodeWriter code_;
+
+ GetStartOfTableVerifier(struct_def, code_ptr);
+
+ // Generate struct fields accessors
+ for (auto it = struct_def.fields.vec.begin();
+ it != struct_def.fields.vec.end(); ++it) {
+ auto &field = **it;
+ if (field.deprecated) continue;
+
+ GenVerifyCall(code_, field, "");
+ }
+
+ *code_ptr += code_.ToString();
+
+ GetEndOfTableVerifier(code_ptr);
+ }
+
+ // Generate struct or table methods.
+ void GenStructVerifier(const StructDef &struct_def, std::string *code_ptr) {
+ if (struct_def.generated) return;
+
+ // cur_name_space_ = struct_def.defined_namespace;
+
+ // Generate verifiers
+ if (struct_def.fixed) {
+ // Fixed size structures do not require table members
+ // verification - instead structure size is verified using VerifyField
+ } else {
+ // Create table verification function
+ GenTableVerifier(struct_def, code_ptr);
+ }
+ }
+
void GenStruct(StructDef &struct_def, std::string *code_ptr,
const IDLOptions &opts) const {
if (struct_def.generated) return;
@@ -688,8 +856,20 @@ class CSharpGenerator : public BaseGenerator {
code += parser_.file_identifier_;
code += "\"); }\n";
}
+
+ // Generate the Verify method that checks if a ByteBuffer is save to
+ // access
+ code += " public static ";
+ code += "bool Verify" + struct_def.name + "(ByteBuffer _bb) {";
+ code += "Google.FlatBuffers.Verifier verifier = new ";
+ code += "Google.FlatBuffers.Verifier(_bb); ";
+ code += "return verifier.VerifyBuffer(\"";
+ code += parser_.file_identifier_;
+ code += "\", false, " + struct_def.name + "Verify.Verify);";
+ code += " }\n";
}
}
+
// Generate the __init method that sets the field in a pre-existing
// accessor object. This is to allow object reuse.
code += " public void __init(int _i, ByteBuffer _bb) ";
@@ -1418,6 +1598,67 @@ class CSharpGenerator : public BaseGenerator {
code += " }\n";
}
+ std::string GenUnionVerify(const Type &union_type) const {
+ if (union_type.enum_def) {
+ const auto &enum_def = *union_type.enum_def;
+
+ auto ret =
+ "\n\nstatic public class " + enum_def.name + "Verify\n";
+ ret += "{\n";
+ ret +=
+ " static public bool Verify(Google.FlatBuffers.Verifier verifier, "
+ "byte typeId, uint tablePos)\n";
+ ret += " {\n";
+ ret += " bool result = true;\n";
+
+ const auto union_enum_loop = [&]() {
+ ret += " switch((" + enum_def.name + ")typeId)\n";
+ ret += " {\n";
+
+ for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
+ const auto &ev = **it;
+ if (ev.IsZero()) { continue; }
+
+ ret += " case " + Name(enum_def) + "." + Name(ev) + ":\n";
+
+ if (IsString(ev.union_type)) {
+ ret +=
+ " result = verifier.VerifyUnionString(tablePos);\n";
+ ret += " break;";
+ } else if (ev.union_type.base_type == BASE_TYPE_STRUCT) {
+ if (! ev.union_type.struct_def->fixed) {
+ auto type = GenTypeGet(ev.union_type);
+ ret += " result = " + type + "Verify.Verify(verifier, tablePos);\n";
+ } else {
+ ret += " result = verifier.VerifyUnionData(tablePos, " +
+ NumToString(InlineSize(ev.union_type)) + ", " +
+ NumToString(InlineAlignment(ev.union_type)) +
+ ");\n";;
+ }
+ ret += " break;";
+ } else {
+ FLATBUFFERS_ASSERT(false);
+ }
+ ret += "\n";
+ }
+
+ ret += " default: result = true;\n";
+ ret += " break;\n";
+ ret += " }\n";
+ ret += " return result;\n";
+ };
+
+ union_enum_loop();
+ ret += " }\n";
+ ret += "}\n";
+ ret += "\n";
+
+ return ret;
+ }
+ FLATBUFFERS_ASSERT(0);
+ return "";
+ }
+
void GenEnum_ObjectAPI(EnumDef &enum_def, std::string *code_ptr,
const IDLOptions &opts) const {
auto &code = *code_ptr;
@@ -1493,6 +1734,9 @@ class CSharpGenerator : public BaseGenerator {
code += " }\n";
code += " }\n";
code += "}\n\n";
+
+ code += GenUnionVerify(enum_def.underlying_type);
+
// JsonConverter
if (opts.cs_gen_json_serializer) {
if (enum_def.attributes.Lookup("private")) {
diff --git a/tests/FlatBuffers.Test/FlatBuffers.Core.Test.csproj b/tests/FlatBuffers.Test/FlatBuffers.Core.Test.csproj
index a82b07af..75f70fef 100644
--- a/tests/FlatBuffers.Test/FlatBuffers.Core.Test.csproj
+++ b/tests/FlatBuffers.Test/FlatBuffers.Core.Test.csproj
@@ -46,6 +46,9 @@
<Compile Include="..\..\net\FlatBuffers\FlatBufferConstants.cs">
<Link>FlatBuffers\FlatBufferConstants.cs</Link>
</Compile>
+ <Compile Include="..\..\net\FlatBuffers\FlatBufferVerify.cs">
+ <Link>FlatBuffers\FlatBufferVerify.cs</Link>
+ </Compile>
<Compile Include="..\..\net\FlatBuffers\Struct.cs">
<Link>FlatBuffers\Struct.cs</Link>
</Compile>
diff --git a/tests/FlatBuffers.Test/FlatBuffersExampleTests.cs b/tests/FlatBuffers.Test/FlatBuffersExampleTests.cs
index 6c9e309c..e3dbea64 100644
--- a/tests/FlatBuffers.Test/FlatBuffersExampleTests.cs
+++ b/tests/FlatBuffers.Test/FlatBuffersExampleTests.cs
@@ -198,6 +198,9 @@ namespace Google.FlatBuffers.Test
private void TestBuffer(ByteBuffer bb)
{
+ bool test = Monster.VerifyMonster(bb);
+ Assert.AreEqual(true, test);
+
Monster monster = Monster.GetRootAsMonster(bb);
Assert.AreEqual(80, monster.Hp);
@@ -299,7 +302,7 @@ namespace Google.FlatBuffers.Test
var jsonText = File.ReadAllText(@"../monsterdata_test.json");
var mon = MonsterT.DeserializeFromJson(jsonText);
var fbb = new FlatBufferBuilder(1);
- fbb.Finish(Monster.Pack(fbb, mon).Value);
+ Monster.FinishMonsterBuffer(fbb, Monster.Pack(fbb, mon));
TestBuffer(fbb.DataBuffer);
}
diff --git a/tests/FlatBuffers.Test/FlatBuffersFuzzTests.cs b/tests/FlatBuffers.Test/FlatBuffersFuzzTests.cs
index 0377a7b4..fb6c4836 100644
--- a/tests/FlatBuffers.Test/FlatBuffersFuzzTests.cs
+++ b/tests/FlatBuffers.Test/FlatBuffersFuzzTests.cs
@@ -15,6 +15,7 @@
*/
using System;
+using Google.FlatBuffers;
namespace Google.FlatBuffers.Test
{
@@ -204,9 +205,21 @@ namespace Google.FlatBuffers.Test
1, // value 0
},
builder.DataBuffer.ToFullArray());
- }
+ var verifier = new Verifier(builder.DataBuffer);
+ var offset = 8;
+ // table must be ok
+ Assert.IsTrue(verifier.VerifyTableStart((uint)offset));
+ // First field must be bool
+ Assert.IsTrue(verifier.VerifyField((uint)offset, 4, 1, 1, true));
+ // Check Error: Second field
+ Assert.IsFalse(verifier.VerifyField((uint)offset, 6, 1, 1, true));
+ // Check Error: First field too big alignment
+ Assert.IsFalse(verifier.VerifyField((uint)offset, 4, 1, 2, true));
+ // Check Error: First size to big
+ Assert.IsFalse(verifier.VerifyField((uint)offset, 4, 2, 1, true));
+ }
- [FlatBuffersTestMethod]
+ [FlatBuffersTestMethod]
public void TestVTableWithOneBool_DefaultValue()
{
var builder = new FlatBufferBuilder(1);
@@ -223,6 +236,14 @@ namespace Google.FlatBuffers.Test
4, 0, 0, 0, // int32 offset for start of vtable
},
builder.DataBuffer.ToFullArray());
+ var verifier = new Verifier(builder.DataBuffer);
+ var offset = 4;
+ // table must be ok
+ Assert.IsTrue(verifier.VerifyTableStart((uint)offset));
+ // First field must be bool
+ Assert.IsTrue(verifier.VerifyField((uint)offset, 4, 1, 1, false));
+ // Error Check: First field not present
+ Assert.IsFalse(verifier.VerifyField((uint)offset, 4, 1, 1, true));
}
[FlatBuffersTestMethod]
@@ -232,7 +253,7 @@ namespace Google.FlatBuffers.Test
builder.StartTable(1);
Assert.ArrayEqual(new byte[] { 0 }, builder.DataBuffer.ToFullArray());
builder.AddShort(0, 0x789A, 0);
- builder.EndTable();
+ int offset = builder.EndTable();
Assert.ArrayEqual(new byte[]
{
0, 0, // padding to 16 bytes
@@ -244,6 +265,18 @@ namespace Google.FlatBuffers.Test
0x9A, 0x78, //value 0
},
builder.DataBuffer.ToFullArray());
+ var verifier = new Verifier(builder.DataBuffer);
+ offset += builder.DataBuffer.Position;
+ // table must be ok
+ Assert.IsTrue(verifier.VerifyTableStart((uint)offset));
+ // First field must be ushort
+ Assert.IsTrue(verifier.VerifyField((uint)offset, 4, 2, 2, true));
+ // Check Error: Second field
+ Assert.IsFalse(verifier.VerifyField((uint)offset, 6, 2, 2, true));
+ // Check Error: First field too big alignment
+ Assert.IsFalse(verifier.VerifyField((uint)offset, 4, 4, 2, true));
+ // Check Error: First field size to big
+ Assert.IsFalse(verifier.VerifyField((uint)offset, 4, 2, 4, true));
}
[FlatBuffersTestMethod]
@@ -254,7 +287,7 @@ namespace Google.FlatBuffers.Test
Assert.ArrayEqual(new byte[] { 0 }, builder.DataBuffer.ToFullArray());
builder.AddShort(0, 0x3456, 0);
builder.AddShort(1, 0x789A, 0);
- builder.EndTable();
+ int offset = builder.EndTable();
Assert.ArrayEqual(new byte[]
{
8, 0, // vtable bytes
@@ -266,6 +299,18 @@ namespace Google.FlatBuffers.Test
0x56, 0x34, // value 0
},
builder.DataBuffer.ToFullArray());
+ var verifier = new Verifier(builder.DataBuffer);
+ offset += builder.DataBuffer.Position;
+ // table must be ok
+ Assert.IsTrue(verifier.VerifyTableStart((uint)offset));
+ // First field must be ushort
+ Assert.IsTrue(verifier.VerifyField((uint)offset, 4, 2, 2, true));
+ // Check Error: Second field
+ Assert.IsTrue(verifier.VerifyField((uint)offset, 6, 2, 2, true));
+ // Check Error: Second field too big alignment
+ Assert.IsFalse(verifier.VerifyField((uint)offset, 4, 4, 2, true));
+ // Check Error: Second field size to big
+ Assert.IsFalse(verifier.VerifyField((uint)offset, 4, 2, 4, true));
}
[FlatBuffersTestMethod]
@@ -276,7 +321,7 @@ namespace Google.FlatBuffers.Test
Assert.ArrayEqual(new byte[] { 0 }, builder.DataBuffer.ToFullArray());
builder.AddShort(0, 0x3456, 0);
builder.AddBool(1, true, false);
- builder.EndTable();
+ int offset = builder.EndTable();
Assert.ArrayEqual(new byte[]
{
8, 0, // vtable bytes
@@ -288,6 +333,18 @@ namespace Google.FlatBuffers.Test
0x56, 0x34, // value 0
},
builder.DataBuffer.ToFullArray());
+ var verifier = new Verifier(builder.DataBuffer);
+ offset += builder.DataBuffer.Position;
+ // table must be ok
+ Assert.IsTrue(verifier.VerifyTableStart((uint)offset));
+ // First field must be ushort
+ Assert.IsTrue(verifier.VerifyField((uint)offset, 4, 2, 2, true));
+ // Check Error: Second field must be bool
+ Assert.IsTrue(verifier.VerifyField((uint)offset, 6, 1, 1, true));
+ // Check Error: Second field too big alignment
+ Assert.IsFalse(verifier.VerifyField((uint)offset, 4, 4, 2, true));
+ // Check Error: Second field size to big
+ Assert.IsFalse(verifier.VerifyField((uint)offset, 4, 2, 4, true));
}
[FlatBuffersTestMethod]
@@ -315,6 +372,12 @@ namespace Google.FlatBuffers.Test
0, 0, 0, 0,
},
builder.DataBuffer.ToFullArray());
+ var verifier = new Verifier(builder.DataBuffer);
+ uint checkOffset = 20;
+ // table must be ok
+ Assert.IsTrue(verifier.VerifyTableStart(checkOffset));
+ // First field must be vector with element size 1
+ Assert.IsTrue(verifier.VerifyVectorOfData(checkOffset, 4, 1, true));
}
[FlatBuffersTestMethod]
@@ -342,7 +405,15 @@ namespace Google.FlatBuffers.Test
0, 0, 0, 0, // length of vector (not in sctruc)
},
builder.DataBuffer.ToFullArray());
- }
+ var verifier = new Verifier(builder.DataBuffer);
+ uint checkOffset = 16;
+ // table must be ok
+ Assert.IsTrue(verifier.VerifyTableStart(checkOffset));
+ // First field must be short
+ Assert.IsTrue(verifier.VerifyField(checkOffset, 4, 2, 2, true));
+ // Second field must be vector with element size 1
+ Assert.IsTrue(verifier.VerifyVectorOfData(checkOffset, 6, 2, true));
+ }
[FlatBuffersTestMethod]
@@ -373,6 +444,16 @@ namespace Google.FlatBuffers.Test
0x34, 0x12, // vector value 1
},
builder.DataBuffer.ToFullArray());
+ var verifier = new Verifier(builder.DataBuffer);
+ uint checkOffset = 12;
+ // table must be ok
+ Assert.IsTrue(verifier.VerifyTableStart(checkOffset));
+ // Second field must be vector with element size 2
+ Assert.IsTrue(verifier.VerifyVectorOfData(checkOffset, 6, 2, true));
+ // Check Error: Second field with too big size
+ Assert.IsFalse(verifier.VerifyVectorOfData(checkOffset, 6, 4, true));
+ // First field must be short
+ Assert.IsTrue(verifier.VerifyField(checkOffset, 4, 2, 2, true));
}
[FlatBuffersTestMethod]
@@ -403,8 +484,17 @@ namespace Google.FlatBuffers.Test
0x00, 0x00, 0x00, 55, // struct value 0
},
builder.DataBuffer.ToFullArray());
+ var verifier = new Verifier(builder.DataBuffer);
+ uint checkOffset = 16;
+ // table must be ok
+ Assert.IsTrue(verifier.VerifyTableStart(checkOffset));
+ // First field must be a struct with 12 bytes
+ Assert.IsTrue(verifier.VerifyField(checkOffset, 4, 12, 4, true));
+ // Check Error: First field with more than 12 bytes
+ Assert.IsFalse(verifier.VerifyField(checkOffset, 4, 16, 4, true));
}
+
[FlatBuffersTestMethod]
public void TestVTableWithAVectorOf_2xStructOf_2xInt8()
{
@@ -437,6 +527,12 @@ namespace Google.FlatBuffers.Test
33, // vector 0, 0
},
builder.DataBuffer.ToFullArray());
+ var verifier = new Verifier(builder.DataBuffer);
+ uint checkOffset = 16;
+ // table must be ok
+ Assert.IsTrue(verifier.VerifyTableStart(checkOffset));
+ // First field must be vector with element size 2
+ Assert.IsTrue(verifier.VerifyVectorOfData(checkOffset, 4, 2, true));
}
[FlatBuffersTestMethod]
@@ -470,6 +566,104 @@ namespace Google.FlatBuffers.Test
byte[] unpadded = new byte[padded.Length - 12];
Buffer.BlockCopy(padded, 12, unpadded, 0, unpadded.Length);
Assert.ArrayEqual(unpadded, builder.DataBuffer.ToSizedArray());
+
+ var verifier = new Verifier(builder.DataBuffer);
+ uint checkOffset = builder.DataBuffer.GetUint(builder.DataBuffer.Position) + (uint)builder.DataBuffer.Position;
+ // table must be ok
+ Assert.IsTrue(verifier.VerifyTableStart(checkOffset));
+ // First field must be a struct with 12 bytes
+ Assert.IsTrue(verifier.VerifyField(checkOffset, 4, 1, 1, true));
+ // Second field must be a struct with 12 bytes
+ Assert.IsTrue(verifier.VerifyField(checkOffset, 6, 2, 2, true));
+ }
+
+ [FlatBuffersTestMethod]
+ public void TestVTableWithStrings()
+ {
+ var builder = new FlatBufferBuilder(64);
+ var str1 = builder.CreateString("foo");
+ var str2 = builder.CreateString("foobar");
+ builder.StartTable(2);
+ builder.AddOffset(0, str1.Value, 0);
+ builder.AddOffset(1, str2.Value, 0);
+ var off = builder.EndTable();
+ builder.Finish(off);
+
+ byte[] padded = new byte[]
+ {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0, //Padding to 32 bytes
+ 12, 0, 0, 0, // root of table, pointing to vtable offset
+ 8, 0, // vtable bytes
+ 12, 0, // object length
+ 8, 0, // start of value 0
+ 4, 0, // start of value 1
+ 8, 0, 0, 0, // int32 offset for start of vtable
+ 8, 0, 0, 0, // pointer to string
+ 16, 0, 0, 0, // pointer to string
+ 6, 0, 0, 0, // length of string
+ 102, 111, 111, 98, 97, 114, 0, 0, // "foobar" + padding
+ 3, 0, 0, 0, // length of string
+ 102, 111, 111, 0 // "bar"
+ };
+ Assert.ArrayEqual(padded, builder.DataBuffer.ToFullArray());
+
+ var verifier = new Verifier(builder.DataBuffer);
+ uint checkOffset = builder.DataBuffer.GetUint(builder.DataBuffer.Position) + (uint)builder.DataBuffer.Position;
+ // table must be ok
+ Assert.IsTrue(verifier.VerifyTableStart(checkOffset));
+ // First field string check
+ Assert.IsTrue(verifier.VerifyString(checkOffset, 4, true));
+ // Second field string check
+ Assert.IsTrue(verifier.VerifyString(checkOffset, 6, true));
+ }
+
+ [FlatBuffersTestMethod]
+ public void TestVTableWithVectorOfStrings()
+ {
+ var builder = new FlatBufferBuilder(64);
+ var str1 = builder.CreateString("foo");
+ var str2 = builder.CreateString("foobar");
+ builder.StartVector(sizeof(int), 2, 1);
+ builder.AddOffset(str1.Value);
+ builder.AddOffset(str2.Value);
+ var vec = builder.EndVector();
+ builder.StartTable(1);
+ builder.AddOffset(0, vec.Value, 0);
+ var off = builder.EndTable();
+ builder.Finish(off);
+
+ byte[] padded = new byte[]
+ {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0, //Padding to 32 bytes
+ 12, 0, 0, 0, // root of table, pointing to vtable offset
+ 0, 0, // padding
+ 6, 0, // vtable bytes
+ 8, 0, // object length
+ 4, 0, // start of value 0
+ 6, 0, 0, 0, // int32 offset for start of vtable
+ 4, 0, 0, 0, // pointer to vector
+ 2, 0, 0, 0, // length of vector
+ 8, 0, 0, 0, // int32 offset to string 1
+ 16, 0, 0, 0, // int32 offset to string 2
+ 6, 0, 0, 0, // length of string
+ 102, 111, 111, 98, 97, 114, 0, 0, // "foobar" + padding
+ 3, 0, 0, 0, // length of string
+ 102, 111, 111, 0 // "bar"
+ };
+ Assert.ArrayEqual(padded, builder.DataBuffer.ToFullArray());
+
+ var verifier = new Verifier(builder.DataBuffer);
+ uint checkOffset = builder.DataBuffer.GetUint(builder.DataBuffer.Position) + (uint)builder.DataBuffer.Position;
+ // table must be ok
+ Assert.IsTrue(verifier.VerifyTableStart(checkOffset));
+ // First field string check
+ Assert.IsTrue(verifier.VerifyVectorOfStrings(checkOffset, 4, true));
}
[FlatBuffersTestMethod]
@@ -521,6 +715,33 @@ namespace Google.FlatBuffers.Test
33,
},
builder.DataBuffer.ToFullArray());
+
+ // check obj1
+ var verifier = new Verifier(builder.DataBuffer);
+ uint checkOffset = builder.DataBuffer.GetUint(builder.DataBuffer.Position) + (uint)builder.DataBuffer.Position;
+ // table must be ok
+ Assert.IsTrue(verifier.VerifyTableStart(checkOffset));
+ // First field must be a struct with 12 bytes
+ Assert.IsTrue(verifier.VerifyField(checkOffset, 4, 1, 1, true));
+ // Second field must be a struct with 12 bytes
+ Assert.IsTrue(verifier.VerifyField(checkOffset, 6, 1, 1, true));
+ // Third field must be a struct with 12 bytes
+ Assert.IsTrue(verifier.VerifyField(checkOffset, 8, 1, 1, true));
+ // Check Error: 4. field did not exist
+ Assert.IsFalse(verifier.VerifyField(checkOffset, 10, 1, 1, true));
+
+ // check obj0
+ checkOffset = 56;
+ // table must be ok
+ Assert.IsTrue(verifier.VerifyTableStart(checkOffset));
+ // First field must be a struct with 12 bytes
+ Assert.IsTrue(verifier.VerifyField(checkOffset, 4, 1, 1, true));
+ // Second field must be a struct with 12 bytes
+ Assert.IsTrue(verifier.VerifyField(checkOffset, 6, 1, 1, true));
+ // Check Error: 3. field did not exist
+ Assert.IsFalse(verifier.VerifyField(checkOffset, 8, 1, 1, true));
+ // Check Error: 4. field did not exist
+ Assert.IsFalse(verifier.VerifyField(checkOffset, 10, 1, 1, true));
}
[FlatBuffersTestMethod]
@@ -569,6 +790,16 @@ namespace Google.FlatBuffers.Test
byte[] unpadded = new byte[padded.Length - 28];
Buffer.BlockCopy(padded, 28, unpadded, 0, unpadded.Length);
Assert.ArrayEqual(unpadded, builder.DataBuffer.ToSizedArray());
+
+ var verifier = new Verifier(builder.DataBuffer);
+ uint checkOffset = builder.DataBuffer.GetUint(builder.DataBuffer.Position) + (uint)builder.DataBuffer.Position;
+ // table must be ok
+ Assert.IsTrue(verifier.VerifyTableStart(checkOffset));
+ for (var i = 0; i < 8; i++)
+ {
+ Assert.IsTrue(verifier.VerifyField(checkOffset, (short)(4 + i * 2), 1, 1, true));
+ }
+ Assert.IsFalse(verifier.VerifyField(checkOffset, (short)(4 + 8 * 2), 1, 1, true));
}
[FlatBuffersTestMethod]
@@ -639,6 +870,16 @@ namespace Google.FlatBuffers.Test
},
builder.DataBuffer.ToFullArray());
+ var verifier = new Verifier(builder.DataBuffer);
+ uint checkOffset = 8;
+ // table must be ok
+ Assert.IsTrue(verifier.VerifyTableStart(checkOffset));
+ // First Field must be float
+ Assert.IsTrue(verifier.VerifyField(checkOffset, 4, 4, 4, true));
+ // Check Error: First Field with to big size
+ Assert.IsFalse(verifier.VerifyField(checkOffset, 4, 8, 4, true));
+ // Check Error: First Field with to big padding
+ Assert.IsFalse(verifier.VerifyField(checkOffset, 4, 4, 8, true));
}
private void CheckObjects(int fieldCount, int objectCount)
diff --git a/tests/KeywordTest/KeywordsInTable.cs b/tests/KeywordTest/KeywordsInTable.cs
index 90030116..9556c9f6 100644
--- a/tests/KeywordTest/KeywordsInTable.cs
+++ b/tests/KeywordTest/KeywordsInTable.cs
@@ -92,4 +92,17 @@ public class KeywordsInTableT
}
+static public class KeywordsInTableVerify
+{
+ static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
+ {
+ return verifier.VerifyTableStart(tablePos)
+ && verifier.VerifyField(tablePos, 4 /*Is*/, 4 /*KeywordTest.ABC*/, 4, false)
+ && verifier.VerifyField(tablePos, 6 /*Private*/, 4 /*KeywordTest.@public*/, 4, false)
+ && verifier.VerifyField(tablePos, 8 /*Type*/, 4 /*int*/, 4, false)
+ && verifier.VerifyField(tablePos, 10 /*Default*/, 1 /*bool*/, 1, false)
+ && verifier.VerifyTableEnd(tablePos);
+ }
+}
+
}
diff --git a/tests/KeywordTest/KeywordsInUnion.cs b/tests/KeywordTest/KeywordsInUnion.cs
index 0efa0668..d8a870f4 100644
--- a/tests/KeywordTest/KeywordsInUnion.cs
+++ b/tests/KeywordTest/KeywordsInUnion.cs
@@ -37,6 +37,28 @@ public class KeywordsInUnionUnion {
}
}
+
+
+static public class KeywordsInUnionVerify
+{
+ static public bool Verify(Google.FlatBuffers.Verifier verifier, byte typeId, uint tablePos)
+ {
+ bool result = true;
+ switch((KeywordsInUnion)typeId)
+ {
+ case KeywordsInUnion.@static:
+ result = KeywordTest.KeywordsInTableVerify.Verify(verifier, tablePos);
+ break;
+ case KeywordsInUnion.@internal:
+ result = KeywordTest.KeywordsInTableVerify.Verify(verifier, tablePos);
+ break;
+ default: result = true;
+ break;
+ }
+ return result;
+ }
+}
+
public class KeywordsInUnionUnion_JsonConverter : Newtonsoft.Json.JsonConverter {
public override bool CanConvert(System.Type objectType) {
return objectType == typeof(KeywordsInUnionUnion) || objectType == typeof(System.Collections.Generic.List<KeywordsInUnionUnion>);
diff --git a/tests/KeywordTest/Table2.cs b/tests/KeywordTest/Table2.cs
index 56ee6898..59cfee06 100644
--- a/tests/KeywordTest/Table2.cs
+++ b/tests/KeywordTest/Table2.cs
@@ -91,4 +91,15 @@ public class Table2T
}
+static public class Table2Verify
+{
+ static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
+ {
+ return verifier.VerifyTableStart(tablePos)
+ && verifier.VerifyField(tablePos, 4 /*TypeType*/, 1 /*KeywordTest.KeywordsInUnion*/, 1, false)
+ && verifier.VerifyUnion(tablePos, 4, 6 /*Type*/, KeywordTest.KeywordsInUnionVerify.Verify, false)
+ && verifier.VerifyTableEnd(tablePos);
+ }
+}
+
}
diff --git a/tests/MyGame/Example/Any.cs b/tests/MyGame/Example/Any.cs
index 90cd22bf..021faa62 100644
--- a/tests/MyGame/Example/Any.cs
+++ b/tests/MyGame/Example/Any.cs
@@ -41,6 +41,31 @@ public class AnyUnion {
}
}
+
+
+static public class AnyVerify
+{
+ static public bool Verify(Google.FlatBuffers.Verifier verifier, byte typeId, uint tablePos)
+ {
+ bool result = true;
+ switch((Any)typeId)
+ {
+ case Any.Monster:
+ result = MyGame.Example.MonsterVerify.Verify(verifier, tablePos);
+ break;
+ case Any.TestSimpleTableWithEnum:
+ result = MyGame.Example.TestSimpleTableWithEnumVerify.Verify(verifier, tablePos);
+ break;
+ case Any.MyGame_Example2_Monster:
+ result = MyGame.Example2.MonsterVerify.Verify(verifier, tablePos);
+ break;
+ default: result = true;
+ break;
+ }
+ return result;
+ }
+}
+
public class AnyUnion_JsonConverter : Newtonsoft.Json.JsonConverter {
public override bool CanConvert(System.Type objectType) {
return objectType == typeof(AnyUnion) || objectType == typeof(System.Collections.Generic.List<AnyUnion>);
diff --git a/tests/MyGame/Example/AnyAmbiguousAliases.cs b/tests/MyGame/Example/AnyAmbiguousAliases.cs
index eec41723..3fb3d779 100644
--- a/tests/MyGame/Example/AnyAmbiguousAliases.cs
+++ b/tests/MyGame/Example/AnyAmbiguousAliases.cs
@@ -41,6 +41,31 @@ public class AnyAmbiguousAliasesUnion {
}
}
+
+
+static public class AnyAmbiguousAliasesVerify
+{
+ static public bool Verify(Google.FlatBuffers.Verifier verifier, byte typeId, uint tablePos)
+ {
+ bool result = true;
+ switch((AnyAmbiguousAliases)typeId)
+ {
+ case AnyAmbiguousAliases.M1:
+ result = MyGame.Example.MonsterVerify.Verify(verifier, tablePos);
+ break;
+ case AnyAmbiguousAliases.M2:
+ result = MyGame.Example.MonsterVerify.Verify(verifier, tablePos);
+ break;
+ case AnyAmbiguousAliases.M3:
+ result = MyGame.Example.MonsterVerify.Verify(verifier, tablePos);
+ break;
+ default: result = true;
+ break;
+ }
+ return result;
+ }
+}
+
public class AnyAmbiguousAliasesUnion_JsonConverter : Newtonsoft.Json.JsonConverter {
public override bool CanConvert(System.Type objectType) {
return objectType == typeof(AnyAmbiguousAliasesUnion) || objectType == typeof(System.Collections.Generic.List<AnyAmbiguousAliasesUnion>);
diff --git a/tests/MyGame/Example/AnyUniqueAliases.cs b/tests/MyGame/Example/AnyUniqueAliases.cs
index bb6a2120..629edb69 100644
--- a/tests/MyGame/Example/AnyUniqueAliases.cs
+++ b/tests/MyGame/Example/AnyUniqueAliases.cs
@@ -41,6 +41,31 @@ public class AnyUniqueAliasesUnion {
}
}
+
+
+static public class AnyUniqueAliasesVerify
+{
+ static public bool Verify(Google.FlatBuffers.Verifier verifier, byte typeId, uint tablePos)
+ {
+ bool result = true;
+ switch((AnyUniqueAliases)typeId)
+ {
+ case AnyUniqueAliases.M:
+ result = MyGame.Example.MonsterVerify.Verify(verifier, tablePos);
+ break;
+ case AnyUniqueAliases.TS:
+ result = MyGame.Example.TestSimpleTableWithEnumVerify.Verify(verifier, tablePos);
+ break;
+ case AnyUniqueAliases.M2:
+ result = MyGame.Example2.MonsterVerify.Verify(verifier, tablePos);
+ break;
+ default: result = true;
+ break;
+ }
+ return result;
+ }
+}
+
public class AnyUniqueAliasesUnion_JsonConverter : Newtonsoft.Json.JsonConverter {
public override bool CanConvert(System.Type objectType) {
return objectType == typeof(AnyUniqueAliasesUnion) || objectType == typeof(System.Collections.Generic.List<AnyUniqueAliasesUnion>);
diff --git a/tests/MyGame/Example/ArrayTable.cs b/tests/MyGame/Example/ArrayTable.cs
index 56b8353f..d38b70c0 100644
--- a/tests/MyGame/Example/ArrayTable.cs
+++ b/tests/MyGame/Example/ArrayTable.cs
@@ -17,6 +17,7 @@ public struct ArrayTable : IFlatbufferObject
public static ArrayTable GetRootAsArrayTable(ByteBuffer _bb) { return GetRootAsArrayTable(_bb, new ArrayTable()); }
public static ArrayTable GetRootAsArrayTable(ByteBuffer _bb, ArrayTable obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
public static bool ArrayTableBufferHasIdentifier(ByteBuffer _bb) { return Table.__has_identifier(_bb, "ARRT"); }
+ public static bool VerifyArrayTable(ByteBuffer _bb) {Google.FlatBuffers.Verifier verifier = new Google.FlatBuffers.Verifier(_bb); return verifier.VerifyBuffer("ARRT", false, ArrayTableVerify.Verify); }
public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
public ArrayTable __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
@@ -72,4 +73,14 @@ public class ArrayTableT
}
+static public class ArrayTableVerify
+{
+ static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
+ {
+ return verifier.VerifyTableStart(tablePos)
+ && verifier.VerifyField(tablePos, 4 /*A*/, 160 /*MyGame.Example.ArrayStruct*/, 8, false)
+ && verifier.VerifyTableEnd(tablePos);
+ }
+}
+
}
diff --git a/tests/MyGame/Example/Monster.cs b/tests/MyGame/Example/Monster.cs
index 4abde535..e7cdd2e8 100644
--- a/tests/MyGame/Example/Monster.cs
+++ b/tests/MyGame/Example/Monster.cs
@@ -18,6 +18,7 @@ public struct Monster : IFlatbufferObject
public static Monster GetRootAsMonster(ByteBuffer _bb) { return GetRootAsMonster(_bb, new Monster()); }
public static Monster GetRootAsMonster(ByteBuffer _bb, Monster obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
public static bool MonsterBufferHasIdentifier(ByteBuffer _bb) { return Table.__has_identifier(_bb, "MONS"); }
+ public static bool VerifyMonster(ByteBuffer _bb) {Google.FlatBuffers.Verifier verifier = new Google.FlatBuffers.Verifier(_bb); return verifier.VerifyBuffer("MONS", false, MonsterVerify.Verify); }
public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
public Monster __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
@@ -1100,4 +1101,74 @@ public class MonsterT
}
+static public class MonsterVerify
+{
+ static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
+ {
+ return verifier.VerifyTableStart(tablePos)
+ && verifier.VerifyField(tablePos, 4 /*Pos*/, 32 /*MyGame.Example.Vec3*/, 8, false)
+ && verifier.VerifyField(tablePos, 6 /*Mana*/, 2 /*short*/, 2, false)
+ && verifier.VerifyField(tablePos, 8 /*Hp*/, 2 /*short*/, 2, false)
+ && verifier.VerifyString(tablePos, 10 /*Name*/, true)
+ && verifier.VerifyVectorOfData(tablePos, 14 /*Inventory*/, 1 /*byte*/, false)
+ && verifier.VerifyField(tablePos, 16 /*Color*/, 1 /*MyGame.Example.Color*/, 1, false)
+ && verifier.VerifyField(tablePos, 18 /*TestType*/, 1 /*MyGame.Example.Any*/, 1, false)
+ && verifier.VerifyUnion(tablePos, 18, 20 /*Test*/, MyGame.Example.AnyVerify.Verify, false)
+ && verifier.VerifyVectorOfData(tablePos, 22 /*Test4*/, 4 /*MyGame.Example.Test*/, false)
+ && verifier.VerifyVectorOfStrings(tablePos, 24 /*Testarrayofstring*/, false)
+ && verifier.VerifyVectorOfTables(tablePos, 26 /*Testarrayoftables*/, MyGame.Example.MonsterVerify.Verify, false)
+ && verifier.VerifyTable(tablePos, 28 /*Enemy*/, MyGame.Example.MonsterVerify.Verify, false)
+ && verifier.VerifyNestedBuffer(tablePos, 30 /*Testnestedflatbuffer*/, MyGame.Example.MonsterVerify.Verify, false)
+ && verifier.VerifyTable(tablePos, 32 /*Testempty*/, MyGame.Example.StatVerify.Verify, false)
+ && verifier.VerifyField(tablePos, 34 /*Testbool*/, 1 /*bool*/, 1, false)
+ && verifier.VerifyField(tablePos, 36 /*Testhashs32Fnv1*/, 4 /*int*/, 4, false)
+ && verifier.VerifyField(tablePos, 38 /*Testhashu32Fnv1*/, 4 /*uint*/, 4, false)
+ && verifier.VerifyField(tablePos, 40 /*Testhashs64Fnv1*/, 8 /*long*/, 8, false)
+ && verifier.VerifyField(tablePos, 42 /*Testhashu64Fnv1*/, 8 /*ulong*/, 8, false)
+ && verifier.VerifyField(tablePos, 44 /*Testhashs32Fnv1a*/, 4 /*int*/, 4, false)
+ && verifier.VerifyField(tablePos, 46 /*Testhashu32Fnv1a*/, 4 /*uint*/, 4, false)
+ && verifier.VerifyField(tablePos, 48 /*Testhashs64Fnv1a*/, 8 /*long*/, 8, false)
+ && verifier.VerifyField(tablePos, 50 /*Testhashu64Fnv1a*/, 8 /*ulong*/, 8, false)
+ && verifier.VerifyVectorOfData(tablePos, 52 /*Testarrayofbools*/, 1 /*bool*/, false)
+ && verifier.VerifyField(tablePos, 54 /*Testf*/, 4 /*float*/, 4, false)
+ && verifier.VerifyField(tablePos, 56 /*Testf2*/, 4 /*float*/, 4, false)
+ && verifier.VerifyField(tablePos, 58 /*Testf3*/, 4 /*float*/, 4, false)
+ && verifier.VerifyVectorOfStrings(tablePos, 60 /*Testarrayofstring2*/, false)
+ && verifier.VerifyVectorOfData(tablePos, 62 /*Testarrayofsortedstruct*/, 8 /*MyGame.Example.Ability*/, false)
+ && verifier.VerifyNestedBuffer(tablePos, 64 /*Flex*/, null, false)
+ && verifier.VerifyVectorOfData(tablePos, 66 /*Test5*/, 4 /*MyGame.Example.Test*/, false)
+ && verifier.VerifyVectorOfData(tablePos, 68 /*VectorOfLongs*/, 8 /*long*/, false)
+ && verifier.VerifyVectorOfData(tablePos, 70 /*VectorOfDoubles*/, 8 /*double*/, false)
+ && verifier.VerifyTable(tablePos, 72 /*ParentNamespaceTest*/, MyGame.InParentNamespaceVerify.Verify, false)
+ && verifier.VerifyVectorOfTables(tablePos, 74 /*VectorOfReferrables*/, MyGame.Example.ReferrableVerify.Verify, false)
+ && verifier.VerifyField(tablePos, 76 /*SingleWeakReference*/, 8 /*ulong*/, 8, false)
+ && verifier.VerifyVectorOfData(tablePos, 78 /*VectorOfWeakReferences*/, 8 /*ulong*/, false)
+ && verifier.VerifyVectorOfTables(tablePos, 80 /*VectorOfStrongReferrables*/, MyGame.Example.ReferrableVerify.Verify, false)
+ && verifier.VerifyField(tablePos, 82 /*CoOwningReference*/, 8 /*ulong*/, 8, false)
+ && verifier.VerifyVectorOfData(tablePos, 84 /*VectorOfCoOwningReferences*/, 8 /*ulong*/, false)
+ && verifier.VerifyField(tablePos, 86 /*NonOwningReference*/, 8 /*ulong*/, 8, false)
+ && verifier.VerifyVectorOfData(tablePos, 88 /*VectorOfNonOwningReferences*/, 8 /*ulong*/, false)
+ && verifier.VerifyField(tablePos, 90 /*AnyUniqueType*/, 1 /*MyGame.Example.AnyUniqueAliases*/, 1, false)
+ && verifier.VerifyUnion(tablePos, 90, 92 /*AnyUnique*/, MyGame.Example.AnyUniqueAliasesVerify.Verify, false)
+ && verifier.VerifyField(tablePos, 94 /*AnyAmbiguousType*/, 1 /*MyGame.Example.AnyAmbiguousAliases*/, 1, false)
+ && verifier.VerifyUnion(tablePos, 94, 96 /*AnyAmbiguous*/, MyGame.Example.AnyAmbiguousAliasesVerify.Verify, false)
+ && verifier.VerifyVectorOfData(tablePos, 98 /*VectorOfEnums*/, 1 /*MyGame.Example.Color*/, false)
+ && verifier.VerifyField(tablePos, 100 /*SignedEnum*/, 1 /*MyGame.Example.Race*/, 1, false)
+ && verifier.VerifyNestedBuffer(tablePos, 102 /*Testrequirednestedflatbuffer*/, MyGame.Example.MonsterVerify.Verify, false)
+ && verifier.VerifyVectorOfTables(tablePos, 104 /*ScalarKeySortedTables*/, MyGame.Example.StatVerify.Verify, false)
+ && verifier.VerifyField(tablePos, 106 /*NativeInline*/, 4 /*MyGame.Example.Test*/, 2, false)
+ && verifier.VerifyField(tablePos, 108 /*LongEnumNonEnumDefault*/, 8 /*MyGame.Example.LongEnum*/, 8, false)
+ && verifier.VerifyField(tablePos, 110 /*LongEnumNormalDefault*/, 8 /*MyGame.Example.LongEnum*/, 8, false)
+ && verifier.VerifyField(tablePos, 112 /*NanDefault*/, 4 /*float*/, 4, false)
+ && verifier.VerifyField(tablePos, 114 /*InfDefault*/, 4 /*float*/, 4, false)
+ && verifier.VerifyField(tablePos, 116 /*PositiveInfDefault*/, 4 /*float*/, 4, false)
+ && verifier.VerifyField(tablePos, 118 /*InfinityDefault*/, 4 /*float*/, 4, false)
+ && verifier.VerifyField(tablePos, 120 /*PositiveInfinityDefault*/, 4 /*float*/, 4, false)
+ && verifier.VerifyField(tablePos, 122 /*NegativeInfDefault*/, 4 /*float*/, 4, false)
+ && verifier.VerifyField(tablePos, 124 /*NegativeInfinityDefault*/, 4 /*float*/, 4, false)
+ && verifier.VerifyField(tablePos, 126 /*DoubleInfDefault*/, 8 /*double*/, 8, false)
+ && verifier.VerifyTableEnd(tablePos);
+ }
+}
+
}
diff --git a/tests/MyGame/Example/Referrable.cs b/tests/MyGame/Example/Referrable.cs
index 095b1f6f..c6434d26 100644
--- a/tests/MyGame/Example/Referrable.cs
+++ b/tests/MyGame/Example/Referrable.cs
@@ -92,4 +92,14 @@ public class ReferrableT
}
+static public class ReferrableVerify
+{
+ static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
+ {
+ return verifier.VerifyTableStart(tablePos)
+ && verifier.VerifyField(tablePos, 4 /*Id*/, 8 /*ulong*/, 8, false)
+ && verifier.VerifyTableEnd(tablePos);
+ }
+}
+
}
diff --git a/tests/MyGame/Example/Stat.cs b/tests/MyGame/Example/Stat.cs
index dc29bd48..c73f2aae 100644
--- a/tests/MyGame/Example/Stat.cs
+++ b/tests/MyGame/Example/Stat.cs
@@ -117,4 +117,16 @@ public class StatT
}
+static public class StatVerify
+{
+ static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
+ {
+ return verifier.VerifyTableStart(tablePos)
+ && verifier.VerifyString(tablePos, 4 /*Id*/, false)
+ && verifier.VerifyField(tablePos, 6 /*Val*/, 8 /*long*/, 8, false)
+ && verifier.VerifyField(tablePos, 8 /*Count*/, 2 /*ushort*/, 2, false)
+ && verifier.VerifyTableEnd(tablePos);
+ }
+}
+
}
diff --git a/tests/MyGame/Example/TestSimpleTableWithEnum.cs b/tests/MyGame/Example/TestSimpleTableWithEnum.cs
index 21841100..2a827a50 100644
--- a/tests/MyGame/Example/TestSimpleTableWithEnum.cs
+++ b/tests/MyGame/Example/TestSimpleTableWithEnum.cs
@@ -62,4 +62,14 @@ internal partial class TestSimpleTableWithEnumT
}
+static public class TestSimpleTableWithEnumVerify
+{
+ static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
+ {
+ return verifier.VerifyTableStart(tablePos)
+ && verifier.VerifyField(tablePos, 4 /*Color*/, 1 /*MyGame.Example.Color*/, 1, false)
+ && verifier.VerifyTableEnd(tablePos);
+ }
+}
+
}
diff --git a/tests/MyGame/Example/TypeAliases.cs b/tests/MyGame/Example/TypeAliases.cs
index 0980db91..e4eecf3e 100644
--- a/tests/MyGame/Example/TypeAliases.cs
+++ b/tests/MyGame/Example/TypeAliases.cs
@@ -208,4 +208,25 @@ public class TypeAliasesT
}
+static public class TypeAliasesVerify
+{
+ static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
+ {
+ return verifier.VerifyTableStart(tablePos)
+ && verifier.VerifyField(tablePos, 4 /*I8*/, 1 /*sbyte*/, 1, false)
+ && verifier.VerifyField(tablePos, 6 /*U8*/, 1 /*byte*/, 1, false)
+ && verifier.VerifyField(tablePos, 8 /*I16*/, 2 /*short*/, 2, false)
+ && verifier.VerifyField(tablePos, 10 /*U16*/, 2 /*ushort*/, 2, false)
+ && verifier.VerifyField(tablePos, 12 /*I32*/, 4 /*int*/, 4, false)
+ && verifier.VerifyField(tablePos, 14 /*U32*/, 4 /*uint*/, 4, false)
+ && verifier.VerifyField(tablePos, 16 /*I64*/, 8 /*long*/, 8, false)
+ && verifier.VerifyField(tablePos, 18 /*U64*/, 8 /*ulong*/, 8, false)
+ && verifier.VerifyField(tablePos, 20 /*F32*/, 4 /*float*/, 4, false)
+ && verifier.VerifyField(tablePos, 22 /*F64*/, 8 /*double*/, 8, false)
+ && verifier.VerifyVectorOfData(tablePos, 24 /*V8*/, 1 /*sbyte*/, false)
+ && verifier.VerifyVectorOfData(tablePos, 26 /*Vf64*/, 8 /*double*/, false)
+ && verifier.VerifyTableEnd(tablePos);
+ }
+}
+
}
diff --git a/tests/MyGame/Example2/Monster.cs b/tests/MyGame/Example2/Monster.cs
index 465f04d5..f9fa7006 100644
--- a/tests/MyGame/Example2/Monster.cs
+++ b/tests/MyGame/Example2/Monster.cs
@@ -47,4 +47,13 @@ public class MonsterT
}
+static public class MonsterVerify
+{
+ static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
+ {
+ return verifier.VerifyTableStart(tablePos)
+ && verifier.VerifyTableEnd(tablePos);
+ }
+}
+
}
diff --git a/tests/MyGame/InParentNamespace.cs b/tests/MyGame/InParentNamespace.cs
index ca99f3e8..8416105f 100644
--- a/tests/MyGame/InParentNamespace.cs
+++ b/tests/MyGame/InParentNamespace.cs
@@ -47,4 +47,13 @@ public class InParentNamespaceT
}
+static public class InParentNamespaceVerify
+{
+ static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
+ {
+ return verifier.VerifyTableStart(tablePos)
+ && verifier.VerifyTableEnd(tablePos);
+ }
+}
+
}
diff --git a/tests/MyGame/MonsterExtra.cs b/tests/MyGame/MonsterExtra.cs
index f5bd71f1..c1061b6b 100644
--- a/tests/MyGame/MonsterExtra.cs
+++ b/tests/MyGame/MonsterExtra.cs
@@ -17,6 +17,7 @@ public struct MonsterExtra : IFlatbufferObject
public static MonsterExtra GetRootAsMonsterExtra(ByteBuffer _bb) { return GetRootAsMonsterExtra(_bb, new MonsterExtra()); }
public static MonsterExtra GetRootAsMonsterExtra(ByteBuffer _bb, MonsterExtra obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
public static bool MonsterExtraBufferHasIdentifier(ByteBuffer _bb) { return Table.__has_identifier(_bb, "MONE"); }
+ public static bool VerifyMonsterExtra(ByteBuffer _bb) {Google.FlatBuffers.Verifier verifier = new Google.FlatBuffers.Verifier(_bb); return verifier.VerifyBuffer("MONE", false, MonsterExtraVerify.Verify); }
public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
public MonsterExtra __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
@@ -206,4 +207,23 @@ public class MonsterExtraT
}
+static public class MonsterExtraVerify
+{
+ static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
+ {
+ return verifier.VerifyTableStart(tablePos)
+ && verifier.VerifyField(tablePos, 4 /*D0*/, 8 /*double*/, 8, false)
+ && verifier.VerifyField(tablePos, 6 /*D1*/, 8 /*double*/, 8, false)
+ && verifier.VerifyField(tablePos, 8 /*D2*/, 8 /*double*/, 8, false)
+ && verifier.VerifyField(tablePos, 10 /*D3*/, 8 /*double*/, 8, false)
+ && verifier.VerifyField(tablePos, 12 /*F0*/, 4 /*float*/, 4, false)
+ && verifier.VerifyField(tablePos, 14 /*F1*/, 4 /*float*/, 4, false)
+ && verifier.VerifyField(tablePos, 16 /*F2*/, 4 /*float*/, 4, false)
+ && verifier.VerifyField(tablePos, 18 /*F3*/, 4 /*float*/, 4, false)
+ && verifier.VerifyVectorOfData(tablePos, 20 /*Dvec*/, 8 /*double*/, false)
+ && verifier.VerifyVectorOfData(tablePos, 22 /*Fvec*/, 4 /*float*/, false)
+ && verifier.VerifyTableEnd(tablePos);
+ }
+}
+
}
diff --git a/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.cs b/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.cs
index 8ec7b8d5..bfb8a8a2 100644
--- a/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.cs
+++ b/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.cs
@@ -62,4 +62,14 @@ public class TableInNestedNST
}
+static public class TableInNestedNSVerify
+{
+ static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
+ {
+ return verifier.VerifyTableStart(tablePos)
+ && verifier.VerifyField(tablePos, 4 /*Foo*/, 4 /*int*/, 4, false)
+ && verifier.VerifyTableEnd(tablePos);
+ }
+}
+
}
diff --git a/tests/namespace_test/NamespaceA/NamespaceB/UnionInNestedNS.cs b/tests/namespace_test/NamespaceA/NamespaceB/UnionInNestedNS.cs
index 08bc431e..8105c3b0 100644
--- a/tests/namespace_test/NamespaceA/NamespaceB/UnionInNestedNS.cs
+++ b/tests/namespace_test/NamespaceA/NamespaceB/UnionInNestedNS.cs
@@ -33,6 +33,25 @@ public class UnionInNestedNSUnion {
}
}
+
+
+static public class UnionInNestedNSVerify
+{
+ static public bool Verify(Google.FlatBuffers.Verifier verifier, byte typeId, uint tablePos)
+ {
+ bool result = true;
+ switch((UnionInNestedNS)typeId)
+ {
+ case UnionInNestedNS.TableInNestedNS:
+ result = NamespaceA.NamespaceB.TableInNestedNSVerify.Verify(verifier, tablePos);
+ break;
+ default: result = true;
+ break;
+ }
+ return result;
+ }
+}
+
public class UnionInNestedNSUnion_JsonConverter : Newtonsoft.Json.JsonConverter {
public override bool CanConvert(System.Type objectType) {
return objectType == typeof(UnionInNestedNSUnion) || objectType == typeof(System.Collections.Generic.List<UnionInNestedNSUnion>);
diff --git a/tests/namespace_test/NamespaceA/SecondTableInA.cs b/tests/namespace_test/NamespaceA/SecondTableInA.cs
index 7e7556cd..b6ea91a9 100644
--- a/tests/namespace_test/NamespaceA/SecondTableInA.cs
+++ b/tests/namespace_test/NamespaceA/SecondTableInA.cs
@@ -62,4 +62,14 @@ public class SecondTableInAT
}
+static public class SecondTableInAVerify
+{
+ static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
+ {
+ return verifier.VerifyTableStart(tablePos)
+ && verifier.VerifyTable(tablePos, 4 /*ReferToC*/, NamespaceC.TableInCVerify.Verify, false)
+ && verifier.VerifyTableEnd(tablePos);
+ }
+}
+
}
diff --git a/tests/namespace_test/NamespaceA/TableInFirstNS.cs b/tests/namespace_test/NamespaceA/TableInFirstNS.cs
index 5c5e7b01..202983ab 100644
--- a/tests/namespace_test/NamespaceA/TableInFirstNS.cs
+++ b/tests/namespace_test/NamespaceA/TableInFirstNS.cs
@@ -116,4 +116,18 @@ public class TableInFirstNST
}
+static public class TableInFirstNSVerify
+{
+ static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
+ {
+ return verifier.VerifyTableStart(tablePos)
+ && verifier.VerifyTable(tablePos, 4 /*FooTable*/, NamespaceA.NamespaceB.TableInNestedNSVerify.Verify, false)
+ && verifier.VerifyField(tablePos, 6 /*FooEnum*/, 1 /*NamespaceA.NamespaceB.EnumInNestedNS*/, 1, false)
+ && verifier.VerifyField(tablePos, 8 /*FooUnionType*/, 1 /*NamespaceA.NamespaceB.UnionInNestedNS*/, 1, false)
+ && verifier.VerifyUnion(tablePos, 8, 10 /*FooUnion*/, NamespaceA.NamespaceB.UnionInNestedNSVerify.Verify, false)
+ && verifier.VerifyField(tablePos, 12 /*FooStruct*/, 8 /*NamespaceA.NamespaceB.StructInNestedNS*/, 4, false)
+ && verifier.VerifyTableEnd(tablePos);
+ }
+}
+
}
diff --git a/tests/namespace_test/NamespaceC/TableInC.cs b/tests/namespace_test/NamespaceC/TableInC.cs
index 42714d2a..5cc60d04 100644
--- a/tests/namespace_test/NamespaceC/TableInC.cs
+++ b/tests/namespace_test/NamespaceC/TableInC.cs
@@ -72,4 +72,15 @@ public class TableInCT
}
+static public class TableInCVerify
+{
+ static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
+ {
+ return verifier.VerifyTableStart(tablePos)
+ && verifier.VerifyTable(tablePos, 4 /*ReferToA1*/, NamespaceA.TableInFirstNSVerify.Verify, false)
+ && verifier.VerifyTable(tablePos, 6 /*ReferToA2*/, NamespaceA.SecondTableInAVerify.Verify, false)
+ && verifier.VerifyTableEnd(tablePos);
+ }
+}
+
}
diff --git a/tests/nested_namespace_test/nested_namespace_test3_generated.cs b/tests/nested_namespace_test/nested_namespace_test3_generated.cs
index b26aae0a..6927bc39 100644
--- a/tests/nested_namespace_test/nested_namespace_test3_generated.cs
+++ b/tests/nested_namespace_test/nested_namespace_test3_generated.cs
@@ -62,4 +62,14 @@ public class ColorTestTableT
}
+static public class ColorTestTableVerify
+{
+ static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
+ {
+ return verifier.VerifyTableStart(tablePos)
+ && verifier.VerifyField(tablePos, 4 /*Color*/, 1 /*global::NamespaceB.Color*/, 1, false)
+ && verifier.VerifyTableEnd(tablePos);
+ }
+}
+
}
diff --git a/tests/optional_scalars/ScalarStuff.cs b/tests/optional_scalars/ScalarStuff.cs
index ec2388b3..74bfb61f 100644
--- a/tests/optional_scalars/ScalarStuff.cs
+++ b/tests/optional_scalars/ScalarStuff.cs
@@ -17,6 +17,7 @@ public struct ScalarStuff : IFlatbufferObject
public static ScalarStuff GetRootAsScalarStuff(ByteBuffer _bb) { return GetRootAsScalarStuff(_bb, new ScalarStuff()); }
public static ScalarStuff GetRootAsScalarStuff(ByteBuffer _bb, ScalarStuff obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
public static bool ScalarStuffBufferHasIdentifier(ByteBuffer _bb) { return Table.__has_identifier(_bb, "NULL"); }
+ public static bool VerifyScalarStuff(ByteBuffer _bb) {Google.FlatBuffers.Verifier verifier = new Google.FlatBuffers.Verifier(_bb); return verifier.VerifyBuffer("NULL", false, ScalarStuffVerify.Verify); }
public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
public ScalarStuff __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
@@ -351,4 +352,49 @@ public class ScalarStuffT
}
+static public class ScalarStuffVerify
+{
+ static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
+ {
+ return verifier.VerifyTableStart(tablePos)
+ && verifier.VerifyField(tablePos, 4 /*JustI8*/, 1 /*sbyte*/, 1, false)
+ && verifier.VerifyField(tablePos, 6 /*MaybeI8*/, 1 /*sbyte*/, 1, false)
+ && verifier.VerifyField(tablePos, 8 /*DefaultI8*/, 1 /*sbyte*/, 1, false)
+ && verifier.VerifyField(tablePos, 10 /*JustU8*/, 1 /*byte*/, 1, false)
+ && verifier.VerifyField(tablePos, 12 /*MaybeU8*/, 1 /*byte*/, 1, false)
+ && verifier.VerifyField(tablePos, 14 /*DefaultU8*/, 1 /*byte*/, 1, false)
+ && verifier.VerifyField(tablePos, 16 /*JustI16*/, 2 /*short*/, 2, false)
+ && verifier.VerifyField(tablePos, 18 /*MaybeI16*/, 2 /*short*/, 2, false)
+ && verifier.VerifyField(tablePos, 20 /*DefaultI16*/, 2 /*short*/, 2, false)
+ && verifier.VerifyField(tablePos, 22 /*JustU16*/, 2 /*ushort*/, 2, false)
+ && verifier.VerifyField(tablePos, 24 /*MaybeU16*/, 2 /*ushort*/, 2, false)
+ && verifier.VerifyField(tablePos, 26 /*DefaultU16*/, 2 /*ushort*/, 2, false)
+ && verifier.VerifyField(tablePos, 28 /*JustI32*/, 4 /*int*/, 4, false)
+ && verifier.VerifyField(tablePos, 30 /*MaybeI32*/, 4 /*int*/, 4, false)
+ && verifier.VerifyField(tablePos, 32 /*DefaultI32*/, 4 /*int*/, 4, false)
+ && verifier.VerifyField(tablePos, 34 /*JustU32*/, 4 /*uint*/, 4, false)
+ && verifier.VerifyField(tablePos, 36 /*MaybeU32*/, 4 /*uint*/, 4, false)
+ && verifier.VerifyField(tablePos, 38 /*DefaultU32*/, 4 /*uint*/, 4, false)
+ && verifier.VerifyField(tablePos, 40 /*JustI64*/, 8 /*long*/, 8, false)
+ && verifier.VerifyField(tablePos, 42 /*MaybeI64*/, 8 /*long*/, 8, false)
+ && verifier.VerifyField(tablePos, 44 /*DefaultI64*/, 8 /*long*/, 8, false)
+ && verifier.VerifyField(tablePos, 46 /*JustU64*/, 8 /*ulong*/, 8, false)
+ && verifier.VerifyField(tablePos, 48 /*MaybeU64*/, 8 /*ulong*/, 8, false)
+ && verifier.VerifyField(tablePos, 50 /*DefaultU64*/, 8 /*ulong*/, 8, false)
+ && verifier.VerifyField(tablePos, 52 /*JustF32*/, 4 /*float*/, 4, false)
+ && verifier.VerifyField(tablePos, 54 /*MaybeF32*/, 4 /*float*/, 4, false)
+ && verifier.VerifyField(tablePos, 56 /*DefaultF32*/, 4 /*float*/, 4, false)
+ && verifier.VerifyField(tablePos, 58 /*JustF64*/, 8 /*double*/, 8, false)
+ && verifier.VerifyField(tablePos, 60 /*MaybeF64*/, 8 /*double*/, 8, false)
+ && verifier.VerifyField(tablePos, 62 /*DefaultF64*/, 8 /*double*/, 8, false)
+ && verifier.VerifyField(tablePos, 64 /*JustBool*/, 1 /*bool*/, 1, false)
+ && verifier.VerifyField(tablePos, 66 /*MaybeBool*/, 1 /*bool*/, 1, false)
+ && verifier.VerifyField(tablePos, 68 /*DefaultBool*/, 1 /*bool*/, 1, false)
+ && verifier.VerifyField(tablePos, 70 /*JustEnum*/, 1 /*optional_scalars.OptionalByte*/, 1, false)
+ && verifier.VerifyField(tablePos, 72 /*MaybeEnum*/, 1 /*optional_scalars.OptionalByte*/, 1, false)
+ && verifier.VerifyField(tablePos, 74 /*DefaultEnum*/, 1 /*optional_scalars.OptionalByte*/, 1, false)
+ && verifier.VerifyTableEnd(tablePos);
+ }
+}
+
}
diff --git a/tests/type_field_collsion/Collision.cs b/tests/type_field_collsion/Collision.cs
index 0d24aba9..c1a877a1 100644
--- a/tests/type_field_collsion/Collision.cs
+++ b/tests/type_field_collsion/Collision.cs
@@ -16,6 +16,7 @@ public struct Collision : IFlatbufferObject
public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_23_3_3(); }
public static Collision GetRootAsCollision(ByteBuffer _bb) { return GetRootAsCollision(_bb, new Collision()); }
public static Collision GetRootAsCollision(ByteBuffer _bb, Collision obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
+ public static bool VerifyCollision(ByteBuffer _bb) {Google.FlatBuffers.Verifier verifier = new Google.FlatBuffers.Verifier(_bb); return verifier.VerifyBuffer("", false, CollisionVerify.Verify); }
public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
public Collision __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
@@ -70,4 +71,14 @@ public class CollisionT
}
+static public class CollisionVerify
+{
+ static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
+ {
+ return verifier.VerifyTableStart(tablePos)
+ && verifier.VerifyField(tablePos, 4 /*Collision*/, 4 /*int*/, 4, false)
+ && verifier.VerifyTableEnd(tablePos);
+ }
+}
+
}
diff --git a/tests/union_value_collsion/union_value_collision_generated.cs b/tests/union_value_collsion/union_value_collision_generated.cs
index c49701eb..6dc1b406 100644
--- a/tests/union_value_collsion/union_value_collision_generated.cs
+++ b/tests/union_value_collsion/union_value_collision_generated.cs
@@ -37,6 +37,25 @@ public class ValueUnion {
}
}
+
+
+static public class ValueVerify
+{
+ static public bool Verify(Google.FlatBuffers.Verifier verifier, byte typeId, uint tablePos)
+ {
+ bool result = true;
+ switch((Value)typeId)
+ {
+ case Value.IntValue:
+ result = union_value_collsion.IntValueVerify.Verify(verifier, tablePos);
+ break;
+ default: result = true;
+ break;
+ }
+ return result;
+ }
+}
+
public class ValueUnion_JsonConverter : Newtonsoft.Json.JsonConverter {
public override bool CanConvert(System.Type objectType) {
return objectType == typeof(ValueUnion) || objectType == typeof(System.Collections.Generic.List<ValueUnion>);
@@ -106,6 +125,25 @@ public class OtherUnion {
}
}
+
+
+static public class OtherVerify
+{
+ static public bool Verify(Google.FlatBuffers.Verifier verifier, byte typeId, uint tablePos)
+ {
+ bool result = true;
+ switch((Other)typeId)
+ {
+ case Other.IntValue:
+ result = union_value_collsion.IntValueVerify.Verify(verifier, tablePos);
+ break;
+ default: result = true;
+ break;
+ }
+ return result;
+ }
+}
+
public class OtherUnion_JsonConverter : Newtonsoft.Json.JsonConverter {
public override bool CanConvert(System.Type objectType) {
return objectType == typeof(OtherUnion) || objectType == typeof(System.Collections.Generic.List<OtherUnion>);
@@ -198,6 +236,16 @@ public class IntValueT
}
}
+
+static public class IntValueVerify
+{
+ static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
+ {
+ return verifier.VerifyTableStart(tablePos)
+ && verifier.VerifyField(tablePos, 4 /*Value*/, 4 /*int*/, 4, false)
+ && verifier.VerifyTableEnd(tablePos);
+ }
+}
public struct Collide : IFlatbufferObject
{
private Table __p;
@@ -302,6 +350,17 @@ public class CollideT
}
}
+
+static public class CollideVerify
+{
+ static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
+ {
+ return verifier.VerifyTableStart(tablePos)
+ && verifier.VerifyString(tablePos, 4 /*Collide*/, true)
+ && verifier.VerifyString(tablePos, 6 /*Value*/, false)
+ && verifier.VerifyTableEnd(tablePos);
+ }
+}
public struct Collision : IFlatbufferObject
{
private Table __p;
@@ -309,6 +368,7 @@ public struct Collision : IFlatbufferObject
public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_23_3_3(); }
public static Collision GetRootAsCollision(ByteBuffer _bb) { return GetRootAsCollision(_bb, new Collision()); }
public static Collision GetRootAsCollision(ByteBuffer _bb, Collision obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
+ public static bool VerifyCollision(ByteBuffer _bb) {Google.FlatBuffers.Verifier verifier = new Google.FlatBuffers.Verifier(_bb); return verifier.VerifyBuffer("", false, CollisionVerify.Verify); }
public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
public Collision __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
@@ -454,4 +514,18 @@ public class CollisionT
}
+static public class CollisionVerify
+{
+ static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
+ {
+ return verifier.VerifyTableStart(tablePos)
+ && verifier.VerifyField(tablePos, 4 /*SomeValueType*/, 1 /*union_value_collsion.Value*/, 1, false)
+ && verifier.VerifyUnion(tablePos, 4, 6 /*SomeValue*/, union_value_collsion.ValueVerify.Verify, false)
+ && verifier.VerifyField(tablePos, 8 /*ValueType*/, 1 /*union_value_collsion.Other*/, 1, false)
+ && verifier.VerifyUnion(tablePos, 8, 10 /*Value*/, union_value_collsion.OtherVerify.Verify, false)
+ && verifier.VerifyVectorOfTables(tablePos, 12 /*Collide*/, union_value_collsion.CollisionVerify.Verify, false)
+ && verifier.VerifyTableEnd(tablePos);
+ }
+}
+
}
diff --git a/tests/union_vector/Attacker.cs b/tests/union_vector/Attacker.cs
index cb48863a..e1716a1d 100644
--- a/tests/union_vector/Attacker.cs
+++ b/tests/union_vector/Attacker.cs
@@ -58,3 +58,13 @@ public class AttackerT
}
}
+
+static public class AttackerVerify
+{
+ static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
+ {
+ return verifier.VerifyTableStart(tablePos)
+ && verifier.VerifyField(tablePos, 4 /*SwordAttackDamage*/, 4 /*int*/, 4, false)
+ && verifier.VerifyTableEnd(tablePos);
+ }
+}
diff --git a/tests/union_vector/Character.cs b/tests/union_vector/Character.cs
index 181f914a..f6e7c88a 100644
--- a/tests/union_vector/Character.cs
+++ b/tests/union_vector/Character.cs
@@ -50,6 +50,40 @@ public class CharacterUnion {
}
}
+
+
+static public class CharacterVerify
+{
+ static public bool Verify(Google.FlatBuffers.Verifier verifier, byte typeId, uint tablePos)
+ {
+ bool result = true;
+ switch((Character)typeId)
+ {
+ case Character.MuLan:
+ result = AttackerVerify.Verify(verifier, tablePos);
+ break;
+ case Character.Rapunzel:
+ result = verifier.VerifyUnionData(tablePos, 4, 4);
+ break;
+ case Character.Belle:
+ result = verifier.VerifyUnionData(tablePos, 4, 4);
+ break;
+ case Character.BookFan:
+ result = verifier.VerifyUnionData(tablePos, 4, 4);
+ break;
+ case Character.Other:
+ result = verifier.VerifyUnionString(tablePos);
+ break;
+ case Character.Unused:
+ result = verifier.VerifyUnionString(tablePos);
+ break;
+ default: result = true;
+ break;
+ }
+ return result;
+ }
+}
+
public class CharacterUnion_JsonConverter : Newtonsoft.Json.JsonConverter {
public override bool CanConvert(System.Type objectType) {
return objectType == typeof(CharacterUnion) || objectType == typeof(System.Collections.Generic.List<CharacterUnion>);
diff --git a/tests/union_vector/Gadget.cs b/tests/union_vector/Gadget.cs
index 8e5ca7b1..32f0d813 100644
--- a/tests/union_vector/Gadget.cs
+++ b/tests/union_vector/Gadget.cs
@@ -34,6 +34,28 @@ public class GadgetUnion {
}
}
+
+
+static public class GadgetVerify
+{
+ static public bool Verify(Google.FlatBuffers.Verifier verifier, byte typeId, uint tablePos)
+ {
+ bool result = true;
+ switch((Gadget)typeId)
+ {
+ case Gadget.FallingTub:
+ result = verifier.VerifyUnionData(tablePos, 4, 4);
+ break;
+ case Gadget.HandFan:
+ result = HandFanVerify.Verify(verifier, tablePos);
+ break;
+ default: result = true;
+ break;
+ }
+ return result;
+ }
+}
+
public class GadgetUnion_JsonConverter : Newtonsoft.Json.JsonConverter {
public override bool CanConvert(System.Type objectType) {
return objectType == typeof(GadgetUnion) || objectType == typeof(System.Collections.Generic.List<GadgetUnion>);
diff --git a/tests/union_vector/HandFan.cs b/tests/union_vector/HandFan.cs
index 63e10539..14cf69ff 100644
--- a/tests/union_vector/HandFan.cs
+++ b/tests/union_vector/HandFan.cs
@@ -58,3 +58,13 @@ public class HandFanT
}
}
+
+static public class HandFanVerify
+{
+ static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
+ {
+ return verifier.VerifyTableStart(tablePos)
+ && verifier.VerifyField(tablePos, 4 /*Length*/, 4 /*int*/, 4, false)
+ && verifier.VerifyTableEnd(tablePos);
+ }
+}
diff --git a/tests/union_vector/Movie.cs b/tests/union_vector/Movie.cs
index f77bc497..faa47fe0 100644
--- a/tests/union_vector/Movie.cs
+++ b/tests/union_vector/Movie.cs
@@ -14,6 +14,7 @@ public struct Movie : IFlatbufferObject
public static Movie GetRootAsMovie(ByteBuffer _bb) { return GetRootAsMovie(_bb, new Movie()); }
public static Movie GetRootAsMovie(ByteBuffer _bb, Movie obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
public static bool MovieBufferHasIdentifier(ByteBuffer _bb) { return Table.__has_identifier(_bb, "MOVI"); }
+ public static bool VerifyMovie(ByteBuffer _bb) {Google.FlatBuffers.Verifier verifier = new Google.FlatBuffers.Verifier(_bb); return verifier.VerifyBuffer("MOVI", false, MovieVerify.Verify); }
public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
public Movie __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
@@ -211,3 +212,15 @@ public class MovieT
}
}
+
+static public class MovieVerify
+{
+ static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
+ {
+ return verifier.VerifyTableStart(tablePos)
+ && verifier.VerifyField(tablePos, 4 /*MainCharacterType*/, 1 /*Character*/, 1, false)
+ && verifier.VerifyUnion(tablePos, 4, 6 /*MainCharacter*/, CharacterVerify.Verify, false)
+ && verifier.VerifyVectorOfData(tablePos, 8 /*CharactersType*/, 1 /*Character*/, false)
+ && verifier.VerifyTableEnd(tablePos);
+ }
+}