imagecreatefrompng (и imagecreatefromstring) приводит к неустранимой фатальной ошибке
Когда я пытаюсь использовать функции php-gd на неверных изображениях png, у меня есть фатальная ошибка 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";
Но скрипт выводит только "start", а затем умирает и показывает описание ошибки, которое я опубликовал выше.
Ubuntu 16.04.2, PHP 7.0, расширение php7.0-gd, обе последние версии.
Так что я не могу справиться с этим с помощью try...поймайте блок, и я не знаю, как с ним справиться или починить его вообще. Какой-нибудь идеи?UPD: это кажется действительно странной ошибкой с окружением, потому что когда я запускаю тот же код под Windows (с PHP 7.0), он выдает правильную ошибку "предупреждение".
UPD2: похоже, что это свежий баг https://bugs.php.net/bug.php?id=73986
3 ответа:
Похоже, это свежий баг (и, возможно, не закрытый): 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 выполнит команду в оболочке. Чем он выведет ошибку в
stderr
.2>&1
используется для вывода потокаstderr
вstdout
поток, чтобы к нему можно было получить доступ через оператор backtrick.
Немного опоздал на вечеринку, но я также столкнулся с этой проблемой и не могу дождаться исправления ошибки, которое будет включено в мою ubuntu LTS Единственный чистый обходной путь, который я нашел, на самом деле использовать Imagick::valid() проверить изображение является допустимым.
function imageIsValid($path) { try { $imagick = new \Imagick($path); return $imagick->valid(); } catch (\Exception $e) { return false; } }
Конечно, на вашем сервере / хостинге должно быть установлено расширение php imagick...