Skip to content

HTMLParser differences from the HTML5 specification #135661

Open
3 of 3 issues completed
Open

Description

@serhiy-storchaka

Bug report

Originally, the definition of the HTML format was not formally strict. It was similar to SGML and XML, but with a lot of looseness. HTMLParser tried its best to parse anything that looked like HTML. But after creation of HTML5, its specification defines the parsing rules for HTML documents, whether they are syntactically correct or not. It is important to follow these rules, for security reasons.

The current HTMLParser mainly follows the HTML5 specification, but there are a number of differences:

  1. ✅ --!> should end the comment. gh-102555: Fix comment parsing in HTMLParser #135664
  2. ✅ -- > should not end the comment. gh-102555: Fix comment parsing in HTMLParser #135664
  3. ✅ <--> and <---> should be abnormally ended empty comments. gh-102555: Fix comment parsing in HTMLParser #135664
  4. ✅ ] ]> and ]] > should not end the CDATA section. gh-135661: Fix CDATA section parsing in HTMLParser #135665
  5. 🤕 CDATA handling should depend on the current node. This is important, because the ending condition are different for the CDATA section and the bogus comment (]]> and >).
  6. ✅ Whitespaces should not be acceptable between </ and the tag name. E.g. </ script> should not end the script section. gh-135661: Fix parsing start and end tags in HTMLParser #135930
  7. ✅ Vertical tabulation (\v) and non-ASCII whitespaces should not be recognized as whitespaces. The only whitespaces are \t\n\r\f . gh-135661: Fix parsing start and end tags in HTMLParser #135930
  8. ✅ Null character (U+0000) should not end the tag name. gh-135661: Fix parsing start and end tags in HTMLParser #135930
  9. Null character (U+0000), surrogate characters and many other special characters should be replaced by \xfffd. I think we can leave this, because it is easy to do in pre-processing or post-processing, and they usually do not cause issues in Python.
  10. ✅ End tag can have attributes and slashes after tag name. It can not end after the first >. E.g. </script/foo=">"/>. gh-135661: Fix parsing start and end tags in HTMLParser #135930
  11. ✅ Case-insensitive matching should only transform ASCII letters. E.g. </script> does not match </ſcript>, and LINK does not match LINK (the last letter is U+212A). gh-135661: Fix parsing start and end tags in HTMLParser #135930
  12. ✅ There may be multiple slashes and whitespaces between the last attribute and closing > in both start and end tags. E.g. <a foo=bar/ //>. gh-135661: Fix parsing start and end tags in HTMLParser #135930
  13. ✅ There should only be one = separator between attribute name and value. E.g. <a foo==bar> should have attribute "foo" with value "=bar". gh-135661: Fix parsing start and end tags in HTMLParser #135930
  14. No whitespace should be acceptable between the = separator and attribute name and value. E.g. <a foo =bar> should have two attributes "foo" and "=bar", both with value None; <a foo= bar> should have two attributes: "foo" with value "" and "bar" with value None.

This can cause security issues for some programs. If the program uses HTMLParser to check the HTML input for dangerous code, it can miss some code. For example, "<!----!><script>...</script><!---->" is parsed by browsers as a script block surrounded by two comments, but the current HTMLParser parses it as a single comment.

Linked PRs

Activity

  1. added a commit that references this issue on Jul 3, 2025
  2. added 4 commits that reference this issue on Jul 3, 2025
  3. added a commit that references this issue on Jul 4, 2025
  4. added 3 commits that reference this issue on Jul 4, 2025
  5. added a commit that references this issue on Jul 11, 2025
  6. added 3 commits that reference this issue on Jul 12, 2025
  7. added a commit that references this issue on Jul 12, 2025
  8. added a commit that references this issue on Jul 13, 2025
  9. cjmayo commented on Jul 19, 2025

    @cjmayo

    14. No whitespace should be acceptable between the = separator and attribute name and value. E.g. <a foo =bar> should have two attributes "foo" and "=bar", both with value None; <a foo= bar> should have two attributes: "foo" with value "" and "bar" with value None.

    "Unquoted attribute value syntax", "Single-quoted attribute value syntax" and "Single-quoted attribute value syntax" [1] all currently (19 July 2025) say:

    The attribute name, followed by zero or more ASCII whitespace, followed by a single U+003D EQUALS SIGN character, followed by zero or more ASCII whitespace

    [1] https://html.spec.whatwg.org/multipage/syntax.html#attributes-2

  10. added a commit that references this issue on Jul 21, 2025
  11. serhiy-storchaka commented on Jul 21, 2025

    @serhiy-storchaka
    MemberAuthor

    Thank you for noticing this @cjmayo. You are right! And the parser specification agrees -- whitespaces are ignored in "after attribute name state" and "before attribute value state".

    https://html.spec.whatwg.org/multipage/parsing.html#attribute-name-state
    https://html.spec.whatwg.org/multipage/parsing.html#after-attribute-name-state
    https://html.spec.whatwg.org/multipage/parsing.html#before-attribute-value-state

    Fortunately there were no releases yet, so we can fix this in #136908.

  12. added a commit that references this issue on Jul 21, 2025
  13. added 5 commits that reference this issue on Jul 21, 2025
  14. added a commit that references this issue on Jul 21, 2025
  15. added a commit that references this issue on Jul 21, 2025
  16. hugovk commented on Jul 22, 2025

    @hugovk
    Member

    3.14 RC1 note: this has been fixed and backported to 3.14 (thank you!), let's keep the release-blocker for the older branches.

  17. serhiy-storchaka commented on Jul 22, 2025

    @serhiy-storchaka
    MemberAuthor

    There are also #135310 and #135665 which all are parts of the same issue.

  18. added 5 commits that reference this issue on Jul 22, 2025
  19. hugovk commented on Jul 22, 2025

    @hugovk
    Member

    One of these has been merged, the other needs more work and will also have security backports, so doesn't need to hold up the RC.

  20. added 2 commits that reference this issue on Jul 30, 2025
  21. added 2 commits that reference this issue on Aug 4, 2025
  22. Yhg1s commented on Aug 14, 2025

    @Yhg1s
    Member

    Does this need more work in 3.13? (Releasing another version today...)

  23. serhiy-storchaka commented on Aug 14, 2025

    @serhiy-storchaka
    MemberAuthor

    It would be nice to have all changes in one version.

  24. Yhg1s commented on Aug 14, 2025

    @Yhg1s
    Member

    Do I need to wait with 3.13 then? When can the remaining changes land, do you think?

  25. serhiy-storchaka commented on Aug 14, 2025

    @serhiy-storchaka
    MemberAuthor

    When the PR is approved. This is not a complete solution to the problem, but it is the only one we can have realistically. The discussion was about whether to make a new method public or private.

  26. Yhg1s commented on Aug 14, 2025

    @Yhg1s
    Member

    Have the other PRs all been backported, at least the ones that should be? (The long list makes it hard to tell.)

  27. serhiy-storchaka commented on Aug 14, 2025

    @serhiy-storchaka
    MemberAuthor

    Yes, all other PRs were successfully backported.

  28. added a commit that references this issue on Aug 14, 2025
  29. added 2 commits that reference this issue on Aug 14, 2025
  30. added 5 commits that reference this issue on Aug 14, 2025
  31. added a commit that references this issue on Aug 17, 2025
  32. added 2 commits that reference this issue on Aug 17, 2025
  33. added 4 commits that reference this issue on Aug 19, 2025
  34. added a commit that references this issue on Sep 8, 2025
  35. added 2 commits that reference this issue on Sep 9, 2025
  36. added a commit that references this issue on Oct 6, 2025
  37. added 3 commits that reference this issue on Oct 6, 2025
  38. added
    3.11only security fixes
    and removed
    3.13only security fixes
    3.14bugs and security fixes
    on Oct 6, 2025
  39. added 3 commits that reference this issue on Oct 7, 2025
  40. encukou commented on Oct 14, 2025

    @encukou
    Member

    All that remains is exposing the context-dependent CDATA parsing in some better way, but that's not a release blocker.

  41. added 4 commits that reference this issue on Jul 4, 2026
  42. serhiy-storchaka commented on Jul 4, 2026

    @serhiy-storchaka
    MemberAuthor

    #153028 provide complete fix of the CDATA issue on the stdlib side. I wonder if it can be backported.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

3.10 (EOL)end of life3.11only security fixes3.15bugs and security fixes3.9 (EOL)end of lifestdlibStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or errortype-securityA security issue

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions