diff options
Diffstat (limited to 'ext/curl/interface.c')
-rw-r--r-- | ext/curl/interface.c | 619 |
1 files changed, 298 insertions, 321 deletions
diff --git a/ext/curl/interface.c b/ext/curl/interface.c index 82d97053ee..1044031a88 100644 --- a/ext/curl/interface.c +++ b/ext/curl/interface.c @@ -97,26 +97,14 @@ static ZEND_ATTRIBUTE_UNUSED unsigned long php_curl_ssl_id(void) # define php_curl_ret(__ret) RETVAL_FALSE; return; #endif -static int php_curl_option_str(php_curl *ch, zend_long option, const char *str, const size_t len, zend_bool make_copy) +static int php_curl_option_str(php_curl *ch, zend_long option, const char *str, const size_t len) { - CURLcode error = CURLE_OK; - if (strlen(str) != len) { zend_value_error("%s(): cURL option must not contain any null bytes", get_active_function_name()); return FAILURE; } - if (make_copy) { - char *copystr; - - /* Strings passed to libcurl as 'char *' arguments, are copied by the library since 7.17.0 */ - copystr = estrndup(str, len); - error = curl_easy_setopt(ch->cp, option, copystr); - zend_llist_add_element(&ch->to_free->str, ©str); - } else { - error = curl_easy_setopt(ch->cp, option, str); - } - + CURLcode error = curl_easy_setopt(ch->cp, option, str); SAVE_CURL_ERROR(ch, error); return error == CURLE_OK ? SUCCESS : FAILURE; @@ -136,11 +124,11 @@ static int php_curl_option_url(php_curl *ch, const char *url, const size_t len) memmove(_tmp, "file:///", sizeof("file:///") - 1); memmove(_tmp + sizeof("file:///") - 1, url + sizeof("file://") - 1, len - sizeof("file://") + 1); - return php_curl_option_str(ch, CURLOPT_URL, _tmp, len + 1, 0); + return php_curl_option_str(ch, CURLOPT_URL, _tmp, len + 1); } #endif - return php_curl_option_str(ch, CURLOPT_URL, url, len, 0); + return php_curl_option_str(ch, CURLOPT_URL, url, len); } /* }}} */ @@ -148,59 +136,59 @@ void _php_curl_verify_handlers(php_curl *ch, int reporterror) /* {{{ */ { php_stream *stream; - ZEND_ASSERT(ch && ch->handlers); + ZEND_ASSERT(ch); - if (!Z_ISUNDEF(ch->handlers->std_err)) { - stream = (php_stream *)zend_fetch_resource2_ex(&ch->handlers->std_err, NULL, php_file_le_stream(), php_file_le_pstream()); + if (!Z_ISUNDEF(ch->handlers.std_err)) { + stream = (php_stream *)zend_fetch_resource2_ex(&ch->handlers.std_err, NULL, php_file_le_stream(), php_file_le_pstream()); if (stream == NULL) { if (reporterror) { php_error_docref(NULL, E_WARNING, "CURLOPT_STDERR resource has gone away, resetting to stderr"); } - zval_ptr_dtor(&ch->handlers->std_err); - ZVAL_UNDEF(&ch->handlers->std_err); + zval_ptr_dtor(&ch->handlers.std_err); + ZVAL_UNDEF(&ch->handlers.std_err); curl_easy_setopt(ch->cp, CURLOPT_STDERR, stderr); } } - if (ch->handlers->read && !Z_ISUNDEF(ch->handlers->read->stream)) { - stream = (php_stream *)zend_fetch_resource2_ex(&ch->handlers->read->stream, NULL, php_file_le_stream(), php_file_le_pstream()); + if (ch->handlers.read && !Z_ISUNDEF(ch->handlers.read->stream)) { + stream = (php_stream *)zend_fetch_resource2_ex(&ch->handlers.read->stream, NULL, php_file_le_stream(), php_file_le_pstream()); if (stream == NULL) { if (reporterror) { php_error_docref(NULL, E_WARNING, "CURLOPT_INFILE resource has gone away, resetting to default"); } - zval_ptr_dtor(&ch->handlers->read->stream); - ZVAL_UNDEF(&ch->handlers->read->stream); - ch->handlers->read->res = NULL; - ch->handlers->read->fp = 0; + zval_ptr_dtor(&ch->handlers.read->stream); + ZVAL_UNDEF(&ch->handlers.read->stream); + ch->handlers.read->res = NULL; + ch->handlers.read->fp = 0; curl_easy_setopt(ch->cp, CURLOPT_INFILE, (void *) ch); } } - if (ch->handlers->write_header && !Z_ISUNDEF(ch->handlers->write_header->stream)) { - stream = (php_stream *)zend_fetch_resource2_ex(&ch->handlers->write_header->stream, NULL, php_file_le_stream(), php_file_le_pstream()); + if (ch->handlers.write_header && !Z_ISUNDEF(ch->handlers.write_header->stream)) { + stream = (php_stream *)zend_fetch_resource2_ex(&ch->handlers.write_header->stream, NULL, php_file_le_stream(), php_file_le_pstream()); if (stream == NULL) { if (reporterror) { php_error_docref(NULL, E_WARNING, "CURLOPT_WRITEHEADER resource has gone away, resetting to default"); } - zval_ptr_dtor(&ch->handlers->write_header->stream); - ZVAL_UNDEF(&ch->handlers->write_header->stream); - ch->handlers->write_header->fp = 0; + zval_ptr_dtor(&ch->handlers.write_header->stream); + ZVAL_UNDEF(&ch->handlers.write_header->stream); + ch->handlers.write_header->fp = 0; - ch->handlers->write_header->method = PHP_CURL_IGNORE; + ch->handlers.write_header->method = PHP_CURL_IGNORE; curl_easy_setopt(ch->cp, CURLOPT_WRITEHEADER, (void *) ch); } } - if (ch->handlers->write && !Z_ISUNDEF(ch->handlers->write->stream)) { - stream = (php_stream *)zend_fetch_resource2_ex(&ch->handlers->write->stream, NULL, php_file_le_stream(), php_file_le_pstream()); + if (ch->handlers.write && !Z_ISUNDEF(ch->handlers.write->stream)) { + stream = (php_stream *)zend_fetch_resource2_ex(&ch->handlers.write->stream, NULL, php_file_le_stream(), php_file_le_pstream()); if (stream == NULL) { if (reporterror) { php_error_docref(NULL, E_WARNING, "CURLOPT_FILE resource has gone away, resetting to default"); } - zval_ptr_dtor(&ch->handlers->write->stream); - ZVAL_UNDEF(&ch->handlers->write->stream); - ch->handlers->write->fp = 0; + zval_ptr_dtor(&ch->handlers.write->stream); + ZVAL_UNDEF(&ch->handlers.write->stream); + ch->handlers.write->fp = 0; - ch->handlers->write->method = PHP_CURL_STDOUT; + ch->handlers.write->method = PHP_CURL_STDOUT; curl_easy_setopt(ch->cp, CURLOPT_FILE, (void *) ch); } } @@ -1153,6 +1141,10 @@ PHP_MINIT_FUNCTION(curl) REGISTER_CURL_CONSTANT(CURLOPT_TLS13_CIPHERS); #endif +#if LIBCURL_VERSION_NUM >= 0x073E00 /* Available since 7.62.0 */ + REGISTER_CURL_CONSTANT(CURLOPT_DOH_URL); +#endif + #if LIBCURL_VERSION_NUM >= 0x074000 /* Available since 7.64.0 */ REGISTER_CURL_CONSTANT(CURLOPT_HTTP09_ALLOWED); #endif @@ -1265,34 +1257,33 @@ static HashTable *curl_get_gc(zend_object *object, zval **table, int *n) zend_get_gc_buffer *gc_buffer = zend_get_gc_buffer_create(); zend_get_gc_buffer_add_zval(gc_buffer, &curl->postfields); - if (curl->handlers) { - if (curl->handlers->read) { - zend_get_gc_buffer_add_zval(gc_buffer, &curl->handlers->read->func_name); - zend_get_gc_buffer_add_zval(gc_buffer, &curl->handlers->read->stream); - } + if (curl->handlers.read) { + zend_get_gc_buffer_add_zval(gc_buffer, &curl->handlers.read->func_name); + zend_get_gc_buffer_add_zval(gc_buffer, &curl->handlers.read->stream); + } - if (curl->handlers->write) { - zend_get_gc_buffer_add_zval(gc_buffer, &curl->handlers->write->func_name); - zend_get_gc_buffer_add_zval(gc_buffer, &curl->handlers->write->stream); - } + if (curl->handlers.write) { + zend_get_gc_buffer_add_zval(gc_buffer, &curl->handlers.write->func_name); + zend_get_gc_buffer_add_zval(gc_buffer, &curl->handlers.write->stream); + } - if (curl->handlers->write_header) { - zend_get_gc_buffer_add_zval(gc_buffer, &curl->handlers->write_header->func_name); - zend_get_gc_buffer_add_zval(gc_buffer, &curl->handlers->write_header->stream); - } + if (curl->handlers.write_header) { + zend_get_gc_buffer_add_zval(gc_buffer, &curl->handlers.write_header->func_name); + zend_get_gc_buffer_add_zval(gc_buffer, &curl->handlers.write_header->stream); + } - if (curl->handlers->progress) { - zend_get_gc_buffer_add_zval(gc_buffer, &curl->handlers->progress->func_name); - } + if (curl->handlers.progress) { + zend_get_gc_buffer_add_zval(gc_buffer, &curl->handlers.progress->func_name); + } #if LIBCURL_VERSION_NUM >= 0x071500 - if (curl->handlers->fnmatch) { - zend_get_gc_buffer_add_zval(gc_buffer, &curl->handlers->fnmatch->func_name); - } + if (curl->handlers.fnmatch) { + zend_get_gc_buffer_add_zval(gc_buffer, &curl->handlers.fnmatch->func_name); + } #endif - zend_get_gc_buffer_add_zval(gc_buffer, &curl->handlers->std_err); - } + zend_get_gc_buffer_add_zval(gc_buffer, &curl->handlers.std_err); + zend_get_gc_buffer_add_zval(gc_buffer, &curl->private_data); zend_get_gc_buffer_use(gc_buffer, table, n); @@ -1348,7 +1339,7 @@ static size_t curl_write_nothing(char *data, size_t size, size_t nmemb, void *ct static size_t curl_write(char *data, size_t size, size_t nmemb, void *ctx) { php_curl *ch = (php_curl *) ctx; - php_curl_write *t = ch->handlers->write; + php_curl_write *t = ch->handlers.write; size_t length = size * nmemb; #if PHP_CURL_DEBUG @@ -1410,43 +1401,38 @@ static size_t curl_write(char *data, size_t size, size_t nmemb, void *ctx) static int curl_fnmatch(void *ctx, const char *pattern, const char *string) { php_curl *ch = (php_curl *) ctx; - php_curl_fnmatch *t = ch->handlers->fnmatch; + php_curl_callback *t = ch->handlers.fnmatch; int rval = CURL_FNMATCHFUNC_FAIL; - switch (t->method) { - case PHP_CURL_USER: { - zval argv[3]; - zval retval; - int error; - zend_fcall_info fci; - - GC_ADDREF(&ch->std); - ZVAL_OBJ(&argv[0], &ch->std); - ZVAL_STRING(&argv[1], pattern); - ZVAL_STRING(&argv[2], string); - - fci.size = sizeof(fci); - ZVAL_COPY_VALUE(&fci.function_name, &t->func_name); - fci.object = NULL; - fci.retval = &retval; - fci.param_count = 3; - fci.params = argv; - fci.named_params = NULL; - - ch->in_callback = 1; - error = zend_call_function(&fci, &t->fci_cache); - ch->in_callback = 0; - if (error == FAILURE) { - php_error_docref(NULL, E_WARNING, "Cannot call the CURLOPT_FNMATCH_FUNCTION"); - } else if (!Z_ISUNDEF(retval)) { - _php_curl_verify_handlers(ch, 1); - rval = zval_get_long(&retval); - } - zval_ptr_dtor(&argv[0]); - zval_ptr_dtor(&argv[1]); - zval_ptr_dtor(&argv[2]); - break; - } - } + zval argv[3]; + zval retval; + int error; + zend_fcall_info fci; + + GC_ADDREF(&ch->std); + ZVAL_OBJ(&argv[0], &ch->std); + ZVAL_STRING(&argv[1], pattern); + ZVAL_STRING(&argv[2], string); + + fci.size = sizeof(fci); + ZVAL_COPY_VALUE(&fci.function_name, &t->func_name); + fci.object = NULL; + fci.retval = &retval; + fci.param_count = 3; + fci.params = argv; + fci.named_params = NULL; + + ch->in_callback = 1; + error = zend_call_function(&fci, &t->fci_cache); + ch->in_callback = 0; + if (error == FAILURE) { + php_error_docref(NULL, E_WARNING, "Cannot call the CURLOPT_FNMATCH_FUNCTION"); + } else if (!Z_ISUNDEF(retval)) { + _php_curl_verify_handlers(ch, 1); + rval = zval_get_long(&retval); + } + zval_ptr_dtor(&argv[0]); + zval_ptr_dtor(&argv[1]); + zval_ptr_dtor(&argv[2]); return rval; } /* }}} */ @@ -1455,7 +1441,7 @@ static int curl_fnmatch(void *ctx, const char *pattern, const char *string) static size_t curl_progress(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow) { php_curl *ch = (php_curl *)clientp; - php_curl_progress *t = ch->handlers->progress; + php_curl_callback *t = ch->handlers.progress; size_t rval = 0; #if PHP_CURL_DEBUG @@ -1463,43 +1449,38 @@ static size_t curl_progress(void *clientp, double dltotal, double dlnow, double fprintf(stderr, "clientp = %x, dltotal = %f, dlnow = %f, ultotal = %f, ulnow = %f\n", clientp, dltotal, dlnow, ultotal, ulnow); #endif - switch (t->method) { - case PHP_CURL_USER: { - zval argv[5]; - zval retval; - int error; - zend_fcall_info fci; - - GC_ADDREF(&ch->std); - ZVAL_OBJ(&argv[0], &ch->std); - ZVAL_LONG(&argv[1], (zend_long)dltotal); - ZVAL_LONG(&argv[2], (zend_long)dlnow); - ZVAL_LONG(&argv[3], (zend_long)ultotal); - ZVAL_LONG(&argv[4], (zend_long)ulnow); - - fci.size = sizeof(fci); - ZVAL_COPY_VALUE(&fci.function_name, &t->func_name); - fci.object = NULL; - fci.retval = &retval; - fci.param_count = 5; - fci.params = argv; - fci.named_params = NULL; - - ch->in_callback = 1; - error = zend_call_function(&fci, &t->fci_cache); - ch->in_callback = 0; - if (error == FAILURE) { - php_error_docref(NULL, E_WARNING, "Cannot call the CURLOPT_PROGRESSFUNCTION"); - } else if (!Z_ISUNDEF(retval)) { - _php_curl_verify_handlers(ch, 1); - if (0 != zval_get_long(&retval)) { - rval = 1; - } - } - zval_ptr_dtor(&argv[0]); - break; - } - } + zval argv[5]; + zval retval; + int error; + zend_fcall_info fci; + + GC_ADDREF(&ch->std); + ZVAL_OBJ(&argv[0], &ch->std); + ZVAL_LONG(&argv[1], (zend_long)dltotal); + ZVAL_LONG(&argv[2], (zend_long)dlnow); + ZVAL_LONG(&argv[3], (zend_long)ultotal); + ZVAL_LONG(&argv[4], (zend_long)ulnow); + + fci.size = sizeof(fci); + ZVAL_COPY_VALUE(&fci.function_name, &t->func_name); + fci.object = NULL; + fci.retval = &retval; + fci.param_count = 5; + fci.params = argv; + fci.named_params = NULL; + + ch->in_callback = 1; + error = zend_call_function(&fci, &t->fci_cache); + ch->in_callback = 0; + if (error == FAILURE) { + php_error_docref(NULL, E_WARNING, "Cannot call the CURLOPT_PROGRESSFUNCTION"); + } else if (!Z_ISUNDEF(retval)) { + _php_curl_verify_handlers(ch, 1); + if (0 != zval_get_long(&retval)) { + rval = 1; + } + } + zval_ptr_dtor(&argv[0]); return rval; } /* }}} */ @@ -1508,7 +1489,7 @@ static size_t curl_progress(void *clientp, double dltotal, double dlnow, double static size_t curl_read(char *data, size_t size, size_t nmemb, void *ctx) { php_curl *ch = (php_curl *)ctx; - php_curl_read *t = ch->handlers->read; + php_curl_read *t = ch->handlers.read; int length = 0; switch (t->method) { @@ -1570,15 +1551,15 @@ static size_t curl_read(char *data, size_t size, size_t nmemb, void *ctx) static size_t curl_write_header(char *data, size_t size, size_t nmemb, void *ctx) { php_curl *ch = (php_curl *) ctx; - php_curl_write *t = ch->handlers->write_header; + php_curl_write *t = ch->handlers.write_header; size_t length = size * nmemb; switch (t->method) { case PHP_CURL_STDOUT: /* Handle special case write when we're returning the entire transfer */ - if (ch->handlers->write->method == PHP_CURL_RETURN && length > 0) { - smart_str_appendl(&ch->handlers->write->buf, data, (int) length); + if (ch->handlers.write->method == PHP_CURL_RETURN && length > 0) { + smart_str_appendl(&ch->handlers.write->buf, data, (int) length); } else { PHPWRITE(data, length); } @@ -1646,13 +1627,6 @@ static int curl_debug(CURL *cp, curl_infotype type, char *buf, size_t buf_len, v } /* }}} */ -/* {{{ curl_free_string */ -static void curl_free_string(void **string) -{ - efree((char *)*string); -} -/* }}} */ - /* {{{ curl_free_post */ static void curl_free_post(void **post) { @@ -1756,19 +1730,17 @@ php_curl *init_curl_handle_into_zval(zval *curl) void init_curl_handle(php_curl *ch) { - ch->to_free = ecalloc(1, sizeof(struct _php_curl_free)); - ch->handlers = ecalloc(1, sizeof(php_curl_handlers)); - ch->handlers->write = ecalloc(1, sizeof(php_curl_write)); - ch->handlers->write_header = ecalloc(1, sizeof(php_curl_write)); - ch->handlers->read = ecalloc(1, sizeof(php_curl_read)); - ch->handlers->progress = NULL; - ch->handlers->fnmatch = NULL; - ch->clone = emalloc(sizeof(uint32_t)); - *ch->clone = 1; + ch->to_free = ecalloc(1, sizeof(struct _php_curl_free)); + ch->handlers.write = ecalloc(1, sizeof(php_curl_write)); + ch->handlers.write_header = ecalloc(1, sizeof(php_curl_write)); + ch->handlers.read = ecalloc(1, sizeof(php_curl_read)); + ch->handlers.progress = NULL; + ch->handlers.fnmatch = NULL; + ch->clone = emalloc(sizeof(uint32_t)); + *ch->clone = 1; memset(&ch->err, 0, sizeof(struct _php_curl_error)); - zend_llist_init(&ch->to_free->str, sizeof(char *), (llist_dtor_func_t)curl_free_string, 0); zend_llist_init(&ch->to_free->post, sizeof(struct HttpPost *), (llist_dtor_func_t)curl_free_post, 0); zend_llist_init(&ch->to_free->stream, sizeof(struct mime_data_cb_arg *), (llist_dtor_func_t)curl_free_cb_arg, 0); @@ -1869,9 +1841,9 @@ PHP_FUNCTION(curl_init) ch->cp = cp; - ch->handlers->write->method = PHP_CURL_STDOUT; - ch->handlers->read->method = PHP_CURL_DIRECT; - ch->handlers->write_header->method = PHP_CURL_IGNORE; + ch->handlers.write->method = PHP_CURL_STDOUT; + ch->handlers.read->method = PHP_CURL_DIRECT; + ch->handlers.write_header->method = PHP_CURL_IGNORE; _php_curl_set_default_options(ch); @@ -1886,35 +1858,35 @@ PHP_FUNCTION(curl_init) void _php_setup_easy_copy_handlers(php_curl *ch, php_curl *source) { - if (!Z_ISUNDEF(source->handlers->write->stream)) { - Z_ADDREF(source->handlers->write->stream); + if (!Z_ISUNDEF(source->handlers.write->stream)) { + Z_ADDREF(source->handlers.write->stream); } - ch->handlers->write->stream = source->handlers->write->stream; - ch->handlers->write->method = source->handlers->write->method; - if (!Z_ISUNDEF(source->handlers->read->stream)) { - Z_ADDREF(source->handlers->read->stream); + ch->handlers.write->stream = source->handlers.write->stream; + ch->handlers.write->method = source->handlers.write->method; + if (!Z_ISUNDEF(source->handlers.read->stream)) { + Z_ADDREF(source->handlers.read->stream); } - ch->handlers->read->stream = source->handlers->read->stream; - ch->handlers->read->method = source->handlers->read->method; - ch->handlers->write_header->method = source->handlers->write_header->method; - if (!Z_ISUNDEF(source->handlers->write_header->stream)) { - Z_ADDREF(source->handlers->write_header->stream); + ch->handlers.read->stream = source->handlers.read->stream; + ch->handlers.read->method = source->handlers.read->method; + ch->handlers.write_header->method = source->handlers.write_header->method; + if (!Z_ISUNDEF(source->handlers.write_header->stream)) { + Z_ADDREF(source->handlers.write_header->stream); } - ch->handlers->write_header->stream = source->handlers->write_header->stream; + ch->handlers.write_header->stream = source->handlers.write_header->stream; - ch->handlers->write->fp = source->handlers->write->fp; - ch->handlers->write_header->fp = source->handlers->write_header->fp; - ch->handlers->read->fp = source->handlers->read->fp; - ch->handlers->read->res = source->handlers->read->res; + ch->handlers.write->fp = source->handlers.write->fp; + ch->handlers.write_header->fp = source->handlers.write_header->fp; + ch->handlers.read->fp = source->handlers.read->fp; + ch->handlers.read->res = source->handlers.read->res; - if (!Z_ISUNDEF(source->handlers->write->func_name)) { - ZVAL_COPY(&ch->handlers->write->func_name, &source->handlers->write->func_name); + if (!Z_ISUNDEF(source->handlers.write->func_name)) { + ZVAL_COPY(&ch->handlers.write->func_name, &source->handlers.write->func_name); } - if (!Z_ISUNDEF(source->handlers->read->func_name)) { - ZVAL_COPY(&ch->handlers->read->func_name, &source->handlers->read->func_name); + if (!Z_ISUNDEF(source->handlers.read->func_name)) { + ZVAL_COPY(&ch->handlers.read->func_name, &source->handlers.read->func_name); } - if (!Z_ISUNDEF(source->handlers->write_header->func_name)) { - ZVAL_COPY(&ch->handlers->write_header->func_name, &source->handlers->write_header->func_name); + if (!Z_ISUNDEF(source->handlers.write_header->func_name)) { + ZVAL_COPY(&ch->handlers.write_header->func_name, &source->handlers.write_header->func_name); } curl_easy_setopt(ch->cp, CURLOPT_ERRORBUFFER, ch->err.str); @@ -1922,24 +1894,24 @@ void _php_setup_easy_copy_handlers(php_curl *ch, php_curl *source) curl_easy_setopt(ch->cp, CURLOPT_INFILE, (void *) ch); curl_easy_setopt(ch->cp, CURLOPT_WRITEHEADER, (void *) ch); - if (source->handlers->progress) { - ch->handlers->progress = ecalloc(1, sizeof(php_curl_progress)); - if (!Z_ISUNDEF(source->handlers->progress->func_name)) { - ZVAL_COPY(&ch->handlers->progress->func_name, &source->handlers->progress->func_name); + if (source->handlers.progress) { + ch->handlers.progress = ecalloc(1, sizeof(php_curl_callback)); + if (!Z_ISUNDEF(source->handlers.progress->func_name)) { + ZVAL_COPY(&ch->handlers.progress->func_name, &source->handlers.progress->func_name); } - ch->handlers->progress->method = source->handlers->progress->method; curl_easy_setopt(ch->cp, CURLOPT_PROGRESSDATA, (void *) ch); } - if (source->handlers->fnmatch) { - ch->handlers->fnmatch = ecalloc(1, sizeof(php_curl_fnmatch)); - if (!Z_ISUNDEF(source->handlers->fnmatch->func_name)) { - ZVAL_COPY(&ch->handlers->fnmatch->func_name, &source->handlers->fnmatch->func_name); + if (source->handlers.fnmatch) { + ch->handlers.fnmatch = ecalloc(1, sizeof(php_curl_callback)); + if (!Z_ISUNDEF(source->handlers.fnmatch->func_name)) { + ZVAL_COPY(&ch->handlers.fnmatch->func_name, &source->handlers.fnmatch->func_name); } - ch->handlers->fnmatch->method = source->handlers->fnmatch->method; curl_easy_setopt(ch->cp, CURLOPT_FNMATCH_DATA, (void *) ch); } + ZVAL_COPY(&ch->private_data, &source->private_data); + efree(ch->to_free->slist); efree(ch->to_free); ch->to_free = source->to_free; @@ -2462,7 +2434,7 @@ static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue, bool i { zend_string *tmp_str; zend_string *str = zval_get_tmp_string(zvalue, &tmp_str); - int ret = php_curl_option_str(ch, option, ZSTR_VAL(str), ZSTR_LEN(str), 0); + int ret = php_curl_option_str(ch, option, ZSTR_VAL(str), ZSTR_LEN(str)); zend_tmp_string_release(tmp_str); return ret; } @@ -2482,6 +2454,9 @@ static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue, bool i #if LIBCURL_VERSION_NUM >= 0x072800 /* Available since 7.40.0 */ case CURLOPT_UNIX_SOCKET_PATH: #endif +#if LIBCURL_VERSION_NUM >= 0x073E00 /* Available since 7.62.0 */ + case CURLOPT_DOH_URL: +#endif case CURLOPT_KRBLEVEL: { if (Z_ISNULL_P(zvalue)) { @@ -2489,7 +2464,7 @@ static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue, bool i } else { zend_string *tmp_str; zend_string *str = zval_get_tmp_string(zvalue, &tmp_str); - int ret = php_curl_option_str(ch, option, ZSTR_VAL(str), ZSTR_LEN(str), 0); + int ret = php_curl_option_str(ch, option, ZSTR_VAL(str), ZSTR_LEN(str)); zend_tmp_string_release(tmp_str); return ret; } @@ -2499,11 +2474,9 @@ static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue, bool i /* Curl private option */ case CURLOPT_PRIVATE: { - zend_string *tmp_str; - zend_string *str = zval_get_tmp_string(zvalue, &tmp_str); - int ret = php_curl_option_str(ch, option, ZSTR_VAL(str), ZSTR_LEN(str), 1); - zend_tmp_string_release(tmp_str); - return ret; + zval_ptr_dtor(&ch->private_data); + ZVAL_COPY(&ch->private_data, zvalue); + return SUCCESS; } /* Curl url option */ @@ -2543,17 +2516,17 @@ static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue, bool i switch (option) { case CURLOPT_FILE: if (!what) { - if (!Z_ISUNDEF(ch->handlers->write->stream)) { - zval_ptr_dtor(&ch->handlers->write->stream); - ZVAL_UNDEF(&ch->handlers->write->stream); + if (!Z_ISUNDEF(ch->handlers.write->stream)) { + zval_ptr_dtor(&ch->handlers.write->stream); + ZVAL_UNDEF(&ch->handlers.write->stream); } - ch->handlers->write->fp = NULL; - ch->handlers->write->method = PHP_CURL_STDOUT; + ch->handlers.write->fp = NULL; + ch->handlers.write->method = PHP_CURL_STDOUT; } else if (what->mode[0] != 'r' || what->mode[1] == '+') { - zval_ptr_dtor(&ch->handlers->write->stream); - ch->handlers->write->fp = fp; - ch->handlers->write->method = PHP_CURL_FILE; - ZVAL_COPY(&ch->handlers->write->stream, zvalue); + zval_ptr_dtor(&ch->handlers.write->stream); + ch->handlers.write->fp = fp; + ch->handlers.write->method = PHP_CURL_FILE; + ZVAL_COPY(&ch->handlers.write->stream, zvalue); } else { zend_value_error("%s(): The provided file handle must be writable", get_active_function_name()); return FAILURE; @@ -2561,17 +2534,17 @@ static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue, bool i break; case CURLOPT_WRITEHEADER: if (!what) { - if (!Z_ISUNDEF(ch->handlers->write_header->stream)) { - zval_ptr_dtor(&ch->handlers->write_header->stream); - ZVAL_UNDEF(&ch->handlers->write_header->stream); + if (!Z_ISUNDEF(ch->handlers.write_header->stream)) { + zval_ptr_dtor(&ch->handlers.write_header->stream); + ZVAL_UNDEF(&ch->handlers.write_header->stream); } - ch->handlers->write_header->fp = NULL; - ch->handlers->write_header->method = PHP_CURL_IGNORE; + ch->handlers.write_header->fp = NULL; + ch->handlers.write_header->method = PHP_CURL_IGNORE; } else if (what->mode[0] != 'r' || what->mode[1] == '+') { - zval_ptr_dtor(&ch->handlers->write_header->stream); - ch->handlers->write_header->fp = fp; - ch->handlers->write_header->method = PHP_CURL_FILE; - ZVAL_COPY(&ch->handlers->write_header->stream, zvalue); + zval_ptr_dtor(&ch->handlers.write_header->stream); + ch->handlers.write_header->fp = fp; + ch->handlers.write_header->method = PHP_CURL_FILE; + ZVAL_COPY(&ch->handlers.write_header->stream, zvalue); } else { zend_value_error("%s(): The provided file handle must be writable", get_active_function_name()); return FAILURE; @@ -2579,28 +2552,28 @@ static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue, bool i break; case CURLOPT_INFILE: if (!what) { - if (!Z_ISUNDEF(ch->handlers->read->stream)) { - zval_ptr_dtor(&ch->handlers->read->stream); - ZVAL_UNDEF(&ch->handlers->read->stream); + if (!Z_ISUNDEF(ch->handlers.read->stream)) { + zval_ptr_dtor(&ch->handlers.read->stream); + ZVAL_UNDEF(&ch->handlers.read->stream); } - ch->handlers->read->fp = NULL; - ch->handlers->read->res = NULL; + ch->handlers.read->fp = NULL; + ch->handlers.read->res = NULL; } else { - zval_ptr_dtor(&ch->handlers->read->stream); - ch->handlers->read->fp = fp; - ch->handlers->read->res = Z_RES_P(zvalue); - ZVAL_COPY(&ch->handlers->read->stream, zvalue); + zval_ptr_dtor(&ch->handlers.read->stream); + ch->handlers.read->fp = fp; + ch->handlers.read->res = Z_RES_P(zvalue); + ZVAL_COPY(&ch->handlers.read->stream, zvalue); } break; case CURLOPT_STDERR: if (!what) { - if (!Z_ISUNDEF(ch->handlers->std_err)) { - zval_ptr_dtor(&ch->handlers->std_err); - ZVAL_UNDEF(&ch->handlers->std_err); + if (!Z_ISUNDEF(ch->handlers.std_err)) { + zval_ptr_dtor(&ch->handlers.std_err); + ZVAL_UNDEF(&ch->handlers.std_err); } } else if (what->mode[0] != 'r' || what->mode[1] == '+') { - zval_ptr_dtor(&ch->handlers->std_err); - ZVAL_COPY(&ch->handlers->std_err, zvalue); + zval_ptr_dtor(&ch->handlers.std_err); + ZVAL_COPY(&ch->handlers.std_err, zvalue); } else { zend_value_error("%s(): The provided file handle must be writable", get_active_function_name()); return FAILURE; @@ -2712,12 +2685,12 @@ static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue, bool i break; case CURLOPT_HEADERFUNCTION: - if (!Z_ISUNDEF(ch->handlers->write_header->func_name)) { - zval_ptr_dtor(&ch->handlers->write_header->func_name); - ch->handlers->write_header->fci_cache = empty_fcall_info_cache; + if (!Z_ISUNDEF(ch->handlers.write_header->func_name)) { + zval_ptr_dtor(&ch->handlers.write_header->func_name); + ch->handlers.write_header->fci_cache = empty_fcall_info_cache; } - ZVAL_COPY(&ch->handlers->write_header->func_name, zvalue); - ch->handlers->write_header->method = PHP_CURL_USER; + ZVAL_COPY(&ch->handlers.write_header->func_name, zvalue); + ch->handlers.write_header->method = PHP_CURL_USER; break; case CURLOPT_POSTFIELDS: @@ -2743,40 +2716,39 @@ static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue, bool i case CURLOPT_PROGRESSFUNCTION: curl_easy_setopt(ch->cp, CURLOPT_PROGRESSFUNCTION, curl_progress); curl_easy_setopt(ch->cp, CURLOPT_PROGRESSDATA, ch); - if (ch->handlers->progress == NULL) { - ch->handlers->progress = ecalloc(1, sizeof(php_curl_progress)); - } else if (!Z_ISUNDEF(ch->handlers->progress->func_name)) { - zval_ptr_dtor(&ch->handlers->progress->func_name); - ch->handlers->progress->fci_cache = empty_fcall_info_cache; + if (ch->handlers.progress == NULL) { + ch->handlers.progress = ecalloc(1, sizeof(php_curl_callback)); + } else if (!Z_ISUNDEF(ch->handlers.progress->func_name)) { + zval_ptr_dtor(&ch->handlers.progress->func_name); + ch->handlers.progress->fci_cache = empty_fcall_info_cache; } - ZVAL_COPY(&ch->handlers->progress->func_name, zvalue); - ch->handlers->progress->method = PHP_CURL_USER; + ZVAL_COPY(&ch->handlers.progress->func_name, zvalue); break; case CURLOPT_READFUNCTION: - if (!Z_ISUNDEF(ch->handlers->read->func_name)) { - zval_ptr_dtor(&ch->handlers->read->func_name); - ch->handlers->read->fci_cache = empty_fcall_info_cache; + if (!Z_ISUNDEF(ch->handlers.read->func_name)) { + zval_ptr_dtor(&ch->handlers.read->func_name); + ch->handlers.read->fci_cache = empty_fcall_info_cache; } - ZVAL_COPY(&ch->handlers->read->func_name, zvalue); - ch->handlers->read->method = PHP_CURL_USER; + ZVAL_COPY(&ch->handlers.read->func_name, zvalue); + ch->handlers.read->method = PHP_CURL_USER; break; case CURLOPT_RETURNTRANSFER: if (zend_is_true(zvalue)) { - ch->handlers->write->method = PHP_CURL_RETURN; + ch->handlers.write->method = PHP_CURL_RETURN; } else { - ch->handlers->write->method = PHP_CURL_STDOUT; + ch->handlers.write->method = PHP_CURL_STDOUT; } break; case CURLOPT_WRITEFUNCTION: - if (!Z_ISUNDEF(ch->handlers->write->func_name)) { - zval_ptr_dtor(&ch->handlers->write->func_name); - ch->handlers->write->fci_cache = empty_fcall_info_cache; + if (!Z_ISUNDEF(ch->handlers.write->func_name)) { + zval_ptr_dtor(&ch->handlers.write->func_name); + ch->handlers.write->fci_cache = empty_fcall_info_cache; } - ZVAL_COPY(&ch->handlers->write->func_name, zvalue); - ch->handlers->write->method = PHP_CURL_USER; + ZVAL_COPY(&ch->handlers.write->func_name, zvalue); + ch->handlers.write->method = PHP_CURL_USER; break; /* Curl off_t options */ @@ -2817,7 +2789,7 @@ static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue, bool i return FAILURE; } - ret = php_curl_option_str(ch, option, ZSTR_VAL(str), ZSTR_LEN(str), 0); + ret = php_curl_option_str(ch, option, ZSTR_VAL(str), ZSTR_LEN(str)); zend_tmp_string_release(tmp_str); return ret; } @@ -2852,14 +2824,13 @@ static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue, bool i case CURLOPT_FNMATCH_FUNCTION: curl_easy_setopt(ch->cp, CURLOPT_FNMATCH_FUNCTION, curl_fnmatch); curl_easy_setopt(ch->cp, CURLOPT_FNMATCH_DATA, ch); - if (ch->handlers->fnmatch == NULL) { - ch->handlers->fnmatch = ecalloc(1, sizeof(php_curl_fnmatch)); - } else if (!Z_ISUNDEF(ch->handlers->fnmatch->func_name)) { - zval_ptr_dtor(&ch->handlers->fnmatch->func_name); - ch->handlers->fnmatch->fci_cache = empty_fcall_info_cache; + if (ch->handlers.fnmatch == NULL) { + ch->handlers.fnmatch = ecalloc(1, sizeof(php_curl_callback)); + } else if (!Z_ISUNDEF(ch->handlers.fnmatch->func_name)) { + zval_ptr_dtor(&ch->handlers.fnmatch->func_name); + ch->handlers.fnmatch->fci_cache = empty_fcall_info_cache; } - ZVAL_COPY(&ch->handlers->fnmatch->func_name, zvalue); - ch->handlers->fnmatch->method = PHP_CURL_USER; + ZVAL_COPY(&ch->handlers.fnmatch->func_name, zvalue); break; default: @@ -2939,7 +2910,7 @@ PHP_FUNCTION(curl_setopt_array) Cleanup an execution phase */ void _php_curl_cleanup_handle(php_curl *ch) { - smart_str_free(&ch->handlers->write->buf); + smart_str_free(&ch->handlers.write->buf); if (ch->header.str) { zend_string_release_ex(ch->header.str, 0); ch->header.str = NULL; @@ -2971,32 +2942,32 @@ PHP_FUNCTION(curl_exec) SAVE_CURL_ERROR(ch, error); if (error != CURLE_OK) { - smart_str_free(&ch->handlers->write->buf); + smart_str_free(&ch->handlers.write->buf); RETURN_FALSE; } - if (!Z_ISUNDEF(ch->handlers->std_err)) { + if (!Z_ISUNDEF(ch->handlers.std_err)) { php_stream *stream; - stream = (php_stream*)zend_fetch_resource2_ex(&ch->handlers->std_err, NULL, php_file_le_stream(), php_file_le_pstream()); + stream = (php_stream*)zend_fetch_resource2_ex(&ch->handlers.std_err, NULL, php_file_le_stream(), php_file_le_pstream()); if (stream) { php_stream_flush(stream); } } - if (ch->handlers->write->method == PHP_CURL_RETURN && ch->handlers->write->buf.s) { - smart_str_0(&ch->handlers->write->buf); - RETURN_STR_COPY(ch->handlers->write->buf.s); + if (ch->handlers.write->method == PHP_CURL_RETURN && ch->handlers.write->buf.s) { + smart_str_0(&ch->handlers.write->buf); + RETURN_STR_COPY(ch->handlers.write->buf.s); } /* flush the file handle, so any remaining data is synched to disk */ - if (ch->handlers->write->method == PHP_CURL_FILE && ch->handlers->write->fp) { - fflush(ch->handlers->write->fp); + if (ch->handlers.write->method == PHP_CURL_FILE && ch->handlers.write->fp) { + fflush(ch->handlers.write->fp); } - if (ch->handlers->write_header->method == PHP_CURL_FILE && ch->handlers->write_header->fp) { - fflush(ch->handlers->write_header->fp); + if (ch->handlers.write_header->method == PHP_CURL_FILE && ch->handlers.write_header->fp) { + fflush(ch->handlers.write_header->fp); } - if (ch->handlers->write->method == PHP_CURL_RETURN) { + if (ch->handlers.write->method == PHP_CURL_RETURN) { RETURN_EMPTY_STRING(); } else { RETURN_TRUE; @@ -3010,7 +2981,7 @@ PHP_FUNCTION(curl_getinfo) zval *zid; php_curl *ch; zend_long option; - zend_bool option_is_null = 1; + bool option_is_null = 1; ZEND_PARSE_PARAMETERS_START(1, 2) Z_PARAM_OBJECT_OF_CLASS(zid, curl_ce) @@ -3184,6 +3155,13 @@ PHP_FUNCTION(curl_getinfo) } break; } + case CURLINFO_PRIVATE: + if (!Z_ISUNDEF(ch->private_data)) { + RETURN_COPY(&ch->private_data); + } else { + RETURN_FALSE; + } + break; default: { int type = CURLINFO_TYPEMASK & option; switch (type) { @@ -3347,7 +3325,6 @@ static void curl_free_obj(zend_object *object) /* cURL destructors should be invoked only by last curl handle */ if (--(*ch->clone) == 0) { - zend_llist_clean(&ch->to_free->str); zend_llist_clean(&ch->to_free->post); zend_llist_clean(&ch->to_free->stream); zend_hash_destroy(ch->to_free->slist); @@ -3356,35 +3333,35 @@ static void curl_free_obj(zend_object *object) efree(ch->clone); } - smart_str_free(&ch->handlers->write->buf); - zval_ptr_dtor(&ch->handlers->write->func_name); - zval_ptr_dtor(&ch->handlers->read->func_name); - zval_ptr_dtor(&ch->handlers->write_header->func_name); - zval_ptr_dtor(&ch->handlers->std_err); + smart_str_free(&ch->handlers.write->buf); + zval_ptr_dtor(&ch->handlers.write->func_name); + zval_ptr_dtor(&ch->handlers.read->func_name); + zval_ptr_dtor(&ch->handlers.write_header->func_name); + zval_ptr_dtor(&ch->handlers.std_err); if (ch->header.str) { zend_string_release_ex(ch->header.str, 0); } - zval_ptr_dtor(&ch->handlers->write_header->stream); - zval_ptr_dtor(&ch->handlers->write->stream); - zval_ptr_dtor(&ch->handlers->read->stream); + zval_ptr_dtor(&ch->handlers.write_header->stream); + zval_ptr_dtor(&ch->handlers.write->stream); + zval_ptr_dtor(&ch->handlers.read->stream); - efree(ch->handlers->write); - efree(ch->handlers->write_header); - efree(ch->handlers->read); + efree(ch->handlers.write); + efree(ch->handlers.write_header); + efree(ch->handlers.read); - if (ch->handlers->progress) { - zval_ptr_dtor(&ch->handlers->progress->func_name); - efree(ch->handlers->progress); + if (ch->handlers.progress) { + zval_ptr_dtor(&ch->handlers.progress->func_name); + efree(ch->handlers.progress); } - if (ch->handlers->fnmatch) { - zval_ptr_dtor(&ch->handlers->fnmatch->func_name); - efree(ch->handlers->fnmatch); + if (ch->handlers.fnmatch) { + zval_ptr_dtor(&ch->handlers.fnmatch->func_name); + efree(ch->handlers.fnmatch); } - efree(ch->handlers); zval_ptr_dtor(&ch->postfields); + zval_ptr_dtor(&ch->private_data); if (ch->share) { OBJ_RELEASE(&ch->share->std); @@ -3417,43 +3394,43 @@ PHP_FUNCTION(curl_strerror) Reset all handlers of a given php_curl */ static void _php_curl_reset_handlers(php_curl *ch) { - if (!Z_ISUNDEF(ch->handlers->write->stream)) { - zval_ptr_dtor(&ch->handlers->write->stream); - ZVAL_UNDEF(&ch->handlers->write->stream); + if (!Z_ISUNDEF(ch->handlers.write->stream)) { + zval_ptr_dtor(&ch->handlers.write->stream); + ZVAL_UNDEF(&ch->handlers.write->stream); } - ch->handlers->write->fp = NULL; - ch->handlers->write->method = PHP_CURL_STDOUT; + ch->handlers.write->fp = NULL; + ch->handlers.write->method = PHP_CURL_STDOUT; - if (!Z_ISUNDEF(ch->handlers->write_header->stream)) { - zval_ptr_dtor(&ch->handlers->write_header->stream); - ZVAL_UNDEF(&ch->handlers->write_header->stream); + if (!Z_ISUNDEF(ch->handlers.write_header->stream)) { + zval_ptr_dtor(&ch->handlers.write_header->stream); + ZVAL_UNDEF(&ch->handlers.write_header->stream); } - ch->handlers->write_header->fp = NULL; - ch->handlers->write_header->method = PHP_CURL_IGNORE; + ch->handlers.write_header->fp = NULL; + ch->handlers.write_header->method = PHP_CURL_IGNORE; - if (!Z_ISUNDEF(ch->handlers->read->stream)) { - zval_ptr_dtor(&ch->handlers->read->stream); - ZVAL_UNDEF(&ch->handlers->read->stream); + if (!Z_ISUNDEF(ch->handlers.read->stream)) { + zval_ptr_dtor(&ch->handlers.read->stream); + ZVAL_UNDEF(&ch->handlers.read->stream); } - ch->handlers->read->fp = NULL; - ch->handlers->read->res = NULL; - ch->handlers->read->method = PHP_CURL_DIRECT; + ch->handlers.read->fp = NULL; + ch->handlers.read->res = NULL; + ch->handlers.read->method = PHP_CURL_DIRECT; - if (!Z_ISUNDEF(ch->handlers->std_err)) { - zval_ptr_dtor(&ch->handlers->std_err); - ZVAL_UNDEF(&ch->handlers->std_err); + if (!Z_ISUNDEF(ch->handlers.std_err)) { + zval_ptr_dtor(&ch->handlers.std_err); + ZVAL_UNDEF(&ch->handlers.std_err); } - if (ch->handlers->progress) { - zval_ptr_dtor(&ch->handlers->progress->func_name); - efree(ch->handlers->progress); - ch->handlers->progress = NULL; + if (ch->handlers.progress) { + zval_ptr_dtor(&ch->handlers.progress->func_name); + efree(ch->handlers.progress); + ch->handlers.progress = NULL; } - if (ch->handlers->fnmatch) { - zval_ptr_dtor(&ch->handlers->fnmatch->func_name); - efree(ch->handlers->fnmatch); - ch->handlers->fnmatch = NULL; + if (ch->handlers.fnmatch) { + zval_ptr_dtor(&ch->handlers.fnmatch->func_name); + efree(ch->handlers.fnmatch); + ch->handlers.fnmatch = NULL; } } |