spectreconsole / spectre.console

A .NET library that makes it easier to create beautiful console applications.
https://spectreconsole.net
MIT License
8.92k stars 454 forks source link

"Input string was not in a correct format" error with `AnsiConsole.Write()` #1495

Open codeconscious opened 3 months ago

codeconscious commented 3 months ago

Information

Describe the bug A string containing the text {Pt.1} (TEST ~ 855D) causes AnsiConsole.Write() to throw the following exception:

System.FormatException: Input string was not in a correct format. Failure to parse near offset 1. Expected an ASCII digit.
   at System.Text.ValueStringBuilder.AppendFormatHelper(IFormatProvider provider, String format, ReadOnlySpan`1 args)
   at System.String.FormatHelper(IFormatProvider provider, String format, ReadOnlySpan`1 args)
   at System.String.Format(IFormatProvider provider, String format, Object[] args)
   at Spectre.Console.AnsiConsole.Write(IFormatProvider provider, String format, Object[] args) in /_/src/Spectre.Console/AnsiConsole.Write.cs:line 247
   at Spectre.Console.AnsiConsole.Write(String format, Object[] args) in /_/src/Spectre.Console/AnsiConsole.Write.cs:line 235
   at Spectre.Console.AnsiConsole.Write(String value) in /_/src/Spectre.Console/AnsiConsole.Write.cs:line 14

Interestingly, this does not occur with AnsiConsole.WriteLine(). Also, using EscapeMarkup() on the string does not resolve the issue.

Similarly-formatted strings behave identically. I believe it's likely some of the text is unexpectedly being treated as markup.

I hope this is information is sufficient. Please let me know if you need anything more or if perhaps I'm overlooking anything (including a potential workaround). Thank you much.

To Reproduce

string text = @"{Pt.1} (TEST ~ 855D)";
AnsiConsole.WriteLine(text); // OK
AnsiConsole.WriteLine(text.EscapeMarkup()); // OK
AnsiConsole.Write(text); // Throws the error
AnsiConsole.Write(text.EscapeMarkup()); // Throws the error

Expected behavior All lines written successfully to the terminal with markup-like text not treated as markup.

Screenshots None.

Additional context None.


Please upvote :+1: this issue if you are interested in it.

BlazeFace commented 2 months ago

In this case the AnsiConsole.Write() is calling an internal function that is using format strings. Trying "{{Pt.1}} (TEST ~ 855D)" will return {Pt.1} (TEST ~ 855D)

codeconscious commented 2 months ago

In this case the AnsiConsole.Write() is calling an internal function that is using format strings. Trying "{{Pt.1}} (TEST ~ 855D)" will return {Pt.1} (TEST ~ 855D)

Thanks for the tip! Indeed, I confirmed that this workaround for Write works:

var text = @"{{Pt.1}} (TEST ~ 855D)";
AnsiConsole.WriteLine(text);
AnsiConsole.WriteLine(text.EscapeMarkup());
AnsiConsole.Write(text + Environment.NewLine);
AnsiConsole.Write(text.EscapeMarkup() + Environment.NewLine);

Output:

{{Pt.1}} (TEST ~ 855D)
{{Pt.1}} (TEST ~ 855D)
{Pt.1} (TEST ~ 855D)
{Pt.1} (TEST ~ 855D)