Remove unsafe code from the Uri.UnescapeString helper#121261
Merged
MihaZupan merged 3 commits intodotnet:mainfrom Nov 3, 2025
Merged
Remove unsafe code from the Uri.UnescapeString helper#121261MihaZupan merged 3 commits intodotnet:mainfrom
MihaZupan merged 3 commits intodotnet:mainfrom
Conversation
Open
3 tasks
Contributor
There was a problem hiding this comment.
Pull Request Overview
This PR refactors the URI unescaping logic by:
- Introducing a simpler
Unescapemethod that unconditionally unescapes percent-encoded sequences - Removing the
UnescapeAllflag fromUnescapeModeenum - Renaming
CopyOnlytoNoneinUnescapeModeenum - Removing unused
unsafecode and theSystem.Runtime.InteropServicesimport - Consolidating various unescape code paths to use the new
Unescapemethod where full unescaping is desired
Key changes:
- New
UriHelper.Unescape()method provides simple unconditional unescaping - Callsites that previously used
UnescapeMode.Unescape | UnescapeMode.UnescapeAllnow use the simplerUnescape()method - The more complex
UnescapeString()method is retained for cases requiring conditional escaping/unescaping with reserved character handling
Reviewed Changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| UriHelper.cs | Adds new Unescape() method, refactors UnescapeString() to use span-based operations instead of pointers, removes unsafe code |
| UriExt.cs | Updates UnescapeDataString and TryUnescapeDataString to use new Unescape() method |
| UriEnumTypes.cs | Renames CopyOnly to None, removes UnescapeAll flag |
| Uri.cs | Updates multiple callsites to use new Unescape() method or simplified logic, removes pointer-based operations |
| PercentEncodingHelper.cs | Adds scoped modifier to parameter, minor cleanup |
Comments suppressed due to low confidence (1)
src/libraries/System.Private.Uri/src/System/Uri.cs:1081
- Potential index out of bounds exception for UNC paths. This code assumes index 1 contains a drive letter separator, but for UNC paths,
result[1]would be the second backslash character. This check should be conditional onIsDosPathor include bounds checking.
if (result[1] == '|')
result[1] = ':';
kronic
reviewed
Nov 1, 2025
EgorBo
reviewed
Nov 3, 2025
This was referenced Nov 3, 2025
Member
Author
|
/ba-g android timing out |
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 subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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.
Closes #31173
We have an
UnescapeStringhelper that escapes/unescapes input based on various flags (copy input as-is, unescape only, escape reserved chars, or both).This PR removes the use of unsafe code from this helper.
I also removed the "copy input as-is" and "unescape only" modes from this helper. For copy-only we just forward to
CopyTo/Appenddirectly, whereas "unescape only" gets a dedicated helper since it's a reasonably hot path (UnescapeDataStringcalls into this).Initial benchmarks look good (no meaningful difference): MihuBot/runtime-utils#1612
Alternating escaped/unescaped
Only unescaped
Escaped at start followed by unescaped