Edit report at https://bugs.php.net/bug.php?id=43177&edit=1
ID: 43177 Updated by: s...@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