GithubHelp home page GithubHelp logo

Comments (24)

cmb69 avatar cmb69 commented on May 27, 2024 2

Hmm, if there is an OPcache bug in PHP 7.3, it won't be resolved anyway. Does this issue also happen with PHP 8.0?

from imagine.

cmb69 avatar cmb69 commented on May 27, 2024 2

There is also to note that not all 7.3 builds seem to affected by this (see https://3v4l.org/AYCSU for example).

Note, though, that 3v4l.org runs with OPcache disabled.

from imagine.

mnocon avatar mnocon commented on May 27, 2024 1

Hi, I've created a repo that allowed me to reproduce this issue:
https://github.com/mnocon/imagine-segfault-reproducer

Please let me know if anything is unclear

You can also see that if you downgrade to imagine 1.2.x then the segmentation fault does not occur.

from imagine.

mlocati avatar mlocati commented on May 27, 2024 1

It seems an opcache bug in particular: by disabling it we don't have the segfault anymore

from imagine.

mlocati avatar mlocati commented on May 27, 2024 1

#828 seems to work just fine

from imagine.

mlocati avatar mlocati commented on May 27, 2024

Without more details it's rather hard to see what's going wrong...

from imagine.

ProRezak avatar ProRezak commented on May 27, 2024

Approve, have same issue

from imagine.

AlexSuvorovKirov avatar AlexSuvorovKirov commented on May 27, 2024

Confirm a problem

from imagine.

ponytime avatar ponytime commented on May 27, 2024

Without more details have the same issue

from imagine.

AntonOkulov avatar AntonOkulov commented on May 27, 2024

Apache error: End of script output before headers: index.php
after this:
$this->getImagine()->open($filePath)

from imagine.

ovgray avatar ovgray commented on May 27, 2024

I have the same issue with ver 1.3.1, php ver 7.3, using gd.

Doing local development on Windows with symfony cli server.

Server crashes when it reaches this:
$imagine - new Imagine\Gd\Imagine();
$image = $imagine->open($filePath);

I'm not very skilled at debugging, but the crash seems to occur where \Imagine\Factory\ClassFactoryInterface::createImage() creates a new \Imagine\Gd\Image.

Server does not crash with imagine/imagine ver 1.2.4.
Also, the code fragment containing Imagine\Gd\Imagine::open seems to run without error in a phpunit test.

from imagine.

mlocati avatar mlocati commented on May 27, 2024

In order to fix this issue, we need to know what's going wrong.
And in order to know what's going wrong, we need:

  1. the image that's causing the problem
  2. the exact version of PHP
  3. the exact version of the imagick PHP module
  4. the exact version of the imagemagick system library

To get the info for points 2., 3., and 4.:

if the problem occurs in a web application

Simply create a sample php file on the server with the following contents:

<?php phpinfo(INFO_GENERAL); phpinfo(INFO_MODULES);

By visiting the page with the browser:

  • The PHP version is at the top of the page
  • The imagick version is in the "imagick" section, row "imagick module version"
  • The imagemagick version is in the "imagick" section, rows "Imagick compiled with ImageMagick version" and "Imagick using ImageMagick library version"

if the problem occurs in a CLI environment:

  • The PHP version can be obtained by running php -v
  • The imagick and the imagemagick versions can be obtained by running php -ri imagick

from imagine.

ovgray avatar ovgray commented on May 27, 2024

Crash occurs opening any one of several different jpg image files.

php version is 7.3.5
phpinfo has no "imagick" section.
$ php -ri imagick
PHP Parse error: syntax error, unexpected end of file in Command line code on line 1
``
Parse error: syntax error, unexpected end of file in Command line code on line 1

php -m confirms it contains no imagick module

from imagine.

hgabka avatar hgabka commented on May 27, 2024

Same problem for me. Imagine open causes segfault. Tried nginx and apache, both have problem.
Using PHP 7.3. GD library, no imagick installed.

from imagine.

mlocati avatar mlocati commented on May 27, 2024

Same answer: in order to fix the issue we need to be able to reproduce it

from imagine.

ovgray avatar ovgray commented on May 27, 2024

Same answer: in order to fix the issue we need to be able to reproduce it

@mlocati
Are you saying that the information I supplied is insufficient to reproduce the issue?
Have you successfully run (new Imagine\Gd\Imagine())->open($filepath) on an image file with a copy of php 7.3 compiled without an imagick module?

from imagine.

mlocati avatar mlocati commented on May 27, 2024

@ovgray the CI tests should already do that

from imagine.

ovgray avatar ovgray commented on May 27, 2024

@mlocati

@ovgray the CI tests should already do that

Have you considered the possibility that your CI tests are using a version of php 7.3 that has an imagick module?

When I look at e.g. https://github.com/php-imagine/Imagine/runs/3935559862?check_suite_focus=true, the two php 7.3 versions are labelled "gd-gimagick (Docker)" and "gd-imagick (Docker)". Does that mean the php versions have gimagick and imagick modules, respectively?

from imagine.

ausi avatar ausi commented on May 27, 2024

This seems to be a PHP bug to me. I was able to reduce the reproducer down to a single file that still causes the segmentation fault:

<?php

function y($x, $y, $z)
{
    switch ($a->a()) {
        default:
            $s = '' . $b;
    }
    $c = array($b);

    switch ($a->a()) {
        case A::B:
            $e = 0;
            $f = 0;
            if (!empty($d[''])) {
                $e = 0;
            } else {
                if (!isset($d[''])) {
                    if (isset($d[''])) {
                        $d[''] = $d[''];
                    }
                }
                if (isset($d[''])) {
                    $e = a(0, a(0, $d['']));
                }
            }
        case A::B:
            if (!isset($d[''])) {
                if (isset($d[''])) {
                    $d[''] = round((0 - $d['']) * 0 * 0);
                }
            }
            if (isset($d[''])) {
                if ($d[''] < 0 || $d[''] > 0) {
                    new Z('');
                }
            }
            if (!isset($d[''])) {
                if (isset($d[''])) {
                    $d[''] = $d[''];
                }
            }
            if (isset($d[''])) {
                $g[] = $d[''];
            }
            break;
        case A::B:
            if (isset($d[''])) {
                $g[] = $d[''];
            }
            break;
        case A::B:
            if (!isset($d[''])) {
                if (isset($d[''])) {
                    $d[''] = $d[''];
                }
            }
            if (isset($d[''])) {
                if ($d[''] < 0) {
                    new Z('');
                }
                $g[] = $d[''];
            }
            break;
    }
}

echo "Success!";

The source of this weird looking function is here:

Imagine/src/Gd/Image.php

Lines 638 to 735 in 303cf35

private function saveOrOutput(Format $format, array $options, $filename = null)
{
switch ($format->getID()) {
default:
$saveFunction = 'image' . $format->getID();
break;
}
$args = array(&$this->resource, $filename);
switch ($format->getID()) {
case Format::ID_AVIF:
// ranges from 0 (worst quality, smaller file) to 100 (best quality, larger file). If -1 is provided, the default value is used
$quality = -1;
// ranges from 0 (slow, smaller file) to 10 (fast, larger file). If -1 is provided, the default value is used
$speed = -1;
if (!empty($options['avif_lossless'])) {
$quality = 100;
} else {
if (!isset($options['avif_quality'])) {
if (isset($options['quality'])) {
$options['avif_quality'] = $options['quality'];
}
}
if (isset($options['avif_quality'])) {
$quality = max(0, min(100, $options['avif_quality']));
}
}
$args[] = $quality;
$args[] = $speed;
break;
case Format::ID_BMP:
if (isset($options['compressed'])) {
$args[] = (bool) $options['compressed'];
}
break;
case Format::ID_JPEG:
if (!isset($options['jpeg_quality'])) {
if (isset($options['quality'])) {
$options['jpeg_quality'] = $options['quality'];
}
}
if (isset($options['jpeg_quality'])) {
$args[] = $options['jpeg_quality'];
}
break;
case Format::ID_PNG:
if (!isset($options['png_compression_level'])) {
if (isset($options['quality'])) {
$options['png_compression_level'] = round((100 - $options['quality']) * 9 / 100);
}
}
if (isset($options['png_compression_level'])) {
if ($options['png_compression_level'] < 0 || $options['png_compression_level'] > 9) {
throw new InvalidArgumentException('png_compression_level option should be an integer from 0 to 9');
}
$args[] = $options['png_compression_level'];
} else {
$args[] = -1; // use default level
}
if (!isset($options['png_compression_filter'])) {
if (isset($options['filters'])) {
$options['png_compression_filter'] = $options['filters'];
}
}
if (isset($options['png_compression_filter'])) {
if (~PNG_ALL_FILTERS & $options['png_compression_filter']) {
throw new InvalidArgumentException('png_compression_filter option should be a combination of the PNG_FILTER_XXX constants');
}
$args[] = $options['png_compression_filter'];
}
break;
case Format::ID_WBMP:
case Format::ID_XBM:
if (isset($options['foreground'])) {
$args[] = $options['foreground'];
}
break;
case Format::ID_WEBP:
if (!isset($options['webp_quality'])) {
if (isset($options['quality'])) {
$options['webp_quality'] = $options['quality'];
}
}
if (isset($options['webp_quality'])) {
if ($options['webp_quality'] < 0 || $options['webp_quality'] > 100) {
throw new InvalidArgumentException('webp_quality option should be an integer from 0 to 100');
}
$args[] = $options['webp_quality'];
}
break;
}
ErrorHandling::throwingRuntimeException(E_WARNING | E_NOTICE, function () use ($saveFunction, $args) {
if (call_user_func_array($saveFunction, $args) === false) {
throw new RuntimeException('Save operation failed');
}
});
}

PHP Version of the reproducer from @mnocon :

PHP 7.3.29 (cli) (built: Aug 17 2021 14:00:32) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.29, Copyright (c) 1998-2018 Zend Technologies
    with Zend OPcache v7.3.29, Copyright (c) 1999-2018, by Zend Technologies
    with blackfire v1.74.1~linux-x64-non_zts73, https://blackfire.io, by Blackfire

from imagine.

mnocon avatar mnocon commented on May 27, 2024

Thanks for investigating!

What would be the options here? Two things come to my mind:

  1. Refactor this function to work around the PHP bug IF the 1.3.x series should support PHP 7.3 and if it's even possible
  2. Bump the minimum required version to PHP 7.4 for the 1.3.x series (including the already released 1.3.0 and 1.3.1 tags IMHO)

What do you think?

from imagine.

mlocati avatar mlocati commented on May 27, 2024

I guess we'd need some help from @cmb69 here...

from imagine.

mnocon avatar mnocon commented on May 27, 2024

It does not happen on PHP 8.0 and 8.1 (on the images that I use):

PHP 8.0.16 (cli) (built: Feb 18 2022 21:20:58) ( NTS )
Copyright (c) The PHP Group
Zend Engine v4.0.16, Copyright (c) Zend Technologies
    with Zend OPcache v8.0.16, Copyright (c), by Zend Technologies
    with blackfire v1.74.1~linux-x64-non_zts80, https://blackfire.io, by Blackfire
PHP 8.1.3 (cli) (built: Feb 18 2022 19:37:16) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.1.3, Copyright (c) Zend Technologies
    with Zend OPcache v8.1.3, Copyright (c), by Zend Technologies
    with blackfire v1.74.1~linux-x64-non_zts81, https://blackfire.io, by Blackfire

I've added them to the reproducer, just in case

from imagine.

ausi avatar ausi commented on May 27, 2024

What would be the options here?

PHP 7.3 reached its end of life so you need to get your distro to patch this in their PHP 7.3 package I think. There is also to note that not all 7.3 builds seem to affected by this (see https://3v4l.org/AYCSU for example).

Refactoring this function to avoid the error should be possible, as many changes in this method I tested stopped the segmentation fault from appearing. I’m not sure if it is the responsibility of the Imagine project, @mlocati has to decide this I think. If desired, I can provide a pull request that does such a “workaround”. already happend in the meantime in #828

from imagine.

mlocati avatar mlocati commented on May 27, 2024

If someone else can confirm that #828 works, I'll merge it and publish a new release

from imagine.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.