Handle negative dictionary capacity in string switch transform - #3878
Merged
Conversation
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.
Contributor
There was a problem hiding this comment.
Pull request overview
This PR fixes a decompiler crash in the string-switch dictionary-pattern transform when the dictionary constructor is given a negative capacity, by treating that pattern as non-matchable and adding a regression test to ensure decompilation completes successfully.
Changes:
- Prevent
SwitchOnStringTransform.ExtractStringValuesFromInitBlockfrom constructing aListwith a negative capacity by rejecting negativevaluesLength. - Add a new Pretty test case (
Issue3877) that includes a negative dictionary capacity in the legacy string-switch pattern. - Register the new test in
PrettyTestRunnerso it runs across Roslyn 2+ (including net40 variants).
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| ICSharpCode.Decompiler/IL/Transforms/SwitchOnStringTransform.cs | Adds a guard to avoid List<T>(capacity) throwing on negative capacities during pattern matching. |
| ICSharpCode.Decompiler.Tests/TestCases/Pretty/Issue3877.cs | New regression test input/expected-output file reproducing the negative-capacity pattern. |
| ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs | Adds the Issue3877 NUnit test to ensure coverage across relevant compiler option sets. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Member
|
Thank you very much for the contribution! |
siegfriedpammer
added a commit
that referenced
this pull request
Jul 13, 2026
MatchSwitchOnCharBlock's case 2 and default paths guarded against a negative character index, but case 1 (a bare switch on get_Chars) did not. Crafted IL whose get_Chars/get_Item index is negative - a value no compiler emits, but valid IL - therefore reached the pattern reconstruction unchecked. For a length-1 group this silently miscompiled the switch (it rebuilds the string switch from the char labels without using the index), turning IL that reads s[-1] into `switch (s)`; for longer strings it threw IndexOutOfRangeException and aborted the method. Move the check into MatchGetChars so all three call sites reject a negative index by construction, and drop the two now-redundant guards. Same class of unvalidated-integer robustness issue as #3878, in a different switch-on-string pattern. Assisted-by: Claude:claude-opus-4-8:Claude Code
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Resolves #3877
Solution