srinatar                                 Tue, 21 Jul 2009 20:32:32 +0000

Revision: http://svn.php.net/viewvc?view=revision&revision=284557

Log:
- Fixed bug #48774 (SIGSEGVs when using curl_copy_handle()).

Bug: http://bugs.php.net/48774 (Assigned) SIGSEGVs when using curl_copy_handle()
      
Changed paths:
    U   php/php-src/branches/PHP_5_2/NEWS
    U   php/php-src/branches/PHP_5_2/ext/curl/interface.c
    U   php/php-src/branches/PHP_5_2/ext/curl/php_curl.h
    A   
php/php-src/branches/PHP_5_2/ext/curl/tests/curl_copy_handle_basic_007.phpt
    U   php/php-src/branches/PHP_5_3/NEWS
    U   php/php-src/branches/PHP_5_3/ext/curl/interface.c
    U   php/php-src/branches/PHP_5_3/ext/curl/php_curl.h
    A   
php/php-src/branches/PHP_5_3/ext/curl/tests/curl_copy_handle_basic_007.phpt
    U   php/php-src/trunk/NEWS
    U   php/php-src/trunk/ext/curl/interface.c
    U   php/php-src/trunk/ext/curl/php_curl.h
    A   php/php-src/trunk/ext/curl/tests/curl_copy_handle_basic_007.phpt

Modified: php/php-src/branches/PHP_5_2/NEWS
===================================================================
--- php/php-src/branches/PHP_5_2/NEWS	2009-07-21 20:11:28 UTC (rev 284556)
+++ php/php-src/branches/PHP_5_2/NEWS	2009-07-21 20:32:32 UTC (rev 284557)
@@ -51,6 +51,8 @@
   (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)

Modified: php/php-src/branches/PHP_5_2/ext/curl/interface.c
===================================================================
--- php/php-src/branches/PHP_5_2/ext/curl/interface.c	2009-07-21 20:11:28 UTC (rev 284556)
+++ php/php-src/branches/PHP_5_2/ext/curl/interface.c	2009-07-21 20:32:32 UTC (rev 284557)
@@ -1160,6 +1160,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);
@@ -1193,6 +1196,7 @@
 PHP_FUNCTION(curl_copy_handle)
 {
 	CURL		*cp;
+ 	zval		*clone;
 	zval		**zid;
 	php_curl	*ch, *dupch;

@@ -1255,6 +1259,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);
 }
@@ -2073,9 +2081,20 @@
 #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);
 	}

Modified: php/php-src/branches/PHP_5_2/ext/curl/php_curl.h
===================================================================
--- php/php-src/branches/PHP_5_2/ext/curl/php_curl.h	2009-07-21 20:11:28 UTC (rev 284556)
+++ php/php-src/branches/PHP_5_2/ext/curl/php_curl.h	2009-07-21 20:32:32 UTC (rev 284557)
@@ -132,6 +132,7 @@
 	long                     id;
 	unsigned int             uses;
 	zend_bool                in_callback;
+	zval                     *clone;
 } php_curl;

 typedef struct {

Added: php/php-src/branches/PHP_5_2/ext/curl/tests/curl_copy_handle_basic_007.phpt
===================================================================
--- php/php-src/branches/PHP_5_2/ext/curl/tests/curl_copy_handle_basic_007.phpt	                        (rev 0)
+++ php/php-src/branches/PHP_5_2/ext/curl/tests/curl_copy_handle_basic_007.phpt	2009-07-21 20:32:32 UTC (rev 284557)
@@ -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===

Modified: php/php-src/branches/PHP_5_3/NEWS
===================================================================
--- php/php-src/branches/PHP_5_3/NEWS	2009-07-21 20:11:28 UTC (rev 284556)
+++ php/php-src/branches/PHP_5_3/NEWS	2009-07-21 20:32:32 UTC (rev 284557)
@@ -41,6 +41,8 @@
   (markril at hotmail dot com, Pierre)
 - Fixed bug #38091 (Mail() does not use FQDN when sending SMTP helo).
   (Kalle, Rick Yorgason)
+- Fixed bug #48774 (SIGSEGVs when using curl_copy_handle()).
+  (Sriram Natarajan)

 30 Jun 2009, PHP 5.3.0
 - Upgraded bundled PCRE to version 7.9. (Nuno)

Modified: php/php-src/branches/PHP_5_3/ext/curl/interface.c
===================================================================
--- php/php-src/branches/PHP_5_3/ext/curl/interface.c	2009-07-21 20:11:28 UTC (rev 284556)
+++ php/php-src/branches/PHP_5_3/ext/curl/interface.c	2009-07-21 20:32:32 UTC (rev 284557)
@@ -1331,6 +1331,7 @@
 {
 	php_curl	*ch;
 	CURL		*cp;
+	zval		*clone;
 	char		*url = NULL;
 	int		url_len = 0;

@@ -1356,6 +1357,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);
@@ -1451,6 +1455,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,9 +2306,20 @@
 #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);
 	}

Modified: php/php-src/branches/PHP_5_3/ext/curl/php_curl.h
===================================================================
--- php/php-src/branches/PHP_5_3/ext/curl/php_curl.h	2009-07-21 20:11:28 UTC (rev 284556)
+++ php/php-src/branches/PHP_5_3/ext/curl/php_curl.h	2009-07-21 20:32:32 UTC (rev 284557)
@@ -139,6 +139,7 @@
 	long                     id;
 	unsigned int             uses;
 	zend_bool                in_callback;
+	zval                     *clone;
 } php_curl;

 typedef struct {

Added: php/php-src/branches/PHP_5_3/ext/curl/tests/curl_copy_handle_basic_007.phpt
===================================================================
--- php/php-src/branches/PHP_5_3/ext/curl/tests/curl_copy_handle_basic_007.phpt	                        (rev 0)
+++ php/php-src/branches/PHP_5_3/ext/curl/tests/curl_copy_handle_basic_007.phpt	2009-07-21 20:32:32 UTC (rev 284557)
@@ -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===

Modified: php/php-src/trunk/NEWS
===================================================================
--- php/php-src/trunk/NEWS	2009-07-21 20:11:28 UTC (rev 284556)
+++ php/php-src/trunk/NEWS	2009-07-21 20:32:32 UTC (rev 284557)
@@ -48,3 +48,4 @@

 - Fixed bug #46647 (SplFileObject::fgetcsv segfaults). (Etienne)
 - Fixed bug #40325 (Vary: header missing in gzip output handlers). (Mike)
+- Fixed bug #48774 (SIGSEGVs when using curl_copy_handle()). (Sriram Natarajan)

Modified: php/php-src/trunk/ext/curl/interface.c
===================================================================
--- php/php-src/trunk/ext/curl/interface.c	2009-07-21 20:11:28 UTC (rev 284556)
+++ php/php-src/trunk/ext/curl/interface.c	2009-07-21 20:32:32 UTC (rev 284557)
@@ -1334,6 +1334,7 @@
 {
 	php_curl	*ch;
 	CURL		*cp;
+ 	zval		*clone;
 	zstr		url = NULL_ZSTR;
 	int		url_len = 0;
 	zend_uchar	url_type = 0;
@@ -1368,6 +1369,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);
@@ -1467,6 +1471,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);
 }
@@ -2364,9 +2372,20 @@
 #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);
 	}

Modified: php/php-src/trunk/ext/curl/php_curl.h
===================================================================
--- php/php-src/trunk/ext/curl/php_curl.h	2009-07-21 20:11:28 UTC (rev 284556)
+++ php/php-src/trunk/ext/curl/php_curl.h	2009-07-21 20:32:32 UTC (rev 284557)
@@ -139,6 +139,7 @@
 	long                     id;
 	unsigned int             uses;
 	zend_bool                in_callback;
+	zval                     *clone;
 } php_curl;

 typedef struct {

Added: php/php-src/trunk/ext/curl/tests/curl_copy_handle_basic_007.phpt
===================================================================
--- php/php-src/trunk/ext/curl/tests/curl_copy_handle_basic_007.phpt	                        (rev 0)
+++ php/php-src/trunk/ext/curl/tests/curl_copy_handle_basic_007.phpt	2009-07-21 20:32:32 UTC (rev 284557)
@@ -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 CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to