[PHP-BUG] Bug #62129 [NEW]: rfc1867 crashes php even though turned off
From: truth at proposaltech dot com Operating system: CentOS PHP version: 5.4.3 Package: Session related Bug Type: Bug Bug description:rfc1867 crashes php even though turned off Description: php_session_rfc1867_callback() tries to call php_session_rfc1867_orig_callback() even if the rfc1867 feature is not enabled. Switching the order of the opening "if" blocks fixes the problem. (The second "if" block immediately returns success if the feature isn't enabled and the first "if" block tries to call the callback. This is all around line 2388 of session.c.) I upgraded from 5.3.3 to 5.4.3 and apache was segfaulting. I produced a core and the debugger showed infinite recursion in php_session_rfc1867_callback(). There are probably deeper problems here, but at the least the feature shouldn't cause problems if it is turned off. In any case, even if something about my configuration is less than ideal, seg faults are Bad Thing. Test script: --- Apparently, my code wasn't executed. I tried using Xdebug, but it didn't report anything. dump_bt didn't return anything in the debugger. Expected result: I expected my code to be executed normally. Actual result: -- apache seg faulted -- Edit bug report at https://bugs.php.net/bug.php?id=62129&edit=1 -- Try a snapshot (PHP 5.4): https://bugs.php.net/fix.php?id=62129&r=trysnapshot54 Try a snapshot (PHP 5.3): https://bugs.php.net/fix.php?id=62129&r=trysnapshot53 Try a snapshot (trunk): https://bugs.php.net/fix.php?id=62129&r=trysnapshottrunk Fixed in SVN: https://bugs.php.net/fix.php?id=62129&r=fixed Fixed in SVN and need be documented: https://bugs.php.net/fix.php?id=62129&r=needdocs Fixed in release: https://bugs.php.net/fix.php?id=62129&r=alreadyfixed Need backtrace: https://bugs.php.net/fix.php?id=62129&r=needtrace Need Reproduce Script: https://bugs.php.net/fix.php?id=62129&r=needscript Try newer version: https://bugs.php.net/fix.php?id=62129&r=oldversion Not developer issue: https://bugs.php.net/fix.php?id=62129&r=support Expected behavior: https://bugs.php.net/fix.php?id=62129&r=notwrong Not enough info: https://bugs.php.net/fix.php?id=62129&r=notenoughinfo Submitted twice: https://bugs.php.net/fix.php?id=62129&r=submittedtwice register_globals: https://bugs.php.net/fix.php?id=62129&r=globals PHP 4 support discontinued: https://bugs.php.net/fix.php?id=62129&r=php4 Daylight Savings:https://bugs.php.net/fix.php?id=62129&r=dst IIS Stability: https://bugs.php.net/fix.php?id=62129&r=isapi Install GNU Sed: https://bugs.php.net/fix.php?id=62129&r=gnused Floating point limitations: https://bugs.php.net/fix.php?id=62129&r=float No Zend Extensions: https://bugs.php.net/fix.php?id=62129&r=nozend MySQL Configuration Error: https://bugs.php.net/fix.php?id=62129&r=mysqlcfg
Bug #62129 [Com]: rfc1867 crashes php even though turned off
Edit report at https://bugs.php.net/bug.php?id=62129&edit=1 ID: 62129 Comment by: truth at proposaltech dot com Reported by:truth at proposaltech dot com Summary:rfc1867 crashes php even though turned off Status: Assigned Type: Bug Package:Session related Operating System: CentOS PHP Version:5.4.3 Assigned To:iliaa Block user comment: N Private report: N New Comment: Here is a the relevant portion of the backtrace from the seg fault: #104648 0x006cd5b8 in php_session_rfc1867_callback (event=0, event_data=0x7fffb2b8f950, extra=) at /cns/build/php-5.4.3/ext/session/session.c:2388 #104649 0x006cd5b8 in php_session_rfc1867_callback (event=0, event_data=0x7fffb2b8f950, extra=) at /cns/build/php-5.4.3/ext/session/session.c:2388 #104650 0x00473841 in rfc1867_post_handler ( content_type_dup=, arg=0x11535e8) at /cns/build/php-5.4.3/main/rfc1867.c:773 #104651 0x00471372 in sapi_handle_post (arg=) at /cns/build/php-5.4.3/main/SAPI.c:182 #104652 0x0067efd8 in mbstr_treat_data (arg=0, str=0x0, destArray=) at /cns/build/php-5.4.3/ext/mbstring/mb_gpc.c:98 #104653 0x00475e9e in php_auto_globals_create_post ( name=0x12a6a60 "_POST", name_len=5) at /cns/build/php-5.4.3/main/php_variables.c:682 #104654 0x0049aa4b in zend_auto_global_init (auto_global=0x110e800) at /cns/build/php-5.4.3/Zend/zend_compile.c: #104655 0x004ca974 in zend_hash_apply (ht=0x111bf20, apply_func=0x49aa30 ) at /cns/build/php-5.4.3/Zend/zend_hash.c:716 #104656 0x004772bb in php_hash_environment () at /cns/build/php-5.4.3/main/php_variables.c:642 #104657 0x004697f5 in php_request_startup () at /cns/build/php-5.4.3/main/main.c:1568 #104658 0x0056084f in apache_php_module_main (r=, display_source_mode=0) at /cns/build/php-5.4.3/sapi/apache/sapi_apache.c:33 #104659 0x00461c00 in send_php () #104660 0x00461c48 in send_parsed_php () #104661 0x0085f773 in ap_invoke_handler () #104662 0x00878d90 in process_request_internal () #104663 0x00878df3 in ap_process_request () #104664 0x0086e46f in child_main () #104665 0x0086e728 in make_child () #104666 0x0086e7e9 in startup_children () #104667 0x0086effb in standalone_main () #104668 0x0086f8cc in main () I don't know much about internals, but I'll try to translate the above based on function names and values I saw in the debugger. While activating auto_globals, the _POST auto_global had a callback to be called: php_auto_globals_create_post(). That used the mbstring extension, which for the case of PARSE_POST, relies on sapi_handle_post(). sapi_handle_post() used rfc1867_post_handler() because the sapi_globals.request_info.post_entry had an rfc1867 post_handler: print *sapi_globals.request_info.post_entry $7 = {content_type = 0x8c4bc9 "multipart/form-data", content_type_len = 19, post_reader = 0, post_handler = 0x473590 } I don't know why that post_handler value was set to rfc1867_post_handler given that my php.ini includes session.upload_progress.enabled = off Similarly, I don't know why php_rfc1867_callback was non-null given my php.ini setting. Once the php_rfc1867_callback() was called, everything died quickly. That callback calls the "orig_callback" (if non-null) and the "orig_callback" was the same as the php_session_rfc1867_callback - endless recursion. Perhaps the real killer is the following lines from session.c (~line 2195): php_session_rfc1867_orig_callback = php_rfc1867_callback; php_rfc1867_callback = php_session_rfc1867_callback; I don't think those lines should be called if I have session.upload_progress.enabled = off in my php.ini. Setting php_rfc1867_callback seems to be what cause rfc1867 code to be called. Setting php_session_rfc1867_orig_callback to php_rfc1867_callback (which is php_session_rfc1867_callback) leads to the endless recursion. Sorry I don't have a fix. Thanks very much for continuing to improve php!!! Previous Comments: [2012-05-24 01:45:19] larue...@php.net yes, the codes seems suspicious, maybe iliaa can look into this :) diff --git a/ext/session/session.c b/ext/session/session.c index 7a8199d..851e4ea 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -2384,13 +2384,14 @@ static int php_session_rfc1867_callback(unsigned int event, void *event_data, vo php_session_rfc1867_progress *progress; int retval = SUCCESS; - if (php_session_rfc1867_orig_callback) { - retval = php_session_rfc1867_orig_callback(event, event_data, extra TSRMLS_CC); - } if (!PS
Req #43177 [Com]: Errors in eval()'ed code produce status code 500
Edit report at https://bugs.php.net/bug.php?id=43177&edit=1 ID: 43177 Comment by: truth at proposaltech dot com Reported by:taneli at crasman dot fi Summary:Errors in eval()'ed code produce status code 500 Status: Open Type: Feature/Change Request Package:*General Issues Operating System: Linux PHP Version:5.2.4 Block user comment: N Private report: N New Comment: 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: --- --- 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. Previous Comments: [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.0 +0200 +++ php-5.2.4/main/main.c 2007-11-01 17:26:45.0 +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: Result: # curl -I http://localhost/test.php HTTP/1.0 500 Internal Server Error
Req #43177 [Com]: Errors in eval()'ed code produce status code 500
Edit report at https://bugs.php.net/bug.php?id=43177&edit=1 ID: 43177 Comment by: truth at proposaltech dot com Reported by:taneli at crasman dot fi Summary:Errors in eval()'ed code produce status code 500 Status: Open Type: Feature/Change Request Package:*General Issues Operating System: Linux PHP Version:5.2.4 Block user comment: N Private report: N New Comment: 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. Previous Comments: [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: --- --- 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.0 +0200 +++ php-5.2.4/main/main.c 2007-11-01 17:26:45.0 +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 nic
#34551 [NEW]: Unadvertised BC break
From: truth at proposaltech dot com Operating system: SuSE w/ rebuilt php & deps PHP version: 4.4.0 PHP Bug Type: Scripting Engine problem Bug description: Unadvertised BC break Description: Based on the discussion on internals that led to the creation of php 4.4 (and based on the release notes for php 4.4), I would expect the only difference in running the following code under 4.3 and 4.4 to be the generation of a notice under 4.4. The code is bad, but it does not rely on corrupting memory. (BTW, this actually doesn't affect me personally because I immediately cleaned up our company's code for every 4.4 notice. I'm just helping isolate the BC break that frustrated a recent internals poster. Unless they are relying on memory corruption, users should be able to hide the notices and get the same behavior with 4.4 as 4.3. (There were posts from Zeev among others supporting this position.)) I hope this is easy to fix. The concept is easy. Whenever the code attempts to set a variable by reference, the variable should be unset as a first step. In the example, $y should be disconnected from $x because of the "$y =& ...". Yes, the reference shouldn't actually work, but that doesn't change the fact that the code clearly indicates that the connection between $y and $x should be broken. If I sound defensive, it's because Derick has already posted on internals that the new behavior is "correct". Please check with other engine gurus before jumping to any conclusions of bogusness. I think a fix to this BC break will save many hours for many, many php developers. (The example is silly, but you can get subtle cases of that problem in loops that are a nightmare to find.) Thanks! - Todd Reproduce code: --- Expected result: $x should end up 5 because the "$y=&..." should disconnect $y from $x even though the new connection can't be made. Actual result: -- Under 4.3, $x ends up 5, but under 4.4, $x ends up 3. -- Edit bug report at http://bugs.php.net/?id=34551&edit=1 -- Try a CVS snapshot (php4): http://bugs.php.net/fix.php?id=34551&r=trysnapshot4 Try a CVS snapshot (php5.0): http://bugs.php.net/fix.php?id=34551&r=trysnapshot50 Try a CVS snapshot (php5.1): http://bugs.php.net/fix.php?id=34551&r=trysnapshot51 Fixed in CVS:http://bugs.php.net/fix.php?id=34551&r=fixedcvs Fixed in release:http://bugs.php.net/fix.php?id=34551&r=alreadyfixed Need backtrace: http://bugs.php.net/fix.php?id=34551&r=needtrace Need Reproduce Script: http://bugs.php.net/fix.php?id=34551&r=needscript Try newer version: http://bugs.php.net/fix.php?id=34551&r=oldversion Not developer issue: http://bugs.php.net/fix.php?id=34551&r=support Expected behavior: http://bugs.php.net/fix.php?id=34551&r=notwrong Not enough info: http://bugs.php.net/fix.php?id=34551&r=notenoughinfo Submitted twice: http://bugs.php.net/fix.php?id=34551&r=submittedtwice register_globals:http://bugs.php.net/fix.php?id=34551&r=globals PHP 3 support discontinued: http://bugs.php.net/fix.php?id=34551&r=php3 Daylight Savings:http://bugs.php.net/fix.php?id=34551&r=dst IIS Stability: http://bugs.php.net/fix.php?id=34551&r=isapi Install GNU Sed: http://bugs.php.net/fix.php?id=34551&r=gnused Floating point limitations: http://bugs.php.net/fix.php?id=34551&r=float No Zend Extensions: http://bugs.php.net/fix.php?id=34551&r=nozend MySQL Configuration Error: http://bugs.php.net/fix.php?id=34551&r=mysqlcfg
#34551 [Bgs]: Unadvertised BC break
ID: 34551 User updated by: truth at proposaltech dot com Reported By: truth at proposaltech dot com Status: Bogus Bug Type: Scripting Engine problem Operating System: SuSE w/ rebuilt php & deps PHP Version: 4.4.0 New Comment: According to http://www.php.net/release_4_4_0.php... It states, "The increased middle digit was required because the fix that corrected the problem with references changed PHP's internal API, breaking binary compatibility with the PHP 4.3.* series." Please note the middle digit change regarded an _internal_ API, not an API visible to the user. It also states, "... will now throw an E_NOTICE when references are incorrectly used in the script. This is intended to alert developers to minor errors in their approach, and does not affect the script's performance in any other way." Not disconnecting a variable from previous reference assignments when using an "=&" does indeed affect a script's performance in a way beyond throwing notices. Previous Comments: [2005-09-19 18:29:44] [EMAIL PROTECTED] Thank you for taking the time to write to us, but this is not a bug. Please double-check the documentation available at http://www.php.net/manual/ and the instructions on how to report a bug at http://bugs.php.net/how-to-report.php Release announcement is pretty clear about this, this is why the release is 4.4.0 and not 4.3.12 ---------------- [2005-09-19 18:15:03] truth at proposaltech dot com Description: Based on the discussion on internals that led to the creation of php 4.4 (and based on the release notes for php 4.4), I would expect the only difference in running the following code under 4.3 and 4.4 to be the generation of a notice under 4.4. The code is bad, but it does not rely on corrupting memory. (BTW, this actually doesn't affect me personally because I immediately cleaned up our company's code for every 4.4 notice. I'm just helping isolate the BC break that frustrated a recent internals poster. Unless they are relying on memory corruption, users should be able to hide the notices and get the same behavior with 4.4 as 4.3. (There were posts from Zeev among others supporting this position.)) I hope this is easy to fix. The concept is easy. Whenever the code attempts to set a variable by reference, the variable should be unset as a first step. In the example, $y should be disconnected from $x because of the "$y =& ...". Yes, the reference shouldn't actually work, but that doesn't change the fact that the code clearly indicates that the connection between $y and $x should be broken. If I sound defensive, it's because Derick has already posted on internals that the new behavior is "correct". Please check with other engine gurus before jumping to any conclusions of bogusness. I think a fix to this BC break will save many hours for many, many php developers. (The example is silly, but you can get subtle cases of that problem in loops that are a nightmare to find.) Thanks! - Todd Reproduce code: --- Expected result: $x should end up 5 because the "$y=&..." should disconnect $y from $x even though the new connection can't be made. Actual result: -- Under 4.3, $x ends up 5, but under 4.4, $x ends up 3. -- Edit this bug report at http://bugs.php.net/?id=34551&edit=1