|
5 | 5 | namespace SimpleSAML\XML; |
6 | 6 |
|
7 | 7 | use Dom; |
8 | | -use LogicException; |
9 | 8 | use SimpleSAML\XML\Assert\Assert; |
10 | 9 | use SimpleSAML\XML\Exception\IOException; |
11 | 10 | use SimpleSAML\XML\Exception\RuntimeException; |
@@ -42,57 +41,29 @@ public static function schemaValidate(Dom\Document $document, ?string $schemaFil |
42 | 41 | $internalErrors = libxml_use_internal_errors(true); |
43 | 42 | libxml_clear_errors(); |
44 | 43 |
|
45 | | - try { |
46 | | - if ($schemaFile === null) { |
47 | | - $schemaFile = self::getSchemaFile(); |
48 | | - } |
49 | | - |
50 | | - if (!$document instanceof Dom\XMLDocument) { |
51 | | - throw new LogicException('Schema validation requires an instance of Dom\\XMLDocument.'); |
52 | | - } |
| 44 | + if ($schemaFile === null) { |
| 45 | + $schemaFile = self::getSchemaFile(); |
| 46 | + } |
53 | 47 |
|
54 | | - $root = $document->documentElement; |
55 | | - if ($root === null) { |
56 | | - throw new SchemaViolationException('The document has no document element.'); |
57 | | - } |
| 48 | + // Must suppress the warnings here in order to throw them as an error below. |
| 49 | + $result = @$document->schemaValidate($schemaFile); |
58 | 50 |
|
59 | | - $xml = $document->saveXml($root); |
60 | | - if ($xml === false || trim($xml) === '') { |
61 | | - throw new SchemaViolationException('Could not serialize XML for schema validation.'); |
| 51 | + if ($result === false) { |
| 52 | + $msgs = []; |
| 53 | + foreach (libxml_get_errors() as $err) { |
| 54 | + $msgs[] = trim($err->message) . ' on line ' . $err->line; |
62 | 55 | } |
63 | 56 |
|
64 | | - /** |
65 | | - * Validates using a legacy \DOMDocument round-trip (serialize + re-parse) before running schema validation. |
66 | | - * This avoids false negatives seen with Dom\Document::schemaValidate(), especially around xs:QName |
67 | | - * prefix scope. Validation is performed against the exact serialized XML that would be |
68 | | - * exchanged externally. |
69 | | - * TODO: Revisit when Dom\Document::schemaValidate() reliably handles xs:QName prefix scope |
70 | | - * (avoid legacy \DOMDocument round-trip). |
71 | | - */ |
72 | | - $legacy = new \DOMDocument('1.0', 'UTF-8'); |
73 | | - $legacy->preserveWhiteSpace = true; |
74 | | - $legacy->formatOutput = false; |
75 | | - $legacy->loadXML($xml); |
76 | | - |
77 | | - $result = $legacy->schemaValidate($schemaFile); |
78 | | - |
79 | | - if ($result === false) { |
80 | | - $msgs = []; |
81 | | - foreach (libxml_get_errors() as $err) { |
82 | | - $msgs[] = trim($err->message) . ' on line ' . $err->line; |
83 | | - } |
| 57 | + throw new SchemaViolationException(sprintf( |
| 58 | + "XML schema validation errors:\n - %s", |
| 59 | + implode("\n - ", array_unique($msgs)), |
| 60 | + )); |
| 61 | + } |
84 | 62 |
|
85 | | - throw new SchemaViolationException(sprintf( |
86 | | - "XML schema validation errors:\n - %s", |
87 | | - implode("\n - ", array_unique($msgs)), |
88 | | - )); |
89 | | - } |
| 63 | + libxml_use_internal_errors($internalErrors); |
| 64 | + libxml_clear_errors(); |
90 | 65 |
|
91 | | - return $document; |
92 | | - } finally { |
93 | | - libxml_clear_errors(); |
94 | | - libxml_use_internal_errors($internalErrors); |
95 | | - } |
| 66 | + return $document; |
96 | 67 | } |
97 | 68 |
|
98 | 69 |
|
|
0 commit comments