Don't panic in RowIterator when stored grapheme runs overflow the row#9995
Don't panic in RowIterator when stored grapheme runs overflow the row#9995anshul-garg27 wants to merge 1 commit intowarpdotdev:masterfrom
Conversation
|
I'm starting a first review of this pull request. You can view the conversation on Warp. I completed the review and no human review was requested for this pull request. Comment Powered by Oz |
There was a problem hiding this comment.
Overview
This PR replaces a RowIterator panic with graceful degradation and guards wide-character spacer marking at the row boundary.
Concerns
- The added regression test does not currently create a stored wide-character run, so it would not fail on the pre-fix panic path.
Verdict
Found: 0 critical, 1 important, 0 suggestions
Request changes
Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).
Powered by Oz
| let mut storage = FlatStorage::new(7, None, Some(2)); | ||
|
|
||
| let mut wide_cell = Cell::default(); | ||
| wide_cell.c = '日'; |
There was a problem hiding this comment.
Flags::WIDE_CHAR is set, so the new test doesn't exercise the overflow/spacer panic path and would pass before the fix.
| wide_cell.c = '日'; | |
| wide_cell.c = '日'; | |
| wide_cell.flags.insert(Flags::WIDE_CHAR); |
…he row Closes warpdotdev#9161. `Workspace::RowIterator::next` could abort the process via `panic!` when a stored row's grapheme runs implied more cells than the row actually held. The reporter's logs show the canonical case: 6 ASCII + 1 wide CJK + 135 ASCII grapheme runs claim 143 cell positions in a row whose length is 142, so once the iterator advances `row.occ` past the wide char's spacer the next `row.get_mut(row.occ)` returns `None` and we unconditionally panic. This regressed the auto-closed warpdotdev#8515 (same panic, same file, same line) and is reproducible whenever any CJK or emoji character sits at a row boundary. Two fixes in `crates/warp_terminal/src/model/grid/flat_storage/row_iterator.rs`: 1. Replace the `panic!` after the diagnostic `log::warn!` with a `break` so the partially-filled row is still returned. The terminal keeps running and the warning preserves the diagnostic context for tracking the underlying writer-side inconsistency separately. 2. Bounds-check the `WIDE_CHAR_SPACER` write at `row[idx + 1]`. When a wide grapheme is the last cell of a row, `idx + 1 == row.len()` and the existing `IndexMut` would panic via the `Row::index_mut` impl. The `WIDE_CHAR` flag is still set on the wide cell itself; we just skip the unreachable spacer cell. Adds `test_row_iterator_handles_wide_char_at_row_boundary_without_panicking` to `mod_tests.rs`, which constructs a 7-cell row whose final cell holds a wide CJK character, pushes it through `FlatStorage`, and asserts that `RowIterator::next` returns the row instead of panicking. The test is written to fail on the pre-fix code (the panic site fires inside `row[idx + 1].flags.insert`).
3789c06 to
4f369dd
Compare
|
Pushed The test now exercises the spacer-overflow panic path correctly. Verified by reverting the production fix in That panic comes from the
|
|
I'm re-reviewing this pull request in response to a review request. You can view the conversation on Warp. I reviewed this pull request and requested human review from: @warpdotdev/oss-maintainers. Comment Powered by Oz |
Oz no longer requests changes for this pull request after the latest automated review.
There was a problem hiding this comment.
Overview
This PR changes RowIterator to degrade gracefully when corrupted grapheme runs overrun a row and guards the wide-character spacer write at row boundaries. The added regression test covers a CJK wide character in the last cell and exercises the prior panic path.
Concerns
- None identified in the changed lines.
Verdict
Found: 0 critical, 0 important, 0 suggestions
Approve
Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).
Powered by Oz
Closes #9161.
Description
RowIterator::nextaborts the process viapanic!when a stored row's grapheme runs imply more cells than the row actually holds. The reporter's panic log captures the canonical case:The grapheme runs claim
6 * 1 + 1 * 2 + 135 * 1 = 143cell positions in a row whose length is142, so once the iterator advancesrow.occpast the wide character's spacer the nextrow.get_mut(row.occ)returnsNoneand we unconditionallypanic!(row_iterator.rs:100). This is the same panic site reported in the auto-closed #8515 (same file, same line) and is reproducible whenever any CJK / emoji grapheme sits at a row boundary on a row whose grapheme bookkeeping has gone out of sync with its allocated length (which the issue reporter hits daily on Windows).Fix
Two changes in
crates/warp_terminal/src/model/grid/flat_storage/row_iterator.rs:Replace the
panic!after the diagnosticlog::warn!with abreak. The partially-filled row is still returned, so the terminal keeps running. The pre-existing warning preserves the diagnostic context for tracking the underlying writer-side inconsistency separately — without aborting the user's session.Bounds-check the
WIDE_CHAR_SPACERwrite atrow[idx + 1]. When a wide grapheme is the last cell of a row,idx + 1 == row.len()and the existingrow[idx + 1].flags.insert(...)would panic via theRow::index_mutimpl regardless of the change above. TheWIDE_CHARflag is still set on the wide cell itself; we just skip the unreachable spacer cell.The reporter's specific row layout (6 ASCII + 1 wide + 135 ASCII overflowing a 142-cell row) is hit by both code paths. The combined fix means neither one aborts.
Testing
test_row_iterator_handles_wide_char_at_row_boundary_without_panicking(mod_tests.rs). It constructs a 7-cell row whose final cell holds the wide CJK character日, pushes it throughFlatStorage, and asserts thatRowIterator::nextreturns the row instead of panicking. The test fails on the pre-fix code via theIndexMutpanic at therow[idx + 1]spacer write.test_row_with_double_width_char,test_row_iteration):cargo fmt -p warp_terminal -- --checkpasses.cargo check --tests -p warp_terminalpasses.Server API
Agent Mode
Changelog Entries
CHANGELOG-BUG-FIX: Fixed a crash on Windows when terminal output containing CJK characters or emoji landed at a row boundary (regression of #8515).