fix(gateway): reject oversized sparse array total_length with InvalidArgument
Guard against proto uint32 total_length values that exceed Array.MaxLength before casting; the previous checked cast threw OverflowException (gRPC Internal) instead of the intended InvalidArgument. Adds tests for the new guard, for the null-value ArgumentNullException path, and removes the checked keyword (redundant after the guard).
This commit is contained in:
@@ -62,7 +62,13 @@ internal static class SparseArrayExpander
|
||||
throw Invalid($"Sparse array element_data_type '{elementType}' is not a supported scalar element type.");
|
||||
}
|
||||
|
||||
int length = checked((int)totalLength);
|
||||
if (totalLength > (uint)Array.MaxLength)
|
||||
{
|
||||
throw Invalid(
|
||||
$"Sparse array total_length {totalLength} exceeds the maximum supported array length {Array.MaxLength}.");
|
||||
}
|
||||
|
||||
int length = (int)totalLength;
|
||||
HashSet<uint> seenIndices = new();
|
||||
|
||||
foreach (MxSparseElement element in sparse.Elements)
|
||||
|
||||
@@ -192,4 +192,19 @@ public sealed class SparseArrayExpanderTests
|
||||
Assert.Equal(MxValue.KindOneofCase.Int32Value, value.KindCase);
|
||||
Assert.Equal(42, value.Int32Value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Expand_NullValue_ThrowsArgumentNull()
|
||||
{
|
||||
Assert.Throws<ArgumentNullException>(() => SparseArrayExpander.Expand(null!));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Expand_TotalLengthExceedsMaxArrayLength_Throws()
|
||||
{
|
||||
MxValue value = SparseValue(MxDataType.Integer, 2_147_483_648u);
|
||||
|
||||
RpcException ex = Assert.Throws<RpcException>(() => SparseArrayExpander.Expand(value));
|
||||
Assert.Equal(StatusCode.InvalidArgument, ex.StatusCode);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user