Textualize/rich

[BUG] spinning forever in _split_cells with negative cut

Closed this issue · 6 comments

See tconbeer/harlequin#659
Started as of: #3521 in 13.9.2

Somehow, the _split_cells function is passed a negative value for cut and it sits in an infinite loop.

I don't really understand what this function is doing, but this patch worked well for me!

@@ -122,11 +122,11 @@
             A tuple of two segments.
         """
         text, style, control = segment
         _Segment = Segment
         cell_length = segment.cell_length
-        if cut >= cell_length:
+        if cut < 0 or cut >= cell_length:
             return segment, _Segment("", style, control)

         cell_size = get_character_cell_size

         pos = int((cut / cell_length) * len(text))

Thank you for your issue. Give us a little time to review it.

PS. You might want to check the FAQ if you haven't done so already.

This is an automated reply, generated by FAQtory

That may make the error go away, but it is unlikely to be the fix.

cut shouldn't be negative. I'd need to know what conditions led to split_cells being called with a negative value.

So it gets passed down from here: https://github.com/Textualize/textual/blob/6f5eb419a6dd48aa1727677360f67ad405c0bd51/src/textual/widgets/_text_area.py#L1218

Where scroll_x is 0, virtual_width is 0, and gutter_width is 3.

I suppose another place to enforce this could be in the crop function:
https://github.com/Textualize/textual/blob/6f5eb419a6dd48aa1727677360f67ad405c0bd51/src/textual/strip.py#L375-L376

Where the start is clamped to zero, but the end isn't clamped to the start?

        start = max(0, start)
+       end = max(start, end)
        end = self.cell_length if end is None else min(self.cell_length, end)

The issue was fixed in Textual. Thanks for the report.

I hope we solved your problem.

If you like using Rich, you might also enjoy Textual