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+ /**
54+ * @return list<string>
55+ */
56+ abstract protected function getMagicStrings (): array ;
57+
58+ abstract protected function getImagickFormatHint (): string ;
59+
4060 /**
4161 * {@inheritDoc}
4262 */
@@ -90,8 +110,19 @@ public function getThumbnail(File $file, int $maxX, int $maxY): ?IImage {
90110 private function getResizedPreview ($ tmpPath , $ maxX , $ maxY ) {
91111 $ bp = new Imagick ();
92112
113+ if (!$ this ->isMagicStringSupported ($ tmpPath )) {
114+ throw new \Exception ('Invalid image type: magic string not recognized ' );
115+ }
116+
117+ // Validate mime type
118+ $ bp ->pingImage ($ this ->getImagickFormatHint () . ': ' . $ tmpPath . '[0] ' );
119+ $ mimeType = $ bp ->getImageMimeType ();
120+ if (!preg_match ($ this ->getAllowedMimeTypes (), $ mimeType )) {
121+ throw new \Exception ('File mime type does not match the preview provider: ' . $ mimeType );
122+ }
123+
93124 // Layer 0 contains either the bitmap or a flat representation of all vector layers
94- $ bp ->readImage ($ tmpPath . '[0] ' );
125+ $ bp ->readImage ($ this -> getImagickFormatHint () . ' : ' . $ tmpPath . '[0] ' );
95126
96127 $ bp = $ this ->resize ($ bp , $ maxX , $ maxY );
97128
@@ -100,6 +131,22 @@ private function getResizedPreview($tmpPath, $maxX, $maxY) {
100131 return $ bp ;
101132 }
102133
134+ private function isMagicStringSupported (string $ filepath ): bool {
135+ $ signatures = $ this ->getMagicStrings ();
136+ if (empty ($ signatures )) {
137+ return true ;
138+ }
139+ $ length = array_reduce ($ signatures , static fn (int $ carry , string $ signature ) => max ($ carry , strlen ($ signature )), 0 );
140+ $ firstBytes = file_get_contents ($ filepath , false , null , 0 , $ length );
141+ foreach ($ signatures as $ signature ) {
142+ if (str_starts_with ($ firstBytes , $ signature )) {
143+ return true ;
144+ }
145+ }
146+
147+ return false ;
148+ }
149+
103150 /**
104151 * Returns a resized \Imagick object
105152 *
0 commit comments