diff --git a/ICSharpCode.Decompiler/IL/Transforms/TransformArrayInitializers.cs b/ICSharpCode.Decompiler/IL/Transforms/TransformArrayInitializers.cs index 2c2983685..aae74209d 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/TransformArrayInitializers.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/TransformArrayInitializers.cs @@ -170,18 +170,25 @@ namespace ICSharpCode.Decompiler.IL.Transforms instructionsToRemove = 0; values = null; values = new ILInstruction[length]; - int index = 0; + int nextMinimumIndex = 0; int elementCount = 0; for (int i = pos; i < block.Instructions.Count; i++) { - if (index >= length) + if (nextMinimumIndex >= length) break; if (!block.Instructions[i].MatchStObj(out ILInstruction target, out ILInstruction value, out IType type) || value.Descendants.OfType().Any(inst => inst.Variable == store)) break; var ldelem = target as LdElema; - if (ldelem == null || !ldelem.Array.MatchLdLoc(store) || ldelem.Indices.Count != 1 || !ldelem.Indices[0].MatchLdcI4(out index)) + if (ldelem == null || !ldelem.Array.MatchLdLoc(store) || ldelem.Indices.Count != 1 || !ldelem.Indices[0].MatchLdcI4(out int index)) break; - values[index] = value; - index++; + // index must be in range [0..length[ and must be greater than or equal to nextMinimumIndex + // to avoid running out of bounds or accidentally reordering instructions or overwriting previous instructions. + // However, leaving array slots empty is allowed, as those are filled with default values when the + // initializer block is generated. + if (index < 0 || index >= length || index < nextMinimumIndex) + break; + nextMinimumIndex = index; + values[nextMinimumIndex] = value; + nextMinimumIndex++; elementCount++; instructionsToRemove++; }