Signed-off-by: Varun Patil <varunpatil@ucla.edu>tags/v27.1.10rc1
@@ -37,6 +37,18 @@ use Psr\Log\LoggerInterface; | |||
* @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} | |||
*/ | |||
@@ -86,10 +98,19 @@ abstract class Bitmap extends ProviderV2 { | |||
* @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]'); | |||
@@ -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$)/'; | |||
} | |||
} |
@@ -44,7 +44,7 @@ class HEIC extends ProviderV2 { | |||
* {@inheritDoc} | |||
*/ | |||
public function getMimeType(): string { | |||
return '/image\/hei(f|c)/'; | |||
return '/image\/(x-)?hei(f|c)/'; | |||
} | |||
/** | |||
@@ -108,10 +108,20 @@ class HEIC extends ProviderV2 { | |||
* @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]'); | |||
@@ -31,4 +31,11 @@ class Illustrator extends Bitmap { | |||
public function getMimeType(): string { | |||
return '/application\/illustrator/'; | |||
} | |||
/** | |||
* {@inheritDoc} | |||
*/ | |||
protected function getAllowedMimeTypes(): string { | |||
return '/application\/(illustrator|pdf)/'; | |||
} | |||
} |
@@ -31,4 +31,11 @@ class PDF extends Bitmap { | |||
public function getMimeType(): string { | |||
return '/application\/pdf/'; | |||
} | |||
/** | |||
* {@inheritDoc} | |||
*/ | |||
protected function getAllowedMimeTypes(): string { | |||
return '/application\/pdf/'; | |||
} | |||
} |
@@ -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)/'; | |||
} | |||
} |
@@ -31,4 +31,11 @@ class Postscript extends Bitmap { | |||
public function getMimeType(): string { | |||
return '/application\/postscript/'; | |||
} | |||
/** | |||
* {@inheritDoc} | |||
*/ | |||
protected function getAllowedMimeTypes(): string { | |||
return '/application\/postscript/'; | |||
} | |||
} |
@@ -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/'; | |||
} | |||
} |
@@ -44,9 +44,6 @@ class SVG extends ProviderV2 { | |||
*/ | |||
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; | |||
@@ -57,13 +54,25 @@ class SVG extends ProviderV2 { | |||
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; | |||
} | |||
@@ -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/'; | |||
} | |||
} |
@@ -31,4 +31,11 @@ class TIFF extends Bitmap { | |||
public function getMimeType(): string { | |||
return '/image\/tiff/'; | |||
} | |||
/** | |||
* {@inheritDoc} | |||
*/ | |||
protected function getAllowedMimeTypes(): string { | |||
return '/image\/tiff/'; | |||
} | |||
} |
@@ -381,9 +381,9 @@ class PreviewManager implements IPreview { | |||
'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) { |