golang.org/x/net/html's tokenizer keeps only the first of repeated attribute names, so FormatHTML's byte-preserving comparison saw <a href="https://x" href="javascript:...">, <img src=ok src="javascript:..."> and a repeated style as unchanged and stored the raw bytes, and CheckHTML accepted them. htmlTokens now scans each start tag's raw bytes for its attribute names, following the tokenizer's own readTag rules, and reports the document as changed when that list differs from the attributes the tokenizer kept. Such input is stored as bluemonday's output, which keeps the first value as browsers do, and CheckHTML refuses it. Input without repeated attributes is still stored byte for byte. A differential run of 2M random tags found no disagreement between the scan and the tokenizer.
3.0 KiB
3.0 KiB