From a4053588b685f17100561c3d80aa228b20e93f21 Mon Sep 17 00:00:00 2001 From: Lucas Vogel Date: Thu, 1 Oct 2026 18:32:50 -0400 Subject: [PATCH] deps: PhoenixmlDb.Xslt 2.4.1 -> 2.5.1 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 Claude-Session: https://claude.ai/code/session_018wZEgtuzaZPswykiGEBxbz --- CHANGELOG.md | 33 +++++++++++++++++++++++ Directory.Packages.props | 2 +- src/Docmd.Cli/packages.lock.json | 14 +++++----- src/Docmd.Word/packages.lock.json | 12 ++++----- tests/Docmd.Word.Tests/packages.lock.json | 14 +++++----- 5 files changed, 54 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d3a058c..8fc3096 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,39 @@ stylesheet writes against is not stable until `1.0`. ## [Unreleased] +### Changed + +- **`PhoenixmlDb.Xslt` 2.4.1 → 2.5.1** (bringing `PhoenixmlDb.XQuery` 2.5.1; Core stays at + 2.0.0). **No behaviour change**: all 13 corpus documents convert byte-identically, confirmed + across four full runs (two on each engine), and the suite is unchanged at 363 tests. + + Taken for a defect, not for speed. `phoenixmldb-xslt#199` — the recursion-depth ceiling that + miscounted, introduced by 2.4.1's stack-exhaustion hotfix — **is fixed**: element construction + no longer counts toward the recursion limit, and transformations now run on a large-stack + thread so the limit is reachable at all (`#197`). 0.2.4's entry recorded that defect 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. That argument was sound but it was still an argument; this + retires it. + + **Performance is neutral: 391,310 ms → 387,352 ms over the 13-document corpus, a 1.0% + difference that is noise.** An earlier pair of runs appeared to show 37%, and that figure was + wrong — the slower arm ran while the machine was loaded. Nothing in the 43 commits between the + tags is performance work, which is what prompted re-measuring rather than reporting it. Quoted + against corpus id `789586bf36247fb0`. + + The release also carries a security fix, `GHSA-86rg-wxgp-9p5j`, enforcing `ResourcePolicy` + across XSLT reads, fetches and `xsl:evaluate`. **docmd is not exposed today** — it configures + no policy, and its stylesheet calls none of the affected constructs (`document()`, + `unparsed-text`, `xsl:evaluate`, `xsl:import`, `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. When `--style-map` ships it should set one, and that only + works on 2.5.1 or newer. + + The remaining 40-odd changes are streaming, accumulator and `current-group()` conformance + fixes. docmd's stylesheet neither streams nor groups, so they do not reach it — which is the + best available explanation for why the output did not move a byte. + + Test infrastructure only. **No product change**: nothing under `src/` was touched, and no shipped package reference moved. diff --git a/Directory.Packages.props b/Directory.Packages.props index 28f87df..444e086 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -3,7 +3,7 @@ true - + diff --git a/src/Docmd.Cli/packages.lock.json b/src/Docmd.Cli/packages.lock.json index 208dfae..c6525a1 100644 --- a/src/Docmd.Cli/packages.lock.json +++ b/src/Docmd.Cli/packages.lock.json @@ -49,8 +49,8 @@ }, "PhoenixmlDb.XQuery": { "type": "Transitive", - "resolved": "2.4.1", - "contentHash": "GUHCOuETC9fAfheDjUikoOS8a3PfUn8FP+m2OAZWkRQwLDQOUOUg8OwILWsLPbGg6KC07p63iBoR9AWHmkW16Q==", + "resolved": "2.5.1", + "contentHash": "RvkLvvp/fSh5dTdKO8CNSDE3NAiARBSpqbBNXBu+GCpUtImngP1AK/YUn2+amlOFm4wwEwX24Tpd9Hfc/FXnVA==", "dependencies": { "Antlr4.Runtime.Standard": "4.13.1", "Lucene.Net": "4.8.0-beta00016", @@ -62,7 +62,7 @@ "type": "Project", "dependencies": { "Ooxml.Md.Core": "[0.2.4, )", - "PhoenixmlDb.Xslt": "[2.4.1, )" + "PhoenixmlDb.Xslt": "[2.5.1, )" } }, "ooxml.md.core": { @@ -80,12 +80,12 @@ }, "PhoenixmlDb.Xslt": { "type": "CentralTransitive", - "requested": "[2.4.1, )", - "resolved": "2.4.1", - "contentHash": "Hm7tAbJoJqK9ZMeC/4JlyU+lZNHIKPKvsHombzoRHeMXIvUM2NtViY7MeARk9E9ITgFzEBZDbznDSgK/VhAB6Q==", + "requested": "[2.5.1, )", + "resolved": "2.5.1", + "contentHash": "amcJK59mvPkrrYoCwseI9ANbmdBXjA4D7y3YXNYcywh5rx/4trRvFLE1J82q0TGzvn8XwCDV6rMNpbapmrRCig==", "dependencies": { "PhoenixmlDb.Core": "2.0.0", - "PhoenixmlDb.XQuery": "2.4.1" + "PhoenixmlDb.XQuery": "2.5.1" } }, "YamlDotNet": { diff --git a/src/Docmd.Word/packages.lock.json b/src/Docmd.Word/packages.lock.json index 2990f1f..3f7fba6 100644 --- a/src/Docmd.Word/packages.lock.json +++ b/src/Docmd.Word/packages.lock.json @@ -4,12 +4,12 @@ "net10.0": { "PhoenixmlDb.Xslt": { "type": "Direct", - "requested": "[2.4.1, )", - "resolved": "2.4.1", - "contentHash": "Hm7tAbJoJqK9ZMeC/4JlyU+lZNHIKPKvsHombzoRHeMXIvUM2NtViY7MeARk9E9ITgFzEBZDbznDSgK/VhAB6Q==", + "requested": "[2.5.1, )", + "resolved": "2.5.1", + "contentHash": "amcJK59mvPkrrYoCwseI9ANbmdBXjA4D7y3YXNYcywh5rx/4trRvFLE1J82q0TGzvn8XwCDV6rMNpbapmrRCig==", "dependencies": { "PhoenixmlDb.Core": "2.0.0", - "PhoenixmlDb.XQuery": "2.4.1" + "PhoenixmlDb.XQuery": "2.5.1" } }, "Antlr4.Runtime.Standard": { @@ -59,8 +59,8 @@ }, "PhoenixmlDb.XQuery": { "type": "Transitive", - "resolved": "2.4.1", - "contentHash": "GUHCOuETC9fAfheDjUikoOS8a3PfUn8FP+m2OAZWkRQwLDQOUOUg8OwILWsLPbGg6KC07p63iBoR9AWHmkW16Q==", + "resolved": "2.5.1", + "contentHash": "RvkLvvp/fSh5dTdKO8CNSDE3NAiARBSpqbBNXBu+GCpUtImngP1AK/YUn2+amlOFm4wwEwX24Tpd9Hfc/FXnVA==", "dependencies": { "Antlr4.Runtime.Standard": "4.13.1", "Lucene.Net": "4.8.0-beta00016", diff --git a/tests/Docmd.Word.Tests/packages.lock.json b/tests/Docmd.Word.Tests/packages.lock.json index 43cdb6d..c2c1c3d 100644 --- a/tests/Docmd.Word.Tests/packages.lock.json +++ b/tests/Docmd.Word.Tests/packages.lock.json @@ -118,8 +118,8 @@ }, "PhoenixmlDb.XQuery": { "type": "Transitive", - "resolved": "2.4.1", - "contentHash": "GUHCOuETC9fAfheDjUikoOS8a3PfUn8FP+m2OAZWkRQwLDQOUOUg8OwILWsLPbGg6KC07p63iBoR9AWHmkW16Q==", + "resolved": "2.5.1", + "contentHash": "RvkLvvp/fSh5dTdKO8CNSDE3NAiARBSpqbBNXBu+GCpUtImngP1AK/YUn2+amlOFm4wwEwX24Tpd9Hfc/FXnVA==", "dependencies": { "Antlr4.Runtime.Standard": "4.13.1", "Lucene.Net": "4.8.0-beta00016", @@ -223,7 +223,7 @@ "type": "Project", "dependencies": { "Ooxml.Md.Core": "[0.2.4, )", - "PhoenixmlDb.Xslt": "[2.4.1, )" + "PhoenixmlDb.Xslt": "[2.5.1, )" } }, "ooxml.md.core": { @@ -235,12 +235,12 @@ }, "PhoenixmlDb.Xslt": { "type": "CentralTransitive", - "requested": "[2.4.1, )", - "resolved": "2.4.1", - "contentHash": "Hm7tAbJoJqK9ZMeC/4JlyU+lZNHIKPKvsHombzoRHeMXIvUM2NtViY7MeARk9E9ITgFzEBZDbznDSgK/VhAB6Q==", + "requested": "[2.5.1, )", + "resolved": "2.5.1", + "contentHash": "amcJK59mvPkrrYoCwseI9ANbmdBXjA4D7y3YXNYcywh5rx/4trRvFLE1J82q0TGzvn8XwCDV6rMNpbapmrRCig==", "dependencies": { "PhoenixmlDb.Core": "2.0.0", - "PhoenixmlDb.XQuery": "2.4.1" + "PhoenixmlDb.XQuery": "2.5.1" } }, "YamlDotNet": {