Skip to content

Commit f249d85

Browse files
committed
validate all XML
Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
1 parent 8668905 commit f249d85

2 files changed

Lines changed: 116 additions & 2 deletions

File tree

tools/src/test/php/composer.json

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
"minimum-stability": "stable",
33
"require": {
44
"php": "^8.1",
5+
"ext-dom": "*",
56
"ext-json": "*",
7+
"ext-libxml": "*",
68
"opis/json-schema": "2.3"
79
},
810
"require-dev": {
@@ -11,7 +13,8 @@
1113
"scripts": {
1214
"test": [
1315
"@test:json-schema-lint",
14-
"@test:json-schema-functional"
16+
"@test:json-schema-functional",
17+
"@test:xml-schema-functional"
1518
],
1619
"test:json-schema-lint": "@php -f json-schema-lint-tests.php --",
1720
"test:json-schema-functional": [
@@ -21,7 +24,19 @@
2124
],
2225
"test:json-schema-functional:1.4": "@php -f json-schema-functional-tests.php -- -v 1.4 --",
2326
"test:json-schema-functional:1.3": "@php -f json-schema-functional-tests.php -- -v 1.3 --",
24-
"test:json-schema-functional:1.2": "@php -f json-schema-functional-tests.php -- -v 1.2 --"
27+
"test:json-schema-functional:1.2": "@php -f json-schema-functional-tests.php -- -v 1.2 --",
28+
"test:xml-schema-functional": [
29+
"@test:xml-schema-functional:1.4",
30+
"@test:xml-schema-functional:1.3",
31+
"@test:xml-schema-functional:1.2",
32+
"@test:xml-schema-functional:1.1",
33+
"@test:xml-schema-functional:1.0"
34+
],
35+
"test:xml-schema-functional:1.4": "@php -f xml-schema-functional-tests.php -- -v 1.4 --",
36+
"test:xml-schema-functional:1.3": "@php -f xml-schema-functional-tests.php -- -v 1.3 --",
37+
"test:xml-schema-functional:1.2": "@php -f xml-schema-functional-tests.php -- -v 1.2 --",
38+
"test:xml-schema-functional:1.1": "@php -f xml-schema-functional-tests.php -- -v 1.1 --",
39+
"test:xml-schema-functional:1.0": "@php -f xml-schema-functional-tests.php -- -v 1.0 --"
2540
},
2641
"scripts-descriptions": {
2742
"test": "run all tests",
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
<?php declare(strict_types=1);
2+
3+
/**
4+
* validate all test data for a given version of CycloneDX.
5+
* call the script via `php -f <this-file> -- -v <CDX-version>`
6+
*/
7+
8+
use Opis\JsonSchema;
9+
10+
require_once __DIR__ . '/vendor/autoload.php';
11+
12+
// region config
13+
14+
define('TESTSCHEMA_VERSION', getopt('v:')['v']);
15+
define('SCHEMA_DIR', realpath(__DIR__ . '/../../../../schema'));
16+
define('SCHEMA_FILE', SCHEMA_DIR . '/bom-' . TESTSCHEMA_VERSION . '.xsd');
17+
define('TESTDATA_DIR', realpath(__DIR__ . '/../resources/' . TESTSCHEMA_VERSION));
18+
19+
if (empty(TESTSCHEMA_VERSION)) {
20+
throw new Exception('missing TESTSCHEMA_VERSION. expected via opt "-v"');
21+
}
22+
fwrite(STDOUT, 'DEBUG | TESTSCHEMA_VERSION = ' . TESTSCHEMA_VERSION . PHP_EOL);
23+
24+
if (!is_file(SCHEMA_FILE)) {
25+
throw new Exception('missing SCHEMA_FILE: ' . SCHEMA_FILE);
26+
}
27+
fwrite(STDOUT, 'DEBUG | SCHEMA_FILE = ' . SCHEMA_FILE . PHP_EOL);
28+
29+
if (!is_dir(TESTDATA_DIR)) {
30+
throw new Exception('missing TESTDATA_DIR: ' . TESTDATA_DIR);
31+
}
32+
fwrite(STDOUT, 'DEBUG | TESTDATA_DIR = ' . TESTDATA_DIR . PHP_EOL);
33+
34+
// endregion config
35+
36+
// region validator
37+
38+
$xmlOptions = \LIBXML_NONET;
39+
if (\defined('LIBXML_COMPACT')) {
40+
$xmlOptions |= \LIBXML_COMPACT;
41+
}
42+
if (\defined('LIBXML_PARSEHUGE')) {
43+
$xmlOptions |= \LIBXML_PARSEHUGE;
44+
}
45+
46+
/**
47+
* @param string $file file path to validate
48+
*/
49+
function validateFile(string $file): ?LibXMLError
50+
{
51+
global $xmlOptions;
52+
53+
libxml_use_internal_errors(true);
54+
libxml_clear_errors();
55+
56+
$doc = new DOMDocument();
57+
if (!$doc->loadXML(file_get_contents($file), $xmlOptions)) {
58+
throw new Exception("failed loading file: $file" . PHP_EOL . libxml_get_last_error()->message);
59+
}
60+
61+
$valid = $doc->schemaValidate(SCHEMA_FILE);
62+
return $valid
63+
? null
64+
: libxml_get_last_error();
65+
}
66+
67+
// endregion validator
68+
69+
$errCnt = 0;
70+
71+
foreach (glob(TESTDATA_DIR . '/valid-*.xml') as $file) {
72+
fwrite(STDOUT, PHP_EOL . "test $file ..." . PHP_EOL);
73+
$validationError = validateFile($file);
74+
if ($validationError === null) {
75+
fwrite(STDOUT, 'OK.' . PHP_EOL);
76+
} else {
77+
++$errCnt;
78+
fwrite(STDERR, "ERROR: Unexpected validation error for file: $file" . PHP_EOL);
79+
fwrite(STDERR, print_r($validationError, true) . PHP_EOL);
80+
}
81+
unset($validationError);
82+
}
83+
84+
foreach (glob(TESTDATA_DIR . '/invalid-*.xml') as $file) {
85+
fwrite(STDOUT, PHP_EOL . "test $file ..." . PHP_EOL);
86+
$validationError = validateFile($file);
87+
if ($validationError === null) {
88+
++$errCnt;
89+
fwrite(STDERR, "ERROR: Missing expected validation error for file: $file" . PHP_EOL);
90+
} else {
91+
fwrite(STDOUT, 'OK.' . PHP_EOL);
92+
}
93+
unset($validationError);
94+
}
95+
96+
97+
// Exit statuses should be in the range 0 to 254, the exit status 255 is reserved by PHP and shall not be used.
98+
// The status 0 is used to terminate the program successfully.
99+
exit(min($errCnt, 254));

0 commit comments

Comments
 (0)