Req #43177 [Opn->Csd]: Errors in eval()'ed code produce status code 500
Edit report at https://bugs.php.net/bug.php?id=43177&edit=1
ID: 43177
Updated by: stas@php.net
Reported by: taneli at crasman dot fi
Summary: Errors in eval()'ed code produce status code 500
-Status: Open
+Status: Closed
Type: Feature/Change Request
Package: *General Issues
Operating System: Linux
PHP Version: 5.2.4
Block user comment: N
Private report: N
New Comment:
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=86c46b96b6e93f566094917f0b24e79b795e062a
Log: add fix #43177
Previous Comments:
------------------------------------------------------------------------
[2012-06-01 21:55:23] truth at proposaltech dot com
A fix is available in
https://github.com/jabouillei/php-src/tree/issue-43177
The changes are in main.c and zend.c. github shows other files as being modified also, but
that's probably from me not understanding part of the merge process. My changes are in commit
a65037ef46.
------------------------------------------------------------------------
[2012-06-01 17:40:36] truth at proposaltech dot com
It's been over 4 years and the fix is known! I can't believe I spent all day yesterday
debugging this. I was filing a bug report and the system found this match. I'm using php
5.4.3. I'll paste the rest of my notes into this comment because they include references to
the documentation, updated line numbers, and other details not present in the original report.
Please commit a fix! More and more people will hit this as more and more people use AJAX.
--- Description: ---
http://us2.php.net/manual/en/function.eval.php
states:
If there is a parse error in the evaluated code, eval() returns FALSE and execution of the following
code continues normally.
In reality, eval() can have the side effect of setting the response code to 500 and leaving it at
500. My guess is that this has gone unnoticed because everything else proceeds normally enough to
produce an otherwise normal page and browsers are willing to display such pages even though the
response code is 500. However, wget complains about the 500 and an AJAX framework that checks
response codes may refuse to display the page. I believe the point of continuing normally is that
eval() should not ruin the current page.
I think the fix is to put
"&& EG(current_execute_data)->opline->extended_value != ZEND_EVAL"
into the "if" block at line 1132 of main.c. The "if" decides whether to set the
response code to 500 in the case of a parse error.
I just noticed the exit status is also modified by eval() a few lines earlier. Given the function
description, it doesn't seem correct to force the exit status to 255. I guess the same
"if" applies.
I'm guessing it is redundant to make sure the type is E_PARSE in the the case of ZEND_EVAL, but
someone how knows more about internals should probably confirm that.
--- Test script: ---
<?php
eval('0+');
print "hello world\n";
?>
--- Expected result: ---
hello world
with exit code 0
--- Actual result ---
That looks good in a browser, but fails with wget (and my AJAX framework and anything else that
relies on the response code). On the command line, the exit code is 255.
------------------------------------------------------------------------
[2007-11-05 11:06:51] holster at iki dot fi
A vote from me. Parse error in eval'ed code should not alter HTTP status
(well, as long as one is not able to catch it).
------------------------------------------------------------------------
[2007-11-02 11:43:10] taneli at crasman dot fi
Here's a patch for this issue:
--- php-5.2.4-vanilla/main/main.c 2007-11-01 15:20:37.000000000 +0200
+++ php-5.2.4/main/main.c 2007-11-01 17:26:45.000000000 +0200
@@ -957,11 +957,15 @@
if (!SG(headers_sent) &&
SG(sapi_headers).http_response_code == 200
) {
- sapi_header_line ctr = {0};
-
- ctr.line = "HTTP/1.0 500 Internal Server Error";
- ctr.line_len = strlen(ctr.line);
- sapi_header_op(SAPI_HEADER_REPLACE, &ctr TSRMLS_CC);
+ if (!EG(current_execute_data) ||
+ !EG(current_execute_data)->opline ||
+ EG(current_execute_data)->opline->opcode !=
ZEND_INCLUDE_OR_EVAL) {
+ sapi_header_line ctr = {0};
+
+ ctr.line = "HTTP/1.0 500 Internal Server
Error";
+ ctr.line_len = strlen(ctr.line);
+ sapi_header_op(SAPI_HEADER_REPLACE, &ctr
TSRMLS_CC);
+ }
}
/* the parser would return 1 (failure), we can bail out nicely */
if (type != E_PARSE) {
------------------------------------------------------------------------
[2007-11-02 11:41:44] taneli at crasman dot fi
Description:
------------
Errors in eval()'ed code produces HTTP status code 500 for the request.
Reproduce code:
---------------
Script:
<?php {
eval("this is not right");
}?>
Result:
# curl -I http://localhost/test.php
HTTP/1.0 500 Internal Server Error
Expected result:
----------------
Since parse errors and such in eval()'ed code don't interrupt the script or make it bail
out, I think 200 would be a more approriate code.
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=43177&edit=1
Thread (6 messages)