Deepen DTD processing in the doctype scanner: - Conditional sections are processed, not skipped: INCLUDE sections have their declarations scanned, IGNORE sections are discarded, the keyword may be a parameter-entity reference, and nested sections are handled. - <!NOTATION> declarations are parsed and stored on DocumentType. - Unparsed entities (<!ENTITY ... NDATA n>) are parsed and stored with their notation, distinct from general entities. - External parameter entities are loaded through the injected resolver so their declarations expand; the default refusing resolver loads nothing, keeping XXE closed. - NOTATION attributes are a distinct type, validated against the declared notations (value must be listed and the notation declared). Tracking unparsed entities also lets ENTITY/ENTITIES attribute values be validated against the declared NDATA entities, closing the gap left when #73 could only check name syntax. Closes #72
28 lines
1.2 KiB
Swift
28 lines
1.2 KiB
Swift
extension PureXML.Validation {
|
|
/// The declared type of a DTD attribute. An enumeration constrains the value to
|
|
/// a fixed set; the tokenized types constrain its lexical form (a name token, a
|
|
/// name); and the ID family drives cross-document uniqueness and reference
|
|
/// checks.
|
|
enum AttributeType: Equatable {
|
|
case cdata
|
|
case enumeration([String])
|
|
/// `NOTATION (a|b)`: the value must be one of the listed notation names,
|
|
/// each of which must be a declared `<!NOTATION>`.
|
|
case notation([String])
|
|
/// `ID`: the value must be unique across the document.
|
|
case id
|
|
/// `IDREF`: the value must match some declared `ID`.
|
|
case idReference
|
|
/// `IDREFS`: each whitespace-separated value must match some declared `ID`.
|
|
case idReferences
|
|
/// `NMTOKEN`: the value must be a single XML name token.
|
|
case nmToken
|
|
/// `NMTOKENS`: each whitespace-separated value must be a name token.
|
|
case nmTokens
|
|
/// `ENTITY`: the value must be an XML name (naming an unparsed entity).
|
|
case entity
|
|
/// `ENTITIES`: each whitespace-separated value must be a name.
|
|
case entities
|
|
}
|
|
}
|