Skip to content

Commit 33441ed

Browse files
committed
Add new curl constants and functionality from curl > 7.80
Fixes GH-10454
1 parent ff84598 commit 33441ed

File tree

5 files changed

+259
-1
lines changed

5 files changed

+259
-1
lines changed

ext/curl/curl.stub.php

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -941,6 +941,18 @@
941941
*/
942942
const CURLINFO_EFFECTIVE_METHOD = UNKNOWN;
943943
#endif
944+
#if LIBCURL_VERSION_NUM >= 0x075400 /* Available since 7.84.0 */
945+
/**
946+
* @var int
947+
* @cvalue CURLINFO_CAPATH
948+
*/
949+
const CURLINFO_CAPATH = UNKNOWN;
950+
/**
951+
* @var int
952+
* @cvalue CURLINFO_CAINFO
953+
*/
954+
const CURLINFO_CAINFO = UNKNOWN;
955+
#endif
944956

945957
/* Other */
946958
/**
@@ -3522,6 +3534,63 @@
35223534
const CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256 = UNKNOWN;
35233535
#endif
35243536

3537+
#if LIBCURL_VERSION_NUM >= 0x075100 /* Available since 7.81.0 */
3538+
/**
3539+
* @var int
3540+
* @cvalue CURLOPT_MIME_OPTIONS
3541+
*/
3542+
const CURLOPT_MIME_OPTIONS = UNKNOWN;
3543+
/**
3544+
* @var int
3545+
* @cvalue CURLMIMEOPT_FORMESCAPE
3546+
*/
3547+
const CURLMIMEOPT_FORMESCAPE = UNKNOWN;
3548+
#endif
3549+
3550+
#if LIBCURL_VERSION_NUM >= 0x075400 /* Available since 7.84.0 */
3551+
/**
3552+
* @var int
3553+
* @cvalue CURLOPT_SSH_HOSTKEYFUNCTION
3554+
*/
3555+
const CURLOPT_SSH_HOSTKEYFUNCTION = UNKNOWN;
3556+
#endif
3557+
3558+
#if LIBCURL_VERSION_NUM >= 0x075500 /* Available since 7.85.0 */
3559+
/**
3560+
* @var int
3561+
* @cvalue CURLOPT_PROTOCOLS_STR
3562+
*/
3563+
const CURLOPT_PROTOCOLS_STR = UNKNOWN;
3564+
/**
3565+
* @var int
3566+
* @cvalue CURLOPT_REDIR_PROTOCOLS_STR
3567+
*/
3568+
const CURLOPT_REDIR_PROTOCOLS_STR = UNKNOWN;
3569+
/**
3570+
* @var int
3571+
* @cvalue CURLOPT_WS_OPTIONS
3572+
*/
3573+
const CURLOPT_WS_OPTIONS = UNKNOWN;
3574+
/**
3575+
* @var int
3576+
* @cvalue CURLWS_RAW_MODE
3577+
*/
3578+
const CURLWS_RAW_MODE = UNKNOWN;
3579+
#endif
3580+
3581+
#if LIBCURL_VERSION_NUM >= 0x075700 /* Available since 7.87.0 */
3582+
/**
3583+
* @var int
3584+
* @cvalue CURLOPT_CA_CACHE_TIMEOUT
3585+
*/
3586+
const CURLOPT_CA_CACHE_TIMEOUT = UNKNOWN;
3587+
/**
3588+
* @var int
3589+
* @cvalue CURLOPT_QUICK_EXIT
3590+
*/
3591+
const CURLOPT_QUICK_EXIT = UNKNOWN;
3592+
#endif
3593+
35253594
/**
35263595
* @var int
35273596
* @cvalue CURLOPT_SAFE_UPLOAD

ext/curl/curl_arginfo.h

Lines changed: 34 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ext/curl/curl_private.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ typedef struct {
7777
php_curl_callback *xferinfo;
7878
#endif
7979
php_curl_callback *fnmatch;
80+
#if LIBCURL_VERSION_NUM >= 0x075400
81+
php_curl_callback *sshhostkey;
82+
#endif
8083
} php_curl_handlers;
8184

8285
struct _php_curl_error {

ext/curl/interface.c

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -757,6 +757,54 @@ static size_t curl_xferinfo(void *clientp, curl_off_t dltotal, curl_off_t dlnow,
757757
/* }}} */
758758
#endif
759759

760+
#if LIBCURL_VERSION_NUM >= 0x075400
761+
static size_t curl_ssh_hostkeyfunction(void *clientp, int keytype, const char *key, size_t keylen)
762+
{
763+
php_curl *ch = (php_curl *)clientp;
764+
php_curl_callback *t = ch->handlers.sshhostkey;
765+
size_t rval = 0;
766+
767+
#if PHP_CURL_DEBUG
768+
fprintf(stderr, "curl_ssh_hostkeyfunction() called\n");
769+
fprintf(stderr, "clientp = %x, keytype = %d, key = %s, keylen = %zu\n", clientp, keytype, key, keylen);
770+
#endif
771+
772+
zval argv[4];
773+
zval retval;
774+
zend_result error;
775+
zend_fcall_info fci;
776+
777+
GC_ADDREF(&ch->std);
778+
ZVAL_OBJ(&argv[0], &ch->std);
779+
ZVAL_LONG(&argv[1], keytype);
780+
ZVAL_STRING(&argv[2], key);
781+
ZVAL_LONG(&argv[3], keylen);
782+
783+
fci.size = sizeof(fci);
784+
ZVAL_COPY_VALUE(&fci.function_name, &t->func_name);
785+
fci.object = NULL;
786+
fci.retval = &retval;
787+
fci.param_count = 4;
788+
fci.params = argv;
789+
fci.named_params = NULL;
790+
791+
ch->in_callback = 1;
792+
error = zend_call_function(&fci, &t->fci_cache);
793+
ch->in_callback = 0;
794+
if (error == FAILURE) {
795+
php_error_docref(NULL, E_WARNING, "Cannot call the CURLOPT_SSH_HOSTKEYFUNCTION");
796+
} else if (!Z_ISUNDEF(retval)) {
797+
_php_curl_verify_handlers(ch, /* reporterror */ true);
798+
if (0 != zval_get_long(&retval)) {
799+
rval = 1;
800+
}
801+
}
802+
zval_ptr_dtor(&argv[0]);
803+
zval_ptr_dtor(&argv[2]);
804+
return rval;
805+
}
806+
#endif
807+
760808
/* {{{ curl_read */
761809
static size_t curl_read(char *data, size_t size, size_t nmemb, void *ctx)
762810
{
@@ -1771,6 +1819,16 @@ static zend_result _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue
17711819
#endif
17721820
#if LIBCURL_VERSION_NUM >= 0x075000 /* Available since 7.80.0 */
17731821
case CURLOPT_MAXLIFETIME_CONN:
1822+
#endif
1823+
#if LIBCURL_VERSION_NUM >= 0x075100 /* Available since 7.81.0 */
1824+
case CURLOPT_MIME_OPTIONS:
1825+
#endif
1826+
#if LIBCURL_VERSION_NUM >= 0x075500 /* Available since 7.85.0 */
1827+
case CURLOPT_WS_OPTIONS:
1828+
#endif
1829+
#if LIBCURL_VERSION_NUM >= 0x075700 /* Available since 7.87.0 */
1830+
case CURLOPT_CA_CACHE_TIMEOUT:
1831+
case CURLOPT_QUICK_EXIT:
17741832
#endif
17751833
lval = zval_get_long(zvalue);
17761834
if ((option == CURLOPT_PROTOCOLS || option == CURLOPT_REDIR_PROTOCOLS) &&
@@ -1886,10 +1944,21 @@ static zend_result _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue
18861944
#endif
18871945
#if LIBCURL_VERSION_NUM >= 0x075000 /* Available since 7.80.0 */
18881946
case CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256:
1947+
#endif
1948+
#if LIBCURL_VERSION_NUM >= 0x075500 /* Available since 7.85.0 */
1949+
case CURLOPT_PROTOCOLS_STR:
1950+
case CURLOPT_REDIR_PROTOCOLS_STR:
18891951
#endif
18901952
{
18911953
zend_string *tmp_str;
18921954
zend_string *str = zval_get_tmp_string(zvalue, &tmp_str);
1955+
#if LIBCURL_VERSION_NUM >= 0x075500 /* Available since 7.85.0 */
1956+
if (option == CURLOPT_PROTOCOLS_STR &&
1957+
(PG(open_basedir) && *PG(open_basedir)) && php_memnistr(ZSTR_VAL(str), "file", sizeof("file") - 1, ZSTR_VAL(str) + ZSTR_LEN(str)) != NULL) {
1958+
php_error_docref(NULL, E_WARNING, "The FILE protocol cannot be activated when an open_basedir is set");
1959+
return FAILURE;
1960+
}
1961+
#endif
18931962
zend_result ret = php_curl_option_str(ch, option, ZSTR_VAL(str), ZSTR_LEN(str));
18941963
zend_tmp_string_release(tmp_str);
18951964
return ret;
@@ -2184,6 +2253,20 @@ static zend_result _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue
21842253
ZVAL_COPY(&ch->handlers.progress->func_name, zvalue);
21852254
break;
21862255

2256+
#if LIBCURL_VERSION_NUM >= 0x075400 /* Available since 7.84.0 */
2257+
case CURLOPT_SSH_HOSTKEYFUNCTION:
2258+
curl_easy_setopt(ch->cp, CURLOPT_SSH_HOSTKEYFUNCTION, curl_ssh_hostkeyfunction);
2259+
curl_easy_setopt(ch->cp, CURLOPT_SSH_HOSTKEYDATA, ch);
2260+
if (ch->handlers.sshhostkey == NULL) {
2261+
ch->handlers.sshhostkey = ecalloc(1, sizeof(php_curl_callback));
2262+
} else if (!Z_ISUNDEF(ch->handlers.sshhostkey->func_name)) {
2263+
zval_ptr_dtor(&ch->handlers.sshhostkey->func_name);
2264+
ch->handlers.sshhostkey->fci_cache = empty_fcall_info_cache;
2265+
}
2266+
ZVAL_COPY(&ch->handlers.sshhostkey->func_name, zvalue);
2267+
break;
2268+
#endif
2269+
21872270
case CURLOPT_READFUNCTION:
21882271
if (!Z_ISUNDEF(ch->handlers.read->func_name)) {
21892272
zval_ptr_dtor(&ch->handlers.read->func_name);
@@ -2640,6 +2723,14 @@ PHP_FUNCTION(curl_getinfo)
26402723
if (curl_easy_getinfo(ch->cp, CURLINFO_EFFECTIVE_METHOD, &s_code) == CURLE_OK) {
26412724
CAAS("effective_method", s_code);
26422725
}
2726+
#endif
2727+
#if LIBCURL_VERSION_NUM >= 0x075400 /* Available since 7.84.0 */
2728+
if (curl_easy_getinfo(ch->cp, CURLINFO_CAPATH, &s_code) == CURLE_OK) {
2729+
CAAS("capath", s_code);
2730+
}
2731+
if (curl_easy_getinfo(ch->cp, CURLINFO_CAINFO, &s_code) == CURLE_OK) {
2732+
CAAS("cainfo", s_code);
2733+
}
26432734
#endif
26442735
} else {
26452736
switch (option) {
@@ -2878,6 +2969,13 @@ static void curl_free_obj(zend_object *object)
28782969
efree(ch->handlers.fnmatch);
28792970
}
28802971

2972+
#if LIBCURL_VERSION_NUM >= 0x075400
2973+
if (ch->handlers.sshhostkey) {
2974+
zval_ptr_dtor(&ch->handlers.sshhostkey->func_name);
2975+
efree(ch->handlers.sshhostkey);
2976+
}
2977+
#endif
2978+
28812979
zval_ptr_dtor(&ch->postfields);
28822980
zval_ptr_dtor(&ch->private_data);
28832981

ext/curl/tests/curl_basic_026.phpt

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
--TEST--
2+
Test curl_getinfo() function with CURLINFO_* and CURLOPT_* from curl >= 7.81.0
3+
--INI--
4+
open_basedir=.
5+
--EXTENSIONS--
6+
curl
7+
--SKIPIF--
8+
<?php $curl_version = curl_version();
9+
if ($curl_version['version_number'] < 0x075100) {
10+
exit("skip: test works only with curl >= 7.81.0");
11+
}
12+
?>
13+
--FILE--
14+
<?php
15+
16+
include 'server.inc';
17+
18+
$ch = curl_init();
19+
var_dump(array_key_exists('capath', curl_getinfo($ch)));
20+
var_dump(array_key_exists('cainfo', curl_getinfo($ch)));
21+
22+
$host = curl_cli_server_start();
23+
24+
$url = "{$host}/get.inc?test=";
25+
curl_setopt($ch, CURLOPT_URL, $url);
26+
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
27+
var_dump(curl_setopt($ch, CURLOPT_MIME_OPTIONS, CURLMIMEOPT_FORMESCAPE));
28+
// NOTE: depends on whether websocket support is compiled in
29+
//var_dump(curl_setopt($ch, CURLOPT_WS_OPTIONS, CURLWS_RAW_MODE));
30+
var_dump(curl_setopt($ch, CURLOPT_PROTOCOLS_STR, "FilE,DICT"));
31+
var_dump(curl_setopt($ch, CURLOPT_PROTOCOLS_STR, "DICT"));
32+
var_dump(curl_setopt($ch, CURLOPT_REDIR_PROTOCOLS_STR, "HTTP"));
33+
var_dump(curl_setopt($ch, CURLOPT_CA_CACHE_TIMEOUT, 1));
34+
var_dump(curl_setopt($ch, CURLOPT_QUICK_EXIT, 1000));
35+
var_dump(curl_setopt($ch, CURLOPT_SSH_HOSTKEYFUNCTION, function ($keytype, $key, $keylen) {
36+
// Can't really trigger this in a test
37+
var_dump($keytype);
38+
var_dump($key);
39+
var_dump($keylen);
40+
}));
41+
curl_exec($ch);
42+
curl_close($ch);
43+
?>
44+
--EXPECTF--
45+
bool(true)
46+
bool(true)
47+
bool(true)
48+
49+
Warning: curl_setopt(): The FILE protocol cannot be activated when an open_basedir is set in %s on line %d
50+
bool(false)
51+
bool(true)
52+
bool(true)
53+
bool(true)
54+
bool(true)
55+
bool(true)

0 commit comments

Comments
 (0)