Skip to content

Commit 15635b5

Browse files
authored
Harden LWWDictionary serialization null check (#6837)
Harden LWWDictionary delta operation de/serialization with null checks to track down possible NRE bug
1 parent 309a495 commit 15635b5

File tree

2 files changed

+9
-4
lines changed

2 files changed

+9
-4
lines changed

src/contrib/cluster/Akka.DistributedData/LWWDictionary.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,7 @@ internal sealed class LWWDictionaryDelta : ORDictionary<TKey, LWWRegister<TValue
344344

345345
public LWWDictionaryDelta(ORDictionary<TKey, LWWRegister<TValue>>.IDeltaOperation underlying)
346346
{
347-
Underlying = underlying;
347+
Underlying = underlying ?? throw new ArgumentNullException(nameof(underlying), "Delta operation can not be null");
348348
if (underlying is IReplicatedDeltaSize s)
349349
{
350350
DeltaSize = s.DeltaSize;

src/contrib/cluster/Akka.DistributedData/Serialization/ReplicatedDataSerializer.cs

+8-3
Original file line numberDiff line numberDiff line change
@@ -990,13 +990,14 @@ private Proto.Msg.ORMapDeltaGroup ToProto(ORDictionary.IDeltaOperation op)
990990
{
991991
switch (op)
992992
{
993+
case null: throw new ArgumentNullException(nameof(op), $"Failed to serialize {nameof(ORDictionary.IDeltaOperation)} to protobuf");
993994
case ORDictionary.IPutDeltaOp p: return ORDictionaryPutToProto(p);
994995
case ORDictionary.IRemoveDeltaOp r: return ORDictionaryRemoveToProto(r);
995996
case ORDictionary.IRemoveKeyDeltaOp r: return ORDictionaryRemoveKeyToProto(r);
996997
case ORDictionary.IUpdateDeltaOp u: return ORDictionaryUpdateToProto(u);
997998
case ORDictionary.IDeltaGroupOp g: return ORDictionaryDeltasToProto(g.OperationsSerialization.ToList());
998999
default:
999-
throw new SerializationException($"Unrecognized delta operation [{op}]");
1000+
throw new SerializationException($"Unrecognized delta operation [({op.GetType().Name}):{op}]");
10001001
}
10011002

10021003
}
@@ -1273,8 +1274,12 @@ private object LWWDictionaryDeltaGroupFromBinary(byte[] bytes)
12731274

12741275
private ILWWDictionaryDeltaOperation LWWDictionaryDeltaFromProto<TKey, TValue>(ORDictionary.IDeltaOperation op)
12751276
{
1276-
var casted = (ORDictionary<TKey, LWWRegister<TValue>>.IDeltaOperation)op;
1277-
return new LWWDictionary<TKey, TValue>.LWWDictionaryDelta(casted);
1277+
return op switch
1278+
{
1279+
null => throw new ArgumentNullException(nameof(op), $"Failed to deserialize {nameof(ILWWDictionaryDeltaOperation)}"),
1280+
ORDictionary<TKey, LWWRegister<TValue>>.IDeltaOperation casted => new LWWDictionary<TKey, TValue>.LWWDictionaryDelta(casted),
1281+
_ => throw new ArgumentException($"Failed to cast cast {op.GetType().FullName} to {typeof(ORDictionary<TKey, LWWRegister<TValue>>.IDeltaOperation).FullName}")
1282+
};
12781283
}
12791284

12801285
#endregion

0 commit comments

Comments
 (0)