coverity fixes
[m6w6/ext-http] / src / php_http_client_curl_user.c
index c2be6807d72cd87ffdd37002cf9dd1325ab6a7cc..d345e27e96bc30b2d7c985038073a011b885b9e5 100644 (file)
 */
 
 #include "php_http_api.h"
-#include "php_http_client.h"
-#include "php_http_client_curl.h"
-#include "php_http_client_curl_user.h"
 
 #include "php_network.h"
 #include "zend_closures.h"
 
 #if PHP_HTTP_HAVE_CURL
 
-typedef struct php_http_client_curl_user_context {
-       php_http_client_t *client;
-       zval *user;
-       zend_function closure;
-       php_http_object_method_t timer;
-       php_http_object_method_t socket;
-       php_http_object_method_t once;
-       php_http_object_method_t wait;
-       php_http_object_method_t send;
-} php_http_client_curl_user_context_t;
-
 typedef struct php_http_client_curl_user_ev {
        php_stream *socket;
        php_http_client_curl_user_context_t *context;
@@ -45,13 +31,13 @@ static void php_http_client_curl_user_handler(INTERNAL_FUNCTION_PARAMETERS)
        php_http_client_object_t *client = NULL;
        php_http_client_curl_t *curl;
 
-       if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|rl", &zclient, php_http_client_class_entry, &zstream, &action)) {
+       if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "O|rl", &zclient, php_http_client_get_class_entry(), &zstream, &action)) {
                return;
        }
 
-       client = zend_object_store_get_object(zclient TSRMLS_CC);
+       client = PHP_HTTP_OBJ(NULL, zclient);
        if (zstream) {
-               php_stream_from_zval(stream, &zstream);
+               php_stream_from_zval(stream, zstream);
 
                if (SUCCESS != php_stream_cast(stream, PHP_STREAM_AS_SOCKETD, (void *) &fd, 1)) {
                        return;
@@ -74,14 +60,11 @@ static void php_http_client_curl_user_timer(CURLM *multi, long timeout_ms, void
        if (timeout_ms <= 0) {
                php_http_client_curl_loop(context->client, CURL_SOCKET_TIMEOUT, 0);
        } else if (timeout_ms > 0) {
-               zval **args[1], *ztimeout;
-               TSRMLS_FETCH_FROM_CTX(context->client->ts);
+               zval args[1], *ztimeout = &args[0];
 
-               MAKE_STD_ZVAL(ztimeout);
                ZVAL_LONG(ztimeout, timeout_ms);
-               args[0] = &ztimeout;
-               php_http_object_method_call(&context->timer, context->user, NULL, 1, args TSRMLS_CC);
-               zval_ptr_dtor(&ztimeout);
+               php_http_object_method_call(&context->timer, &context->user, NULL, 1, args);
+               zval_ptr_dtor(ztimeout);
        }
 }
 
@@ -90,8 +73,7 @@ static int php_http_client_curl_user_socket(CURL *easy, curl_socket_t sock, int
        php_http_client_curl_user_context_t *ctx = socket_data;
        php_http_client_curl_t *curl = ctx->client->ctx;
        php_http_client_curl_user_ev_t *ev = assign_data;
-       zval **args[2], *zaction, *zsocket;
-       TSRMLS_FETCH_FROM_CTX(ctx->client->ts);
+       zval args[2], *zaction = &args[1], *zsocket = &args[0];
 
 #if DBG_EVENTS
        fprintf(stderr, "S");
@@ -111,24 +93,23 @@ static int php_http_client_curl_user_socket(CURL *easy, curl_socket_t sock, int
                case CURL_POLL_INOUT:
                case CURL_POLL_REMOVE:
                case CURL_POLL_NONE:
-                       MAKE_STD_ZVAL(zsocket);
                        php_stream_to_zval(ev->socket, zsocket);
-                       args[0] = &zsocket;
-                       MAKE_STD_ZVAL(zaction);
+                       Z_TRY_ADDREF_P(zsocket);
                        ZVAL_LONG(zaction, action);
-                       args[1] = &zaction;
-                       php_http_object_method_call(&ctx->socket, ctx->user, NULL, 2, args TSRMLS_CC);
-                       zval_ptr_dtor(&zsocket);
-                       zval_ptr_dtor(&zaction);
+                       php_http_object_method_call(&ctx->socket, &ctx->user, NULL, 2, args);
+                       zval_ptr_dtor(zsocket);
+                       zval_ptr_dtor(zaction);
                        break;
 
                default:
-                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown socket action %d", action);
+                       php_error_docref(NULL, E_WARNING, "Unknown socket action %d", action);
                        return -1;
        }
 
-       if (action == CURL_POLL_REMOVE && ev) {
+       if (action == CURL_POLL_REMOVE) {
+               php_stream_close(ev->socket);
                efree(ev);
+               curl_multi_assign(curl->handle->multi, sock, NULL);
        }
        return 0;
 }
@@ -136,22 +117,20 @@ static int php_http_client_curl_user_socket(CURL *easy, curl_socket_t sock, int
 static ZEND_RESULT_CODE php_http_client_curl_user_once(void *context)
 {
        php_http_client_curl_user_context_t *ctx = context;
-       TSRMLS_FETCH_FROM_CTX(ctx->client->ts);
 
 #if DBG_EVENTS
        fprintf(stderr, "O");
 #endif
 
-       return php_http_object_method_call(&ctx->once, ctx->user, NULL, 0, NULL TSRMLS_CC);
+       return php_http_object_method_call(&ctx->once, &ctx->user, NULL, 0, NULL);
 }
 
 static ZEND_RESULT_CODE php_http_client_curl_user_wait(void *context, struct timeval *custom_timeout)
 {
        php_http_client_curl_user_context_t *ctx = context;
        struct timeval timeout;
-       zval **args[1], *ztimeout;
+       zval args[1], *ztimeout = &args[0];
        ZEND_RESULT_CODE rv;
-       TSRMLS_FETCH_FROM_CTX(ctx->client->ts);
 
 #if DBG_EVENTS
        fprintf(stderr, "W");
@@ -162,11 +141,9 @@ static ZEND_RESULT_CODE php_http_client_curl_user_wait(void *context, struct tim
                custom_timeout = &timeout;
        }
 
-       MAKE_STD_ZVAL(ztimeout);
        ZVAL_LONG(ztimeout, custom_timeout->tv_sec * 1000 + custom_timeout->tv_usec / 1000);
-       args[0] = &ztimeout;
-       rv = php_http_object_method_call(&ctx->wait, ctx->user, NULL, 1, args TSRMLS_CC);
-       zval_ptr_dtor(&ztimeout);
+       rv = php_http_object_method_call(&ctx->wait, &ctx->user, NULL, 1, args);
+       zval_ptr_dtor(ztimeout);
 
        return rv;
 }
@@ -175,7 +152,6 @@ static ZEND_RESULT_CODE php_http_client_curl_user_exec(void *context)
 {
        php_http_client_curl_user_context_t *ctx = context;
        php_http_client_curl_t *curl = ctx->client->ctx;
-       TSRMLS_FETCH_FROM_CTX(ctx->client->ts);
 
 #if DBG_EVENTS
        fprintf(stderr, "E");
@@ -185,7 +161,7 @@ static ZEND_RESULT_CODE php_http_client_curl_user_exec(void *context)
        php_http_client_curl_loop(ctx->client, CURL_SOCKET_TIMEOUT, 0);
 
        do {
-               if (SUCCESS != php_http_object_method_call(&ctx->send, ctx->user, NULL, 0, NULL TSRMLS_CC)) {
+               if (SUCCESS != php_http_object_method_call(&ctx->send, &ctx->user, NULL, 0, NULL)) {
                        return FAILURE;
                }
        } while (curl->unfinished && !EG(exception));
@@ -198,8 +174,7 @@ static void *php_http_client_curl_user_init(php_http_client_t *client, void *use
        php_http_client_curl_t *curl = client->ctx;
        php_http_client_curl_user_context_t *ctx;
        php_http_object_method_t init;
-       zval *zclosure, **args[1];
-       TSRMLS_FETCH_FROM_CTX(client->ts);
+       zval args[1], *zclosure = &args[0];
 
 #if DBG_EVENTS
        fprintf(stderr, "I");
@@ -207,28 +182,25 @@ static void *php_http_client_curl_user_init(php_http_client_t *client, void *use
 
        ctx = ecalloc(1, sizeof(*ctx));
        ctx->client = client;
-       ctx->user = user_data;
-       Z_ADDREF_P(ctx->user);
+       ZVAL_COPY(&ctx->user, user_data);
 
        memset(&ctx->closure, 0, sizeof(ctx->closure));
        ctx->closure.common.type = ZEND_INTERNAL_FUNCTION;
-       ctx->closure.common.function_name = "php_http_client_curl_user_handler";
+       ctx->closure.common.function_name = zend_string_init(ZEND_STRL("php_http_client_curl_user_handler"), 0);
        ctx->closure.internal_function.handler = php_http_client_curl_user_handler;
 
-       MAKE_STD_ZVAL(zclosure);
-       zend_create_closure(zclosure, &ctx->closure, NULL, NULL TSRMLS_CC);
-       args[0] = &zclosure;
+       zend_create_closure(zclosure, &ctx->closure, NULL, NULL, NULL);
 
-       php_http_object_method_init(&init, ctx->user, ZEND_STRL("init") TSRMLS_CC);
-       php_http_object_method_call(&init, ctx->user, NULL, 1, args TSRMLS_CC);
+       php_http_object_method_init(&init, &ctx->user, ZEND_STRL("init"));
+       php_http_object_method_call(&init, &ctx->user, NULL, 1, args);
        php_http_object_method_dtor(&init);
-       zval_ptr_dtor(&zclosure);
+       zval_ptr_dtor(zclosure);
 
-       php_http_object_method_init(&ctx->timer, ctx->user, ZEND_STRL("timer") TSRMLS_CC);
-       php_http_object_method_init(&ctx->socket, ctx->user, ZEND_STRL("socket") TSRMLS_CC);
-       php_http_object_method_init(&ctx->once, ctx->user, ZEND_STRL("once") TSRMLS_CC);
-       php_http_object_method_init(&ctx->wait, ctx->user, ZEND_STRL("wait") TSRMLS_CC);
-       php_http_object_method_init(&ctx->send, ctx->user, ZEND_STRL("send") TSRMLS_CC);
+       php_http_object_method_init(&ctx->timer, &ctx->user, ZEND_STRL("timer"));
+       php_http_object_method_init(&ctx->socket, &ctx->user, ZEND_STRL("socket"));
+       php_http_object_method_init(&ctx->once, &ctx->user, ZEND_STRL("once"));
+       php_http_object_method_init(&ctx->wait, &ctx->user, ZEND_STRL("wait"));
+       php_http_object_method_init(&ctx->send, &ctx->user, ZEND_STRL("send"));
 
        curl_multi_setopt(curl->handle->multi, CURLMOPT_SOCKETDATA, ctx);
        curl_multi_setopt(curl->handle->multi, CURLMOPT_SOCKETFUNCTION, php_http_client_curl_user_socket);
@@ -260,6 +232,7 @@ static void php_http_client_curl_user_dtor(void **context)
        php_http_object_method_dtor(&ctx->wait);
        php_http_object_method_dtor(&ctx->send);
 
+       zend_string_release(ctx->closure.common.function_name);
        zval_ptr_dtor(&ctx->user);
 
        efree(ctx);
@@ -279,10 +252,16 @@ php_http_client_curl_ops_t *php_http_client_curl_user_ops_get()
        return &php_http_client_curl_user_ops;
 }
 
-zend_class_entry *php_http_client_curl_user_class_entry;
+static zend_class_entry *php_http_client_curl_user_class_entry;
+
+zend_class_entry *php_http_client_curl_user_get_class_entry()
+{
+       return php_http_client_curl_user_class_entry;
+}
 
 ZEND_BEGIN_ARG_INFO_EX(ai_init, 0, 0, 1)
-       ZEND_ARG_TYPE_INFO(0, run, IS_CALLABLE, 0)
+       /* using IS_CALLABLE type hint would create a forwards compatibility break */
+       ZEND_ARG_INFO(0, run)
 ZEND_END_ARG_INFO();
 ZEND_BEGIN_ARG_INFO_EX(ai_timer, 0, 0, 1)
 #if PHP_VERSION_ID >= 70000
@@ -292,11 +271,10 @@ ZEND_BEGIN_ARG_INFO_EX(ai_timer, 0, 0, 1)
 #endif
 ZEND_END_ARG_INFO();
 ZEND_BEGIN_ARG_INFO_EX(ai_socket, 0, 0, 2)
+       ZEND_ARG_INFO(0, socket)
 #if PHP_VERSION_ID >= 70000
-       ZEND_ARG_TYPE_INFO(0, socket, IS_RESOURCE, 0)
        ZEND_ARG_TYPE_INFO(0, action, IS_LONG, 0)
 #else
-       ZEND_ARG_INFO(0, socket)
        ZEND_ARG_INFO(0, action)
 #endif
 ZEND_END_ARG_INFO();
@@ -327,13 +305,13 @@ PHP_MINIT_FUNCTION(http_client_curl_user)
        zend_class_entry ce = {0};
 
        INIT_NS_CLASS_ENTRY(ce, "http\\Client\\Curl", "User", php_http_client_curl_user_methods);
-       php_http_client_curl_user_class_entry = zend_register_internal_interface(&ce TSRMLS_CC);
+       php_http_client_curl_user_class_entry = zend_register_internal_interface(&ce);
 
-       zend_declare_class_constant_long(php_http_client_curl_user_class_entry, ZEND_STRL("POLL_NONE"), CURL_POLL_NONE TSRMLS_CC);
-       zend_declare_class_constant_long(php_http_client_curl_user_class_entry, ZEND_STRL("POLL_IN"), CURL_POLL_IN TSRMLS_CC);
-       zend_declare_class_constant_long(php_http_client_curl_user_class_entry, ZEND_STRL("POLL_OUT"), CURL_POLL_OUT TSRMLS_CC);
-       zend_declare_class_constant_long(php_http_client_curl_user_class_entry, ZEND_STRL("POLL_INOUT"), CURL_POLL_INOUT TSRMLS_CC);
-       zend_declare_class_constant_long(php_http_client_curl_user_class_entry, ZEND_STRL("POLL_REMOVE"), CURL_POLL_REMOVE TSRMLS_CC);
+       zend_declare_class_constant_long(php_http_client_curl_user_class_entry, ZEND_STRL("POLL_NONE"), CURL_POLL_NONE);
+       zend_declare_class_constant_long(php_http_client_curl_user_class_entry, ZEND_STRL("POLL_IN"), CURL_POLL_IN);
+       zend_declare_class_constant_long(php_http_client_curl_user_class_entry, ZEND_STRL("POLL_OUT"), CURL_POLL_OUT);
+       zend_declare_class_constant_long(php_http_client_curl_user_class_entry, ZEND_STRL("POLL_INOUT"), CURL_POLL_INOUT);
+       zend_declare_class_constant_long(php_http_client_curl_user_class_entry, ZEND_STRL("POLL_REMOVE"), CURL_POLL_REMOVE);
 
        return SUCCESS;
 }