Browse Source

Add Issue3877 test and handle negative dict capacity

Added Issue3877 test to PrettyTestRunner and new test case source to verify dictionary initialization with negative capacity. Updated SwitchOnStringTransform to skip processing when a negative dictionary capacity is detected.
pull/3878/head
ds5678 2 months ago
parent
commit
898c2a3f9f
  1. 6
      ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs
  2. 65
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/Issue3877.cs
  3. 2
      ICSharpCode.Decompiler/IL/Transforms/SwitchOnStringTransform.cs

6
ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs

@ -836,6 +836,12 @@ namespace ICSharpCode.Decompiler.Tests
await RunForLibrary(cscOptions: cscOptions); await RunForLibrary(cscOptions: cscOptions);
} }
[Test]
public async Task Issue3877([ValueSource(nameof(roslyn2OrNewerWithNet40Options))] CompilerOptions cscOptions)
{
await RunForLibrary(cscOptions: cscOptions);
}
[Test] [Test]
public async Task AssemblyCustomAttributes([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions) public async Task AssemblyCustomAttributes([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
{ {

65
ICSharpCode.Decompiler.Tests/TestCases/Pretty/Issue3877.cs

@ -0,0 +1,65 @@
using System.Collections.Generic;
using System.Runtime.CompilerServices;
namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
{
internal static class Issue3877
{
[CompilerGenerated]
private static Dictionary<string, int> backingField;
public static void M(string s)
{
N(0);
if (s != null)
{
if (backingField == null)
{
#if OPT
backingField = new Dictionary<string, int>(-87) {
{ "string0", 0 },
{ "string1", 1 },
{ "string2", 2 },
{ "string3", 3 },
{ "string4", 4 }
};
#else
Dictionary<string, int> dictionary = new Dictionary<string, int>(-87);
dictionary.Add("string0", 0);
dictionary.Add("string1", 1);
dictionary.Add("string2", 2);
dictionary.Add("string3", 3);
dictionary.Add("string4", 4);
backingField = dictionary;
#endif
}
if (backingField.TryGetValue(s, out var value))
{
switch (value)
{
case 0:
N(10);
break;
case 1:
N(20);
break;
case 2:
N(30);
break;
case 3:
N(40);
break;
case 4:
N(50);
break;
}
}
}
N(60);
}
public static void N(int i)
{
}
}
}

2
ICSharpCode.Decompiler/IL/Transforms/SwitchOnStringTransform.cs

@ -818,6 +818,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms
if (!newObj.Arguments[0].MatchLdcI4(out valuesLength)) if (!newObj.Arguments[0].MatchLdcI4(out valuesLength))
return false; return false;
} }
if (valuesLength < 0)
return false;
values = new List<(string, int)>(valuesLength); values = new List<(string, int)>(valuesLength);
int i = 0; int i = 0;
while (MatchAddCall(dictionaryType, block.Instructions[i + 1], dictVar, out var index, out var value)) while (MatchAddCall(dictionaryType, block.Instructions[i + 1], dictVar, out var index, out var value))

Loading…
Cancel
Save