Skip to content

Commit

Permalink
Harden LWWDictionary serialization null check (#6837)
Browse files Browse the repository at this point in the history
Harden LWWDictionary delta operation de/serialization with null checks to track down possible NRE bug
  • Loading branch information
Arkatufus authored Jul 14, 2023
1 parent 309a495 commit 15635b5
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 4 deletions.
2 changes: 1 addition & 1 deletion src/contrib/cluster/Akka.DistributedData/LWWDictionary.cs
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ internal sealed class LWWDictionaryDelta : ORDictionary<TKey, LWWRegister<TValue

public LWWDictionaryDelta(ORDictionary<TKey, LWWRegister<TValue>>.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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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}]");
}

}
Expand Down Expand Up @@ -1273,8 +1274,12 @@ private object LWWDictionaryDeltaGroupFromBinary(byte[] bytes)

private ILWWDictionaryDeltaOperation LWWDictionaryDeltaFromProto<TKey, TValue>(ORDictionary.IDeltaOperation op)
{
var casted = (ORDictionary<TKey, LWWRegister<TValue>>.IDeltaOperation)op;
return new LWWDictionary<TKey, TValue>.LWWDictionaryDelta(casted);
return op switch
{
null => throw new ArgumentNullException(nameof(op), $"Failed to deserialize {nameof(ILWWDictionaryDeltaOperation)}"),
ORDictionary<TKey, LWWRegister<TValue>>.IDeltaOperation casted => new LWWDictionary<TKey, TValue>.LWWDictionaryDelta(casted),
_ => throw new ArgumentException($"Failed to cast cast {op.GetType().FullName} to {typeof(ORDictionary<TKey, LWWRegister<TValue>>.IDeltaOperation).FullName}")
};
}

#endregion
Expand Down

0 comments on commit 15635b5

Please sign in to comment.