summaryrefslogtreecommitdiff
path: root/ext/curl
diff options
context:
space:
mode:
authorPierrick Charron <pierrick@php.net>2011-11-22 05:19:37 +0000
committerPierrick Charron <pierrick@php.net>2011-11-22 05:19:37 +0000
commita1f1e0bcf952ed36884f47dd7064200767a5de92 (patch)
tree8fa6765b0ee18609a2e70543bb6e073efe924b76 /ext/curl
parentf7048d092515fabc3469429eaa249cfce5b1d43a (diff)
downloadphp-git-a1f1e0bcf952ed36884f47dd7064200767a5de92.tar.gz
Fix memory leak when using libcurl < 7.17.0
Diffstat (limited to 'ext/curl')
-rw-r--r--ext/curl/interface.c38
-rw-r--r--ext/curl/php_curl.h2
2 files changed, 17 insertions, 23 deletions
diff --git a/ext/curl/interface.c b/ext/curl/interface.c
index 7d49738101..af6133e533 100644
--- a/ext/curl/interface.c
+++ b/ext/curl/interface.c
@@ -198,7 +198,7 @@ static int php_curl_option_url(php_curl *ch, const char *url, const int len) /*
#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 @@ PHP_FUNCTION(curl_version)
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 @@ static void alloc_curl_handle(php_curl **ch)
(*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,12 +1655,8 @@ PHP_FUNCTION(curl_copy_handle)
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;
-
- zend_llist_copy(&dupch->to_free.slist, &ch->to_free.slist);
- zend_llist_copy(&dupch->to_free.post, &ch->to_free.post);
+ efree(dupch->to_free);
+ dupch->to_free = ch->to_free;
/* Keep track of cloned copies to avoid invoking curl destructors for every clone */
Z_ADDREF_P(ch->clone);
@@ -1853,7 +1850,7 @@ string_copy:
#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 @@ string_copy:
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 @@ string_copy:
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 @@ string_copy:
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 @@ string_copy:
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 @@ static void _php_curl_close_ex(php_curl *ch TSRMLS_DC)
_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) {
diff --git a/ext/curl/php_curl.h b/ext/curl/php_curl.h
index a50a2b8270..fe771970cb 100644
--- a/ext/curl/php_curl.h
+++ b/ext/curl/php_curl.h
@@ -131,7 +131,7 @@ struct _php_curl_free {
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;