Skip to content

fix: handle CRLF line endings in code frame positions - #23219

Open
nyxst4ck wants to merge 1 commit into
vitejs:mainfrom
nyxst4ck:fix/codeframe-crlf
Open

fix: handle CRLF line endings in code frame positions#23219
nyxst4ck wants to merge 1 commit into
vitejs:mainfrom
nyxst4ck:fix/codeframe-crlf

Conversation

@nyxst4ck

Copy link
Copy Markdown

posToNumber() and generateCodeFrame() split source text with /\r?\n/g, but added one character for every line terminator when converting line/column data back to absolute offsets. With CRLF input, the offset therefore drifted by one character for every preceding line, which could underline the wrong range or produce an empty frame.

This change accounts for the actual terminator width at each source offset. It keeps LF behavior unchanged and makes posToNumber() consistent with numberToPos(), which already handles CRLF.

The regression coverage checks:

  • line/column conversion after a CRLF terminator;
  • equal code frames for the same absolute location in LF and CRLF sources;
  • a multi-line range rendered from a CRLF source.

Verification:

  • pnpm vitest run packages/vite/src/node/__tests__/utils.spec.ts — 123 passed.
  • pnpm exec eslint packages/vite/src/node/utils.ts packages/vite/src/node/__tests__/utils.spec.ts — passed.
  • pnpm --filter vite typecheck — passed across the package TypeScript projects.

No public API or documentation changes are required; this only corrects source-position accounting for an existing supported line-ending form.

`posToNumber` and `generateCodeFrame` split the source with `splitRE`
(`/\r?\n/g`) but then assumed every line terminator was a single
character when converting back to character offsets.

For a source using CRLF, the computed offset drifts by one character per
preceding line, so an error reported with a character offset (as done by
the SSR transform, terser, import analysis and the plugin container) is
highlighted on the wrong line, or produces an empty frame entirely when
the drift pushes the offset past the last line.

Use the actual terminator length at the current offset instead. This also
makes `posToNumber` round-trip with `numberToPos`, which already handled
CRLF correctly.
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