3737 * @package OC\Preview
3838 */
3939abstract class Bitmap extends ProviderV2 {
40+ /**
41+ * List of MIME types that this preview provider is allowed to process.
42+ *
43+ * These should correspond to the MIME types *identified* by Imagemagick
44+ * for files to be processed by this provider. These do / will not
45+ * necessarily need to match the MIME types stored in the database
46+ * (which are identified by IMimeTypeDetector).
47+ *
48+ * @return string Regular expression
49+ */
50+ abstract protected function getAllowedMimeTypes (): string ;
51+
52+ /**
53+ * @return list<string>
54+ */
55+ abstract protected function getMagicStrings (): array ;
56+
57+ abstract protected function getImagickFormatHint (): string ;
58+
4059 /**
4160 * {@inheritDoc}
4261 */
@@ -86,12 +105,25 @@ public function getThumbnail(File $file, int $maxX, int $maxY): ?IImage {
86105 * @param int $maxY
87106 *
88107 * @return \Imagick
108+ *
109+ * @throws \Exception
89110 */
90111 private function getResizedPreview ($ tmpPath , $ maxX , $ maxY ) {
91112 $ bp = new Imagick ();
92113
114+ if (!$ this ->isMagicStringSupported ($ tmpPath )) {
115+ throw new \Exception ('Invalid image type: magic string not recognized ' );
116+ }
117+
118+ // Validate mime type
119+ $ bp ->pingImage ($ this ->getImagickFormatHint () . ': ' . $ tmpPath . '[0] ' );
120+ $ mimeType = $ bp ->getImageMimeType ();
121+ if (!preg_match ($ this ->getAllowedMimeTypes (), $ mimeType )) {
122+ throw new \Exception ('File mime type does not match the preview provider: ' . $ mimeType );
123+ }
124+
93125 // Layer 0 contains either the bitmap or a flat representation of all vector layers
94- $ bp ->readImage ($ tmpPath . '[0] ' );
126+ $ bp ->readImage ($ this -> getImagickFormatHint () . ' : ' . $ tmpPath . '[0] ' );
95127
96128 $ bp = $ this ->resize ($ bp , $ maxX , $ maxY );
97129
@@ -100,6 +132,22 @@ private function getResizedPreview($tmpPath, $maxX, $maxY) {
100132 return $ bp ;
101133 }
102134
135+ private function isMagicStringSupported (string $ filepath ): bool {
136+ $ signatures = $ this ->getMagicStrings ();
137+ if (empty ($ signatures )) {
138+ return true ;
139+ }
140+ $ length = array_reduce ($ signatures , static fn (int $ carry , string $ signature ) => max ($ carry , strlen ($ signature )), 0 );
141+ $ firstBytes = file_get_contents ($ filepath , false , null , 0 , $ length );
142+ foreach ($ signatures as $ signature ) {
143+ if (str_starts_with ($ firstBytes , $ signature )) {
144+ return true ;
145+ }
146+ }
147+
148+ return false ;
149+ }
150+
103151 /**
104152 * Returns a resized \Imagick object
105153 *
0 commit comments