Skip to content

Fix CompositeFormat brace escaping ignored in string.Format fast-path#127819

Merged
tarekgh merged 2 commits intomainfrom
copilot/fix-compositeformat-escaping
May 6, 2026
Merged

Fix CompositeFormat brace escaping ignored in string.Format fast-path#127819
tarekgh merged 2 commits intomainfrom
copilot/fix-compositeformat-escaping

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 5, 2026

Fixes #127794

string.Format with CompositeFormat returned the raw format string instead of unescaping {{{ and }}} when no format holes were present.

Root Cause

Two fast-paths in String.Manipulation.cs short-circuit to format.Format (the original unparsed string) without checking whether brace escaping occurred:

  1. args.Length == 0 branch returns format.Format unconditionally
  2. _formattedCount == 0 guard in the private Format<TArg0,TArg1,TArg2> returns format.Format unconditionally

StringBuilder.AppendFormat and MemoryExtensions.TryWrite lack 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 is false and execution falls through to the correct segment-iteration path.

// Before:
0 => format.Format,

// After:
0 => format._literalLength == format.Format.Length
    ? format.Format
    : Format(provider, format, (object?)null, 0, 0, args),
// Before:
if (format._formattedCount == 0) { return format.Format; }

// After:
if (format._formattedCount == 0 && format._literalLength == format.Format.Length)
{ return format.Format; }

Test Coverage

Three new entries in Format_Valid_TestData (reused by StringFormat_Valid, StringBuilderAppendFormat_Valid, and MemoryExtensionsTryWrite_Valid):

Format Expected
"{{" "{"
"}}" "}"
"{{text}}" "{text}"

Copilot AI self-assigned this May 5, 2026
Copilot AI review requested due to automatic review settings May 5, 2026 18:00
Copilot AI review requested due to automatic review settings May 5, 2026 18:00
Copilot AI linked an issue May 5, 2026 that may be closed by this pull request
Copilot AI requested review from Copilot and removed request for Copilot May 5, 2026 18:48
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
Copilot finished work on behalf of tarekgh May 5, 2026 18:50
Copilot AI requested a review from tarekgh May 5, 2026 18:50
@dotnet-policy-service
Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @dotnet/area-system-runtime
See info in area-owners.md if you want to be subscribed.

@tarekgh
Copy link
Copy Markdown
Member

tarekgh commented May 6, 2026

/ba-g the failing iOS tests are not related.

@tarekgh tarekgh merged commit 2e33a3e into main May 6, 2026
142 of 151 checks passed
@tarekgh tarekgh deleted the copilot/fix-compositeformat-escaping branch May 6, 2026 01:27
Copilot AI review requested due to automatic review settings May 6, 2026 01:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

CompositeFormat escaping { or } does not work as expected

4 participants