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, ©str); + zend_llist_add_element(&ch->to_free->str, ©str); #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, ©str); + zend_llist_add_element(&ch->to_free->str, ©str); } 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, ©str); + zend_llist_add_element(&ch->to_free->str, ©str); #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, ©str); + zend_llist_add_element(&ch->to_free->str, ©str); #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, ©str); + zend_llist_add_element(&ch->to_free->str, ©str); } 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, ©str); + zend_llist_add_element(&ch->to_free->str, ©str); #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, ©str); + zend_llist_add_element(&ch->to_free->str, ©str); #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, ©str); + zend_llist_add_element(&ch->to_free->str, ©str); } 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, ©str); + zend_llist_add_element(&ch->to_free->str, ©str); #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