Skip to content

fix: prevent infinite loop in Segment._split_cells with non-unit characters#4066

Closed
thakoreh wants to merge 1 commit intoTextualize:masterfrom
thakoreh:fix/split-cells-infinite-loop
Closed

fix: prevent infinite loop in Segment._split_cells with non-unit characters#4066
thakoreh wants to merge 1 commit intoTextualize:masterfrom
thakoreh:fix/split-cells-infinite-loop

Conversation

@thakoreh
Copy link
Copy Markdown

@thakoreh thakoreh commented Apr 7, 2026

Problem

Fixes #3299

Segment._split_cells could enter an infinite loop when cutting at positions within multi-codepoint grapheme clusters (e.g. ZWJ sequences like 👨‍👩‍👧). The while True loop had no exit condition for cases where:

  1. out_by was not exactly 0, -1, or +1
  2. The cell_size checks didn't match the characters at the split position

This happens because some multi-codepoint clusters have intermediate positions where cell_size returns 0 (for combining characters and ZWJ), and the loop keeps adjusting pos without ever hitting the exact boundary.

Fix

  • Added bounds checking (pos < 0 and pos > len(text))
  • Added a max iteration guard (len(text) + 2) that falls back to splitting at the closest position
  • All 952 existing tests pass
  • Verified the fix with ZWJ sequences that previously caused hangs

Testing

from rich.segment import Segment

# Previously caused infinite loop
s = Segment('👨‍👩‍👧', None, None)
result = s.split_cells(2)
# Now returns in <1ms instead of hanging

…acters

Segment._split_cells could enter an infinite loop when cutting at
positions within multi-codepoint grapheme clusters (e.g. ZWJ sequences
like family emojis). The while True loop had no exit condition for
cases where out_by was not 0, -1, or +1 and the cell_size checks
didn't match.

Added bounds checking and a max iteration guard that falls back to
splitting at the closest position instead of looping forever.

Fixes Textualize#3299
@TomJGooding
Copy link
Copy Markdown
Contributor

TomJGooding commented Apr 7, 2026

Your example doesn't hang without these changes.

I suspect this was generated with AI - please see https://github.com/Textualize/rich/blob/master/AI_POLICY.md

@willmcgugan willmcgugan closed this Apr 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Segment._split_cells doesn't handle non-unit characters well

3 participants