diff --git a/net/FlatBuffers/FlatBufferVerify.cs b/net/FlatBuffers/FlatBufferVerify.cs index 15064e8a505..e32256725dd 100644 --- a/net/FlatBuffers/FlatBufferVerify.cs +++ b/net/FlatBuffers/FlatBufferVerify.cs @@ -684,10 +684,10 @@ public bool VerifyUnion(uint tablePos, short typeIdVOffset, short valueVOffset, { return false; } - // Check union data - offset = GetVOffset(tablePos, valueVOffset); // Take type id var typeId = verifier_buffer.Get(Convert.ToInt32(offset)); + // Check union data + offset = GetVOffset(tablePos, valueVOffset); if (offset == 0) { // When value data is not present, allow union verification function to deal with illegal offset diff --git a/tests/FlatBuffers.Test/FlatBuffersExampleTests.cs b/tests/FlatBuffers.Test/FlatBuffersExampleTests.cs index 33d524358fb..5efd0319ddd 100644 --- a/tests/FlatBuffers.Test/FlatBuffersExampleTests.cs +++ b/tests/FlatBuffers.Test/FlatBuffersExampleTests.cs @@ -1194,5 +1194,35 @@ public void SortKey_WithDefaultedValue_IsFindable() { Assert.AreEqual(monster.ScalarKeySortedTablesByKey(i).Value.Count, i); } } + + [FlatBuffersTestMethod] + public void TestVerifyingUnions() + { + var fbb = new FlatBufferBuilder(1); + var name_inner = fbb.CreateString("inner"); + var name_outer = fbb.CreateString("outer"); + Monster.StartMonster(fbb); + Monster.AddName(fbb, name_inner); + var monster_inner = Monster.EndMonster(fbb); + Monster.StartMonster(fbb); + Monster.AddName(fbb, name_outer); + Monster.AddTest(fbb, monster_inner.Value); + Monster.AddTestType(fbb, Any.Monster); + var monster_outer = Monster.EndMonster(fbb); + fbb.Finish(monster_outer.Value); + var bytes = fbb.SizedByteArray(); + var bytes_to_corrupt_inner_name = fbb.SizedByteArray(); + var bytes_to_corrupt_outer_name = fbb.SizedByteArray(); + + bytes_to_corrupt_inner_name[bytes.Length - name_inner.Value] = 0xFF; + bytes_to_corrupt_outer_name[bytes.Length - name_outer.Value] = 0xFF; + var valid = Monster.VerifyMonster(new ByteBuffer(bytes)); + var valid_after_inner_corrupt = Monster.VerifyMonster(new ByteBuffer(bytes_to_corrupt_inner_name)); + var valid_after_outer_corrupt = Monster.VerifyMonster(new ByteBuffer(bytes_to_corrupt_outer_name)); + + Assert.IsTrue(valid); + Assert.IsFalse(valid_after_inner_corrupt); + Assert.IsFalse(valid_after_outer_corrupt); + } } }