Skip to content

Paragraph.SplitLines fails to split a string if it contains Japanese characters #1787

@Tyrrrz

Description

@Tyrrrz

Information

  • OS: Windows 11
  • Version: 0.49.1
  • Terminal: Windows Terminal (also see additional context)

Describe the bug

I'm using Spectre.Console.Progress to report progress on several parallel tasks:

https://github.com/Tyrrrz/DiscordChatExporter/blob/09e0b3f1334bcbe413c5e577f3e812fb19a0f62b/DiscordChatExporter.Cli/Commands/Base/ExportCommandBase.cs#L192-L245

It appears that, when a new task is started with the following description, Spectre.Console throws an exception:

神様達が下界に来る前は、魔法は特定の種族の専売特許に過ぎなかった。けれど、神様達の『恩恵』はいかなる者でも魔法を発現させることを可能としたのだ。

Exception:

System.ArgumentOutOfRangeException: Index and length must refer to a location within the string. (Parameter 'length')
   at System.String.ThrowSubstringArgumentOutOfRange(Int32 startIndex, Int32 length)
   at System.String.Substring(Int32 startIndex, Int32 length)
   at Spectre.Console.Rendering.Segment.SplitOverflow(Segment segment, Nullable`1 overflow, Int32 maxWidth) in /_/src/Spectre.Console/Rendering/Segment.cs:line 371
   at Spectre.Console.Paragraph.SplitLines(Int32 maxWidth) in /_/src/Spectre.Console/Widgets/Paragraph.cs:line 236
   at Spectre.Console.Paragraph.Render(RenderOptions options, Int32 maxWidth) in /_/src/Spectre.Console/Widgets/Paragraph.cs:line 141
   at Spectre.Console.Rendering.Renderable.Spectre.Console.Rendering.IRenderable.Render(RenderOptions options, Int32 maxWidth) in /_/src/Spectre.Console/Rendering/Renderable.cs:line 19
   at Spectre.Console.Markup.Render(RenderOptions options, Int32 maxWidth) in /_/src/Spectre.Console/Widgets/Markup.cs:line 54
   at Spectre.Console.Rendering.Renderable.Spectre.Console.Rendering.IRenderable.Render(RenderOptions options, Int32 maxWidth) in /_/src/Spectre.Console/Rendering/Renderable.cs:line 19
   at Spectre.Console.TableRenderer.Render(TableRendererContext context, List`1 columnWidths) in /_/src/Spectre.Console/Widgets/Table/TableRenderer.cs:line 31
   at Spectre.Console.Table.Render(RenderOptions options, Int32 maxWidth) in /_/src/Spectre.Console/Widgets/Table/Table.cs:line 147
   at Spectre.Console.Rendering.Renderable.Spectre.Console.Rendering.IRenderable.Render(RenderOptions options, Int32 maxWidth) in /_/src/Spectre.Console/Rendering/Renderable.cs:line 19
   at Spectre.Console.Rendering.JustInTimeRenderable.Render(RenderOptions context, Int32 width) in /_/src/Spectre.Console/Rendering/JustInTimeRenderable.cs:line 21
   at Spectre.Console.Rendering.Renderable.Spectre.Console.Rendering.IRenderable.Render(RenderOptions options, Int32 maxWidth) in /_/src/Spectre.Console/Rendering/Renderable.cs:line 19
   at Spectre.Console.TableRenderer.Render(TableRendererContext context, List`1 columnWidths) in /_/src/Spectre.Console/Widgets/Table/TableRenderer.cs:line 31
   at Spectre.Console.Table.Render(RenderOptions options, Int32 maxWidth) in /_/src/Spectre.Console/Widgets/Table/Table.cs:line 147
   at Spectre.Console.Rendering.Renderable.Spectre.Console.Rendering.IRenderable.Render(RenderOptions options, Int32 maxWidth) in /_/src/Spectre.Console/Rendering/Renderable.cs:line 19
   at Spectre.Console.Rendering.JustInTimeRenderable.Render(RenderOptions context, Int32 width) in /_/src/Spectre.Console/Rendering/JustInTimeRenderable.cs:line 21
   at Spectre.Console.Rendering.Renderable.Spectre.Console.Rendering.IRenderable.Render(RenderOptions options, Int32 maxWidth) in /_/src/Spectre.Console/Rendering/Renderable.cs:line 19
   at Spectre.Console.Padder.Render(RenderOptions options, Int32 maxWidth) in /_/src/Spectre.Console/Widgets/Padder.cs:line 69
   at Spectre.Console.Rendering.Renderable.Spectre.Console.Rendering.IRenderable.Render(RenderOptions options, Int32 maxWidth) in /_/src/Spectre.Console/Rendering/Renderable.cs:line 19
   at Spectre.Console.Rendering.LiveRenderable.Render(RenderOptions options, Int32 maxWidth)+MoveNext() in /_/src/Spectre.Console/Live/LiveRenderable.cs:line 78
   at System.Collections.Generic.List`1.AddRange(IEnumerable`1 collection)
   at Spectre.Console.RenderableExtensions.GetSegments(IAnsiConsole console, RenderOptions options, IEnumerable`1 renderables) in /_/src/Spectre.Console/Extensions/RenderableExtensions.cs:line 37
   at Spectre.Console.RenderableExtensions.GetSegments(IRenderable renderable, IAnsiConsole console) in /_/src/Spectre.Console/Extensions/RenderableExtensions.cs:line 29
   at Spectre.Console.AnsiBuilder.Build(IAnsiConsole console, IRenderable renderable) in /_/src/Spectre.Console/Internal/Backends/Ansi/AnsiBuilder.cs:line 17
   at Spectre.Console.AnsiConsoleBackend.Write(IRenderable renderable) in /_/src/Spectre.Console/Internal/Backends/Ansi/AnsiConsoleBackend.cs:line 30
   at Spectre.Console.AnsiConsoleFacade.Write(IRenderable renderable) in /_/src/Spectre.Console/Internal/Backends/AnsiConsoleFacade.cs:line 40
   at Spectre.Console.ProgressContext.Refresh() in /_/src/Spectre.Console/Live/Progress/ProgressContext.cs:line 178
   at Spectre.Console.ProgressRefreshThread.Run() in /_/src/Spectre.Console/Live/Progress/ProgressRefreshThread.cs:line 45

I'm able to debug the callstack a bit and these are the last few frames that could be of interest:

Image

Image

Image

To Reproduce

I've decomposed the issue to the following simplest reproduction sample:

Segment.SplitOverflow(
            new Segment(
                "神様達が下界に来る前は、魔法は特定の種族の専売特許に過ぎなかった。けれど、神様達の『恩恵』はいかなる者でも魔法を発現させることを可能としたのだ。"
            ),
            Overflow.Ellipsis,
            118
        );

Expected behavior

There should be no exception.

Screenshots

See above.

Additional context

I've noticed that the issue is not reproduced in the JetBrains Rider's integrated terminal, where the Japanese characters are replaced by ?. However, that might be unrelated.

Original issue: Tyrrrz/DiscordChatExporter#1354


Please upvote 👍 this issue if you are interested in it.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status

    Todo 🕑

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions