pierrick                                 Tue, 22 Nov 2011 05:19:37 +0000

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

Log:
Fix memory leak when using libcurl < 7.17.0

Changed paths:
    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
    U   php/php-src/branches/PHP_5_4/ext/curl/interface.c
    U   php/php-src/branches/PHP_5_4/ext/curl/php_curl.h
    U   php/php-src/trunk/ext/curl/interface.c
    U   php/php-src/trunk/ext/curl/php_curl.h

Modified: php/php-src/branches/PHP_5_3/ext/curl/interface.c
===================================================================
--- php/php-src/branches/PHP_5_3/ext/curl/interface.c	2011-11-22 03:39:12 UTC (rev 319661)
+++ php/php-src/branches/PHP_5_3/ext/curl/interface.c	2011-11-22 05:19:37 UTC (rev 319662)
@@ -198,7 +198,7 @@
 #else
 	copystr = estrndup(url, len);
 	error = curl_easy_setopt(ch->cp, CURLOPT_URL, copystr);
-	zend_llist_add_element(&ch->to_free.str, &copystr);
+	zend_llist_add_element(&ch->to_free->str, &copystr);
 #endif

 	return (error == CURLE_OK ? 1 : 0);
@@ -1412,6 +1412,7 @@
 static void alloc_curl_handle(php_curl **ch)
 {
 	*ch                           = emalloc(sizeof(php_curl));
+	(*ch)->to_free                = ecalloc(1, sizeof(struct _php_curl_free));
 	(*ch)->handlers               = ecalloc(1, sizeof(php_curl_handlers));
 	(*ch)->handlers->write        = ecalloc(1, sizeof(php_curl_write));
 	(*ch)->handlers->write_header = ecalloc(1, sizeof(php_curl_write));
@@ -1426,9 +1427,9 @@
 	(*ch)->handlers->write_header->stream = NULL;
 	(*ch)->handlers->read->stream = NULL;

-	zend_llist_init(&(*ch)->to_free.str,   sizeof(char *),            (llist_dtor_func_t) curl_free_string, 0);
-	zend_llist_init(&(*ch)->to_free.slist, sizeof(struct curl_slist), (llist_dtor_func_t) curl_free_slist,  0);
-	zend_llist_init(&(*ch)->to_free.post,  sizeof(struct HttpPost),   (llist_dtor_func_t) curl_free_post,   0);
+	zend_llist_init(&(*ch)->to_free->str,   sizeof(char *),            (llist_dtor_func_t) curl_free_string, 0);
+	zend_llist_init(&(*ch)->to_free->slist, sizeof(struct curl_slist), (llist_dtor_func_t) curl_free_slist,  0);
+	zend_llist_init(&(*ch)->to_free->post,  sizeof(struct HttpPost),   (llist_dtor_func_t) curl_free_post,   0);
 }
 /* }}} */

@@ -1654,13 +1655,9 @@
 	curl_easy_setopt(dupch->cp, CURLOPT_INFILE,            (void *) dupch);
 	curl_easy_setopt(dupch->cp, CURLOPT_WRITEHEADER,       (void *) dupch);

-	zend_llist_copy(&dupch->to_free.str, &ch->to_free.str);
-	/* Don't try to free copied strings, they're free'd when the original handle is destroyed */
-	dupch->to_free.str.dtor = NULL;
+	efree(dupch->to_free);
+	dupch->to_free = ch->to_free;

-	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;
@@ -1853,7 +1850,7 @@
 #endif
 					copystr = estrndup(Z_STRVAL_PP(zvalue), Z_STRLEN_PP(zvalue));
 					error = curl_easy_setopt(ch->cp, option, copystr);
-					zend_llist_add_element(&ch->to_free.str, &copystr);
+					zend_llist_add_element(&ch->to_free->str, &copystr);
 				} else {
 #if LIBCURL_VERSION_NUM >= 0x071100
 					/* Strings passed to libcurl as ’char *’ arguments, are copied by the library... NOTE: before 7.17.0 strings were not copied. */
@@ -2094,7 +2091,7 @@
 					return 1;
 				}

-				zend_llist_add_element(&ch->to_free.post, &first);
+				zend_llist_add_element(&ch->to_free->post, &first);
 				error = curl_easy_setopt(ch->cp, CURLOPT_HTTPPOST, first);

 			} else {
@@ -2108,7 +2105,7 @@

 				convert_to_string_ex(zvalue);
 				post = estrndup(Z_STRVAL_PP(zvalue), Z_STRLEN_PP(zvalue));
-				zend_llist_add_element(&ch->to_free.str, &post);
+				zend_llist_add_element(&ch->to_free->str, &post);

 				error = curl_easy_setopt(ch->cp, CURLOPT_POSTFIELDS, post);
 				error = curl_easy_setopt(ch->cp, CURLOPT_POSTFIELDSIZE, Z_STRLEN_PP(zvalue));
@@ -2144,7 +2141,7 @@
 					return 1;
 				}
 			}
-			zend_llist_add_element(&ch->to_free.slist, &slist);
+			zend_llist_add_element(&ch->to_free->slist, &slist);

 			error = curl_easy_setopt(ch->cp, option, slist);

@@ -2174,7 +2171,7 @@
 			copystr = estrndup(Z_STRVAL_PP(zvalue), Z_STRLEN_PP(zvalue));

 			error = curl_easy_setopt(ch->cp, option, copystr);
-			zend_llist_add_element(&ch->to_free.str, &copystr);
+			zend_llist_add_element(&ch->to_free->str, &copystr);
 #endif
 			break;
 		}
@@ -2592,19 +2589,16 @@

 	_php_curl_verify_handlers(ch, 0 TSRMLS_CC);
 	curl_easy_cleanup(ch->cp);
-	zend_llist_clean(&ch->to_free.str);

 	/* 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);
+		zend_llist_clean(&ch->to_free->str);
+		zend_llist_clean(&ch->to_free->slist);
+		zend_llist_clean(&ch->to_free->post);
+		efree(ch->to_free);
 		FREE_ZVAL(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) {

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	2011-11-22 03:39:12 UTC (rev 319661)
+++ php/php-src/branches/PHP_5_3/ext/curl/php_curl.h	2011-11-22 05:19:37 UTC (rev 319662)
@@ -131,7 +131,7 @@

 typedef struct {
 	struct _php_curl_error   err;
-	struct _php_curl_free    to_free;
+	struct _php_curl_free    *to_free;
 	struct _php_curl_send_headers header;
 	void ***thread_ctx;
 	CURL                    *cp;

Modified: php/php-src/branches/PHP_5_4/ext/curl/interface.c
===================================================================
--- php/php-src/branches/PHP_5_4/ext/curl/interface.c	2011-11-22 03:39:12 UTC (rev 319661)
+++ php/php-src/branches/PHP_5_4/ext/curl/interface.c	2011-11-22 05:19:37 UTC (rev 319662)
@@ -196,7 +196,7 @@
 #else
 	copystr = estrndup(url, len);
 	error = curl_easy_setopt(ch->cp, CURLOPT_URL, copystr);
-	zend_llist_add_element(&ch->to_free.str, &copystr);
+	zend_llist_add_element(&ch->to_free->str, &copystr);
 #endif

 	return (error == CURLE_OK ? 1 : 0);
@@ -1410,6 +1410,7 @@
 static void alloc_curl_handle(php_curl **ch)
 {
 	*ch                           = emalloc(sizeof(php_curl));
+	(*ch)->to_free                = ecalloc(1, sizeof(struct _php_curl_free));
 	(*ch)->handlers               = ecalloc(1, sizeof(php_curl_handlers));
 	(*ch)->handlers->write        = ecalloc(1, sizeof(php_curl_write));
 	(*ch)->handlers->write_header = ecalloc(1, sizeof(php_curl_write));
@@ -1424,9 +1425,9 @@
 	(*ch)->handlers->write_header->stream = NULL;
 	(*ch)->handlers->read->stream = NULL;

-	zend_llist_init(&(*ch)->to_free.str,   sizeof(char *),            (llist_dtor_func_t) curl_free_string, 0);
-	zend_llist_init(&(*ch)->to_free.slist, sizeof(struct curl_slist), (llist_dtor_func_t) curl_free_slist,  0);
-	zend_llist_init(&(*ch)->to_free.post,  sizeof(struct HttpPost),   (llist_dtor_func_t) curl_free_post,   0);
+	zend_llist_init(&(*ch)->to_free->str,   sizeof(char *),            (llist_dtor_func_t) curl_free_string, 0);
+	zend_llist_init(&(*ch)->to_free->slist, sizeof(struct curl_slist), (llist_dtor_func_t) curl_free_slist,  0);
+	zend_llist_init(&(*ch)->to_free->post,  sizeof(struct HttpPost),   (llist_dtor_func_t) curl_free_post,   0);
 }
 /* }}} */

@@ -1650,13 +1651,9 @@
 	curl_easy_setopt(dupch->cp, CURLOPT_INFILE,            (void *) dupch);
 	curl_easy_setopt(dupch->cp, CURLOPT_WRITEHEADER,       (void *) dupch);

-	zend_llist_copy(&dupch->to_free.str, &ch->to_free.str);
-	/* Don't try to free copied strings, they're free'd when the original handle is destroyed */
-	dupch->to_free.str.dtor = NULL;
+	efree(dupch->to_free);
+	dupch->to_free = ch->to_free;

-	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;
@@ -1849,7 +1846,7 @@
 #endif
 					copystr = estrndup(Z_STRVAL_PP(zvalue), Z_STRLEN_PP(zvalue));
 					error = curl_easy_setopt(ch->cp, option, copystr);
-					zend_llist_add_element(&ch->to_free.str, &copystr);
+					zend_llist_add_element(&ch->to_free->str, &copystr);
 				} else {
 #if LIBCURL_VERSION_NUM >= 0x071100
 					/* Strings passed to libcurl as ’char *’ arguments, are copied by the library... NOTE: before 7.17.0 strings were not copied. */
@@ -2104,7 +2101,7 @@
 					return 1;
 				}

-				zend_llist_add_element(&ch->to_free.post, &first);
+				zend_llist_add_element(&ch->to_free->post, &first);
 				error = curl_easy_setopt(ch->cp, CURLOPT_HTTPPOST, first);

 			} else {
@@ -2118,7 +2115,7 @@

 				convert_to_string_ex(zvalue);
 				post = estrndup(Z_STRVAL_PP(zvalue), Z_STRLEN_PP(zvalue));
-				zend_llist_add_element(&ch->to_free.str, &post);
+				zend_llist_add_element(&ch->to_free->str, &post);

 				error = curl_easy_setopt(ch->cp, CURLOPT_POSTFIELDS, post);
 				error = curl_easy_setopt(ch->cp, CURLOPT_POSTFIELDSIZE, Z_STRLEN_PP(zvalue));
@@ -2154,7 +2151,7 @@
 					return 1;
 				}
 			}
-			zend_llist_add_element(&ch->to_free.slist, &slist);
+			zend_llist_add_element(&ch->to_free->slist, &slist);

 			error = curl_easy_setopt(ch->cp, option, slist);

@@ -2184,7 +2181,7 @@
 			copystr = estrndup(Z_STRVAL_PP(zvalue), Z_STRLEN_PP(zvalue));

 			error = curl_easy_setopt(ch->cp, option, copystr);
-			zend_llist_add_element(&ch->to_free.str, &copystr);
+			zend_llist_add_element(&ch->to_free->str, &copystr);
 #endif
 			break;
 		}
@@ -2629,19 +2626,16 @@

 	_php_curl_verify_handlers(ch, 0 TSRMLS_CC);
 	curl_easy_cleanup(ch->cp);
-	zend_llist_clean(&ch->to_free.str);

 	/* 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);
+		zend_llist_clean(&ch->to_free->str);
+		zend_llist_clean(&ch->to_free->slist);
+		zend_llist_clean(&ch->to_free->post);
+		efree(ch->to_free);
 		FREE_ZVAL(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) {

Modified: php/php-src/branches/PHP_5_4/ext/curl/php_curl.h
===================================================================
--- php/php-src/branches/PHP_5_4/ext/curl/php_curl.h	2011-11-22 03:39:12 UTC (rev 319661)
+++ php/php-src/branches/PHP_5_4/ext/curl/php_curl.h	2011-11-22 05:19:37 UTC (rev 319662)
@@ -131,7 +131,7 @@

 typedef struct {
 	struct _php_curl_error   err;
-	struct _php_curl_free    to_free;
+	struct _php_curl_free    *to_free;
 	struct _php_curl_send_headers header;
 	void ***thread_ctx;
 	CURL                    *cp;

Modified: php/php-src/trunk/ext/curl/interface.c
===================================================================
--- php/php-src/trunk/ext/curl/interface.c	2011-11-22 03:39:12 UTC (rev 319661)
+++ php/php-src/trunk/ext/curl/interface.c	2011-11-22 05:19:37 UTC (rev 319662)
@@ -196,7 +196,7 @@
 #else
 	copystr = estrndup(url, len);
 	error = curl_easy_setopt(ch->cp, CURLOPT_URL, copystr);
-	zend_llist_add_element(&ch->to_free.str, &copystr);
+	zend_llist_add_element(&ch->to_free->str, &copystr);
 #endif

 	return (error == CURLE_OK ? 1 : 0);
@@ -1410,6 +1410,7 @@
 static void alloc_curl_handle(php_curl **ch)
 {
 	*ch                           = emalloc(sizeof(php_curl));
+	(*ch)->to_free                = ecalloc(1, sizeof(struct _php_curl_free));
 	(*ch)->handlers               = ecalloc(1, sizeof(php_curl_handlers));
 	(*ch)->handlers->write        = ecalloc(1, sizeof(php_curl_write));
 	(*ch)->handlers->write_header = ecalloc(1, sizeof(php_curl_write));
@@ -1424,9 +1425,9 @@
 	(*ch)->handlers->write_header->stream = NULL;
 	(*ch)->handlers->read->stream = NULL;

-	zend_llist_init(&(*ch)->to_free.str,   sizeof(char *),            (llist_dtor_func_t) curl_free_string, 0);
-	zend_llist_init(&(*ch)->to_free.slist, sizeof(struct curl_slist), (llist_dtor_func_t) curl_free_slist,  0);
-	zend_llist_init(&(*ch)->to_free.post,  sizeof(struct HttpPost),   (llist_dtor_func_t) curl_free_post,   0);
+	zend_llist_init(&(*ch)->to_free->str,   sizeof(char *),            (llist_dtor_func_t) curl_free_string, 0);
+	zend_llist_init(&(*ch)->to_free->slist, sizeof(struct curl_slist), (llist_dtor_func_t) curl_free_slist,  0);
+	zend_llist_init(&(*ch)->to_free->post,  sizeof(struct HttpPost),   (llist_dtor_func_t) curl_free_post,   0);
 }
 /* }}} */

@@ -1650,13 +1651,9 @@
 	curl_easy_setopt(dupch->cp, CURLOPT_INFILE,            (void *) dupch);
 	curl_easy_setopt(dupch->cp, CURLOPT_WRITEHEADER,       (void *) dupch);

-	zend_llist_copy(&dupch->to_free.str, &ch->to_free.str);
-	/* Don't try to free copied strings, they're free'd when the original handle is destroyed */
-	dupch->to_free.str.dtor = NULL;
+	efree(dupch->to_free);
+	dupch->to_free = ch->to_free;

-	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;
@@ -1849,7 +1846,7 @@
 #endif
 					copystr = estrndup(Z_STRVAL_PP(zvalue), Z_STRLEN_PP(zvalue));
 					error = curl_easy_setopt(ch->cp, option, copystr);
-					zend_llist_add_element(&ch->to_free.str, &copystr);
+					zend_llist_add_element(&ch->to_free->str, &copystr);
 				} else {
 #if LIBCURL_VERSION_NUM >= 0x071100
 					/* Strings passed to libcurl as ’char *’ arguments, are copied by the library... NOTE: before 7.17.0 strings were not copied. */
@@ -2104,7 +2101,7 @@
 					return 1;
 				}

-				zend_llist_add_element(&ch->to_free.post, &first);
+				zend_llist_add_element(&ch->to_free->post, &first);
 				error = curl_easy_setopt(ch->cp, CURLOPT_HTTPPOST, first);

 			} else {
@@ -2118,7 +2115,7 @@

 				convert_to_string_ex(zvalue);
 				post = estrndup(Z_STRVAL_PP(zvalue), Z_STRLEN_PP(zvalue));
-				zend_llist_add_element(&ch->to_free.str, &post);
+				zend_llist_add_element(&ch->to_free->str, &post);

 				error = curl_easy_setopt(ch->cp, CURLOPT_POSTFIELDS, post);
 				error = curl_easy_setopt(ch->cp, CURLOPT_POSTFIELDSIZE, Z_STRLEN_PP(zvalue));
@@ -2154,7 +2151,7 @@
 					return 1;
 				}
 			}
-			zend_llist_add_element(&ch->to_free.slist, &slist);
+			zend_llist_add_element(&ch->to_free->slist, &slist);

 			error = curl_easy_setopt(ch->cp, option, slist);

@@ -2184,7 +2181,7 @@
 			copystr = estrndup(Z_STRVAL_PP(zvalue), Z_STRLEN_PP(zvalue));

 			error = curl_easy_setopt(ch->cp, option, copystr);
-			zend_llist_add_element(&ch->to_free.str, &copystr);
+			zend_llist_add_element(&ch->to_free->str, &copystr);
 #endif
 			break;
 		}
@@ -2629,19 +2626,16 @@

 	_php_curl_verify_handlers(ch, 0 TSRMLS_CC);
 	curl_easy_cleanup(ch->cp);
-	zend_llist_clean(&ch->to_free.str);

 	/* 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);
+		zend_llist_clean(&ch->to_free->str);
+		zend_llist_clean(&ch->to_free->slist);
+		zend_llist_clean(&ch->to_free->post);
+		efree(ch->to_free);
 		FREE_ZVAL(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) {

Modified: php/php-src/trunk/ext/curl/php_curl.h
===================================================================
--- php/php-src/trunk/ext/curl/php_curl.h	2011-11-22 03:39:12 UTC (rev 319661)
+++ php/php-src/trunk/ext/curl/php_curl.h	2011-11-22 05:19:37 UTC (rev 319662)
@@ -131,7 +131,7 @@

 typedef struct {
 	struct _php_curl_error   err;
-	struct _php_curl_free    to_free;
+	struct _php_curl_free    *to_free;
 	struct _php_curl_send_headers header;
 	void ***thread_ctx;
 	CURL                    *cp;
-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to