Skip to content

editor: Fix underflow panic in block map sync when blocks overlap#51078

Merged
Veykril merged 2 commits intomainfrom
veykril/push-xvuxwnuvrtso
Mar 9, 2026
Merged

editor: Fix underflow panic in block map sync when blocks overlap#51078
Veykril merged 2 commits intomainfrom
veykril/push-xvuxwnuvrtso

Conversation

@Veykril
Copy link
Copy Markdown
Member

@Veykril Veykril commented Mar 9, 2026

In BlockMap::sync, blocks within an edited region are sorted and processed sequentially. Each block placement computes rows_before_block by subtracting new_transforms.summary().input_rows from the block's target position. The Near/Below cases have a guard that skips the block if the target is already behind the current progress, but Above and Replace were missing this guard.

When a Replace block (tie_break 0) is processed before an Above block (tie_break 1) at the same or overlapping position, the Replace block consumes multiple input rows, advancing input_rows past the Above block's position. The subsequent position - input_rows subtraction underflows on u32, producing a huge RowDelta that wraps wrap_row_end past wrap_row_start, creating an inverted range that propagates through the display map layers and panics as begin <= end (47 <= 0) in a rope chunk slice.

Add underflow guards to Above and Replace, matching the existing pattern in Near/Below.

Release Notes:

  • Fixed a source of underflowing subtractions causing spurious panics

In `BlockMap::sync`, blocks within an edited region are sorted and
processed sequentially. Each block placement computes
`rows_before_block` by subtracting `new_transforms.summary().input_rows`
from the block's target position. The `Near`/`Below` cases have a guard
that skips the block if the target is already behind the current
progress, but `Above` and `Replace` were missing this guard.

When a `Replace` block (tie_break 0) is processed before an `Above`
block (tie_break 1) at the same or overlapping position, the `Replace`
block consumes multiple input rows, advancing `input_rows` past the
`Above` block's position. The subsequent `position - input_rows`
subtraction underflows on `u32`, producing a huge `RowDelta` that wraps
`wrap_row_end` past `wrap_row_start`, creating an inverted range that
propagates through the display map layers and panics as
`begin <= end (47 <= 0)` in a rope chunk slice.

Add underflow guards to `Above` and `Replace`, matching the existing
pattern in `Near`/`Below`.
@cla-bot cla-bot bot added the cla-signed The user has signed the Contributor License Agreement label Mar 9, 2026
@zed-community-bot zed-community-bot bot added the staff Pull requests authored by a current member of Zed staff label Mar 9, 2026
@Veykril Veykril enabled auto-merge (squash) March 9, 2026 08:36
@Veykril
Copy link
Copy Markdown
Member Author

Veykril commented Mar 9, 2026

/cherry-pick preview

@Veykril Veykril merged commit 8d5689a into main Mar 9, 2026
29 checks passed
@Veykril Veykril deleted the veykril/push-xvuxwnuvrtso branch March 9, 2026 08:45
github-actions bot pushed a commit that referenced this pull request Mar 9, 2026
…1078)

In `BlockMap::sync`, blocks within an edited region are sorted and
processed sequentially. Each block placement computes
`rows_before_block` by subtracting `new_transforms.summary().input_rows`
from the block's target position. The `Near`/`Below` cases have a guard
that skips the block if the target is already behind the current
progress, but `Above` and `Replace` were missing this guard.

When a `Replace` block (tie_break 0) is processed before an `Above`
block (tie_break 1) at the same or overlapping position, the `Replace`
block consumes multiple input rows, advancing `input_rows` past the
`Above` block's position. The subsequent `position - input_rows`
subtraction underflows on `u32`, producing a huge `RowDelta` that wraps
`wrap_row_end` past `wrap_row_start`, creating an inverted range that
propagates through the display map layers and panics as `begin <= end
(47 <= 0)` in a rope chunk slice.

Add underflow guards to `Above` and `Replace`, matching the existing
pattern in `Near`/`Below`.

Release Notes:

- Fixed a source of underflowing subtractions causing spurious panics
zed-zippy bot added a commit that referenced this pull request Mar 9, 2026
…1078) (cherry-pick to preview) (#51081)

Cherry-pick of #51078 to preview

----
In `BlockMap::sync`, blocks within an edited region are sorted and
processed sequentially. Each block placement computes
`rows_before_block` by subtracting `new_transforms.summary().input_rows`
from the block's target position. The `Near`/`Below` cases have a guard
that skips the block if the target is already behind the current
progress, but `Above` and `Replace` were missing this guard.

When a `Replace` block (tie_break 0) is processed before an `Above`
block (tie_break 1) at the same or overlapping position, the `Replace`
block consumes multiple input rows, advancing `input_rows` past the
`Above` block's position. The subsequent `position - input_rows`
subtraction underflows on `u32`, producing a huge `RowDelta` that wraps
`wrap_row_end` past `wrap_row_start`, creating an inverted range that
propagates through the display map layers and panics as `begin <= end
(47 <= 0)` in a rope chunk slice.

Add underflow guards to `Above` and `Replace`, matching the existing
pattern in `Near`/`Below`.

Release Notes:

- Fixed a source of underflowing subtractions causing spurious panics

Co-authored-by: Lukas Wirth <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cla-signed The user has signed the Contributor License Agreement staff Pull requests authored by a current member of Zed staff

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant