From: Sriram Natarajan Date: Tue, 21 Jul 2009 20:32:32 +0000 (+0000) Subject: - Fixed bug #48774 (SIGSEGVs when using curl_copy_handle()). X-Git-Tag: php-5.2.11RC1~125 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7f87b7e15c18f428daf7608608cdeea477fb7ee7;p=php - Fixed bug #48774 (SIGSEGVs when using curl_copy_handle()). --- diff --git a/NEWS b/NEWS index 7b1a7905d2..cfb9f25833 100644 --- a/NEWS +++ b/NEWS @@ -51,6 +51,8 @@ PHP NEWS (markril at hotmail dot com, Pierre) - Fixed bug #45280 (Reflection of instantiated COM classes causes PHP to crash) (Paul Richards, Kalle) +- Fixed bug #48774 (SIGSEGVs when using curl_copy_handle()). + (Sriram Natarajan) 17 Jun 2009, PHP 5.2.10 - Updated timezone database to version 2009.9 (2009i) (Derick) diff --git a/ext/curl/interface.c b/ext/curl/interface.c index 791d15b32f..241df05bf8 100644 --- a/ext/curl/interface.c +++ b/ext/curl/interface.c @@ -1160,6 +1160,9 @@ PHP_FUNCTION(curl_init) ch->uses = 0; + MAKE_STD_ZVAL(clone); + ch->clone = clone; + curl_easy_setopt(ch->cp, CURLOPT_NOPROGRESS, 1); curl_easy_setopt(ch->cp, CURLOPT_VERBOSE, 0); curl_easy_setopt(ch->cp, CURLOPT_ERRORBUFFER, ch->err.str); @@ -1193,6 +1196,7 @@ PHP_FUNCTION(curl_init) PHP_FUNCTION(curl_copy_handle) { CURL *cp; + zval *clone; zval **zid; php_curl *ch, *dupch; @@ -1255,6 +1259,10 @@ PHP_FUNCTION(curl_copy_handle) zend_llist_copy(&dupch->to_free.slist, &ch->to_free.slist); zend_llist_copy(&dupch->to_free.post, &ch->to_free.post); + /* Keep track of cloned copies to avoid invoking curl destructors for every clone */ + Z_ADDREF_P(ch->clone); + dupch->clone = ch->clone; + ZEND_REGISTER_RESOURCE(return_value, dupch, le_curl); dupch->id = Z_LVAL_P(return_value); } @@ -2073,8 +2081,19 @@ static void _php_curl_close_ex(php_curl *ch TSRMLS_DC) #if LIBCURL_VERSION_NUM < 0x071101 zend_llist_clean(&ch->to_free.str); #endif - zend_llist_clean(&ch->to_free.slist); - zend_llist_clean(&ch->to_free.post); + + /* cURL destructors should be invoked only by last curl handle */ + if (Z_REFCOUNT_P(ch->clone) <= 1) { + zend_llist_clean(&ch->to_free.slist); + zend_llist_clean(&ch->to_free.post); + zval_ptr_dtor(&ch->clone); + } else { + Z_DELREF_P(ch->clone); + ch->to_free.slist.dtor = NULL; + ch->to_free.post.dtor = NULL; + zend_llist_clean(&ch->to_free.slist); + zend_llist_clean(&ch->to_free.post); + } if (ch->handlers->write->buf.len > 0) { smart_str_free(&ch->handlers->write->buf); diff --git a/ext/curl/php_curl.h b/ext/curl/php_curl.h index 87bf710759..e3675c64ba 100644 --- a/ext/curl/php_curl.h +++ b/ext/curl/php_curl.h @@ -132,6 +132,7 @@ typedef struct { long id; unsigned int uses; zend_bool in_callback; + zval *clone; } php_curl; typedef struct { diff --git a/ext/curl/tests/curl_copy_handle_basic_007.phpt b/ext/curl/tests/curl_copy_handle_basic_007.phpt new file mode 100644 index 0000000000..5be9048af6 --- /dev/null +++ b/ext/curl/tests/curl_copy_handle_basic_007.phpt @@ -0,0 +1,44 @@ +--TEST-- +Test curl_copy_handle() with simple POST +--SKIPIF-- + +--FILE-- + "World", "Foo" => "Bar", "Person" => "John Doe")); + curl_setopt($ch, CURLOPT_URL, $url); //set the url we want to use + + $copy = curl_copy_handle($ch); + curl_close($ch); + + $curl_content = curl_exec($copy); + curl_close($copy); + + var_dump( $curl_content ); +?> +===DONE=== +--EXPECTF-- +*** Testing curl copy handle with simple POST using array as arguments *** +string(163) "array(1) { + ["test"]=> + string(7) "getpost" +} +array(3) { + ["Hello"]=> + string(5) "World" + ["Foo"]=> + string(3) "Bar" + ["Person"]=> + string(8) "John Doe" +} +" +===DONE===