diff options
author | tira-misu <gunter.burchardt@boschrexroth.de> | 2023-04-06 00:29:14 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-04-06 00:29:14 +0200 |
commit | 876a64aae138be5d9eb9245348719a18161d8e09 (patch) | |
tree | 14940818e1a6506eeb180150d610e41a06735732 | |
parent | 2803983c708ff6f4861c324597fd8e5f74660f67 (diff) | |
download | flatbuffers-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>
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); + } +} |