-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Remove unsafe code from Uri PrivateParseMinimal, CheckAuthorityHelper, and related helpers #121671
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -69,62 +69,55 @@ internal static bool CheckIriUnicodeRange(uint value, bool isQuery) | |||||
| public static bool IsInInclusiveRange(uint value, uint min, uint max) | ||||||
| => (value - min) <= (max - min); | ||||||
|
|
||||||
| // | ||||||
| // IRI normalization for strings containing characters that are not allowed or | ||||||
| // escaped characters that should be unescaped in the context of the specified Uri component. | ||||||
| // | ||||||
| internal static unsafe string EscapeUnescapeIri(char* pInput, int start, int end, bool isQuery) | ||||||
| internal static string EscapeUnescapeIri(ReadOnlySpan<char> span, bool isQuery) | ||||||
| { | ||||||
| Debug.Assert(end >= 0 && start >= 0 && start <= end); | ||||||
|
|
||||||
| int size = end - start; | ||||||
| var dest = size <= Uri.StackallocThreshold | ||||||
| var dest = span.Length <= Uri.StackallocThreshold | ||||||
| ? new ValueStringBuilder(stackalloc char[Uri.StackallocThreshold]) | ||||||
| : new ValueStringBuilder(size); | ||||||
| : new ValueStringBuilder(span.Length); | ||||||
|
|
||||||
| Span<byte> maxUtf8EncodedSpan = stackalloc byte[4]; | ||||||
|
|
||||||
| for (int i = start; i < end; ++i) | ||||||
| for (int i = 0; (uint)i < (uint)span.Length; i++) | ||||||
| { | ||||||
| char ch = pInput[i]; | ||||||
| char ch = span[i]; | ||||||
|
|
||||||
| if (ch == '%') | ||||||
| { | ||||||
| if (end - i > 2) | ||||||
| if ((uint)(i + 2) < (uint)span.Length) | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
To avoid re-computing
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
It does not with the proposed change.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @EgorBo can the JIT learn to elide the bound checks here (or in M2 in this demo)? |
||||||
| { | ||||||
| ch = UriHelper.DecodeHexChars(pInput[i + 1], pInput[i + 2]); | ||||||
| ch = UriHelper.DecodeHexChars(span[i + 1], span[i + 2]); | ||||||
|
|
||||||
| // Do not unescape a reserved char | ||||||
| if (ch == Uri.c_DummyChar || UriHelper.IsNotSafeForUnescape(ch)) | ||||||
| { | ||||||
| // keep as is | ||||||
| dest.Append(pInput[i++]); | ||||||
| dest.Append(pInput[i++]); | ||||||
| dest.Append(pInput[i]); | ||||||
| continue; | ||||||
| dest.Append(span[i]); | ||||||
| dest.Append(span[i + 1]); | ||||||
| dest.Append(span[i + 2]); | ||||||
| i += 2; | ||||||
| } | ||||||
| else if (ch <= '\x7F') | ||||||
| { | ||||||
| // ASCII | ||||||
| dest.Append(ch); | ||||||
| i += 2; | ||||||
| continue; | ||||||
| } | ||||||
| else | ||||||
| { | ||||||
| // possibly utf8 encoded sequence of unicode | ||||||
| int charactersRead = PercentEncodingHelper.UnescapePercentEncodedUTF8Sequence( | ||||||
| new ReadOnlySpan<char>(pInput + i, end - i), | ||||||
| span.Slice(i), | ||||||
EgorBo marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
| ref dest, | ||||||
| isQuery, | ||||||
| iriParsing: true); | ||||||
|
|
||||||
| Debug.Assert(charactersRead > 0); | ||||||
| i += charactersRead - 1; // -1 as i will be incremented in the loop | ||||||
| } | ||||||
| } | ||||||
| else | ||||||
| { | ||||||
| dest.Append(pInput[i]); | ||||||
|
|
||||||
| continue; | ||||||
| } | ||||||
| } | ||||||
| else if (ch > '\x7f') | ||||||
|
|
@@ -136,9 +129,9 @@ internal static unsafe string EscapeUnescapeIri(char* pInput, int start, int end | |||||
|
|
||||||
| char ch2 = '\0'; | ||||||
|
|
||||||
| if ((char.IsHighSurrogate(ch)) && (i + 1 < end)) | ||||||
| if ((char.IsHighSurrogate(ch)) && (uint)(i + 1) < (uint)span.Length) | ||||||
MihaZupan marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
| { | ||||||
| ch2 = pInput[i + 1]; | ||||||
| ch2 = span[i + 1]; | ||||||
| isInIriUnicodeRange = CheckIriUnicodeRange(ch, ch2, out surrogatePair, isQuery); | ||||||
| } | ||||||
| else | ||||||
|
|
@@ -179,12 +172,12 @@ internal static unsafe string EscapeUnescapeIri(char* pInput, int start, int end | |||||
| { | ||||||
| i++; | ||||||
| } | ||||||
|
|
||||||
| continue; | ||||||
| } | ||||||
| else | ||||||
| { | ||||||
| // ASCII, just copy the character | ||||||
| dest.Append(pInput[i]); | ||||||
| } | ||||||
|
|
||||||
| // ASCII, just copy the character | ||||||
| dest.Append(ch); | ||||||
| } | ||||||
|
|
||||||
| return dest.ToString(); | ||||||
|
|
||||||
Uh oh!
There was an error while loading. Please reload this page.