Browse Source

InlineArrayTransform: Add more bounds checking

feature/inlinearrays
Siegfried Pammer 1 week ago
parent
commit
298c247355
  1. 35
      ICSharpCode.Decompiler/IL/Transforms/InlineArrayTransform.cs

35
ICSharpCode.Decompiler/IL/Transforms/InlineArrayTransform.cs

@ -93,7 +93,10 @@ namespace ICSharpCode.Decompiler.IL.Transforms
if (!MatchInlineArrayHelper(targetInst.Method, "InlineArrayAsReadOnlySpan", out var inlineArrayType)) if (!MatchInlineArrayHelper(targetInst.Method, "InlineArrayAsReadOnlySpan", out var inlineArrayType))
return false; return false;
if (targetInst.Arguments is not [var addrInst, LdcI4]) if (targetInst.Arguments is not [var addrInst, LdcI4 { Value: var length }])
return false;
if (length < 0 || length > inlineArrayType.GetInlineArrayLength())
return false; return false;
type = inlineArrayType; type = inlineArrayType;
@ -110,7 +113,10 @@ namespace ICSharpCode.Decompiler.IL.Transforms
if (!MatchInlineArrayHelper(targetInst.Method, "InlineArrayAsSpan", out var inlineArrayType)) if (!MatchInlineArrayHelper(targetInst.Method, "InlineArrayAsSpan", out var inlineArrayType))
return false; return false;
if (targetInst.Arguments is not [var addrInst, LdcI4]) if (targetInst.Arguments is not [var addrInst, LdcI4 { Value: var length }])
return false;
if (length < 0 || length > inlineArrayType.GetInlineArrayLength())
return false; return false;
type = inlineArrayType; type = inlineArrayType;
@ -135,28 +141,33 @@ namespace ICSharpCode.Decompiler.IL.Transforms
index = null; index = null;
isReadOnly = false; isReadOnly = false;
if (inst.Arguments is not [var addrInst, var indexInst]) if (inst.Arguments is not [var addrInst, LdcI4 { Value: var indexValue } indexInst])
return false; return false;
addr = addrInst;
index = indexInst;
if (MatchInlineArrayHelper(inst.Method, "InlineArrayElementRef", out var inlineArrayType)) if (MatchInlineArrayHelper(inst.Method, "InlineArrayElementRef", out var inlineArrayType))
{ {
isReadOnly = false; isReadOnly = false;
type = inlineArrayType; type = inlineArrayType;
addr = addrInst;
index = indexInst;
return true;
} }
else if (MatchInlineArrayHelper(inst.Method, "InlineArrayElementRefReadOnly", out inlineArrayType))
if (MatchInlineArrayHelper(inst.Method, "InlineArrayElementRefReadOnly", out inlineArrayType))
{ {
isReadOnly = true; isReadOnly = true;
type = inlineArrayType; type = inlineArrayType;
addr = addrInst; }
index = indexInst; else
return true; {
return false;
} }
return false; if (indexValue < 0 || indexValue >= inlineArrayType.GetInlineArrayLength())
{
return false;
}
return true;
} }
private static bool MatchInlineArrayFirstElementRef(Call inst, [NotNullWhen(true)] out IType? type, [NotNullWhen(true)] out ILInstruction? addr, out bool isReadOnly) private static bool MatchInlineArrayFirstElementRef(Call inst, [NotNullWhen(true)] out IType? type, [NotNullWhen(true)] out ILInstruction? addr, out bool isReadOnly)

Loading…
Cancel
Save