问题
When I'm trying use php-gd functions on incorrect png images, I have Fatal PHP error. It seems to be some kind of bug, because accordingly to the functions documentation (imagecreatefrompng
, for example):
* @return resource an image resource identifier on success, false on errors.
But when I try to do it with my incorrect image, I have:
Fatal error: imagecreatefrompng(): gd-png: fatal libpng error: Read Error: truncated data in /var/www/common/models/Utils.php on line 61
The code that leads to this error is simple:
$handle = imagecreatefrompng($fname);
No code executes after this string.
The same behaviour is for imagecreatefromstring
when trying to create an image from the same string.
I can't "fix" this picture, because it is user-provided, so I need to handle this cases.
I tried to use try...catch
block like this:
echo 'start'."\n";
try {
imagecreatefromstring($result);
} catch (\Throwable $e) {
echo 'error'."\n";
return null;
}
echo 'success'."\n";
But script outputs only "start", and then dies and shows error description I have posted above.
Ubuntu 16.04.2, PHP 7.0, php7.0-gd extension, both are latest version.
So I can't handle it with try...catch block and I don't know how to handle or fix it at all. Any ideas?
UPD: It seems to be really weird bug with environment, because when I run same code under Windows (with PHP 7.0) it produces correct "Warning" error.
UPD2: It seems to be that fresh bug https://bugs.php.net/bug.php?id=73986
回答1:
A bit late to the party, but i ran into this problem as well, and cannot wait for the bug fix to be included in my ubuntu LTS The only clean workaround i found is actually to use Imagick::valid() check the image is valid.
function imageIsValid($path)
{
try
{
$imagick = new \Imagick($path);
return $imagick->valid();
}
catch (\Exception $e)
{
return false;
}
}
Of course, your server/hosting needs to have php imagick extension installed...
回答2:
It seems to be fresh bug (and possibly not closed): https://bugs.php.net/bug.php?id=73986
So until I will find better way, I think it is only one way to check image. It is BAD code and i know it, but I have no other ideas. The idea is to try create an image in another thread and return check value depends on it's output.
$fname = tempnam('/tmp', 'test_');
$handle = fopen($fname, 'w');
fwrite($handle, $result);
fclose($handle);
$output = `php -r "imagecreatefrompng('$fname');" 2>&1`;
unlink($fname);
if (!empty($output)) {
return null; // error
}
// good image
Backtrick operator will execute command in shell. Than it will output error to stderr
. 2>&1
used to make stderr
stream output to stdout
stream so it can be accessed via backtrick operator.
回答3:
Since PHP7 all errors are exceptions so you can simply wrap fragile code part inside try-catch block to catch the \Throwable exception and handle accordingly.
来源:https://stackoverflow.com/questions/45174672/imagecreatefrompng-and-imagecreatefromstring-causes-to-unrecoverable-fatal-err