@@ -30,12 +30,12 @@ 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+ $ content = ltrim ($ content );
3334 if (substr ($ content , 0 , 5 ) !== '<?xml ' ) {
3435 $ content = '<?xml version="1.0" encoding="UTF-8" standalone="no"?> ' . $ content ;
3536 }
3637
37- // Do not parse SVG files with references
38- if (preg_match ('/["\s](xlink:)?href\s*=/i ' , $ content )) {
38+ if (!$ this ->canBeProcessed ($ content )) {
3939 return null ;
4040 }
4141
@@ -72,4 +72,26 @@ public function getThumbnail(File $file, int $maxX, int $maxY): ?IImage {
7272 }
7373 return null ;
7474 }
75+
76+ /**
77+ * Check if the file can be processed by this provider,
78+ * meaning the SVG is safe to be processed and does not contain any external references.
79+ */
80+ protected function canBeProcessed (string $ content ): bool {
81+ // check for allowed encodings and convert if necessary
82+ $ encoding = mb_detect_encoding ($ content , ['UTF-8 ' , 'ISO-2022-JP ' , 'ISO-8859-1 ' ], true );
83+ if ($ encoding === false ) {
84+ return false ;
85+ } elseif ($ encoding !== 'UTF-8 ' ) {
86+ $ content = mb_convert_encoding ($ content , 'UTF-8 ' , $ encoding );
87+ }
88+
89+ // Strip all non-printable/control characters except newlines/tabs
90+ $ content = preg_replace ('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/ ' , '' , $ content );
91+ // check for any potential external reference (include custom namespace prefix)
92+ if (preg_match ('/["\s \']([a-z_][a-z0-9_.]*:)?href\s*=/i ' , $ content )) {
93+ return false ;
94+ }
95+ return true ;
96+ }
7597}
0 commit comments