diff --git a/src/Orleans.Core/Messaging/MessageSerializer.cs b/src/Orleans.Core/Messaging/MessageSerializer.cs index 76a41537569..943e0015a4e 100644 --- a/src/Orleans.Core/Messaging/MessageSerializer.cs +++ b/src/Orleans.Core/Messaging/MessageSerializer.cs @@ -301,13 +301,18 @@ private void Deserialize(ref Reader reader, Message result) internal List ReadCacheInvalidationHeaders(ref Reader reader) { - var n = (int)reader.ReadVarUInt32(); + var n = reader.ReadVarUInt32(); if (n > 0) { - var list = new List(n); - for (int i = 0; i < n; i++) + var count = Math.Min(n, (uint)Message.MaxCacheInvalidationHeaderEntries); + var list = new List((int)count); + for (uint i = 0; i < n; i++) { - list.Add(_grainAddressCacheUpdateCodec.ReadValue(ref reader, reader.ReadFieldHeader())); + var update = _grainAddressCacheUpdateCodec.ReadValue(ref reader, reader.ReadFieldHeader()); + if (i < count) + { + list.Add(update); + } } return list; diff --git a/test/Orleans.Core.Tests/Serialization/MessageSerializerTests.cs b/test/Orleans.Core.Tests/Serialization/MessageSerializerTests.cs index c8df3f640da..39d24a39ff5 100644 --- a/test/Orleans.Core.Tests/Serialization/MessageSerializerTests.cs +++ b/test/Orleans.Core.Tests/Serialization/MessageSerializerTests.cs @@ -276,6 +276,40 @@ public void MessageTest_CacheInvalidationHeader_RoundTripCompatibility() } } + [Fact, TestCategory("BVT")] + public void MessageTest_CacheInvalidationHeader_DeserializeCapsHeaderCount() + { + var fromNew = new List(); + for (var i = 0; i < Message.MaxCacheInvalidationHeaderEntries + 1; i++) + { + var grainId = GrainId.Create("test", i.ToString()); + fromNew.Add(new GrainAddressCacheUpdate( + GrainAddress.NewActivationAddress(SiloAddress.New(new IPEndPoint(IPAddress.Loopback, 11_000 + i), 11_000 + i), grainId), + GrainAddress.NewActivationAddress(SiloAddress.New(new IPEndPoint(IPAddress.Loopback, 22_000 + i), 22_000 + i), grainId))); + } + + using var writer1Session = _serializerSessionPool.GetSession(); + var writer = Writer.CreatePooled(writer1Session); + var message = new Message { CacheInvalidationHeader = fromNew }; + messageSerializer.WriteCacheInvalidationHeaders(ref writer, message); + writer.WriteVarUInt32(42); + writer.Commit(); + + using var reader1Session = _serializerSessionPool.GetSession(); + var reader = Reader.Create(writer.Output.AsReadOnlySequence(), reader1Session); + var toNew = messageSerializer.ReadCacheInvalidationHeaders(ref reader); + Assert.NotNull(toNew); + Assert.Equal(Message.MaxCacheInvalidationHeaderEntries, toNew.Count); + for (var i = 0; i < Message.MaxCacheInvalidationHeaderEntries; i++) + { + Assert.Equal(fromNew[i].InvalidGrainAddress, toNew[i].InvalidGrainAddress); + Assert.Equal(fromNew[i].ValidGrainAddress, toNew[i].ValidGrainAddress); + } + + Assert.Equal(42u, reader.ReadVarUInt32()); + writer.Dispose(); + } + private class MessageSerializerBackwardsCompatibilityStub { private readonly IFieldCodec _grainAddressCodec;