mirror of
https://github.com/php/php-src.git
synced 2025-08-16 14:08:47 +02:00
Retain reference to share handle from curl handle
Not keeping a reference will not result in use after free, because curl protects against it, but it will result in a memory leak, because curl_share_cleanup() will fail. We should make sure that the share handle object stays alive as long as the curl handles use it.
This commit is contained in:
parent
11c4821ba9
commit
b4a2a9662b
3 changed files with 42 additions and 1 deletions
|
@ -104,6 +104,8 @@ typedef struct {
|
||||||
zend_bool in_callback;
|
zend_bool in_callback;
|
||||||
uint32_t* clone;
|
uint32_t* clone;
|
||||||
zval postfields;
|
zval postfields;
|
||||||
|
/* CurlShareHandle object set using CURLOPT_SHARE. */
|
||||||
|
struct _php_curlsh *share;
|
||||||
zend_object std;
|
zend_object std;
|
||||||
} php_curl;
|
} php_curl;
|
||||||
|
|
||||||
|
@ -124,7 +126,7 @@ typedef struct {
|
||||||
zend_object std;
|
zend_object std;
|
||||||
} php_curlm;
|
} php_curlm;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct _php_curlsh {
|
||||||
CURLSH *share;
|
CURLSH *share;
|
||||||
struct {
|
struct {
|
||||||
int no;
|
int no;
|
||||||
|
|
|
@ -2832,6 +2832,12 @@ static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue, bool i
|
||||||
if (Z_TYPE_P(zvalue) == IS_OBJECT && Z_OBJCE_P(zvalue) == curl_share_ce) {
|
if (Z_TYPE_P(zvalue) == IS_OBJECT && Z_OBJCE_P(zvalue) == curl_share_ce) {
|
||||||
php_curlsh *sh = Z_CURL_SHARE_P(zvalue);
|
php_curlsh *sh = Z_CURL_SHARE_P(zvalue);
|
||||||
curl_easy_setopt(ch->cp, CURLOPT_SHARE, sh->share);
|
curl_easy_setopt(ch->cp, CURLOPT_SHARE, sh->share);
|
||||||
|
|
||||||
|
if (ch->share) {
|
||||||
|
OBJ_RELEASE(&ch->share->std);
|
||||||
|
}
|
||||||
|
GC_ADDREF(&sh->std);
|
||||||
|
ch->share = sh;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -3373,6 +3379,10 @@ static void curl_free_obj(zend_object *object)
|
||||||
efree(ch->handlers);
|
efree(ch->handlers);
|
||||||
zval_ptr_dtor(&ch->postfields);
|
zval_ptr_dtor(&ch->postfields);
|
||||||
|
|
||||||
|
if (ch->share) {
|
||||||
|
OBJ_RELEASE(&ch->share->std);
|
||||||
|
}
|
||||||
|
|
||||||
zend_object_std_dtor(&ch->std);
|
zend_object_std_dtor(&ch->std);
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
29
ext/curl/tests/curl_share_basic.phpt
Normal file
29
ext/curl/tests/curl_share_basic.phpt
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
--TEST--
|
||||||
|
Basic curl_share test
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$sh = curl_share_init();
|
||||||
|
|
||||||
|
$ch1 = curl_init();
|
||||||
|
curl_setopt($ch1, CURLOPT_URL, 'file://' . __DIR__ . '/curl_testdata1.txt');
|
||||||
|
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true);
|
||||||
|
curl_setopt($ch1, CURLOPT_SHARE, $sh);
|
||||||
|
|
||||||
|
$ch2 = curl_init();
|
||||||
|
curl_setopt($ch2, CURLOPT_URL, 'file://' . __DIR__ . '/curl_testdata2.txt');
|
||||||
|
curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true);
|
||||||
|
curl_setopt($ch2, CURLOPT_SHARE, $sh);
|
||||||
|
|
||||||
|
// Make sure nothing bad handles if the share handle is unset early.
|
||||||
|
unset($sh);
|
||||||
|
|
||||||
|
var_dump(curl_exec($ch1));
|
||||||
|
var_dump(curl_exec($ch2));
|
||||||
|
|
||||||
|
?>
|
||||||
|
--EXPECT--
|
||||||
|
string(6) "CURL1
|
||||||
|
"
|
||||||
|
string(6) "CURL2
|
||||||
|
"
|
Loading…
Add table
Add a link
Reference in a new issue