Skip to content

Commit 1a733cc

Browse files
committed
MFH: fix bug #33222 (segfault when CURL handle is closed in a callback).
1 parent 473e88e commit 1a733cc

File tree

3 files changed

+18
-2
lines changed

3 files changed

+18
-2
lines changed

NEWS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ PHP 4 NEWS
88
- Changed sha1_file() and md5_file() functions to use streams instead of
99
low level IO. (Uwe)
1010
- Fixed memory corruption in stristr(). (Derick)
11+
- Fixed bug #33222 (segfault when CURL handle is closed in a callback). (Tony)
1112
- Fixed bug #33214 (odbc_next_result does not signal SQL errors with
1213
2-statement SQL batches). (rich at kastle dot com, Tony)
1314
- Fixed bug #33210 (relax jpeg recursive loop protection). (Ilia)

ext/curl/curl.c

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -436,10 +436,12 @@ static size_t curl_write(char *data, size_t size, size_t nmemb, void *ctx)
436436
zend_list_addref(ch->id);
437437
ZVAL_STRINGL(argv[1], data, length, 1);
438438

439+
ch->in_callback = 1;
439440
error = call_user_function(EG(function_table),
440441
NULL,
441442
t->func,
442443
retval, 2, argv TSRMLS_CC);
444+
ch->in_callback = 0;
443445
if (error == FAILURE) {
444446
php_error(E_WARNING, "%s(): Couldn't call the CURLOPT_WRITEFUNCTION",
445447
get_active_function_name(TSRMLS_C));
@@ -495,10 +497,12 @@ static size_t curl_read(char *data, size_t size, size_t nmemb, void *ctx)
495497
zend_list_addref(t->fd);
496498
ZVAL_LONG(argv[2], (int) size * nmemb);
497499

500+
ch->in_callback = 1;
498501
error = call_user_function(EG(function_table),
499502
NULL,
500503
t->func,
501504
retval, 3, argv TSRMLS_CC);
505+
ch->in_callback = 0;
502506
if (error == FAILURE) {
503507
php_error(E_WARNING, "%s(): Cannot call the CURLOPT_READFUNCTION",
504508
get_active_function_name(TSRMLS_C));
@@ -553,10 +557,12 @@ static size_t curl_write_header(char *data, size_t size, size_t nmemb, void *ctx
553557
zend_list_addref(ch->id);
554558
ZVAL_STRINGL(argv[1], data, length, 1);
555559

560+
ch->in_callback = 1;
556561
error = call_user_function(EG(function_table),
557562
NULL,
558563
t->func,
559564
retval, 2, argv TSRMLS_CC);
565+
ch->in_callback = 0;
560566
if (error == FAILURE) {
561567
php_error(E_WARNING, "%s(): Couldn't call the CURLOPT_HEADERFUNCTION",
562568
get_active_function_name(TSRMLS_C));
@@ -606,10 +612,12 @@ static size_t curl_passwd(void *ctx, char *prompt, char *buf, int buflen)
606612
ZVAL_STRING(argv[1], prompt, 1);
607613
ZVAL_LONG(argv[2], buflen);
608614

615+
ch->in_callback = 1;
609616
error = call_user_function(EG(function_table),
610617
NULL,
611618
func,
612619
retval, 2, argv TSRMLS_CC);
620+
ch->in_callback = 0;
613621
if (error == FAILURE) {
614622
php_error(E_WARNING, "%s(): Couldn't call the CURLOPT_PASSWDFUNCTION", get_active_function_name(TSRMLS_C));
615623
} else if (Z_TYPE_P(retval) == IS_STRING) {
@@ -680,7 +688,9 @@ static void alloc_curl_handle(php_curl **ch)
680688
(*ch)->handlers->write_header = ecalloc(1, sizeof(php_curl_write));
681689
(*ch)->handlers->read = ecalloc(1, sizeof(php_curl_read));
682690
memset(&(*ch)->err, 0, sizeof((*ch)->err));
683-
691+
692+
(*ch)->in_callback = 0;
693+
684694
zend_llist_init(&(*ch)->to_free.str, sizeof(char *),
685695
(void(*)(void *)) curl_free_string, 0);
686696
zend_llist_init(&(*ch)->to_free.slist, sizeof(struct curl_slist),
@@ -1337,7 +1347,11 @@ PHP_FUNCTION(curl_close)
13371347
WRONG_PARAM_COUNT;
13381348
}
13391349
ZEND_FETCH_RESOURCE(ch, php_curl *, zid, -1, le_curl_name, le_curl);
1340-
1350+
1351+
if (ch->in_callback) {
1352+
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attempt to close CURL handle from a callback");
1353+
return;
1354+
}
13411355
zend_list_delete(Z_LVAL_PP(zid));
13421356
}
13431357
/* }}} */

ext/curl/php_curl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ typedef struct {
9393
struct _php_curl_free to_free;
9494
long id;
9595
unsigned int uses;
96+
zend_bool in_callback;
9697
} php_curl;
9798

9899
/* streams support */

0 commit comments

Comments
 (0)