Skip to content

Report tree-construction parse errors for dropped tokens and misnesting (0.4.0) - #4

Merged
casoon merged 1 commit into
masterfrom
fix/report-dropped-end-tags
Sep 14, 2026
Merged

casoon merged 1 commit into
masterfrom
fix/report-dropped-end-tags

Conversation

@casoon

@casoon casoon commented Sep 14, 2026

Copy link
Copy Markdown
Owner

Summary

The tree builder ignored many tokens, and ran the adoption agency algorithm's error steps, without recording the parse error the WHATWG spec requires (§13.2.6). This PR records those errors. Tree construction does not change.

html-conform needs this. It pins =0.3.0 and currently can't report a stray </div> or misnested <b><i>…</b></i>, which vnu flags.

New ParseErrorKind variants (the enum is #[non_exhaustive])

Variant Spec
StrayStartTag §13.2.6.4.7 "in body": html / body / frameset start tags ("Parse error."), caption/col/colgroup/frame/head/tbody/td/tfoot/th/thead/tr ("Parse error. Ignore the token."), nested select; §13.2.6.4.4–.6: a second head / noscript
NestedFormattingElement §13.2.6.4.7: a start tag while an a is still in the active formatting list; nobr while a nobr is in scope
MisnestedFormattingElement adoption agency step 4.6 ("formattingElement is not the current node")
FormattingElementNotInScope adoption agency step 4.5

Existing kinds, now reported at more sites

  • StrayEndTag:
    • §13.2.6.4.7 end-tag rules with no matching element in scope: the addressul group incl. div/header/select, plus li, dd/dt, h1h6, form (all three branches), applet/marquee/object, body, html;
    • "any other end tag" in "before html", "before head", "in head", "in head noscript", "after head" and "in template";
    • </template> in head with no template open;
    • adoption agency step 4.4.
  • StrayEndTagInTable / MisplacedTokenInTable: tokens ignored in "in table" (</table> out of scope, <form>), "in caption", "in column group", "in table body", "in row" and "in cell".
  • StrayDoctype: a DOCTYPE in foreign content (§13.2.6.5).

Not covered here

These are spec parse errors where the token is not dropped, e.g. "current node is not an X element" on a matching end tag, or "after after body" reprocessing. Also not covered: frameset modes, and U+0000 in body, which the tokenizer already reports at the same position.

Numbers

  • html5lib-tests tree conformance: 1,726/1,726, unchanged. No tree-shape change.
  • html5lib-tests #errors counts, measured with a throwaway harness (not committed):
    • exact matches: 482 → 568 of 1,726 cases;
    • errors reported: 1,641 → 2,144 (expected 3,806);
    • cases reporting more errors than expected: 53 → 53.
  • cargo test: 267 lib tests (9 new), plus conformance.
  • cargo fmt --check and cargo clippy --all-targets -- -D warnings pass.
  • cargo publish --dry-run passes.

Version: 0.4.0

The API change is additive only (ParseErrorKind is #[non_exhaustive]). Behaviour does change: ParseResult::errors returns more entries for the same input. That is the same kind of change that took 0.2.0 to 0.3.0, so this is a minor (0.x-breaking) bump rather than 0.3.1. The PR also adds CHANGELOG.md.

Not published or tagged.

Records the WHATWG §13.2.6 parse errors at every site where the tree
builder ignored a token or ran the adoption agency algorithm's error
steps without reporting anything. Tree construction is unchanged:
html5lib-tests conformance stays at 1,726/1,726.

New ParseErrorKind variants (the enum is #[non_exhaustive]):
- StrayStartTag: html/body/frameset in body, a second head, table
  structure tags outside a table, a nested select.
- NestedFormattingElement: <a> while an a is still active, <nobr>
  while one is in scope.
- MisnestedFormattingElement: adoption agency step 4.6.
- FormattingElementNotInScope: adoption agency step 4.5.

Existing kinds now reported at more sites:
- StrayEndTag: the "in body" end-tag rules with no matching element in
  scope (</div>, </li>, </dd>, </h1>-</h6>, </form>, </object>,
  </body>, </html>, ...), "any other end tag" in the head-phase modes
  and "in template", and adoption agency step 4.4.
- StrayEndTagInTable / MisplacedTokenInTable: tokens ignored by the
  caption, column group, table body, row and cell modes; <form> in a
  table.
- StrayDoctype: a DOCTYPE in foreign content.

close_table_body/close_row now return bool like close_caption, so the
callers can report the ignored-token error; no behaviour change.

html5lib-tests error counts: exact matches 482 -> 568 of 1,726 cases,
reported errors 1,641 -> 2,144 (expected 3,806), cases reporting more
errors than expected unchanged at 53.

Bump to 0.4.0: ParseResult::errors changes for the same input, the
same kind of change that took 0.2.0 to 0.3.0. Add CHANGELOG.md.
@casoon
casoon merged commit 45ecfb0 into master Sep 14, 2026
2 checks passed
@casoon
casoon deleted the fix/report-dropped-end-tags branch September 14, 2026 05:45
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