imagecreatefrompng(和 imagecreatefromstring)导致不可恢复的致命错误
imagecreatefrompng (and imagecreatefromstring) causes to unrecoverable fatal error
当我尝试在不正确的 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
的行为相同。
我不能"fix"这张图,因为它是用户提供的,所以我需要处理这种情况。
我试过像这样使用 try...catch
块:
echo 'start'."\n";
try {
imagecreatefromstring($result);
} catch (\Throwable $e) {
echo 'error'."\n";
return null;
}
echo 'success'."\n";
但脚本只输出 "start",然后死掉并显示我在上面发布的错误描述。
Ubuntu 16.04.2, PHP 7.0, php7.0-gd 扩展,都是最新版本。
所以我无法用 try...catch 块处理它,我根本不知道如何处理或修复它。有什么想法吗?
UPD: 这似乎是一个非常奇怪的环境错误,因为当我 运行 在 Windows 下使用相同的代码时(与 PHP 7.0) 它产生正确的 "Warning" 错误。
UPD2: 好像是那个新鲜的bug https://bugs.php.net/bug.php?id=73986
似乎是新的错误(可能还没有关闭):https://bugs.php.net/bug.php?id=73986
所以在我找到更好的方法之前,我认为这只是检查图像的一种方法。
这是错误的代码,我知道,但我没有其他想法。这个想法是尝试在另一个线程中创建一个图像,return 检查值取决于它的输出。
$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 中执行命令。然后它会将错误输出到 stderr
。 2>&1
用于将 stderr
流输出到 stdout
流,以便可以通过回溯运算符访问它。
因为PHP7所有错误都是异常,所以你可以简单地将脆弱的代码部分包装在 try-catch 块中以捕获 \Throwable 异常并进行相应处理。
晚会有点晚了,但我 运行 也遇到了这个问题,迫不及待地想将错误修复包含在我的 ubuntu LTS 中
我发现的唯一干净的解决方法实际上是使用 Imagick::valid() 检查图像是否有效。
function imageIsValid($path)
{
try
{
$imagick = new \Imagick($path);
return $imagick->valid();
}
catch (\Exception $e)
{
return false;
}
}
当然,您的 server/hosting 需要安装 php imagick 扩展...
当我尝试在不正确的 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
的行为相同。
我不能"fix"这张图,因为它是用户提供的,所以我需要处理这种情况。
我试过像这样使用 try...catch
块:
echo 'start'."\n";
try {
imagecreatefromstring($result);
} catch (\Throwable $e) {
echo 'error'."\n";
return null;
}
echo 'success'."\n";
但脚本只输出 "start",然后死掉并显示我在上面发布的错误描述。
Ubuntu 16.04.2, PHP 7.0, php7.0-gd 扩展,都是最新版本。
所以我无法用 try...catch 块处理它,我根本不知道如何处理或修复它。有什么想法吗?
UPD: 这似乎是一个非常奇怪的环境错误,因为当我 运行 在 Windows 下使用相同的代码时(与 PHP 7.0) 它产生正确的 "Warning" 错误。
UPD2: 好像是那个新鲜的bug https://bugs.php.net/bug.php?id=73986
似乎是新的错误(可能还没有关闭):https://bugs.php.net/bug.php?id=73986
所以在我找到更好的方法之前,我认为这只是检查图像的一种方法。 这是错误的代码,我知道,但我没有其他想法。这个想法是尝试在另一个线程中创建一个图像,return 检查值取决于它的输出。
$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 中执行命令。然后它会将错误输出到 stderr
。 2>&1
用于将 stderr
流输出到 stdout
流,以便可以通过回溯运算符访问它。
因为PHP7所有错误都是异常,所以你可以简单地将脆弱的代码部分包装在 try-catch 块中以捕获 \Throwable 异常并进行相应处理。
晚会有点晚了,但我 运行 也遇到了这个问题,迫不及待地想将错误修复包含在我的 ubuntu LTS 中 我发现的唯一干净的解决方法实际上是使用 Imagick::valid() 检查图像是否有效。
function imageIsValid($path)
{
try
{
$imagick = new \Imagick($path);
return $imagick->valid();
}
catch (\Exception $e)
{
return false;
}
}
当然,您的 server/hosting 需要安装 php imagick 扩展...