ID: 48590 Updated by: srina...@php.net Reported By: erik at datahack dot se -Status: Verified +Status: Closed Bug Type: Reproducible crash Operating System: * PHP Version: 5.3.0RC3 -Assigned To: +Assigned To: srinatar New Comment:
This bug has been fixed in SVN. Snapshots of the sources are packaged every three hours; this change will be in the next snapshot. You can grab the snapshot at http://snaps.php.net/. Thank you for the report, and for helping us make PHP better. here is a patch that should address this issue Index: ext/soap/php_http.c =================================================================== --- ext/soap/php_http.c (revision 293128) +++ ext/soap/php_http.c (working copy) @@ -207,6 +207,7 @@ int http_1_1; int http_status; int content_type_xml = 0; + long redirect_max = 20; char *content_encoding; char *http_msg = NULL; zend_bool old_allow_url_fopen; @@ -283,6 +284,14 @@ context = php_stream_context_from_zval(*tmp, 0); } + if (context && + php_stream_context_get_option(context, "http", "max_redirects", &tmp) == SUCCESS) { + if (Z_TYPE_PP(tmp) != IS_STRING || !is_numeric_string(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp), &redirect_max, NULL, 1)) { + if (Z_TYPE_PP(tmp) == IS_LONG) + redirect_max = Z_LVAL_PP(tmp); + } + } + try_again: if (phpurl == NULL || phpurl->host == NULL) { if (phpurl != NULL) {php_url_free(phpurl);} @@ -1012,6 +1021,12 @@ } phpurl = new_url; + if (--redirect_max < 1) { + smart_str_free(&soap_headers_z); + add_soap_fault(this_ptr, "HTTP", "Redirection limit reached, aborting", NULL, NULL TSRMLS_CC); + return FALSE; + } + goto try_again; } } Previous Comments: ------------------------------------------------------------------------ [2009-09-10 15:08:04] sjo...@php.net Could reproduce with latest 5.3. ------------------------------------------------------------------------ [2009-06-17 21:11:45] erik at datahack dot se The sample code has an extra comma after the "'stream_context' => $context,". ------------------------------------------------------------------------ [2009-06-17 21:05:23] erik at datahack dot se Description: ------------ A SOAPClient can be stuck in a redirect loop (and in some cases crash). Other PHP functions have solved this by a default redirection limit of 20 redirects (maybe a php.ini setting) or a custom value of a stream context -> http -> max_redirects. I provide two examples, one where PHP crashes after ~200 requests and one where it just loops forever. Reproduce code: --------------- redirection-loop.php: <?php header("Location: /redirection-loop.php"); ?> client code (crashes): <? $context = stream_context_create( array('http' => array('max_redirects' => 3)) ); $soap = new SOAPClient(NULL, array( 'uri' => 'foo', 'location' => 'http://example.com/redirection-loop.php', 'stream_context' => $context, ) ); $soap->test(); ?> client code (never finishes): <? $soap = new SOAPClient(NULL, array( 'uri' => 'foo', 'location' => 'http://example.com/redirection-loop.php' ) ); $soap->test(); ?> Expected result: ---------------- I expect it to have a default limit of 20 but also respect the max_requests value in the stream context. If the limit is reached I would expect a SOAPFault with a similar error description as below. When requesting the same file (redirection-loop.php) with file_get_contents() you get a warning and a empty result is returned. Warning: file_get_contents(http://example.com/redirection-loop.php): failed to open stream: Redirection limit reached, aborting in Command line code on line 1 Actual result: -------------- This is what happens if you specify a stream_context and tries to make it respect the max_requests (which is does not)... (gdb) bt #0 0x082e2c9e in php_stream_context_get_option (context=0xa2eb5b4, wrappername=0x85eb353 "socket", optionname=0x8623e2a "bindto", optionvalue=0xbf866d04) at php-5.3.0RC3/main/streams/streams.c:2036 #1 0x082ef2e3 in php_tcp_sockop_set_option (stream=0xa2eac68, option=7, value=0, ptrparam=0xbf866dd0) at php-5.3.0RC3/main/streams/xp_socket.c:641 #2 0x082e27d2 in _php_stream_set_option (stream=0xa2eac68, option=7, value=0, ptrparam=0xbf866dd0) at php-5.3.0RC3/main/streams/streams.c:1175 #3 0x082ed90f in php_stream_xport_connect (stream=0xa2eac68, name=0xa2eac16 "example.com:80", namelen=16, asynchronous=0, timeout=0xbf866e84, error_text=0xbf866e8c, error_code=0x0) at php-5.3.0RC3/main/streams/transports.c:230 #4 0x082edcca in _php_stream_xport_create (name=0xa2eac16 "example.org:80", namelen=16, options=12, flags=0, persistent_id=0x0, timeout=0xbf866e84, context=0xa2eb5b4, error_string=0x0, error_code=0x0) at php-5.3.0RC3/main/streams/transports.c:143 #5 0x081d56c6 in make_http_soap_request (this_ptr=0xa2ea634, buf=0xa35d5f0 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ns1=\"foo\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:SOAP-ENC="..., buf_size=378, location=0xa2eaa18 "http://example.com/redirection-loop.php", soapaction=0xa2eab9c "foo#test", soap_version=1, buffer=0xa2eab1c, buffer_len=0xa2eab20) at php-5.3.0RC3/ext/soap/php_http.c:120 #6 0x081b41d0 in zim_SoapClient___doRequest (ht=5, return_value=0xa2eab1c, return_value_ptr=0xbf8673c8, this_ptr=0xa2ea634, return_value_used=1) at php-5.3.0RC3/ext/soap/soap.c:3249 (gdb) f 0 #0 0x082e2c9e in php_stream_context_get_option (context=0xa2eb5b4, wrappername=0x85eb353 "socket", optionname=0x8623e2a "bindto", optionvalue=0xbf866d04) at php-5.3.0RC3/main/streams/streams.c:2036 2036 if (FAILURE == zend_hash_find(Z_ARRVAL_P(context->options), (char*)wrappername, strlen(wrappername)+1, (void**)&wrapperhash)) { ------------------------------------------------------------------------ -- Edit this bug report at http://bugs.php.net/?id=48590&edit=1