fix: clamp completion range when scanner crosses tag boundary#247
Open
maruthang wants to merge 2 commits intomicrosoft:mainfrom
Open
fix: clamp completion range when scanner crosses tag boundary#247maruthang wants to merge 2 commits intomicrosoft:mainfrom
maruthang wants to merge 2 commits intomicrosoft:mainfrom
Conversation
When an attribute value has an unclosed quote but the scanner latches onto an unrelated later quote in the document, the completion replace range could still extend across HTML tag boundaries, wiping markup between the cursor and that later quote. Extend the clamp to also trigger when any '<' appears between the cursor and the alleged closing quote. Refs microsoft/vscode#273226 Signed-off-by: Maruthan G <maruthang4@gmail.com>
aeschli
requested changes
Apr 23, 2026
| // delete subsequent markup. See microsoft/vscode#273226. | ||
| let crossesTagBoundary = false; | ||
| for (let i = offset; i < valueEnd - 1; i++) { | ||
| if (text.charCodeAt(i) === 0x3C /* < */) { |
Collaborator
There was a problem hiding this comment.
use the constant in the htmlScanner
Signed-off-by: Maruthan G <maruthang4@gmail.com>
Contributor
Author
|
Done in 0365fb7 — exported |
Contributor
Author
|
Friendly ping @aeschli — addressed the inline comment in |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Follow-up to #239 for the same issue microsoft/vscode#273226. That PR handled the case where the attribute value has no closing quote anywhere; @federicobrancasi reported that the bug still reproduces in 1.117.0 Insiders when the document contains an unrelated later quote.
Root cause
In
htmlCompletion.tsthe replace range usesvalueEnd, which comes from the scanner. When the opening"of an attribute value has no matching close on the same logical context, the scanner continues across</tag>boundaries and latches onto the next"it finds — e.g. the opening"of a differenttitle="..."attribute elsewhere in the document. At that pointtext[valueEnd - 1] === text[valueStart]is true, so my previouselseclamp didn't trigger and the replace range spanned the entire intervening markup.Accepting
checkboxfrom a completion onwould produce
wiping out
</th><p. The regression test<th><input type="che|</th><p title="later"></p>(added in this PR) fails onmainwith exactly that output; see the test output in the repro notes below.Fix
Even when a matching closing quote is found, scan the stretch from the cursor to that quote. If any
<appears in that region, treat the value as unclosed and clampvalueContentEndtooffset. Any legitimate attribute-value content containing<would already be HTML-escaped to<, so an unescaped<in that region is a reliable signal that the scanner crossed a tag boundary.Changes
src/services/htmlCompletion.ts— detect tag-boundary-crossing between cursor and alleged closing quote; clamp tooffsetin that case.src/test/completion.test.ts— three regression tests:"on the same line (exact federicobrancasi scenario)"on a later line\nbefore the closing tagTesting
mainwith the expected buggy output before the fix is applied.npm test— 155/155 pass,npm run lintclean.Fixes microsoft/vscode#273226 (round two).