fix(lsp): do not panic on positions that are out of range by dsherret · Pull Request #1267 · dprint/dprint · GitHub
Skip to content

fix(lsp): do not panic on positions that are out of range - #1267

Merged
dsherret merged 1 commit into
mainfrom
fix/lsp-position-clamping
Oct 1, 2026
Merged

dsherret merged 1 commit into
mainfrom
fix/lsp-position-clamping

Conversation

@dsherret

@dsherret dsherret commented Oct 1, 2026

Copy link
Copy Markdown
Member

LineIndex::offset used a position's character as is, without clamping it to the line. The language server protocol says a character past the end of a line means the end of that line, so these are valid requests that the server mishandled:

  • Range formatting "ab\ncd" with the range (0, 100)-(1, 0) made the start offset (100) greater than the end (3) and hit the assertion in TextRange::new, which panics.
  • An incremental change past the end of a line was applied at the wrong offset (silently corrupting the server's copy of the document) or panicked in String::replace_range when the offset was past the end of the text.
  • A position between the two UTF-16 code units of a surrogate pair gave an offset in the middle of a character, which panics when slicing.
  • A huge character value overflowed.

Now:

  • A position past the end of a line is the end of that line, excluding the line ending.
  • A position past the last line is the end of the text.
  • A position in the middle of a surrogate pair is the start of that character.
  • A range whose start is after its end is an error (logged, and range formatting returns no edits) instead of a panic.

LineIndex::offset no longer returns a Result because it can't fail anymore.

A position past the end of a line is valid in the language server
protocol and means the end of that line, but it was used as is. That
could make the start of a range after its end, which panicked, or
produce an offset past the end of the text or in the middle of a
character, which panicked or corrupted the stored text when applying an
incremental change.

Positions are now clamped to the end of their line, a position past the
last line is the end of the text, a position in the middle of a
surrogate pair is the start of the character, and a range whose start
is after its end is an error instead of a panic.
@dsherret
dsherret merged commit 45619ef into main Oct 1, 2026
16 checks passed
@dsherret
dsherret deleted the fix/lsp-position-clamping branch October 1, 2026 19:17
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