diff --git a/Capnp.Net.Runtime.Tests/SerializationTests.cs b/Capnp.Net.Runtime.Tests/SerializationTests.cs index 67ae5bc..35983ca 100644 --- a/Capnp.Net.Runtime.Tests/SerializationTests.cs +++ b/Capnp.Net.Runtime.Tests/SerializationTests.cs @@ -16,7 +16,7 @@ namespace Capnp.Net.Runtime.Tests public class SerializationTests { [TestMethod] - public void ListOfBits() + public void ListOfBits1() { void CheckList(IEnumerable items) { @@ -69,6 +69,34 @@ namespace Capnp.Net.Runtime.Tests CheckList(list3); } + [TestMethod] + public void ListOfBits2() + { + var b = MessageBuilder.Create(); + var wrong = b.CreateObject(); + wrong.SetListOfValues(8, 7); + wrong.Allocate(); + Assert.ThrowsException(() => wrong.ListWriteValue(0, true)); + Assert.ThrowsException(() => wrong.ListWriteValues(new bool[7])); + var list = b.CreateObject(); + list.SetListOfValues(1, 70); + list.ListWriteValue(0, true); + Assert.ThrowsException(() => list.ListWriteValue(-1, true)); + Assert.ThrowsException(() => list.ListWriteValue(70, true)); + var values = new bool[70]; + values[63] = true; + values[65] = true; + list.ListWriteValues(values, true); + var los = list.Rewrap(); + Assert.IsTrue(!los[63]); + Assert.IsFalse(!los[64]); + Assert.IsTrue(!los[65]); + Assert.IsFalse(!los[66]); + Assert.ThrowsException(() => list.ListWriteValues(null)); + Assert.ThrowsException(() => list.ListWriteValues(new bool[1])); + Assert.ThrowsException(() => list.ListWriteValues(new bool[71])); + } + [TestMethod] public void ListOfCaps() { @@ -229,11 +257,72 @@ namespace Capnp.Net.Runtime.Tests Assert.AreEqual(3.0f, list3[3]); } + [TestMethod] + public void ListOfBytes() + { + var b = MessageBuilder.Create(); + var wrong = b.CreateObject(); + wrong.SetListOfValues(1, 64); + wrong.Allocate(); + Assert.ThrowsException(() => wrong.ListWriteValue(0, (byte)1)); + Assert.ThrowsException(() => wrong.ListGetBytes()); + var list = b.CreateObject(); + list.SetListOfValues(8, 3); + Assert.ThrowsException(() => list.ListWriteValue(-1, (byte)1)); + Assert.ThrowsException(() => list.ListWriteValue(64, (byte)1)); + list.ListWriteValue(1, (byte)1); + list.ListWriteValue(2, (byte)2); + CollectionAssert.AreEqual(new byte[] { 0, 1, 2 }, list.ListGetBytes().ToArray()); + } + + [TestMethod] + public void ListOfUShorts() + { + var b = MessageBuilder.Create(); + var wrong = b.CreateObject(); + wrong.SetListOfValues(1, 64); + wrong.Allocate(); + Assert.ThrowsException(() => wrong.ListWriteValue(0, (ushort)1)); + var list = b.CreateObject(); + list.SetListOfValues(16, 3); + Assert.ThrowsException(() => list.ListWriteValue(-1, (ushort)1)); + Assert.ThrowsException(() => list.ListWriteValue(64, (ushort)1)); + } + + [TestMethod] + public void ListOfUInts() + { + var b = MessageBuilder.Create(); + var wrong = b.CreateObject(); + wrong.SetListOfValues(1, 64); + wrong.Allocate(); + Assert.ThrowsException(() => wrong.ListWriteValue(0, 1u)); + var list = b.CreateObject(); + list.SetListOfValues(32, 3); + Assert.ThrowsException(() => list.ListWriteValue(-1, 1u)); + Assert.ThrowsException(() => list.ListWriteValue(64, 1u)); + } + + [TestMethod] + public void ListOfULongs() + { + var b = MessageBuilder.Create(); + var wrong = b.CreateObject(); + wrong.SetListOfValues(1, 64); + wrong.Allocate(); + Assert.ThrowsException(() => wrong.ListWriteValue(0, 1ul)); + var list = b.CreateObject(); + list.SetListOfValues(64, 3); + Assert.ThrowsException(() => list.ListWriteValue(-1, 1ul)); + Assert.ThrowsException(() => list.ListWriteValue(64, 1ul)); + } + [TestMethod] public void ListOfStructs1() { var b = MessageBuilder.Create(); var list = b.CreateObject>(); + Assert.ThrowsException(() => list.Init(-1)); Assert.ThrowsException(() => { var _ = list[0]; }); list.Init(4); @@ -273,6 +362,25 @@ namespace Capnp.Net.Runtime.Tests Assert.ThrowsException(() => list.StructWriteData(0, 1, 1)); } + [TestMethod] + public void ListOfStructs3() + { + var b = MessageBuilder.Create(); + var list = b.CreateObject>(); + Assert.ThrowsException(() => list.Any()); + list.Init(3); + int i = 0; + foreach (var item in list) + { + item.SomeText = i.ToString(); + Assert.AreEqual(item, list[i]); + ++i; + } + Assert.AreEqual("0", list[0].SomeText); + Assert.AreEqual("1", list[1].SomeText); + Assert.AreEqual("2", list[2].SomeText); + } + [TestMethod] public void ListOfText() { @@ -844,11 +952,13 @@ namespace Capnp.Net.Runtime.Tests } [TestMethod] - public void StructReadCapNoCapTable() + public void NoCapTable() { var dss = new DynamicSerializerState(MessageBuilder.Create()); dss.SetStruct(0, 1); Assert.ThrowsException(() => dss.ReadCap(0)); + Assert.ThrowsException(() => dss.ProvideCapability(new TestInterfaceImpl2())); + Assert.ThrowsException(() => dss.ProvideCapability(new TestInterface_Skeleton())); } [TestMethod] @@ -921,5 +1031,52 @@ namespace Capnp.Net.Runtime.Tests Assert.ThrowsException(() => dss.SetCapability(8)); Assert.ThrowsException(() => dss.SetCapability(null)); } + + [TestMethod] + public void StructReadData() + { + var mb = MessageBuilder.Create(); + var dss = mb.CreateObject(); + Assert.ThrowsException(() => dss.StructReadData(0, 1)); + dss.SetStruct(2, 0); + Assert.AreEqual(0ul, dss.StructReadData(0, 64)); + dss.Allocate(); + Assert.AreEqual(0ul, dss.StructReadData(0, 64)); + Assert.AreEqual(0ul, dss.StructReadData(256, 64)); + Assert.ThrowsException(() => dss.StructReadData(0, -1)); + Assert.ThrowsException(() => dss.StructReadData(1, 64)); + Assert.ThrowsException(() => dss.StructReadData(0, 65)); + Assert.ThrowsException(() => dss.StructReadData(ulong.MaxValue, 2)); + } + + [TestMethod] + public void TryGetPointer() + { + var mb = MessageBuilder.Create(); + var dss = mb.CreateObject(); + Assert.ThrowsException(() => dss.TryGetPointer(0)); + dss.SetStruct(0, 1); + Assert.IsNull(dss.TryGetPointer(0)); + Assert.ThrowsException(() => dss.TryGetPointer(1)); + } + + [TestMethod] + public void ListBuildStruct() + { + var mb = MessageBuilder.Create(); + var dss1 = mb.CreateObject(); + dss1.SetStruct(1, 1); + Assert.ThrowsException(() => dss1.ListBuildStruct(0)); + var dss2 = mb.CreateObject(); + dss2.SetListOfStructs(2, 1, 1); + var s0 = dss2.ListBuildStruct(0); + Assert.AreEqual(s0, dss2.ListBuildStruct(0)); + Assert.ThrowsException(() => dss2.ListBuildStruct(-1)); + Assert.ThrowsException(() => dss2.ListBuildStruct(2)); + var s1 = dss2.ListBuildStruct(1); + Assert.AreEqual(s1, dss2.ListBuildStruct(1)); + Assert.ThrowsException(() => dss2.ListBuildStruct(-1)); + Assert.ThrowsException(() => dss2.ListBuildStruct(2)); + } } } diff --git a/Capnp.Net.Runtime/SerializerState.cs b/Capnp.Net.Runtime/SerializerState.cs index b5323ee..b18ce3c 100644 --- a/Capnp.Net.Runtime/SerializerState.cs +++ b/Capnp.Net.Runtime/SerializerState.cs @@ -80,6 +80,7 @@ namespace Capnp { SegmentIndex = other.SegmentIndex; Offset = other.Offset; + WordsAllocated = other.WordsAllocated; ListElementCount = other.ListElementCount; StructDataCount = other.StructDataCount; StructPtrCount = other.StructPtrCount; @@ -712,6 +713,9 @@ namespace Capnp if (index >= data.Length) return 0; // Assume backwards-compatible change + if (count < 0) + throw new ArgumentOutOfRangeException(nameof(count)); + if (relBitOffset + count > 64) throw new ArgumentOutOfRangeException(nameof(count)); @@ -773,6 +777,9 @@ namespace Capnp if (Kind != ObjectKind.Struct && Kind != ObjectKind.ListOfPointers) throw new InvalidOperationException("This is not a struct or list of pointers"); + if (index < 0 || index >= _linkedStates!.Length) + throw new ArgumentOutOfRangeException(nameof(index)); + var state = _linkedStates![index]; if (state == null) return null; @@ -870,6 +877,9 @@ namespace Capnp if (Kind != ObjectKind.ListOfStructs) throw new InvalidOperationException("This is not a list of structs"); + if (index < 0 || index >= _linkedStates!.Length) + throw new ArgumentOutOfRangeException(nameof(index)); + ref var state = ref _linkedStates![index]; if (state == null) @@ -897,6 +907,9 @@ namespace Capnp if (Kind != ObjectKind.ListOfStructs) throw new InvalidOperationException("This is not a list of structs"); + if (index < 0 || index >= _linkedStates!.Length) + throw new ArgumentOutOfRangeException(nameof(index)); + ref var state = ref _linkedStates![index]; if (state == null) @@ -1045,7 +1058,7 @@ namespace Capnp /// /// The list bytes /// The underlying object was not set to a list of bytes. - Span ListGetBytes() + public Span ListGetBytes() { if (Kind != ObjectKind.ListOfBytes) throw new InvalidOperationException("This is not a list of bytes");