Skip to content

Commit 7fd3aa1

Browse files
pulsejetbackportbot[bot]
authored andcommitted
fix(preview): check mime type before processing with Imagick
Signed-off-by: Varun Patil <varunpatil@ucla.edu>
1 parent f816957 commit 7fd3aa1

File tree

12 files changed

+109
-13
lines changed

12 files changed

+109
-13
lines changed

lib/private/Preview/Bitmap.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,18 @@
3737
* @package OC\Preview
3838
*/
3939
abstract 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+
4052
/**
4153
* {@inheritDoc}
4254
*/
@@ -86,10 +98,19 @@ public function getThumbnail(File $file, int $maxX, int $maxY): ?IImage {
8698
* @param int $maxY
8799
*
88100
* @return \Imagick
101+
*
102+
* @throws \Exception
89103
*/
90104
private function getResizedPreview($tmpPath, $maxX, $maxY) {
91105
$bp = new Imagick();
92106

107+
// Validate mime type
108+
$bp->pingImage($tmpPath . '[0]');
109+
$mimeType = $bp->getImageMimeType();
110+
if (!preg_match($this->getAllowedMimeTypes(), $mimeType)) {
111+
throw new \Exception('File mime type does not match the preview provider: ' . $mimeType);
112+
}
113+
93114
// Layer 0 contains either the bitmap or a flat representation of all vector layers
94115
$bp->readImage($tmpPath . '[0]');
95116

lib/private/Preview/Font.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,11 @@ class Font extends Bitmap {
3030
public function getMimeType(): string {
3131
return '/application\/(?:font-sfnt|x-font$)/';
3232
}
33+
34+
/**
35+
* {@inheritDoc}
36+
*/
37+
protected function getAllowedMimeTypes(): string {
38+
return '/(application|image)\/(?:font-sfnt|x-font|x-otf|x-ttf|x-pfb$)/';
39+
}
3340
}

lib/private/Preview/HEIC.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class HEIC extends ProviderV2 {
4444
* {@inheritDoc}
4545
*/
4646
public function getMimeType(): string {
47-
return '/image\/hei(f|c)/';
47+
return '/image\/(x-)?hei(f|c)/';
4848
}
4949

5050
/**
@@ -108,10 +108,20 @@ public function getThumbnail(File $file, int $maxX, int $maxY): ?IImage {
108108
* @param int $maxY
109109
*
110110
* @return \Imagick
111+
*
112+
* @throws \Exception
111113
*/
112114
private function getResizedPreview($tmpPath, $maxX, $maxY) {
113115
$bp = new \Imagick();
114116

117+
// Some HEIC files just contain (or at least are identified as) other formats
118+
// like JPEG. We just need to check if the image is safe to process.
119+
$bp->pingImage($tmpPath . '[0]');
120+
$mimeType = $bp->getImageMimeType();
121+
if (!preg_match('/^image\/(x-)?(png|jpeg|gif|bmp|tiff|webp|hei(f|c)|avif)$/', $mimeType)) {
122+
throw new \Exception('File mime type does not match the preview provider: ' . $mimeType);
123+
}
124+
115125
// Layer 0 contains either the bitmap or a flat representation of all vector layers
116126
$bp->readImage($tmpPath . '[0]');
117127

lib/private/Preview/Illustrator.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,11 @@ class Illustrator extends Bitmap {
3131
public function getMimeType(): string {
3232
return '/application\/illustrator/';
3333
}
34+
35+
/**
36+
* {@inheritDoc}
37+
*/
38+
protected function getAllowedMimeTypes(): string {
39+
return '/application\/(illustrator|pdf)/';
40+
}
3441
}

lib/private/Preview/PDF.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,11 @@ class PDF extends Bitmap {
3131
public function getMimeType(): string {
3232
return '/application\/pdf/';
3333
}
34+
35+
/**
36+
* {@inheritDoc}
37+
*/
38+
protected function getAllowedMimeTypes(): string {
39+
return '/application\/pdf/';
40+
}
3441
}

lib/private/Preview/Photoshop.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,11 @@ class Photoshop extends Bitmap {
3131
public function getMimeType(): string {
3232
return '/application\/x-photoshop/';
3333
}
34+
35+
/**
36+
* {@inheritDoc}
37+
*/
38+
protected function getAllowedMimeTypes(): string {
39+
return '/(application|image)\/(x-photoshop|x-psd)/';
40+
}
3441
}

lib/private/Preview/Postscript.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,11 @@ class Postscript extends Bitmap {
3131
public function getMimeType(): string {
3232
return '/application\/postscript/';
3333
}
34+
35+
/**
36+
* {@inheritDoc}
37+
*/
38+
protected function getAllowedMimeTypes(): string {
39+
return '/application\/postscript/';
40+
}
3441
}

lib/private/Preview/SGI.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,13 @@ class SGI extends Bitmap {
2828
* {@inheritDoc}
2929
*/
3030
public function getMimeType(): string {
31-
return '/image\/sgi/';
31+
return '/image\/(x-)?sgi/';
32+
}
33+
34+
/**
35+
* {@inheritDoc}
36+
*/
37+
protected function getAllowedMimeTypes(): string {
38+
return '/image\/(x-)?sgi/';
3239
}
3340
}

lib/private/Preview/SVG.php

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,6 @@ public function getMimeType(): string {
4444
*/
4545
public function getThumbnail(File $file, int $maxX, int $maxY): ?IImage {
4646
try {
47-
$svg = new \Imagick();
48-
$svg->setBackgroundColor(new \ImagickPixel('transparent'));
49-
5047
$content = stream_get_contents($file->fopen('r'));
5148
if (substr($content, 0, 5) !== '<?xml') {
5249
$content = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>' . $content;
@@ -57,13 +54,25 @@ public function getThumbnail(File $file, int $maxX, int $maxY): ?IImage {
5754
return null;
5855
}
5956

57+
$svg = new \Imagick();
58+
59+
$svg->pingImageBlob($content);
60+
$mimeType = $svg->getImageMimeType();
61+
if (!preg_match($this->getMimeType(), $mimeType)) {
62+
throw new \Exception('File mime type does not match the preview provider: ' . $mimeType);
63+
}
64+
65+
$svg->setBackgroundColor(new \ImagickPixel('transparent'));
6066
$svg->readImageBlob($content);
6167
$svg->setImageFormat('png32');
6268
} catch (\Exception $e) {
63-
\OC::$server->get(LoggerInterface::class)->error($e->getMessage(), [
64-
'exception' => $e,
65-
'app' => 'core',
66-
]);
69+
\OC::$server->get(LoggerInterface::class)->error(
70+
'File: ' . $file->getPath() . ' Imagick says:',
71+
[
72+
'exception' => $e,
73+
'app' => 'core',
74+
]
75+
);
6776
return null;
6877
}
6978

lib/private/Preview/TGA.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,13 @@ class TGA extends Bitmap {
2828
* {@inheritDoc}
2929
*/
3030
public function getMimeType(): string {
31-
return '/image\/t(ar)?ga/';
31+
return '/image\/(x-)?t(ar)?ga/';
32+
}
33+
34+
/**
35+
* {@inheritDoc}
36+
*/
37+
protected function getAllowedMimeTypes(): string {
38+
return '/image\/(x-)?t(ar)?ga/';
3239
}
3340
}

0 commit comments

Comments
 (0)