Merge branch 'v2.6.x'
authorMichael Wallner <mike@php.net>
Wed, 10 Aug 2016 13:41:09 +0000 (15:41 +0200)
committerMichael Wallner <mike@php.net>
Wed, 10 Aug 2016 13:41:09 +0000 (15:41 +0200)
1  2 
src/php_http_client.c
src/php_http_client.h
src/php_http_client_curl.c
src/php_http_url.c
tests/gh-issue50.phpt

@@@ -470,20 -429,24 +470,22 @@@ static ZEND_RESULT_CODE handle_response
                zend_llist_add_element(&client->responses, &msg_obj);
  
                if (e->closure.fci.size) {
 -                      zval *retval = NULL;
 +                      zval retval;
                        zend_error_handling zeh;
  
 -                      zend_fcall_info_argn(&e->closure.fci TSRMLS_CC, 1, &zresponse);
 -                      zend_replace_error_handling(EH_NORMAL, NULL, &zeh TSRMLS_CC);
 +                      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 TSRMLS_CC);
 +                      zend_fcall_info_call(&e->closure.fci, &e->closure.fcc, &retval, NULL);
+                       --client->callback.depth;
 -                      zend_restore_error_handling(&zeh TSRMLS_CC);
 -                      zend_fcall_info_argn(&e->closure.fci TSRMLS_CC, 0);
 +                      zend_restore_error_handling(&zeh);
 +                      zend_fcall_info_argn(&e->closure.fci, 0);
  
 -                      if (retval) {
 -                              if (Z_TYPE_P(retval) == IS_BOOL) {
 -                                      dequeue = Z_BVAL_P(retval);
 -                              }
 -                              zval_ptr_dtor(&retval);
 +                      if (Z_TYPE(retval) == IS_TRUE) {
 +                              dequeue = 1;
                        }
 +                      zval_ptr_dtor(&retval);
                }
  
                zval_ptr_dtor(&zresponse);
  
  static void handle_progress(void *arg, php_http_client_t *client, php_http_client_enqueue_t *e, php_http_client_progress_state_t *progress)
  {
 -      zval *zrequest, *zprogress, *zclient, **args[2];
 +      zval zclient, args[2];
        php_http_client_object_t *client_obj = arg;
        zend_error_handling zeh;
 -      TSRMLS_FETCH_FROM_CTX(client->ts);
 -
 -      MAKE_STD_ZVAL(zclient);
 -      ZVAL_OBJVAL(zclient, client_obj->zv, 1);
 -
 -      MAKE_STD_ZVAL(zrequest);
 -      ZVAL_OBJVAL(zrequest, ((php_http_message_object_t *) e->opaque)->zv, 1);
 -      args[0] = &zrequest;
 -
 -      MAKE_STD_ZVAL(zprogress);
 -      object_init(zprogress);
 -      add_property_bool(zprogress, "started", progress->started);
 -      add_property_bool(zprogress, "finished", progress->finished);
 -      add_property_string(zprogress, "info", STR_PTR(progress->info), 1);
 -      add_property_double(zprogress, "dltotal", progress->dl.total);
 -      add_property_double(zprogress, "dlnow", progress->dl.now);
 -      add_property_double(zprogress, "ultotal", progress->ul.total);
 -      add_property_double(zprogress, "ulnow", progress->ul.now);
 -      args[1] = &zprogress;
 -
 -      zend_replace_error_handling(EH_NORMAL, NULL, &zeh TSRMLS_CC);
 +
 +      ZVAL_OBJECT(&zclient, &client_obj->zo, 1);
 +      ZVAL_OBJECT(&args[0], &((php_http_message_object_t *) e->opaque)->zo, 1);
 +      object_init(&args[1]);
 +      add_property_bool(&args[1], "started", progress->started);
 +      add_property_bool(&args[1], "finished", progress->finished);
 +      add_property_string(&args[1], "info", STR_PTR(progress->info));
 +      add_property_double(&args[1], "dltotal", progress->dl.total);
 +      add_property_double(&args[1], "dlnow", progress->dl.now);
 +      add_property_double(&args[1], "ultotal", progress->ul.total);
 +      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 TSRMLS_CC);
 +      php_http_object_method_call(&client_obj->notify, &zclient, NULL, 2, args);
+       --client->callback.depth;
 -      zend_restore_error_handling(&zeh TSRMLS_CC);
 +      zend_restore_error_handling(&zeh);
  
        zval_ptr_dtor(&zclient);
 -      zval_ptr_dtor(&zrequest);
 -      zval_ptr_dtor(&zprogress);
 +      zval_ptr_dtor(&args[0]);
 +      zval_ptr_dtor(&args[1]);
  }
  
  static void handle_debug(void *arg, php_http_client_t *client, php_http_client_enqueue_t *e, unsigned type, const char *data, size_t size)
  {
 -      zval *ztype, *zdata, *zreq, *zclient;
 +      zval ztype, zdata, zreq, zclient;
        php_http_client_object_t *client_obj = arg;
        zend_error_handling zeh;
 -      TSRMLS_FETCH_FROM_CTX(client->ts);
 -
 -      MAKE_STD_ZVAL(zclient);
 -      ZVAL_OBJVAL(zclient, client_obj->zv, 1);
 -      MAKE_STD_ZVAL(zreq);
 -      ZVAL_OBJVAL(zreq, ((php_http_message_object_t *) e->opaque)->zv, 1);
 -      MAKE_STD_ZVAL(ztype);
 -      ZVAL_LONG(ztype, type);
 -      MAKE_STD_ZVAL(zdata);
 -      ZVAL_STRINGL(zdata, data, size, 1);
 -
 -      zend_replace_error_handling(EH_NORMAL, NULL, &zeh TSRMLS_CC);
 -      if (SUCCESS == zend_fcall_info_argn(&client_obj->debug.fci TSRMLS_CC, 4, &zclient, &zreq, &ztype, &zdata)) {
 -              ++client_obj->client->callback.depth;
 -              zend_fcall_info_call(&client_obj->debug.fci, &client_obj->debug.fcc, NULL, NULL TSRMLS_CC);
 -              --client_obj->client->callback.depth;
 +
 +      ZVAL_OBJECT(&zclient, &client_obj->zo, 1);
 +      ZVAL_OBJECT(&zreq, &((php_http_message_object_t *) e->opaque)->zo, 1);
 +      ZVAL_LONG(&ztype, type);
 +      ZVAL_STRINGL(&zdata, data, size);
 +
 +      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 TSRMLS_CC);
 +      zend_restore_error_handling(&zeh);
  
        zval_ptr_dtor(&zclient);
        zval_ptr_dtor(&zreq);
Simple merge
@@@ -2194,7 -2163,13 +2191,12 @@@ static ZEND_RESULT_CODE php_http_client
        CURLMcode rs;
        php_http_client_curl_t *curl = h->ctx;
        php_http_client_curl_handler_t *handler = enqueue->opaque;
 -      TSRMLS_FETCH_FROM_CTX(h->ts);
  
 -              php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not dequeue request while executing callbacks");
+       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);
@@@ -1119,7 -1115,7 +1119,7 @@@ static ZEND_RESULT_CODE parse_hostinfo(
                                /* 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);
index 0000000,61e0865..6cef7d9
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,39 +1,39 @@@
 -exception 'http\Exception\RuntimeException' with message 'http\Client::dequeue(): Could not dequeue request while executing callbacks' in %sgh-issue50.php:9
+ --TEST--
+ segfault with Client::setDebug and Client::dequeue()
+ --SKIPIF--
+ <?php
+ include "skipif.inc";
+ skip_client_test();
+ skip_online_test();
+ ?>
+ --FILE--
+ <?php
+ echo "Test\n";
+ $c = new http\Client;
+ $c->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===