Commit 48e8d0d
Tell two same-valued attributes of one element apart (#356)
register_id's shadow body decided "the attribute being registered is
already the declared one" from the *element* XPath id() returned. An
element can carry the value twice: <N xml:id="dup" ID="dup"/> answers N
whichever attribute is asked about, so register_id(N, 'ID') recorded a
spec where the fast path registers ID, finds xml:id holding the value
and raises "duplicated id.". The registry half had the same shape, by
local name only: a spec for a:Id and a call for Id are two attributes,
and the second cannot win the lookup either.
Both halves now compare attributes. PyXmlSec_LxmlAttrValue became
AttrFind, which also reports the lxml key of the attribute
xmlHasProp/xmlHasNsProp would pick, and a registry spec is resolved
through it on the node it was recorded for. For the declared half, a
match on the element itself settles nothing when two of its attributes
carry the value, and no lxml API names the declared attribute — id()
names elements, and an ATTLIST without an ELEMENT leaves lxml's DTD
objects empty. It is named instead by copying the document the way a
whole-document shadow copies it (same base URL, same subsets) and
reading that copy's own id hash. Only a value already declared for the
element, on an element carrying it twice, pays for that copy.
Nine collision shapes now answer identically on the raw path, the
forced shadow and the mismatch build: xml:id beside ID, a DTD-declared
ID beside a twin attribute (both directions), and namespaced/
unqualified registry pairs in both orders.
Tests in tests/test_ds.py: the two "rejects" cases fail on the pre-fix
build; the two "accepts" cases guard the no-op against an over-eager
check. Validation: 318 passed / 6 skipped on the mismatch build, also
at PYXMLSEC_TEST_ITERATIONS=50; 330 / 6 on the matched static wheel,
plain and with PYXMLSEC_FORCE_SHADOW=1; a 10k loop of no-op plus
refused registration over the DTD document with RSS 23.3 -> 24.7 MiB.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>1 parent 3a50b04 commit 48e8d0d
3 files changed
Lines changed: 269 additions & 51 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
226 | 226 | | |
227 | 227 | | |
228 | 228 | | |
229 | | - | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
230 | 245 | | |
231 | 246 | | |
232 | 247 | | |
| |||
0 commit comments