imagecreatefrompng(和imagecreatefromstring)导致无法恢复的致命错误

时间:2017-07-18 18:41:15

标签: php php-7 php-gd

当我尝试在不正确的png图像上使用php-gd函数时,我有致命的PHP错误。它似乎是某种bug,因为相应的函数文档(例如imagecreatefrompng):

* @return resource an image resource identifier on success, false on errors.

但是当我尝试使用不正确的图像时,我有:

Fatal error: imagecreatefrompng(): gd-png: fatal libpng error: Read Error: truncated data in /var/www/common/models/Utils.php on line 61

导致此错误的代码很简单:

$handle = imagecreatefrompng($fname);

此字符串后没有代码执行。

尝试从同一个字符串创建图像时,imagecreatefromstring的行为相同。

我无法修复"这张照片,因为它是用户提供的,所以我需要处理这种情况。

我试图像这样使用try...catch块:

echo 'start'."\n";
try {
    imagecreatefromstring($result);
} catch (\Throwable $e) {
    echo 'error'."\n";
    return null;
}
echo 'success'."\n";

但脚本只输出"开始",然后死掉并显示我上面发布的错误说明。

Ubuntu 16.04.2,PHP 7.0,php7.0-gd扩展,都是最新版本。

所以我无法用try ... catch块处理它,我根本不知道如何处理或修复它。有什么想法吗?

UPD:这似乎是一个非常奇怪的环境错误,因为当我在Windows下运行相同的代码(使用PHP 7.0)时,它产生正确的"警告"错误。

UPD2:似乎是新鲜的错误https://bugs.php.net/bug.php?id=73986

3 个答案:

答案 0 :(得分:2)

派对有点晚了,但我也遇到了这个问题,不能等待我的ubuntu LTS中包含bug修复 我找到的唯一干净的解决方法实际上是使用Imagick :: valid()检查图像是否有效。

function imageIsValid($path)
{
    try
    {
        $imagick = new \Imagick($path);

        return $imagick->valid();
    }
    catch (\Exception $e)
    {
        return false;
    }
}

当然,你的服务器/托管需要安装php imagick扩展......

答案 1 :(得分:1)

似乎是新鲜的bug(可能没有关闭):https://bugs.php.net/bug.php?id=73986

所以,直到我找到更好的方法,我认为这只是检查图像的一种方法。 它是BAD代码,我知道,但我没有其他想法。我的想法是尝试在另一个线程中创建一个图像,并返回检查值取决于它的输出。

$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运算符将在shell中执行命令。比它将错误输出到stderr2>&1用于将stderr流输出到stdout流,因此可以通过backtrick运算符进行访问。

答案 2 :(得分:0)

由于PHP7所有错误都是异常所以你可以简单地将脆弱的代码部分包装在try-catch块中以捕获\ Throwable异常并相应地处理。