PureXML/Sources
Mihaela Mihaljevic 8f2725b62a
fix(schema): reject an identity-constraint field that selects a non-simple node (#381)
XSD 1.0 §3.11.4 (cvc-identity-constraint.3) requires each key/keyref/unique
field to identify a node of simple type. A field that reaches an element
declared with no type (the ur-type anyType) or an inline complex type without
simple content does not, so the instance is invalid; the reference (libxml2)
rejects it identically. PureXML accepted such instances because its identity
validator could resolve a field target's type only for a global element reached
by a direct-child name, not for a local element reached through a path (the W3C
XSTS case idZ010 nests anyType fields several levels deep, e.g. a key field
./b/c where c has no type).

A compile-time pass (XSDParser.identityNonSimpleFieldKeys) resolves each field's
target element through its selector and field paths, by element-name steps, and
records the fields whose declared target is provably non-simple. The validator
rejects those at runtime unless the instance gives the node a simple type
through xsi:type, since cvc reads the node's governing type (a text-only anyType
element with xsi:type="xsd:int" is a valid field). The resolution is
conservative: any wildcard, descendant axis, predicate, ref, or named
non-builtin type leaves the field unflagged, so a valid field is never rejected.
The one residual divergence path, two same-name child elements of differing
simplicity in one inline model, is an Element-Declarations-Consistent violation
the compiler already rejects.

Verified over the full W3C XSTS corpus in release: invalid-instances-accepted
8 -> 7 (idZ010 now rejects), valid-instances-rejected held at 0 across all 14383
groups (no false positive), full suite (1837 tests), wasm, and lint all green.
An adversarial critic that read every file and probed for a false positive could
not construct one; the failure mode is under-rejection, the safe direction.
2026-06-29 09:08:25 +02:00
..
Canonical perf(canonical): make the prefix rewrite and node-subset emit depth-safe (#355) 2026-06-27 17:08:37 +02:00
Catalog feat(catalog): honor group-level prefer override 2026-06-08 18:05:03 +02:00
Emitting perf(serialize): scan bytes, not graphemes, to find characters to escape (#297) 2026-06-25 15:39:20 +02:00
HTML perf(html): make HTML serialization depth-safe (#353) 2026-06-27 16:22:54 +02:00
Model fix(xpath): make string-value extraction iterative and comment-correct (#351) 2026-06-26 20:44:49 +02:00
Parsing perf(parsing): resolve namespaces in O(1), making parse linear in depth (#346) 2026-06-26 17:44:27 +02:00
Pattern feat(pattern): streaming xmlPattern matching 2026-06-08 05:49:13 +02:00
Regex fix(schema): back XSD \i and \c with the XML 1.0 Appendix B name classes (#378) 2026-06-29 07:05:27 +02:00
Schema fix(schema): reject an identity-constraint field that selects a non-simple node (#381) 2026-06-29 09:08:25 +02:00
Stream chore: scaffold PureXML pure-Swift XML package 2026-06-07 23:20:20 +02:00
Validation perf: make tree-to-tree transforms depth-safe (DTD defaults, canonicalization) (#352) 2026-06-26 19:27:37 +02:00
XInclude perf(xinclude): make XInclude processing depth-safe (#354) 2026-06-27 16:55:03 +02:00
XPath fix(xpath): make string-value extraction iterative and comment-correct (#351) 2026-06-26 20:44:49 +02:00
XPointer perf(xpointer): linear-time string-range() search (#314) 2026-06-26 04:01:41 +02:00
XSLT perf(xslt): make the template evaluator iterative (#358) 2026-06-27 19:29:51 +02:00
API.swift perf(parse): build the TreeNode tree directly from the event stream (#295) 2026-06-25 14:15:57 +02:00
Lint.swift feat(editor): unified lint surface merging parse and validation diagnostics 2026-06-08 13:18:29 +02:00
PureXML.swift feat(html): lenient HTML parser and serializer 2026-06-08 07:12:42 +02:00
QuickFix.swift feat(editor): structured quick-fixes from completions 2026-06-08 13:35:33 +02:00