diff --git a/src/System.Private.CoreLib/shared/System/Text/StringBuilder.cs b/src/System.Private.CoreLib/shared/System/Text/StringBuilder.cs index 38d59450761..ec9d2c4b355 100644 --- a/src/System.Private.CoreLib/shared/System/Text/StringBuilder.cs +++ b/src/System.Private.CoreLib/shared/System/Text/StringBuilder.cs @@ -1538,7 +1538,6 @@ internal StringBuilder AppendFormatHelper(IFormatProvider? provider, string form int pos = 0; int len = format.Length; char ch = '\x0'; - StringBuilder? unescapedItemFormat = null; ICustomFormatter? cf = null; if (provider != null) @@ -1665,7 +1664,7 @@ internal StringBuilder AppendFormatHelper(IFormatProvider? provider, string form // Start of parsing of optional formatting parameter. // object? arg = args[index]; - string? itemFormat = null; + ReadOnlySpan itemFormatSpan = default; // used if itemFormat is null // Is current character a colon? which indicates start of formatting parameter. if (ch == ':') @@ -1678,67 +1677,40 @@ internal StringBuilder AppendFormatHelper(IFormatProvider? provider, string form // If reached end of text then error. (Unexpected end of text) if (pos == len) FormatError(); ch = format[pos]; - pos++; - // Is character a opening or closing brace? - if (ch == '}' || ch == '{') + if (ch == '}') { - if (ch == '{') - { - // Yes, is next character also a opening brace, then treat as escaped. eg {{ - if (pos < len && format[pos] == '{') - pos++; - else - // Error Argument Holes can not be nested. - FormatError(); - } - else - { - // Yes, is next character also a closing brace, then treat as escaped. eg }} - if (pos < len && format[pos] == '}') - pos++; - else - { - // No, then treat it as the closing brace of an Arg Hole. - pos--; - break; - } - } - - // Reaching here means the brace has been escaped - // so we need to build up the format string in segments - if (unescapedItemFormat == null) - { - unescapedItemFormat = new StringBuilder(); - } - unescapedItemFormat.Append(format, startPos, pos - startPos - 1); - startPos = pos; + // Argument hole closed + break; } - } - - if (unescapedItemFormat == null || unescapedItemFormat.Length == 0) - { - if (startPos != pos) + else if (ch == '{') { - // There was no brace escaping, extract the item format as a single string - itemFormatSpan = format.AsSpan(startPos, pos - startPos); + // Braces inside the argument hole are not supported + FormatError(); } + + pos++; } - else + + if (pos > startPos) { - unescapedItemFormat.Append(format, startPos, pos - startPos); - itemFormatSpan = itemFormat = unescapedItemFormat.ToString(); - unescapedItemFormat.Clear(); + itemFormatSpan = format.AsSpan(startPos, pos - startPos); } } - // If current character is not a closing brace then error. (Unexpected Character) - if (ch != '}') FormatError(); + else if (ch != '}') + { + // Unexpected character + FormatError(); + } + // Construct the output for this arg hole. pos++; string? s = null; + string? itemFormat = null; + if (cf != null) { - if (itemFormatSpan.Length != 0 && itemFormat == null) + if (itemFormatSpan.Length != 0) { itemFormat = new string(itemFormatSpan); }