Skip to content

fix(lint): preserve opening-tag source bounds after multiline closes - #3917

Merged
jrusso1020 merged 2 commits into
heygen-com:mainfrom
harimkang:fix/lint-tag-source-bounds
Sep 14, 2026
Merged

fix(lint): preserve opening-tag source bounds after multiline closes#3917
jrusso1020 merged 2 commits into
heygen-com:mainfrom
harimkang:fix/lint-tag-source-bounds

Conversation

@harimkang

Copy link
Copy Markdown
Contributor

What

Preserve correct opening-tag source bounds in parseHtmlStructure (packages/lint/src/utils.ts) so the unclosed_tag_swallowed_element rule no longer misreports valid siblings after a multiline closing tag.

Fixes #3916.

Why

Reproduced with HyperFrames v0.8.36, official source f86aae655ae5aae7a9a2c124fa016f3bc30ebe52, and htmlparser2@10.1.0.

A closing tag with whitespace before > can leave Parser.startIndex inside that closing tag. The next opening tag then includes the preceding whitespace and > in its raw range, causing a valid sibling to trigger unclosed_tag_swallowed_element:

<span>A</span
    ><span>B</span>

How

Capture the original opening-name bounds in onopentagname, before attributes are scanned. Bound the search using HTML name delimiters while retaining < inside malformed names, and use the original name end for attributes: a lowercased Unicode name can have a different UTF-16 length. Implied opening tags retain their existing parser-reported ranges. The source text and the lint rule/severity remain unchanged.

Test plan

  • Unit tests added/updated
  • Manual testing performed
  • Documentation updated (not applicable)

Validation executed:

  • From packages/lint: node ../../node_modules/vitest/vitest.mjs run --config vitest.config.ts — 16 files, 651 tests passed.
  • From the repository root: node node_modules/typescript/bin/tsc --project packages/lint/tsconfig.json --noEmit --types node — passed.
  • npx --yes oxfmt@0.41.0 --check packages/lint/src/utils.ts packages/lint/src/utils.test.ts packages/lint/src/rules/core.test.ts and npx --yes oxlint@1.64.0 packages/lint/src/utils.ts packages/lint/src/utils.test.ts packages/lint/src/rules/core.test.ts — passed.
  • From packages/lint: node ../../node_modules/tsup/dist/cli-default.js — Node and browser lint entrypoints built successfully.

Tests cover adjacent and multiline closing tags, malformed names containing <, quoted < values, ignored markup inside a malformed close, implied p/br opens, Unicode lowercase expansion, and genuine missing->/unquoted-attribute negatives.

Capture explicit source name bounds before attributes are parsed. Preserve malformed names, Unicode lowercase expansion, and existing implied-tag ranges while retaining malformed-attribute lint failures.
@harimkang
harimkang force-pushed the fix/lint-tag-source-bounds branch from e3798b5 to 84d6226 Compare September 13, 2026 06:16

@jrusso1020 jrusso1020 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed revision 5721b91. No blocking findings.

The opening-name callback preserves original source boundaries, including Unicode names whose lowercase representation changes length (packages/lint/src/utils.ts:76). Regression tests retain genuine malformed-tag detection alongside the valid multiline-close cases (packages/lint/src/rules/core.test.ts:965).

Validation: all 651 lint tests passed with local workspace-source aliases. An independent adversarial pass compared source ranges with tokenizer offsets across 101,512 HTML inputs without mismatches, covering implied tags, malformed names, raw-text content, and quoted attributes.

— Codex

Verdict: APPROVE
Reasoning: The change fixes the false positive while preserving malformed-input detection; no introduced correctness issues were found.

@jrusso1020
jrusso1020 enabled auto-merge (squash) September 14, 2026 07:36
@jrusso1020
jrusso1020 merged commit f6041d7 into heygen-com:main Sep 14, 2026
48 checks passed
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.

lint: unclosed_tag_swallowed_element false positive after a multiline closing tag (v0.8.35+)

2 participants