badges / badges/shields

Dynamic XML badge HTML mode fails on github.com pages (xmldom lacks HTML5 optional end-tag support)

Open
#12,063 1 comment 0 reactions 0 assignees View on GitHub
needs-upstream-help service-badge
Dominant language
JavaScript
Stars
27.2k
Forks
5.6k
Avg merge
1d 8h
Merged PRs (30d)
46

Description

### Are you experiencing an issue with...

shields.io

### 🐞 Description

The Dynamic XML badge's HTML-tolerant mode (`dynamic-xml.service.js`, using `@xmldom/xmldom`'s `DOMParser` with `contentType: 'text/html'`) fails to parse almost any real-world `github.com` page. The reason is that `@xmldom/xmldom` does not implement the HTML5 spec's "optional tags" rule, which allows elements like ``, `

  • `, ``, ``, and `

    ` to omit their closing tag because a following sibling implicitly closes them. See https://html.spec.whatwg.org/#optional-tags for the spec definition. This is a documented, acknowledged limitation in xmldom's own source comments (`lib/conventions.js`):

    > "xmldom does not have any logic for optional end tags cases (like `li`, `tr` and others)... will report them as a warning. Content that would go into the unopened element will instead be added as a sibling text node."

    In practice this throws, or produces an opaque empty message error rendered as "invalid", on virtually every `github.com` page that uses a ``/`` dropdown. That is nearly all of them (repo pages, org profiles, login, package pages, etc.), because those dropdowns rely on implied closing of ``. Only GitHub's separate docs style templates (e.g. `github.com/site/terms`) happen to avoid this and parse successfully.

    This makes it impossible to use Dynamic XML badges against most real world sites, not just github.com, that use standard, spec valid HTML5 markup relying on optional end tags. This is a very common markup pattern.

    ### 🔗 Link to the badge

    Failing (real GitHub pages, all valid HTML5):
    - https://img.shields.io/badge/dynamic/xml.json?url=https%3A%2F%2Fgithub.com%2Flogin&query=%2F%2Ftitle returns "invalid"
    - https://img.shields.io/badge/dynamic/xml.json?url=https%3A%2F%2Fgithub.com%2FGitHubSecurityLab%2FCodeQL-Community-Packs%2Fblob%2Fmain%2F.codeqlversion&query=%2F%2Ftitle returns "Opening and ending tag mismatch: \"div\" != \"option\""
    - https://img.shields.io/badge/dynamic/xml.json?url=https%3A%2F%2Fgithub.com%2FGitHubSecurityLab&query=%2F%2Ftitle returns "invalid"

    Working (pages without ``/optional-tag markup):
    - https://img.shields.io/badge/dynamic/xml.json?url=https%3A%2F%2Fgithub.com%2Fsite%2Fterms&query=%2F%2Ftitle returns "GitHub Terms of Service - GitHub Docs"
    - https://img.shields.io/badge/dynamic/xml.json?url=https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FHTML&query=%2F%2Ftitle returns "HTML - Wikipedia"

    ### 💡 Possible Solution

    Two possible fix directions:
    1. Contribute HTML5 "optional end tag" inference to `@xmldom/xmldom` itself. It is a finite, well defined element list per spec, so this should be a bounded change that stops the parser from mis-nesting content and throwing.
    2. Longer term, swap the HTML-tolerant parsing path in `dynamic-xml.service.js` for a spec compliant HTML5 parser, such as `parse5` (the reference implementation also used by `jsdom`). This correctly implements tree construction including implied tag closing. Its output tree would need a small adapter for the existing `xpath` npm package to query.

    Related existing issue on the same code path: #10827 (lowercase `` also breaks parsing here).

  • Contributor guide

    Open the contributing guide

    Research direction

    Start in dynamic-xml.service.js and review the acknowledged optional-end-tag limitation in @xmldom/xmldom's lib/conventions.js. Reproduce the failing GitHub URLs and compare the existing DOMParser path with the parse5 direction and its required xpath adapter. Done means valid HTML5 pages with implied option and other optional closing tags parse successfully and the title XPath returns the expected badge value.

    Written by the indexing model from the issue text.

    Assessment

    Tech stack
    javascript
    Domain
    backend
    Issue type
    Bug
    Difficulty
    4/5
    Estimated time
    3-5 days
    Activity status
    Quiet
    Clarity
    Mostly clear
    Newbie friendliness
    48/100

    Get new issues in your inbox

    A short digest of beginner-friendly GitHub issues.