Skip to content

fix(macOS): prevent Replace crash when search highlight ranges are stale after body edits#247

Draft
cursor[bot] wants to merge 1 commit into
mainfrom
cursor/critical-bug-inspection-cc87
Draft

fix(macOS): prevent Replace crash when search highlight ranges are stale after body edits#247
cursor[bot] wants to merge 1 commit into
mainfrom
cursor/critical-bug-inspection-cc87

Conversation

@cursor
Copy link
Copy Markdown

@cursor cursor Bot commented May 13, 2026

Bug and impact

With the find bar open, editing the note body (without changing the search query) leaves lastSearchHighlightRanges populated from the last scrollToSearchMatch. Debounced markdown restyle calls reapplySearchHighlights(), which skips out-of-bounds ranges but does not shrink or refresh that array. Replace then called NSTextStorage.replaceCharacters(in:with:) with a stale NSRange, raising NSRangeException and terminating the app.

Root cause

Highlight bookkeeping assumed ranges stay valid until the next explicit highlight pass. Body edits can invalidate ranges without updating lastSearchHighlightRanges; reapplySearchHighlights only guards addAttribute and does not reconcile the cached array.

Fix

Before replacing, if the cached range no longer fits the storage length, call applySearchHighlights(query:focusIndex:) to recompute matches from the live document, then bail if there is still no valid range at the requested index.

Validation

  • Added test_replaceCurrentMatch_doesNotCrashWhenCachedHighlightRangeIsStaleAfterBodyEdit in EditorViewPendingStateConsumptionTests.swift (repro: search → full-body replace via storage → Replace notification).
  • macOS XCTest suite not executed in this Linux agent environment; CI should run Synapse tests on macOS.
Open in Web View Automation 

Find bar only reposts highlights when the query changes, not on every body
edit. Debounced restyle skips out-of-bounds cached ranges in reapplySearchHighlights
but leaves lastSearchHighlightRanges unchanged, so Replace could call
replaceCharacters with an invalid NSRange and abort the app.

Resync highlights before replace when the cached range no longer fits the
storage, and add a regression test.

Co-authored-by: Danny Peck <dannypeck@gmail.com>
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.

1 participant