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