PureXML/Sources/Schema/SchemaCompositionValidations.swift
Mihaela Mihaljevic 880137a955 fix(schema): a redefined group's self-reference must occur exactly once (src-redefine.6.1.2); invalid-schemas-accepted 79 to 77 (#161)
A group inside xs:redefine may reference itself (the group being redefined) at
most once, and that self-reference must have minOccurs = maxOccurs = 1. A
self-reference with minOccurs="0", maxOccurs="unbounded", or a count above 1 is
invalid. redefineGroupSelfReferenceErrors flags it, surfaced by the pre-compile
Validation redefineGroupSelfReferencesAreUnit.

The self-reference is matched by NAMESPACE (referenceNamespace == the redefining
schema's targetNamespace), not local name alone, so a redefined group that
references an imported group merely sharing its local name is correctly left
unconstrained -- the false-positive boundary an adversarial review flagged
before merge, mirroring the namespace guard the sibling redefine/cycle rules use.

XSTS: invalid-schemas-accepted 79 to 77 (schR3, schR4), valid-schemas-rejected
held at 0, no other bucket moved.
2026-06-18 00:52:40 +02:00

49 lines
2.7 KiB
Swift

extension PureXML.Validation.SchemaCompile {
/// src-resolve: a resolved `include`/`import`/`redefine` `schemaLocation` (one the
/// loader returned content for) must be a well-formed schema document. The
/// failures are recorded on the context during composition; an unresolved
/// location (the loader returned nothing) is not recorded, since resolution is
/// the processor's choice.
static var referencedSchemasResolveToSchemas: PureXML.Validation.Validation<PureXML.Schema.SchemaCompileRoot, PureXML.Schema.SchemaCompileContext> {
compileRule("A resolved schemaLocation reference is a valid schema") { document in
PureXML.Schema.SchemaLocatedFinding.unlocated(
document.context.failedSchemaReferences.map {
"the referenced schema document '\($0)' is not a valid schema"
},
)
}
}
/// src-redefine.5: every type inside `xs:redefine` must restrict or extend the
/// type it redefines (same local name, in the redefining schema's own target
/// namespace).
static var redefinitionsDeriveFromThemselves: PureXML.Validation.Validation<PureXML.Schema.SchemaCompileRoot, PureXML.Schema.SchemaCompileContext> {
compileRule("A redefined type restricts or extends itself") { document in
PureXML.Schema.SchemaLocatedFinding.unlocated(
PureXML.Schema.XSDParser.redefineDerivationErrors(document.containers),
)
}
}
/// src-redefine.6.1.2: a redefined group's self-reference has minOccurs = maxOccurs = 1.
static var redefineGroupSelfReferencesAreUnit: PureXML.Validation.Validation<PureXML.Schema.SchemaCompileRoot, PureXML.Schema.SchemaCompileContext> {
compileRule("A redefined group's self-reference occurs exactly once") { document in
PureXML.Schema.SchemaLocatedFinding.unlocated(
PureXML.Schema.XSDParser.redefineGroupSelfReferenceErrors(document.containers),
)
}
}
/// Facet definition validity and pattern syntax validity (XSD Part 2 4.3): a
/// constraining facet must be applicable to and valid for its base type, and a
/// `pattern` must compile. These are gathered during simple-type compilation
/// (where the resolved base type is available) into the context's finding sink,
/// then surfaced here as a named, located validation rather than reported
/// straight to the diagnostics collector during parsing.
static var simpleTypeFacetsAreValid: PureXML.Validation.Validation<PureXML.Schema.SchemaCompileRoot, PureXML.Schema.SchemaCompileContext> {
compileRule("Simple-type facets are valid for their base type") { document in
document.context.facetFindingSink.findings
}
}
}