@@ -29,15 +29,19 @@ public function getMimeType(): string {
2929 public function getThumbnail (File $ file , int $ maxX , int $ maxY ): ?IImage {
3030 try {
3131 $ content = stream_get_contents ($ file ->fopen ('r ' ));
32- if (substr ( $ content, 0 , 5 ) !== ' <?xml ' ) {
33- $ content = ' <?xml version="1.0" encoding="UTF-8" standalone="no"?> ' . $ content ;
32+ if ($ content === false ) {
33+ return null ;
3434 }
35-
36- // Do not parse SVG files with references
37- if (preg_match ('/["\s](xlink:)?href\s*=/i ' , $ content )) {
35+ // check if the file can be processed by this provider
36+ if (!$ this ->canBeProcessed ($ content )) {
3837 return null ;
3938 }
4039
40+ $ content = ltrim ($ content );
41+ if (substr ($ content , 0 , 5 ) !== '<?xml ' ) {
42+ $ content = '<?xml version="1.0" encoding="UTF-8" standalone="no"?> ' . $ content ;
43+ }
44+
4145 $ svg = new \Imagick ();
4246
4347 $ svg ->pingImageBlob ($ content );
@@ -71,4 +75,30 @@ public function getThumbnail(File $file, int $maxX, int $maxY): ?IImage {
7175 }
7276 return null ;
7377 }
78+
79+ /**
80+ * Check if the file can be processed by this provider,
81+ * meaning the SVG is safe to be processed and does not contain any external references.
82+ */
83+ protected function canBeProcessed (string $ content ): bool {
84+ // check for allowed encodings and convert if necessary
85+ $ encoding = mb_detect_encoding ($ content , ['UTF-8 ' , 'ISO-2022-JP ' , 'ISO-8859-1 ' ], true );
86+ if ($ encoding === false ) {
87+ return false ;
88+ } elseif ($ encoding !== 'UTF-8 ' ) {
89+ $ content = mb_convert_encoding ($ content , 'UTF-8 ' , $ encoding );
90+ }
91+
92+ // Strip all non-printable/control characters except newlines/tabs
93+ $ content = preg_replace ('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/ ' , '' , $ content );
94+ if ($ content === null ) {
95+ return false ;
96+ }
97+
98+ // check for any potential external reference (include custom namespace prefix)
99+ if (preg_match ('/["\s \']([a-z_][a-z0-9_.-]*:)?href\s*=/i ' , $ content )) {
100+ return false ;
101+ }
102+ return true ;
103+ }
74104}
0 commit comments