Repository navigation
✨ feat(fuzz): stop XPath and XSLT at an op limit - #1219
Merged
gaborbernat merged 1 commit intoOct 8, 2026
Merged
Conversation
Merging this PR will regress 1 benchmark
|
| Benchmark | BASE |
HEAD |
Efficiency | |
|---|---|---|---|---|
| ❌ | test_feature[select-relative-sibling] |
42.7 µs | 45.3 µs | -5.74% |
| ⚡ | test_feature[shadow-slot-comments] |
137.9 µs | 83.6 µs | +64.81% |
Tip
Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.
Comparing gaborbernat:feat/xml-operation-limit-1016 (dc40c2f) with main (2ffa2f0)
Footnotes
-
32 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩
gaborbernat
force-pushed
the
feat/xml-operation-limit-1016
branch
3 times, most recently
from
October 8, 2026 01:34
a490024 to
aaa3c6a
Compare
A super-linear XPath expression or XSLT stylesheet runs until the fuzz harness times out, and the timeout hides every other finding in that run. libxslt bounds its own fuzzers the same way: it charges each parsed and each applied instruction (xslt.c, transform.c) and libxml2 charges each XPath operation and yielded node (xpath.c xmlXPathCheckOpLimit). The fuzz environments now compile with -DTH_OPERATION_LIMIT=100000, the XPath limit libxslt's fuzzer sets (tests/fuzz/fuzz.c). XPath evaluation, stylesheet compilation and stylesheet application each count steps and raise ValueError past the limit. Release builds leave the macro undefined; their preprocessed sources differ from upstream only by trailing commas in struct initializers, so the CodSpeed gate measures the same code. fuzz-smoke runs tests/fuzz_build against the limited build; the coverage matrix skips that directory because its build compiles no counter. Refs tox-dev#1016
gaborbernat
force-pushed
the
feat/xml-operation-limit-1016
branch
from
October 8, 2026 02:37
aaa3c6a to
dc40c2f
Compare
gaborbernat
added a commit
to gaborbernat/turbohtml
that referenced
this pull request
Oct 8, 2026
Once the live removal paths run the NodeIterator pre-removing steps, no public call leaves an iterator pointer outside its root, so no test showed that _tree_verify's iterator check reports one. Deleting that check would pass the whole suite. The -Dfuzzing=true build gains _fuzz_escape_iterators, which points the registered iterators at the document, in the style of tox-dev#1217's _fuzz_crash, and a test in tests/fuzz_build, which fuzz-smoke runs since tox-dev#1219, requires the verifier to count the escaped pointer. With the reference check deleted from th_tree_verify, fuzz-smoke fails.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The #1016 differential fuzzing of XPath and XSLT needs a bound on work that a slow input cannot dodge: a Python timeout fires only after the native call returns. Fuzz builds now compile operation counters into XPath evaluation, XSLT apply and stylesheet compilation, and an input that exceeds the limit raises
ValueError. Closes #1016. ⏱️The counters exist only when the build defines
TH_OPERATION_LIMIT, which the fuzz, smoke, oracle and round-trip builds do with a limit of 100000, the XPath limit libxslt's own fuzzer sets. XPath charges each evaluated node and each node a step yields, as libxml2'sxmlXPathCheckOpLimitdoes, and predicate sub-contexts share the counter; XSLT charges each instantiated instruction, asxsltApplySequenceConstructordoes in libxslt, and compilation charges each stylesheet element.Production builds compile none of it: callgrind counts 2,441,131 instructions for
transformand 570,300 forxpath-compare-unequalon both main and this branch. The amplify job keeps its unlimited build because it measures time growth.