@@ -45,15 +45,19 @@ public function getMimeType(): string {
4545 public function getThumbnail (File $ file , int $ maxX , int $ maxY ): ?IImage {
4646 try {
4747 $ content = stream_get_contents ($ file ->fopen ('r ' ));
48- if (substr ( $ content, 0 , 5 ) !== ' <?xml ' ) {
49- $ content = ' <?xml version="1.0" encoding="UTF-8" standalone="no"?> ' . $ content ;
48+ if ($ content === false ) {
49+ return null ;
5050 }
51-
52- // Do not parse SVG files with references
53- if (preg_match ('/["\s](xlink:)?href\s*=/i ' , $ content )) {
51+ // check if the file can be processed by this provider
52+ if (!$ this ->canBeProcessed ($ content )) {
5453 return null ;
5554 }
5655
56+ $ content = ltrim ($ content );
57+ if (substr ($ content , 0 , 5 ) !== '<?xml ' ) {
58+ $ content = '<?xml version="1.0" encoding="UTF-8" standalone="no"?> ' . $ content ;
59+ }
60+
5761 $ svg = new \Imagick ();
5862
5963 $ svg ->pingImageBlob ($ content );
@@ -87,4 +91,30 @@ public function getThumbnail(File $file, int $maxX, int $maxY): ?IImage {
8791 }
8892 return null ;
8993 }
94+
95+ /**
96+ * Check if the file can be processed by this provider,
97+ * meaning the SVG is safe to be processed and does not contain any external references.
98+ */
99+ protected function canBeProcessed (string $ content ): bool {
100+ // check for allowed encodings and convert if necessary
101+ $ encoding = mb_detect_encoding ($ content , ['ISO-2022-JP ' , 'UTF-8 ' , 'ISO-8859-1 ' ], true );
102+ if ($ encoding === false ) {
103+ return false ;
104+ } elseif ($ encoding !== 'UTF-8 ' ) {
105+ $ content = mb_convert_encoding ($ content , 'UTF-8 ' , $ encoding );
106+ }
107+
108+ // Strip all non-printable/control characters except newlines/tabs
109+ $ content = preg_replace ('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/ ' , '' , $ content );
110+ if ($ content === null ) {
111+ return false ;
112+ }
113+
114+ // check for any potential external reference (include custom namespace prefix)
115+ if (preg_match ('/["\s \']([a-z_][a-z0-9_.-]*:)?href\s*=/i ' , $ content )) {
116+ return false ;
117+ }
118+ return true ;
119+ }
90120}
0 commit comments