【问题标题】:imagecreatefrompng (and imagecreatefromstring) causes to unrecoverable fatal errorimagecreatefrompng(和 imagecreatefromstring)导致不可恢复的致命错误
【发布时间】:2017-12-23 18:53:55
【问题描述】:

当我尝试在不正确的 png 图像上使用 php-gd 函数时,我遇到了致命的 PHP 错误。这似乎是某种错误,因为根据函数文档(例如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:好像是那个新鲜的bughttps://bugs.php.net/bug.php?id=73986

【问题讨论】:

  • 也许这会对你有所帮助(png已损坏)stackoverflow.com/questions/41338201/…
  • @matiaslauriti 感谢您的评论。但有问题的是,你给那个人收到了可以轻松处理的“警告”错误。就我而言,我遇到了致命错误,所以事情变得更难处理了。
  • 但问题是您遇到的错误,您的 PNG 似乎已损坏,您能否通过打开它们来确保您的 PNG 没有损坏?搜索Fatal error,你会发现很多信息。
  • @matiaslauriti 我必须使用 PHP 检查此文件是否损坏。此图片由用户提供,我不知道如何检查它是否损坏。如果我使用 getimagesize 进行此类检查,它会返回正确的值(显示 mime 类型和大小)。你知道其他检查图像的方法吗?
  • 更新了问题和我的答案,可能的原因是:这是错误。谢谢你的帮助。

标签: php php-7 php-gd


【解决方案1】:

聚会有点晚了,但我也遇到了这个问题,等不及要在我的 ubuntu LTS 中包含错误修复了 我发现的唯一干净的解决方法实际上是使用 Imagick::valid() 检查图像是否有效。

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

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

当然,您的服务器/主机需要安装 php imagick 扩展...

【讨论】:

  • 感谢您分享另一种方法!
【解决方案2】:

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

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

$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 运算符访问。

【讨论】:

  • 不不不不不!!!!这是一个可轻易利用的远程代码执行漏洞。
【解决方案3】:

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

【讨论】:

  • 感谢您的建议,但就我而言,当我用try{...code...}catch(\Throwable $e){...echo...} 包装这部分代码时,不会执行echo。脚本只是在 stderr 中显示错误消息而死。这似乎是某种不可恢复的错误或类似的东西。什么样的错误会导致这种行为?
  • 我用我用于检查的确切代码更新了我的问题
  • 更新了问题和我的答案,可能的原因是:这是错误。谢谢你的帮助。
  • 我们正在运行 PHP7 并使用 @ 前缀函数但错误是致命的:/
猜你喜欢
  • 2014-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多