Skip to content

Commit 8a487f2

Browse files
committed
Unify the shadow reflection engine and prune its API (#356)
Review pass over the shadow-copy branch. The design stands; the helper layer had grown two reflection engines (End for single-site template calls, ReflectAll for multi-site sign/encrypt) plus five single-use entry points. Collapse them into one engine so every binding uses the same few lines: - One reflection walk: fresh nodes are grafted at their child index, and every parent that gained a node has its text slots (.text and the children's .tail) synced wholesale from the re-parsed copy. The sync replaces the old per-element "mirror" heuristic and also covers text the call removed (encrypt Type=Content), which no fresh-node scan can see. - End maps the result node back after reflecting: grafted, or found (attributes synced; a renamed prefix swaps in the copy's version). It serves every Begin flavour, so EndNewDoc and EndReplace go away. - Reflect(shadow, rv, error) ends status-returning calls in one line (sign, encrypt_binary, encrypt_uri, C14N inclusive namespaces); FindFresh is gone. - BeginDoc replays the registered IDs itself; ReplayIds and DumpCopy become static. Header: 15 -> 10 functions. - Our re-parse uses XML_PARSE_HUGE and a cached huge_tree lxml parser, so a CipherValue above libxml2's 10 MB text-node limit reflects (12 MB encrypt_binary/decrypt round trip verified); path depth 256. - The enc.c shadow bodies clear XMLSEC_ENC_RETURN_REPLACED_NODE explicitly: xmlsec must free replaced nodes with our libxml2 before the copy is discarded (it already did, implicitly). Also fixes a pre-existing crash on the raw path, found by the new tests: encrypt_xml with Type=Content on text or mixed content put text nodes into xmlsec's replaced-node list, and PyXmlSec_ClearReplacedNodes handed them to lxml's elementFactory; lxml frees the text siblings that follow an element when its proxy is released, so the next list entry was freed under our feet. Each node is now severed from the chain before release and non-element nodes are freed directly. Tests: decrypt of Type=Content with whitespace around EncryptedData and with mixed content, register_id sign/verify round trip, prefix rename on a live KeyInfo. Docs consolidated into developer.md (356-summary.md and converting-functions.md removed). Validated: real 2.14.6/2.15.3 mismatch 292 passed / 6 skipped, 10k loop with flat RSS and byte-identical output; matched static wheel 304 / 6 on both the fast path and PYXMLSEC_FORCE_SHADOW=1.
1 parent 92d68ad commit 8a487f2

11 files changed

Lines changed: 1072 additions & 1187 deletions

File tree

356-summary.md

Lines changed: 0 additions & 103 deletions
This file was deleted.

converting-functions.md

Lines changed: 0 additions & 133 deletions
This file was deleted.

0 commit comments

Comments
 (0)