From: Michael Wallner Date: Wed, 10 Aug 2016 13:41:09 +0000 (+0200) Subject: Merge branch 'v2.6.x' X-Git-Tag: RELEASE_3_1_0_BETA1~3 X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-http;a=commitdiff_plain;h=512de8cdaf8a02b4329e0ceb8368cb8f15eba7cb;hp=e1d5ca36e13696a2e87b618165669fc7c53709c1 Merge branch 'v2.6.x' --- diff --git a/src/php_http_client.c b/src/php_http_client.c index b719d2f..d0e6e80 100644 --- a/src/php_http_client.c +++ b/src/php_http_client.c @@ -476,7 +476,9 @@ static ZEND_RESULT_CODE handle_response(void *arg, php_http_client_t *client, ph ZVAL_UNDEF(&retval); zend_fcall_info_argn(&e->closure.fci, 1, &zresponse); zend_replace_error_handling(EH_NORMAL, NULL, &zeh); + ++client->callback.depth; zend_fcall_info_call(&e->closure.fci, &e->closure.fcc, &retval, NULL); + --client->callback.depth; zend_restore_error_handling(&zeh); zend_fcall_info_argn(&e->closure.fci, 0); @@ -521,7 +523,9 @@ static void handle_progress(void *arg, php_http_client_t *client, php_http_clien add_property_double(&args[1], "ulnow", progress->ul.now); zend_replace_error_handling(EH_NORMAL, NULL, &zeh); + ++client->callback.depth; php_http_object_method_call(&client_obj->notify, &zclient, NULL, 2, args); + --client->callback.depth; zend_restore_error_handling(&zeh); zval_ptr_dtor(&zclient); @@ -542,7 +546,9 @@ static void handle_debug(void *arg, php_http_client_t *client, php_http_client_e zend_replace_error_handling(EH_NORMAL, NULL, &zeh); if (SUCCESS == zend_fcall_info_argn(&client_obj->debug.fci, 4, &zclient, &zreq, &ztype, &zdata)) { + ++client->callback.depth; zend_fcall_info_call(&client_obj->debug.fci, &client_obj->debug.fcc, NULL, NULL); + --client->callback.depth; zend_fcall_info_args_clear(&client_obj->debug.fci, 0); } zend_restore_error_handling(&zeh); diff --git a/src/php_http_client.h b/src/php_http_client.h index 08743e6..0edd1bb 100644 --- a/src/php_http_client.h +++ b/src/php_http_client.h @@ -117,6 +117,7 @@ typedef struct php_http_client { php_http_client_debug_callback_t func; void *arg; } debug; + unsigned depth; } callback; zend_llist requests; diff --git a/src/php_http_client_curl.c b/src/php_http_client_curl.c index be04be8..1e92fbe 100644 --- a/src/php_http_client_curl.c +++ b/src/php_http_client_curl.c @@ -177,22 +177,19 @@ static int php_http_curle_progress_callback(void *ctx, double dltotal, double dl #endif { php_http_client_curl_handler_t *h = ctx; - zend_bool update = 0; if (h->progress.dl.total != dltotal || h->progress.dl.now != dlnow || h->progress.ul.total != ultotal || h->progress.ul.now != ulnow ) { - update = 1; - h->progress.dl.total = dltotal; h->progress.dl.now = dlnow; h->progress.ul.total = ultotal; h->progress.ul.now = ulnow; } - if (update && h->client->callback.progress.func) { + if (h->client->callback.progress.func) { h->client->callback.progress.func(h->client->callback.progress.arg, h->client, &h->queue, &h->progress); } @@ -2195,6 +2192,11 @@ static ZEND_RESULT_CODE php_http_client_curl_dequeue(php_http_client_t *h, php_h php_http_client_curl_t *curl = h->ctx; php_http_client_curl_handler_t *handler = enqueue->opaque; + if (h->callback.depth) { + php_error_docref(NULL, E_WARNING, "Could not dequeue request while executing callbacks"); + return FAILURE; + } + php_http_client_curl_handler_clear(handler); if (CURLM_OK == (rs = curl_multi_remove_handle(curl->handle->multi, handler->handle))) { zend_llist_del_element(&h->requests, handler->handle, (int (*)(void *, void *)) compare_queue); diff --git a/src/php_http_url.c b/src/php_http_url.c index 8352608..1520ae9 100644 --- a/src/php_http_url.c +++ b/src/php_http_url.c @@ -1119,7 +1119,7 @@ static ZEND_RESULT_CODE parse_hostinfo(struct parse_state *state, const char *pt /* sort of a compromise, just ensure we don't end up * with a hyphen at the beginning */ - php_error_docref(NULL TSRMLS_CC, E_WARNING, + php_error_docref(NULL, E_WARNING, "Failed to parse %s; unexpected '%c' at pos %u in '%s'", port ? "port" : "host", (unsigned char) *ptr, (unsigned) (ptr - tmp), tmp); diff --git a/tests/gh-issue50.phpt b/tests/gh-issue50.phpt new file mode 100644 index 0000000..6cef7d9 --- /dev/null +++ b/tests/gh-issue50.phpt @@ -0,0 +1,39 @@ +--TEST-- +segfault with Client::setDebug and Client::dequeue() +--SKIPIF-- + +--FILE-- +enqueue(new http\Client\Request("GET", "http://example.com")); + +$c->setDebug(function(http\Client $c, http\Client\Request $r, $type, $data) { + if ($type & http\Client::DEBUG_HEADER) { + $c->dequeue($r); + } +}); + +try { + $c->send(); +} catch (Exception $e) { + echo $e; +} + +?> + +===DONE=== +--EXPECTF-- +Test +http\Exception\RuntimeException: http\Client::dequeue(): Could not dequeue request while executing callbacks in %sgh-issue50.php:9 +Stack trace: +#0 %sgh-issue50.php(9): http\Client->dequeue(Object(http\Client\Request)) +#1 [internal function]: {closure}(Object(http\Client), Object(http\Client\Request), 18, 'GET / HTTP/1.1\r...') +#2 %sgh-issue50.php(14): http\Client->send() +#3 {main} +===DONE===