php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #70315 imagecreatefromstring() returns 500 Server Error but page is fully rendered
Submitted: 2015-08-20 19:24 UTC Modified: 2016-07-20 23:53 UTC
Votes:3
Avg. Score:5.0 ± 0.0
Reproduced:3 of 3 (100.0%)
Same Version:3 (100.0%)
Same OS:2 (66.7%)
From: patriciotarantino at gmail dot com Assigned: cmb (profile)
Status: Closed Package: GD related
PHP Version: 5.6.12 OS: Ubuntu
Private report: No CVE-ID: None
View Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
If you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: patriciotarantino at gmail dot com
New email:
PHP Version: OS:

 

 [2015-08-20 19:24 UTC] patriciotarantino at gmail dot com
Description:
------------
Condition: display_errors is off.

If you use imagecreatefromstring() with an invalid string, it returns a 500 Internal Server Error in the HTTP headers, but the page is fully renderized. It should return 200 OK (and the full page), or a 500 Error but without the full HTML. Not both at the same time.

5.3.10 and 5.4.44 are not affected.
5.5.9 and 5.6.12 are affected.

Test script:
---------------
<?php
ini_set("display_errors", 0);

$data = "iVBORw0KGgoAAAANSUhEUgAAAuwAAAUeCAYAAAAl3WR...LkAAAAAElFTkSuQmCC";
$data = base64_decode($data);
$im = imagecreatefromstring($data);

echo "This should not render";


Patches

Pull Requests

Pull requests:

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-06-21 21:32 UTC] cmb@php.net
-Status: Open +Status: Feedback -Assigned To: +Assigned To: cmb
 [2016-06-21 21:32 UTC] cmb@php.net
> If you use imagecreatefromstring() with an invalid string, it
> returns a 500 Internal Server Error in the HTTP headers, […]

Indeed, that is not supposed to happen, and I can't reproduce it,
actually. Please double-check with any of the recent PHP versions
(5.5.36, 5.6.22, 7.0.7).
 [2016-06-22 07:19 UTC] pajoye@php.net
The header itself does not control the code execution.

The imagecreatefromstring returns false on error. That means the echo will happen.

It is the caller job to check the value and act accordingly. In case you expect the echo to never happen on error, that's not the case using this piece of code.
 [2016-06-27 19:22 UTC] razzari at gmail dot com
@cmb can repro in PHP version 5.5.35. 

@pajoye it's OK if the echo happens. The problem is that the page also includes an HTTP Error 500 header. Which is hugely wrong.
 [2016-07-03 04:22 UTC] php-bugs at lists dot php dot net
No feedback was provided. The bug is being suspended because
we assume that you are no longer experiencing the problem.
If this is not the case and you are able to provide the
information that was requested earlier, please do so and
change the status of the bug back to "Re-Opened". Thank you.
 [2016-07-03 04:47 UTC] requinix@php.net
-Status: No Feedback +Status: Open
 [2016-07-03 05:20 UTC] pajoye@php.net
-Status: Assigned +Status: Feedback
 [2016-07-03 05:20 UTC] pajoye@php.net
Cmb cannot reproduce it.

Also I do not see the 500 header.

Doyou have either logs or backtrace if the 500 is due to something else?

In any case it is definitely not GD as everything goes aa expected from a gd point of view.
 [2016-07-03 22:13 UTC] razzari at gmail dot com
This is still happening on PHP Version 5.6.23.

Screenshot: https://i.imgur.com/p680DMk.png

Note that BOTH the test text AND the 500 status code are displayed. 

As noted by the OP, this only happens if display_errors is off. 

If I enable errors, things work as expected. The error is displayed, and the page returns with a 200 OK status.  Screenshot: https://i.imgur.com/8jyuiot.png

Compare this with standard platform behavior, where an error with display_errors off will produce a 500 error AND a blank page. It is NOT displaying the test text. Screenshot https://i.imgur.com/VCBOmun.png and sample code:

<?php
# This works as expected.
ini_set("display_errors", 0);
trigger_error("Some error.", E_USER_ERROR);
echo "This should not render";
?>

So to recap, expected behavior is:
Display errors OFF: Blank page, 500 status code. 
Display errors ON: Visible error text, some page content that worked, and 200 status code. 

Actual result in this situation is:
Display errors OFF: Some page content that worked, 500 status code.

Why this is a serious issue: site owners and visitors will believe the site is working OK. But Google will believe it's utterly broken and won't bother crawling it.
 [2016-07-03 22:27 UTC] razzari at gmail dot com
Here's the logs as text (Sorry, I had included them in the screenshot in the prev comment).

PHP Unknown error:  imagecreatefromstring(): gd-png: fatal libpng error: IHDR: CRC error\n in Unknown on line 0
PHP Parse error:  imagecreatefromstring(): gd-png error: setjmp returns error condition 1\n in /var/www/test.php on line 6
PHP Warning:  imagecreatefromstring(): Passed data is not in 'PNG' format in /var/www/test.php on line 6
PHP Warning:  imagecreatefromstring(): Couldn't create GD Image Stream out of Data in /var/www/test.php on line 6

I can repro this consistently.

Please let me know if I can provide further info/tests. 

This is a barebones install in Ubuntu 12.04, Apache/2.4.2, PHP 5.6.23-2+deb.sury.org~precise+1. I've just installed this in a Vagrant box for testing. (That is, this isn't a prod server with weird configs or a dev server wit cruft that's piled up over the years).
 [2016-07-04 11:25 UTC] cmb@php.net
-Status: Feedback +Status: Open
 [2016-07-04 11:25 UTC] cmb@php.net
@razzari Thanks for the detailed explanation. I'll try to
reproduce with your environement. Do you use FPM or mod_apache?
 [2016-07-04 11:25 UTC] cmb@php.net
> mod_apache

Of course I meant mod_php!
 [2016-07-04 13:32 UTC] razzari at gmail dot com
This was mod_php (libapache2-mod-php5.6).
 [2016-07-04 14:17 UTC] razzari at gmail dot com
I can also repro with Nginx and FPM/FastCGI. 
PHP Version 5.5.9-1ubuntu4.17.
GD Version 2.1.1-dev.
 [2016-07-07 11:59 UTC] cmb@php.net
-Summary: imagecreatefromstring() returns 500 Server Error but page full renderized +Summary: imagecreatefromstring() returns 500 Server Error but page is fully rendered
 [2016-07-07 12:55 UTC] cmb@php.net
-Status: Assigned +Status: Analyzed
 [2016-07-07 12:55 UTC] cmb@php.net
Okay, I'am able to reproduce the reported behavior now. It happens
only when an external libgd is used, not with PHP's bundled libgd.

> PHP Unknown error:  imagecreatefromstring(): gd-png: fatal […]
> PHP Parse error:  imagecreatefromstring(): gd-png error: […]

That's the crux. The bundled libgd reports instead:

| Warning: imagecreatefromstring(): gd-png: fatal […]
| Warning: imagecreatefromstring(): gd-png error: […]

One culprit is php_gd_error_method()[1] which simply forwards to
php_verror() without adjusting the type argument, although libgd
uses other error codes than PHP (for instance, GD_ERROR is 3,
which is unknown to PHP). While a simple mapping of the error
codes would solve this problem, it still would cause different
behavior depending whether the bundled or an external libgd is
used. In this case the bundled libgd would raise warnings only and
simply go on, while an external libgd would raise errors and abort
the script.

As changing libgd obviously isn't an option due to the ABI break,
we probably should change PHP's bundled libgd (i.e. raise E_ERROR
instead of E_WARNING), but that would cause a BC break, so maybe
it's best to do that only for PHP 7.1.0, and to accept the
different behavior for older versions. php_gd_error_method(),
however, should be fixed for PHP 5.6+.

I'll prepare a PR.


[1] <https://github.com/php/php-src/blob/php-7.0.8/ext/gd/gd.c#L1021-L1025>
 [2016-07-18 22:59 UTC] cmb@php.net
Automatic comment on behalf of cmbecker69@gmx.de
Revision: http://git.php.net/?p=php-src.git;a=commit;h=6cb75fb1e8208d79f58351340923059d0d077ee6
Log: Fix #70315: 500 Server Error but page is fully rendered
 [2016-07-18 22:59 UTC] cmb@php.net
-Status: Analyzed +Status: Closed
 [2016-07-18 23:18 UTC] razzari at gmail dot com
I'm not familiar with PHP internals. Not at all. 
But have to ask. 
Feel free to ignore if it's a dumb question:

Isn't it a more general bug, at the architecture level, that an "unknown" error code can cause PHP to render pages in a half-broken state?

Where "half-broken" is the worst kind: looks good to the naked eye, but rejects search engine crawlers.
 [2016-07-20 23:53 UTC] cmb@php.net
> Isn't it a more general bug, at the architecture level, that an
> "unknown" error code can cause PHP to render pages in a
> half-broken state?

In my opinion, passing unknown error codes is a programmer error
(core or extension), and should be reported (and fixed) as bug on
a case-by-case basis (like this one).
 [2016-10-17 10:11 UTC] bwoebi@php.net
Automatic comment on behalf of cmbecker69@gmx.de
Revision: http://git.php.net/?p=php-src.git;a=commit;h=6cb75fb1e8208d79f58351340923059d0d077ee6
Log: Fix #70315: 500 Server Error but page is fully rendered
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Dec 03 17:01:29 2024 UTC