1#!/usr/local/bin/php
2<?php
3
4/*
5 * Simple program that uses svg-sanitizer
6 * to find issues in files specified on the
7 * command line, and prints a JSON output with
8 * the issues found on exit.
9 */
10
11require_once( __DIR__ . '/data/AttributeInterface.php' );
12require_once( __DIR__ . '/data/TagInterface.php' );
13require_once( __DIR__ . '/data/AllowedAttributes.php' );
14require_once( __DIR__ . '/data/AllowedTags.php' );
15require_once( __DIR__ . '/data/XPath.php' );
16require_once( __DIR__ . '/ElementReference/Resolver.php' );
17require_once( __DIR__ . '/ElementReference/Subject.php' );
18require_once( __DIR__ . '/ElementReference/Usage.php' );
19require_once( __DIR__ . '/Exceptions/NestingException.php' );
20require_once( __DIR__ . '/Helper.php' );
21require_once( __DIR__ . '/Sanitizer.php' );
22
23/*
24 * Print array as JSON and then
25 * exit program with a particular
26 * exit-code.
27 */
28
29function sysexit(
30	$results,
31	$status
32) {
33	echo json_encode(
34		$results,
35		JSON_PRETTY_PRINT
36	);
37
38	exit( $status );
39}
40
41
42/*
43 * Main part begins
44 */
45
46global $argv;
47
48/*
49 * Set up results array, to
50 * be printed on exit.
51 */
52$results = array(
53	'totals' => array(
54		'errors' => 0,
55	),
56
57	'files' => array(
58	),
59);
60
61
62/*
63 * Catch files to scan from $argv.
64 */
65
66$files_to_scan = $argv;
67unset( $files_to_scan[0] );
68
69$files_to_scan = array_values(
70	$files_to_scan
71);
72
73/*
74 * Catch no file specified.
75 */
76
77if ( empty( $files_to_scan ) ) {
78	$results['totals']['errors']++;
79	$results['messages'] = array(
80		array( 'No files to scan specified' ),
81	);
82
83	sysexit(
84		$results,
85		1
86	);
87}
88
89/*
90 * Initialize the SVG scanner.
91 *
92 * Make sure to allow custom attributes,
93 * and to remove remote references.
94 */
95$sanitizer = new enshrined\svgSanitize\Sanitizer();
96
97$sanitizer->removeRemoteReferences( true );
98
99/*
100 * Scan each file specified to be scanned.
101 */
102
103foreach( $files_to_scan as $file_name ) {
104	/*
105	 * Read SVG file.
106	 */
107	$svg_file = @file_get_contents( $file_name );
108
109	/*
110	 * If not found, report that and continue.
111	 */
112	if ( false === $svg_file ) {
113		$results['totals']['errors']++;
114
115		$results['files'][ $file_name ][] = array(
116			'errors' => 1,
117			'messages' => array(
118				array(
119					'message' => 'File specified could not be read (' . $file_name . ')',
120					'line' => null,
121				),
122			),
123		);
124
125		continue;
126	}
127
128	/*
129	 * Sanitize file and get issues found.
130	 */
131	$sanitize_status = $sanitizer->sanitize( $svg_file );
132
133	$xml_issues = $sanitizer->getXmlIssues();
134
135	/*
136	 * If we find no issues, simply note that.
137	 */
138	if ( empty( $xml_issues ) && ( false !== $sanitize_status ) ) {
139		$results['files'][ $file_name ] = array(
140			'errors' => 0,
141			'messages' => array()
142		);
143	}
144
145	/*
146	 * Could not sanitize the file.
147	 */
148	else if (
149		( '' === $sanitize_status ) ||
150		( false === $sanitize_status )
151	) {
152		$results['totals']['errors']++;
153
154		$results['files'][ $file_name ] = array(
155			'errors' => 1,
156			'messages' => array(
157				array(
158					'message' => 'Unable to sanitize file \'' . $file_name . '\'' ,
159					'line' => null,
160				)
161			),
162		);
163	}
164
165	/*
166	 * If we find issues, note it and update statistics.
167	 */
168
169	else {
170		$results['totals']['errors'] += count( $xml_issues );
171
172		$results['files'][ $file_name ] = array(
173			'errors' => count( $xml_issues ),
174			'messages' => $xml_issues,
175		);
176	}
177
178	unset( $svg_file );
179	unset( $xml_issues );
180	unset( $sanitize_status );
181}
182
183
184/*
185 * Exit with a status
186 * that reflects what issues
187 * we found.
188 */
189sysexit(
190	$results,
191	( $results['totals']['errors'] === 0 ? 0 : 1 )
192);
193