From 6fe6e06badaf565597fd77d49d9c9c9015882ae5 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Thu, 6 Aug 2026 23:45:35 +0200 Subject: [PATCH] Fix overflow computing the element count of a multi-dim array initializer HandleSimpleArrayInitializer multiplies the array dimensions to size the list it collects elements into. The dimensions come from the input assembly and need not multiply within int range, and ICSharpCode.Decompiler is built with CheckForOverflowUnderflow, so an implausible pair of dimensions aborted decompilation of the whole member. The product is only a capacity hint, so it can saturate. Found by fuzzing nuget.org; reproduces on obfuscated assemblies. Assisted-by: Claude:claude-opus-5[1m]:Claude Code --- .../TestCases/Pretty/MultidimensionalArray.cs | 10 ++++++++++ .../IL/Transforms/TransformArrayInitializers.cs | 4 +++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/MultidimensionalArray.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/MultidimensionalArray.cs index 3e32fdb44..e2086b1f2 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/MultidimensionalArray.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/MultidimensionalArray.cs @@ -52,5 +52,15 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty { return new int[10][,]; } + + // The dimensions multiply to more than int.MaxValue; the initializer transform + // must cope with that instead of overflowing while sizing its element list. + public int[,] DimensionsExceedingIntRange() + { + int[,] array = new int[65536, 65536]; + array[0, 0] = 1; + array[0, 1] = 2; + return array; + } } } \ No newline at end of file diff --git a/ICSharpCode.Decompiler/IL/Transforms/TransformArrayInitializers.cs b/ICSharpCode.Decompiler/IL/Transforms/TransformArrayInitializers.cs index 165141c41..b3a76661e 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/TransformArrayInitializers.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/TransformArrayInitializers.cs @@ -594,7 +594,9 @@ namespace ICSharpCode.Decompiler.IL.Transforms { instructionsToRemove = 0; int elementCount = 0; - int length = arrayLength.Aggregate(1, (t, l) => t * l); + // The dimensions come from the IL and need not multiply within int range. + // This is only a capacity hint, so saturate rather than overflow. + int length = arrayLength.Aggregate(1, (t, l) => (int)Math.Min((long)t * l, int.MaxValue)); // Cannot pre-allocate the result array, because we do not know yet, // whether there is in fact an array initializer. // To prevent excessive allocations, use min(|block|, arraySize) als initial capacity.