PureXML/Sources/Regex
Mihaela Mihaljevic 2eb9f83958
fix(schema): back XSD \i and \c with the XML 1.0 Appendix B name classes (#378)
XSD 1.0 (Datatypes Appendix F) defines the regex escape \i as the characters
that may begin an XML Name (Letter | '_' | ':') and \c as the characters that
may appear in one (NameChar), citing the XML 1.0 Second Edition productions:
the enumerated, Unicode-2.0-era character classes of XML 1.0 Appendix B
(BaseChar, Ideographic, CombiningChar, Digit, Extender). \i and \c were wired
to PureXML.Parsing.XMLCharacter, which correctly implements the Fifth Edition
Name production used to parse live XML, but the two genuinely differ: the Fifth
Edition admits whole blocks where the Second Edition has gaps, so \c
over-accepted, e.g. the combining mark U+0346 (COMBINING BRIDGE ABOVE), which
Appendix B's CombiningChar excludes (its first range ends at U+0345).

Add XSDNameCharacter, transcribed clean-room from the Appendix B grammar
(identical across editions one through four) and stored as sorted, non-
overlapping code-point ranges with binary-search membership; the parser's own
name check is untouched. The two tables reproduce the W3C XSTS \i/\c
enumerations (reZ005, reZ006: 34516 and 35122 code points) exactly and in both
directions, so the more restrictive definition rejects no spec-valid input:
there is no false-positive surface.

Verified over the full W3C XSTS corpus in release: invalid-instances-accepted
12 -> 11 (reZ006i, whose value is U+0346, now rejects), both false-positive
buckets at 0. Full suite (1834 tests) green; an adversarial critic brute-forced
the binary search over the whole code-point space (0 mismatches), confirmed the
tables are sorted and non-overlapping and equal the oracle sets, and that the
parser's Fifth Edition path is left intact. Found by triaging the invalid-
instance tail to a single boundary code point (U+0345 valid vs U+0346 invalid)
and reading the XML 1.0 Appendix B grammar.
2026-06-29 07:05:27 +02:00
..
RegexAutomaton.swift fix(schema): advance XSTS valid-instances-rejected to 4 (#146) 2026-06-16 22:22:05 +02:00
RegexCategory.swift fix(schema): reject an unknown \p{...} category or block name (#248) 2026-06-23 02:15:26 +02:00
RegexParser.swift fix(schema): reject an unknown \p{...} category or block name (#248) 2026-06-23 02:15:26 +02:00
RegexSyntax.swift 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
Unicode32Assigned.swift fix(schema): advance XSTS valid-instances-rejected to 4 (#146) 2026-06-16 22:22:05 +02:00
XSDCategory.swift fix(schema): match Ethiopic digits against \d at the pinned Unicode 3.2 repertoire (#377) 2026-06-29 06:27:27 +02:00
XSDNameCharacter.swift 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