From 15635b5ffc98dfefb2efc1311a7016ffb956d372 Mon Sep 17 00:00:00 2001 From: Gregorius Soedharmo Date: Fri, 14 Jul 2023 21:34:07 +0700 Subject: [PATCH] Harden LWWDictionary serialization null check (#6837) Harden LWWDictionary delta operation de/serialization with null checks to track down possible NRE bug --- .../cluster/Akka.DistributedData/LWWDictionary.cs | 2 +- .../Serialization/ReplicatedDataSerializer.cs | 11 ++++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/contrib/cluster/Akka.DistributedData/LWWDictionary.cs b/src/contrib/cluster/Akka.DistributedData/LWWDictionary.cs index a2f9fc1e8e5..ec2d6a3b451 100644 --- a/src/contrib/cluster/Akka.DistributedData/LWWDictionary.cs +++ b/src/contrib/cluster/Akka.DistributedData/LWWDictionary.cs @@ -344,7 +344,7 @@ internal sealed class LWWDictionaryDelta : ORDictionary>.IDeltaOperation underlying) { - Underlying = underlying; + Underlying = underlying ?? throw new ArgumentNullException(nameof(underlying), "Delta operation can not be null"); if (underlying is IReplicatedDeltaSize s) { DeltaSize = s.DeltaSize; diff --git a/src/contrib/cluster/Akka.DistributedData/Serialization/ReplicatedDataSerializer.cs b/src/contrib/cluster/Akka.DistributedData/Serialization/ReplicatedDataSerializer.cs index e99ccfb1fd8..49967b48b8b 100644 --- a/src/contrib/cluster/Akka.DistributedData/Serialization/ReplicatedDataSerializer.cs +++ b/src/contrib/cluster/Akka.DistributedData/Serialization/ReplicatedDataSerializer.cs @@ -990,13 +990,14 @@ private Proto.Msg.ORMapDeltaGroup ToProto(ORDictionary.IDeltaOperation op) { switch (op) { + case null: throw new ArgumentNullException(nameof(op), $"Failed to serialize {nameof(ORDictionary.IDeltaOperation)} to protobuf"); case ORDictionary.IPutDeltaOp p: return ORDictionaryPutToProto(p); case ORDictionary.IRemoveDeltaOp r: return ORDictionaryRemoveToProto(r); case ORDictionary.IRemoveKeyDeltaOp r: return ORDictionaryRemoveKeyToProto(r); case ORDictionary.IUpdateDeltaOp u: return ORDictionaryUpdateToProto(u); case ORDictionary.IDeltaGroupOp g: return ORDictionaryDeltasToProto(g.OperationsSerialization.ToList()); default: - throw new SerializationException($"Unrecognized delta operation [{op}]"); + throw new SerializationException($"Unrecognized delta operation [({op.GetType().Name}):{op}]"); } } @@ -1273,8 +1274,12 @@ private object LWWDictionaryDeltaGroupFromBinary(byte[] bytes) private ILWWDictionaryDeltaOperation LWWDictionaryDeltaFromProto(ORDictionary.IDeltaOperation op) { - var casted = (ORDictionary>.IDeltaOperation)op; - return new LWWDictionary.LWWDictionaryDelta(casted); + return op switch + { + null => throw new ArgumentNullException(nameof(op), $"Failed to deserialize {nameof(ILWWDictionaryDeltaOperation)}"), + ORDictionary>.IDeltaOperation casted => new LWWDictionary.LWWDictionaryDelta(casted), + _ => throw new ArgumentException($"Failed to cast cast {op.GetType().FullName} to {typeof(ORDictionary>.IDeltaOperation).FullName}") + }; } #endregion