Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions lib/private/Preview/Bitmap.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,18 @@
* @package OC\Preview
*/
abstract class Bitmap extends ProviderV2 {
/**
* List of MIME types that this preview provider is allowed to process.
*
* These should correspond to the MIME types *identified* by Imagemagick
* for files to be processed by this provider. These do / will not
* necessarily need to match the MIME types stored in the database
* (which are identified by IMimeTypeDetector).
*
* @return string Regular expression
*/
abstract protected function getAllowedMimeTypes(): string;

/**
* {@inheritDoc}
*/
Expand Down Expand Up @@ -86,10 +98,19 @@ public function getThumbnail(File $file, int $maxX, int $maxY): ?IImage {
* @param int $maxY
*
* @return \Imagick
*
* @throws \Exception
*/
private function getResizedPreview($tmpPath, $maxX, $maxY) {
$bp = new Imagick();

// Validate mime type
$bp->pingImage($tmpPath . '[0]');
$mimeType = $bp->getImageMimeType();
if (!preg_match($this->getAllowedMimeTypes(), $mimeType)) {
throw new \Exception('File mime type does not match the preview provider: ' . $mimeType);
}

// Layer 0 contains either the bitmap or a flat representation of all vector layers
$bp->readImage($tmpPath . '[0]');

Expand Down
7 changes: 7 additions & 0 deletions lib/private/Preview/Font.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,11 @@ class Font extends Bitmap {
public function getMimeType(): string {
return '/application\/(?:font-sfnt|x-font$)/';
}

/**
* {@inheritDoc}
*/
protected function getAllowedMimeTypes(): string {
return '/(application|image)\/(?:font-sfnt|x-font|x-otf|x-ttf|x-pfb$)/';
}
}
12 changes: 11 additions & 1 deletion lib/private/Preview/HEIC.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class HEIC extends ProviderV2 {
* {@inheritDoc}
*/
public function getMimeType(): string {
return '/image\/hei(f|c)/';
return '/image\/(x-)?hei(f|c)/';
}

/**
Expand Down Expand Up @@ -108,10 +108,20 @@ public function getThumbnail(File $file, int $maxX, int $maxY): ?IImage {
* @param int $maxY
*
* @return \Imagick
*
* @throws \Exception
*/
private function getResizedPreview($tmpPath, $maxX, $maxY) {
$bp = new \Imagick();

// Some HEIC files just contain (or at least are identified as) other formats
// like JPEG. We just need to check if the image is safe to process.
$bp->pingImage($tmpPath . '[0]');
$mimeType = $bp->getImageMimeType();
if (!preg_match('/^image\/(x-)?(png|jpeg|gif|bmp|tiff|webp|hei(f|c)|avif)$/', $mimeType)) {
throw new \Exception('File mime type does not match the preview provider: ' . $mimeType);
}

// Layer 0 contains either the bitmap or a flat representation of all vector layers
$bp->readImage($tmpPath . '[0]');

Expand Down
7 changes: 7 additions & 0 deletions lib/private/Preview/Illustrator.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,11 @@ class Illustrator extends Bitmap {
public function getMimeType(): string {
return '/application\/illustrator/';
}

/**
* {@inheritDoc}
*/
protected function getAllowedMimeTypes(): string {
return '/application\/(illustrator|pdf)/';
}
}
7 changes: 7 additions & 0 deletions lib/private/Preview/PDF.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,11 @@ class PDF extends Bitmap {
public function getMimeType(): string {
return '/application\/pdf/';
}

/**
* {@inheritDoc}
*/
protected function getAllowedMimeTypes(): string {
return '/application\/pdf/';
}
}
7 changes: 7 additions & 0 deletions lib/private/Preview/Photoshop.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,11 @@ class Photoshop extends Bitmap {
public function getMimeType(): string {
return '/application\/x-photoshop/';
}

/**
* {@inheritDoc}
*/
protected function getAllowedMimeTypes(): string {
return '/(application|image)\/(x-photoshop|x-psd)/';
}
}
7 changes: 7 additions & 0 deletions lib/private/Preview/Postscript.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,11 @@ class Postscript extends Bitmap {
public function getMimeType(): string {
return '/application\/postscript/';
}

/**
* {@inheritDoc}
*/
protected function getAllowedMimeTypes(): string {
return '/application\/postscript/';
}
}
9 changes: 8 additions & 1 deletion lib/private/Preview/SGI.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@ class SGI extends Bitmap {
* {@inheritDoc}
*/
public function getMimeType(): string {
return '/image\/sgi/';
return '/image\/(x-)?sgi/';
}

/**
* {@inheritDoc}
*/
protected function getAllowedMimeTypes(): string {
return '/image\/(x-)?sgi/';
}
}
23 changes: 16 additions & 7 deletions lib/private/Preview/SVG.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,6 @@ public function getMimeType(): string {
*/
public function getThumbnail(File $file, int $maxX, int $maxY): ?IImage {
try {
$svg = new \Imagick();
$svg->setBackgroundColor(new \ImagickPixel('transparent'));

$content = stream_get_contents($file->fopen('r'));
if (substr($content, 0, 5) !== '<?xml') {
$content = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>' . $content;
Expand All @@ -57,13 +54,25 @@ public function getThumbnail(File $file, int $maxX, int $maxY): ?IImage {
return null;
}

$svg = new \Imagick();

$svg->pingImageBlob($content);
$mimeType = $svg->getImageMimeType();
if (!preg_match($this->getMimeType(), $mimeType)) {
throw new \Exception('File mime type does not match the preview provider: ' . $mimeType);
}

$svg->setBackgroundColor(new \ImagickPixel('transparent'));
$svg->readImageBlob($content);
$svg->setImageFormat('png32');
} catch (\Exception $e) {
\OC::$server->get(LoggerInterface::class)->error($e->getMessage(), [
'exception' => $e,
'app' => 'core',
]);
\OC::$server->get(LoggerInterface::class)->error(
'File: ' . $file->getPath() . ' Imagick says:',
[
'exception' => $e,
'app' => 'core',
]
);
return null;
}

Expand Down
9 changes: 8 additions & 1 deletion lib/private/Preview/TGA.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@ class TGA extends Bitmap {
* {@inheritDoc}
*/
public function getMimeType(): string {
return '/image\/t(ar)?ga/';
return '/image\/(x-)?t(ar)?ga/';
}

/**
* {@inheritDoc}
*/
protected function getAllowedMimeTypes(): string {
return '/image\/(x-)?t(ar)?ga/';
}
}
7 changes: 7 additions & 0 deletions lib/private/Preview/TIFF.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,11 @@ class TIFF extends Bitmap {
public function getMimeType(): string {
return '/image\/tiff/';
}

/**
* {@inheritDoc}
*/
protected function getAllowedMimeTypes(): string {
return '/image\/tiff/';
}
}
6 changes: 3 additions & 3 deletions lib/private/PreviewManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -376,9 +376,9 @@ protected function registerCoreProviders() {
'PSD' => ['mimetype' => '/application\/x-photoshop/', 'class' => Preview\Photoshop::class],
'EPS' => ['mimetype' => '/application\/postscript/', 'class' => Preview\Postscript::class],
'TTF' => ['mimetype' => '/application\/(?:font-sfnt|x-font$)/', 'class' => Preview\Font::class],
'HEIC' => ['mimetype' => '/image\/hei(f|c)/', 'class' => Preview\HEIC::class],
'TGA' => ['mimetype' => '/image\/t(ar)?ga/', 'class' => Preview\TGA::class],
'SGI' => ['mimetype' => '/image\/sgi/', 'class' => Preview\SGI::class],
'HEIC' => ['mimetype' => '/image\/(x-)?hei(f|c)/', 'class' => Preview\HEIC::class],
'TGA' => ['mimetype' => '/image\/(x-)?t(ar)?ga/', 'class' => Preview\TGA::class],
'SGI' => ['mimetype' => '/image\/(x-)?sgi/', 'class' => Preview\SGI::class],
];

foreach ($imagickProviders as $queryFormat => $provider) {
Expand Down