Intervention / image

PHP Image Processing
https://image.intervention.io
MIT License
13.88k stars 1.5k forks source link

Failed image format detection #1370

Closed pierrejoye closed 3 months ago

pierrejoye commented 3 months ago

Describe the bug $image = $manager->read('logo.png');

failed to detect a valid PNG file.

Code Example use Intervention\Image\ImageManager; use Intervention\Image\Drivers\Gd\Driver;

// create image manager with desired driver $manager = new ImageManager( new Driver()); $image = $manager->read('test.png'); $image->toPng()->save('foo.png');

Expected behavior logo.png loaded and saved as foo.png.

The reason is if there is no exif data, it is not a corrupt png, but exif_read_data will fail (horrible API):

$ exif logo.png
Corrupt data
The data provided does not follow the specification.
ExifLoader: The data supplied does not seem to contain EXIF data.

$ php -r "exif_read_data('logo.png');"
PHP Warning:  exif_read_data(logo.png): File not supported in Command line code on line 1
PHP Stack trace:
PHP   1. {main}() Command line code:0
PHP   2. exif_read_data($file = 'logo.png') Command line code:1

While the imagesize function does the format validation (signature+header):

 php -r 'print_r(getimagesize("test.png"));'
Array
(
    [0] => 434
    [1] => 83
    [2] => 3
    [3] => width="434" height="83"
    [bits] => 8
    [mime] => image/png
)

If fileinfo is available, I would recommed to use it instead:

php finfo.php
image/png; charset=binary%

using

<?php
$finfo = new finfo(FILEINFO_MIME);
echo $finfo->file('test.png');

However getimagesize is good enough for a sanity check (signatures can be tricked, so check of w/h could be done, GD/imagic do it as well).

It was working on older version of this package, so not really sure when this exif_read_data was introduced :)

Images (any without exif would do it but here is one) test

Environment (please complete the following information):

olivervogel commented 3 months ago

Thanks for the bug report. You are right, the exif_read_data() function gives a warning when reading one of the mentioned images. I'm just wondering why you see the warning since it should be suppressed. Do you have other settings active that disable the error control operator?

matthieuuu commented 3 months ago

Hello! Just ran into the same issue :) I use an error handler with set_error_handler() function, and the error was not suppressed since I didn't check error_reporting() return. I fixed it and now everything works fine, the error is suppressed as intended!

olivervogel commented 3 months ago

Thank you @matthieuuu . I suspected something similar. However, the implementation in the library can still be improved, as certain file formats cannot contain any EXIF data at all, but exif_read_data is still called. I will try to improve this.

pierrejoye commented 3 months ago

Hello,

Sorry for the late reply, been busy :)

Yes, it was the issue.

However I would still recommend not to use this function but to actually read the exif information. I suspect most users don't need these exif but on specific cases.

For the purpose of selecting a codec, getimagesize or fileinfo would do a faster job.

I have the code for a generic imageload (which provides the type as part of the gd instance then) in libgd, I need to do a release and add it to php, that would be even better :-)

olivervogel commented 3 months ago

As of version 3.7.1, calls to exif_read_data are avoided for PNG formats and other formats that do not support EXIF data. Adjustments to a custom error handler are no longer absolutely necessary.

pierrejoye commented 3 months ago

@olivervogel Danke! :)