Jani Taskinen wrote:
Sriram Natarajan wrote:
Hi
I was looking into CR:
48774(http://bugs.php.net/bug.php?id=48774&thanks=3) and was hoping
if some one can kindly review this patch. This patch does address
the SEGV issue reported in the bug. Can this be applied to PHP 5.3
and PHP 5.2 as well ?
Fix your whitespace first. We use tabs only in .c files..
Please find the updated patch below
--- interface.c.ORIG 2009-07-09 15:24:00.000000000 -0700
+++ interface.c 2009-07-15 16:34:17.000000000 -0700
@@ -1328,6 +1328,7 @@
{
php_curl *ch;
CURL *cp;
+ zval *clone;
char *url = NULL;
int url_len = 0;
@@ -1353,6 +1354,9 @@
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);
@@ -1448,6 +1452,10 @@
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);
}
@@ -2298,8 +2306,19 @@
#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);
--- php_curl.h.ORIG 2009-07-14 23:42:08.000000000 -0700
+++ php_curl.h 2009-07-15 15:25:34.000000000 -0700
@@ -139,6 +139,7 @@
long id;
unsigned int uses;
zend_bool in_callback;
+ zval *clone;
} php_curl;
typedef struct {
--- /dev/null 2009-05-08 12:42:52.457160733 -0700
+++ tests/curl_copy_handle_basic_007.phpt 2009-07-14 17:40:47.000000000
-0700
@@ -0,0 +1,44 @@
+--TEST--
+Test curl_copy_handle() with simple POST
+--SKIPIF--
+<?php if (!extension_loaded("curl") || false ===
getenv('PHP_CURL_HTTP_REMOTE_SERVER')) print "skip"; ?>
+--FILE--
+<?php
+ $host = getenv('PHP_CURL_HTTP_REMOTE_SERVER');
+
+ echo '*** Testing curl copy handle with simple POST using array as arguments
***' . "\n";
+
+ $url = "{$host}/get.php?test=getpost";
+ $ch = curl_init();
+
+ ob_start(); // start output buffering
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($ch, CURLOPT_POST, 1);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, array("Hello" => "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===
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php