1
0
mirror of https://github.com/Intervention/image.git synced 2025-08-23 22:12:51 +02:00

Drop support for PHP 8.1

This commit is contained in:
Oliver Vogel
2025-06-21 11:38:22 +02:00
parent 19d4ea411e
commit 77bdf1648e
11 changed files with 37 additions and 29 deletions

View File

@@ -8,7 +8,7 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
php: [ '8.1', '8.2', '8.3', '8.4' ] php: [ '8.2', '8.3', '8.4' ]
imagemagick: [ '6.9.13-25', '7.1.1-47' ] imagemagick: [ '6.9.13-25', '7.1.1-47' ]
imagick: [ '3.8.0' ] imagick: [ '3.8.0' ]

View File

@@ -1,4 +1,4 @@
FROM php:8.1-cli FROM php:8.2-cli
# install dependencies # install dependencies
RUN apt update \ RUN apt update \

View File

@@ -19,7 +19,7 @@
} }
], ],
"require": { "require": {
"php": "^8.1", "php": "^8.2",
"ext-mbstring": "*", "ext-mbstring": "*",
"intervention/gif": "^4.2" "intervention/gif": "^4.2"
}, },

View File

@@ -63,15 +63,27 @@ abstract class AbstractDecoder implements DecoderInterface
} }
/** /**
* Determine if given input is base64 encoded data * Decodes given base 64 encoded data
*
* @throws DecoderException
*/ */
protected function isValidBase64(mixed $input): bool protected function decodeBase64Data(mixed $input): string
{ {
if (!is_string($input)) { if (!is_string($input)) {
return false; throw new DecoderException('Input is not Base64-encoded data.');
} }
return base64_encode(base64_decode($input)) === str_replace(["\n", "\r"], '', $input); $decoded = base64_decode($input);
if ($decoded === false) {
throw new DecoderException('Input can not be Base64-decoded.');
}
if (base64_encode($decoded) !== str_replace(["\n", "\r"], '', $input)) {
throw new DecoderException('Input is not Base64-decoded data.');
}
return $decoded;
} }
/** /**

View File

@@ -4,7 +4,6 @@ declare(strict_types=1);
namespace Intervention\Image\Drivers\Gd\Decoders; namespace Intervention\Image\Drivers\Gd\Decoders;
use Intervention\Image\Exceptions\DecoderException;
use Intervention\Image\Interfaces\ColorInterface; use Intervention\Image\Interfaces\ColorInterface;
use Intervention\Image\Interfaces\DecoderInterface; use Intervention\Image\Interfaces\DecoderInterface;
use Intervention\Image\Interfaces\ImageInterface; use Intervention\Image\Interfaces\ImageInterface;
@@ -18,10 +17,6 @@ class Base64ImageDecoder extends BinaryImageDecoder implements DecoderInterface
*/ */
public function decode(mixed $input): ImageInterface|ColorInterface public function decode(mixed $input): ImageInterface|ColorInterface
{ {
if (!$this->isValidBase64($input)) { return parent::decode($this->decodeBase64Data($input));
throw new DecoderException('Unable to decode input');
}
return parent::decode(base64_decode((string) $input));
} }
} }

View File

@@ -21,8 +21,8 @@ class BinaryImageDecoder extends NativeObjectDecoder implements DecoderInterface
*/ */
public function decode(mixed $input): ImageInterface|ColorInterface public function decode(mixed $input): ImageInterface|ColorInterface
{ {
if (!is_string($input)) { if (!is_string($input) || empty($input)) {
throw new DecoderException('Unable to decode input'); throw new DecoderException('Input does not contain binary image data.');
} }
return match ($this->isGifFormat($input)) { return match ($this->isGifFormat($input)) {
@@ -41,7 +41,7 @@ class BinaryImageDecoder extends NativeObjectDecoder implements DecoderInterface
$gd = @imagecreatefromstring($input); $gd = @imagecreatefromstring($input);
if ($gd === false) { if ($gd === false) {
throw new DecoderException('Unable to decode input'); throw new DecoderException('Unsupported image format.');
} }
// create image instance // create image instance

View File

@@ -28,7 +28,7 @@ class FilePathImageDecoder extends NativeObjectDecoder implements DecoderInterfa
// detect media (mime) type // detect media (mime) type
$mediaType = $this->getMediaTypeByFilePath($path); $mediaType = $this->getMediaTypeByFilePath($path);
} catch (Throwable) { } catch (Throwable) {
throw new DecoderException('Unable to decode input - file contains unsupported file type.'); throw new DecoderException('File contains unsupported image format.');
} }
$image = match ($mediaType->format()) { $image = match ($mediaType->format()) {
@@ -41,7 +41,7 @@ class FilePathImageDecoder extends NativeObjectDecoder implements DecoderInterfa
Format::PNG => @imagecreatefrompng($path), Format::PNG => @imagecreatefrompng($path),
Format::AVIF => @imagecreatefromavif($path), Format::AVIF => @imagecreatefromavif($path),
Format::BMP => @imagecreatefrombmp($path), Format::BMP => @imagecreatefrombmp($path),
default => throw new DecoderException('Unable to decode input'), default => throw new DecoderException('File contains unsupported image format.'),
}), }),
}; };

View File

@@ -4,7 +4,6 @@ declare(strict_types=1);
namespace Intervention\Image\Drivers\Imagick\Decoders; namespace Intervention\Image\Drivers\Imagick\Decoders;
use Intervention\Image\Exceptions\DecoderException;
use Intervention\Image\Interfaces\ColorInterface; use Intervention\Image\Interfaces\ColorInterface;
use Intervention\Image\Interfaces\ImageInterface; use Intervention\Image\Interfaces\ImageInterface;
@@ -17,10 +16,6 @@ class Base64ImageDecoder extends BinaryImageDecoder
*/ */
public function decode(mixed $input): ImageInterface|ColorInterface public function decode(mixed $input): ImageInterface|ColorInterface
{ {
if (!$this->isValidBase64($input)) { return parent::decode($this->decodeBase64Data($input));
throw new DecoderException('Unable to decode input');
}
return parent::decode(base64_decode((string) $input));
} }
} }

View File

@@ -20,15 +20,15 @@ class BinaryImageDecoder extends NativeObjectDecoder
*/ */
public function decode(mixed $input): ImageInterface|ColorInterface public function decode(mixed $input): ImageInterface|ColorInterface
{ {
if (!is_string($input)) { if (!is_string($input) || empty($input)) {
throw new DecoderException('Unable to decode input'); throw new DecoderException('Input does not contain binary image data.');
} }
try { try {
$imagick = new Imagick(); $imagick = new Imagick();
$imagick->readImageBlob($input); $imagick->readImageBlob($input);
} catch (ImagickException) { } catch (ImagickException) {
throw new DecoderException('Unable to decode input'); throw new DecoderException('Unsupported image format.');
} }
// decode image // decode image

View File

@@ -26,7 +26,7 @@ class FilePathImageDecoder extends NativeObjectDecoder
$imagick = new Imagick(); $imagick = new Imagick();
$imagick->readImage($path); $imagick->readImage($path);
} catch (ImagickException) { } catch (ImagickException) {
throw new DecoderException('Unable to decode input'); throw new DecoderException('Unsupported image format.');
} }
// decode image // decode image

View File

@@ -16,6 +16,7 @@ use Intervention\Image\Tests\BaseTestCase;
use Mockery; use Mockery;
use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\DataProvider;
use stdClass; use stdClass;
use Throwable;
#[CoversClass(AbstractDecoder::class)] #[CoversClass(AbstractDecoder::class)]
final class AbstractDecoderTest extends BaseTestCase final class AbstractDecoderTest extends BaseTestCase
@@ -95,7 +96,12 @@ final class AbstractDecoderTest extends BaseTestCase
{ {
public function isValid(mixed $input): bool public function isValid(mixed $input): bool
{ {
return parent::isValidBase64($input); try {
parent::decodeBase64Data($input);
} catch (Throwable) {
return false;
}
return true;
} }
public function decode(mixed $input): ImageInterface|ColorInterface public function decode(mixed $input): ImageInterface|ColorInterface