Skip to content

deps: PhoenixmlDb.Xslt 2.4.1 -> 2.5.1 - #41

Merged
elvogel merged 1 commit into
mainfrom
deps/engine-2.5.1
Oct 2, 2026
Merged

elvogel merged 1 commit into
mainfrom
deps/engine-2.5.1

Conversation

@elvogel

@elvogel elvogel commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

Taken for a defect, not for speed.

What it buys us

phoenixmldb-xslt#199 is fixed. That is the recursion-depth ceiling 2.4.1's stack-exhaustion
hotfix introduced and then miscounted. 0.2.4's changelog recorded it as open and argued around
it — w:ilvl caps at 8, so docmd's nested-list rebuild never approaches the ceiling. The argument
was sound, and it was still an argument. 2.5.1 stops counting element construction toward the
limit (#202) and runs transformations on a large-stack thread so the limit is reachable at all
(#197/#200). Both issues are now closed upstream.

Verified

Suite 363 tests, 362 pass, 1 skip, 0 failures (unchanged)
Corpus output 13 of 13 byte-identical, across four full runs — two per engine, 52 conversions, same bytes every time
Build clean, 0 warnings / 0 errors
dotnet restore --locked-mode exit 0
Corpus id 789586bf36247fb0

Performance is neutral, and my first measurement was wrong

391,310 ms → 387,352 ms over the corpus. 1.0%. Noise.

An earlier pair showed 648,552 → 407,956 ms, which reads as 37% and is wrong: the slow arm ran
while the machine was loaded. The tell was that the fast arm started at load 14.69 and still
won, which meant the comparator had been measured against something else entirely.

What prompted re-measuring rather than reporting it: nothing in the 43 commits between the tags
is performance work.
A large gain with no mechanism is a measurement bug until proven otherwise.
The bogus figure is recorded in the commit message and changelog on purpose — the first pair's
output is still on disk, and without the correction attached someone could re-derive 37% and
publish it.

The security fix, and why it matters later rather than now

The release carries GHSA-86rg-wxgp-9p5j, enforcing ResourcePolicy across XSLT reads, fetches
and xsl:evaluate. docmd is not exposed: it configures no policy, and the stylesheet calls
none of the affected constructs — no document(), unparsed-text, xsl:evaluate, xsl:import
or xsl:source-document. The advisory concerns callers relying on a policy to sandbox untrusted
stylesheets.

It becomes load-bearing the moment --style-map ships, because a user-supplied stylesheet is
untrusted code and sandboxing it needs a policy that is actually enforced. --style-map is
otherwise unblocked now (phoenixmldb-xslt#12 is closed). Noted in docs/deferred-work.md beside
the flag rather than left to be rediscovered.

Why the output did not move a byte

The other ~40 changes are streaming, accumulator and current-group() conformance fixes. docmd's
stylesheet neither streams nor groups, so they do not reach it. That is a mechanism, not luck —
and it is the strongest prior for the byte-identical result, which then held across four runs.

🤖 Generated with Claude Code

https://claude.ai/code/session_018wZEgtuzaZPswykiGEBxbz

Taken for a defect, not for speed.

phoenixmldb-xslt#199 is FIXED. That is the recursion-depth ceiling 2.4.1's
stack-exhaustion hotfix introduced and then miscounted; 0.2.4's changelog
recorded it as open and argued around it, on the grounds that w:ilvl caps at 8
so docmd's nested-list rebuild never approaches the ceiling. The argument was
sound and it was still an argument. 2.5.1 stops counting element construction
toward the limit (#202) and runs transformations on a large-stack thread so the
limit is reachable at all (#197/#200), which retires it.

Measured, not assumed
  suite                 363 tests, 362 pass, 1 skip, 0 failures (unchanged)
  corpus output         13 of 13 BYTE-IDENTICAL, confirmed across four full
                        runs, two per engine - 52 conversions, same bytes
  build                 clean, 0 warnings, 0 errors
  restore --locked-mode exit 0
  corpus id             789586bf36247fb0

PERFORMANCE IS NEUTRAL: 391,310 ms -> 387,352 ms over the corpus, 1.0%, noise.

An earlier pair of runs showed 648,552 -> 407,956 ms, which reads as 37% and is
WRONG: the slow arm ran while the machine was loaded (the fast arm started at
load 14.69 and still won, which is what exposed it). Nothing in the 43 commits
between the tags is performance work. Reading the release before trusting the
stopwatch is what caught it, and the bogus figure is recorded here so nobody
re-derives it from the first pair.

The release also carries GHSA-86rg-wxgp-9p5j, enforcing ResourcePolicy across
XSLT reads, fetches and xsl:evaluate. docmd is NOT exposed: it configures no
policy, and the stylesheet calls none of the affected constructs - no
document(), unparsed-text, xsl:evaluate, xsl:import or xsl:source-document.
It matters later. --style-map means running a stylesheet somebody else wrote,
and sandboxing that needs a policy that is actually enforced, so when
--style-map ships it should set one and will need 2.5.1 or newer to do it.

The other 40-odd changes are streaming, accumulator and current-group()
conformance fixes. docmd's stylesheet neither streams nor groups, so they do
not reach it - the best available explanation for output that did not move a
byte.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018wZEgtuzaZPswykiGEBxbz
@elvogel
elvogel merged commit fbf4b5d into main Oct 2, 2026
1 check passed
@elvogel
elvogel deleted the deps/engine-2.5.1 branch October 2, 2026 09:01
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