Fix CompositeFormat brace escaping ignored in string.Format fast-path#127819
Merged
Fix CompositeFormat brace escaping ignored in string.Format fast-path#127819
Conversation
Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/1f8d9a85-88f6-4bce-af71-d3c2e352c827 Co-authored-by: tarekgh <10833894+tarekgh@users.noreply.github.com>
Copilot
AI
changed the title
[WIP] Fix CompositeFormat escaping for curly braces
Fix CompositeFormat brace escaping ignored in string.Format fast-path
May 5, 2026
tarekgh
approved these changes
May 5, 2026
Contributor
|
Tagging subscribers to this area: @dotnet/area-system-runtime |
tannergooding
approved these changes
May 5, 2026
Member
|
/ba-g the failing iOS tests are not related. |
This was referenced May 6, 2026
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.
Fixes #127794
string.FormatwithCompositeFormatreturned the raw format string instead of unescaping{{→{and}}→}when no format holes were present.Root Cause
Two fast-paths in
String.Manipulation.csshort-circuit toformat.Format(the original unparsed string) without checking whether brace escaping occurred:args.Length == 0branch returnsformat.Formatunconditionally_formattedCount == 0guard in the privateFormat<TArg0,TArg1,TArg2>returnsformat.FormatunconditionallyStringBuilder.AppendFormatandMemoryExtensions.TryWritelack these fast-paths and work correctly by always iterating parsed segments.Fix
Both conditions additionally check
format._literalLength == format.Format.Length. When escaped braces are present, the unescaped literal length is shorter than the raw format string, so the condition isfalseand execution falls through to the correct segment-iteration path.Test Coverage
Three new entries in
Format_Valid_TestData(reused byStringFormat_Valid,StringBuilderAppendFormat_Valid, andMemoryExtensionsTryWrite_Valid):"{{""{""}}""}""{{text}}""{text}"