From 52c91f0fb707efde04fb32667178e4246c7ffe23 Mon Sep 17 00:00:00 2001 From: David Zhong <91637806+davnotdev@users.noreply.github.com> Date: Sun, 16 Feb 2025 23:27:11 -0800 Subject: [PATCH 1/3] Fix FFI Parsing of Pointer Declaration Lists (#17794) * Fix ffi parsing of pointer declaration lists * Fix ffi pointer declaration lists grammar --- ext/ffi/ffi.g | 4 ++- ext/ffi/ffi_parser.c | 4 ++- ext/ffi/tests/ptr_declaration_list.phpt | 33 +++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 ext/ffi/tests/ptr_declaration_list.phpt diff --git a/ext/ffi/ffi.g b/ext/ffi/ffi.g index d70075267e54f..3648372428900 100644 --- a/ext/ffi/ffi.g +++ b/ext/ffi/ffi.g @@ -264,12 +264,14 @@ struct_contents(zend_ffi_dcl *dcl): struct_declaration(zend_ffi_dcl *struct_dcl): {zend_ffi_dcl common_field_dcl = ZEND_FFI_ATTR_INIT;} + {zend_ffi_dcl base_field_dcl = ZEND_FFI_ATTR_INIT;} specifier_qualifier_list(&common_field_dcl) + {base_field_dcl = common_field_dcl;} ( /* empty */ {zend_ffi_add_anonymous_field(struct_dcl, &common_field_dcl);} | struct_declarator(struct_dcl, &common_field_dcl) ( "," - {zend_ffi_dcl field_dcl = common_field_dcl;} + {zend_ffi_dcl field_dcl = base_field_dcl;} attributes(&field_dcl)? struct_declarator(struct_dcl, &field_dcl) )* diff --git a/ext/ffi/ffi_parser.c b/ext/ffi/ffi_parser.c index 2589ae81e0259..26d623a40290e 100644 --- a/ext/ffi/ffi_parser.c +++ b/ext/ffi/ffi_parser.c @@ -2472,14 +2472,16 @@ static int parse_struct_contents(int sym, zend_ffi_dcl *dcl) { static int parse_struct_declaration(int sym, zend_ffi_dcl *struct_dcl) { zend_ffi_dcl common_field_dcl = ZEND_FFI_ATTR_INIT; + zend_ffi_dcl base_field_dcl = ZEND_FFI_ATTR_INIT; sym = parse_specifier_qualifier_list(sym, &common_field_dcl); + base_field_dcl = common_field_dcl; if (sym == YY__SEMICOLON || sym == YY__RBRACE) { zend_ffi_add_anonymous_field(struct_dcl, &common_field_dcl); } else if (sym == YY__STAR || sym == YY_ID || sym == YY__LPAREN || sym == YY__COLON) { sym = parse_struct_declarator(sym, struct_dcl, &common_field_dcl); while (sym == YY__COMMA) { sym = get_sym(); - zend_ffi_dcl field_dcl = common_field_dcl; + zend_ffi_dcl field_dcl = base_field_dcl; if (YY_IN_SET(sym, (YY___ATTRIBUTE,YY___ATTRIBUTE__,YY___DECLSPEC,YY___CDECL,YY___STDCALL,YY___FASTCALL,YY___THISCALL,YY___VECTORCALL), "\000\000\000\000\000\000\360\017\000\000\000\000\000")) { sym = parse_attributes(sym, &field_dcl); } diff --git a/ext/ffi/tests/ptr_declaration_list.phpt b/ext/ffi/tests/ptr_declaration_list.phpt new file mode 100644 index 0000000000000..cb8ecafd935ba --- /dev/null +++ b/ext/ffi/tests/ptr_declaration_list.phpt @@ -0,0 +1,33 @@ +--TEST-- +Declaration Lists with Pointers +--EXTENSIONS-- +ffi +--SKIPIF-- +--FILE-- +new('struct MyStruct'); +$one = $ffi->new("uint8_t"); +$oneptr = $ffi->new("uint8_t*"); +$oneptrptr = $ffi->new("uint8_t**"); +$one->cdata = 1; +$oneptr = FFI::addr($one); +$oneptrptr = FFI::addr($oneptr); + +$test_struct->a = $oneptrptr; +$test_struct->b = $oneptr; +$test_struct->c = $one; + +var_dump($test_struct->a[0][0]); +var_dump($test_struct->b[0]); +var_dump($test_struct->c); +?> +--EXPECT-- +int(1) +int(1) +int(1) From 6a319928c412fb4d09b13f9763d15b2d5165023a Mon Sep 17 00:00:00 2001 From: Ayesh Karunaratne Date: Sun, 19 Jan 2025 11:32:20 +0700 Subject: [PATCH 2/3] ext/curl: Add `CURLINFO_{USED_PROXY,HTTPAUTH_USED,PROXYAUTH_USED}` Adds support for `curl_getinfo()` info keys and additional array keys: - [`CURLINFO_USED_PROXY`](https://curl.se/libcurl/c/CURLINFO_USED_PROXY.html) - `libcurl` >= 8.7.9 - Zero if no proxy was used in the previous transfer or a non-zero value if a proxy was used. - [`CURLINFO_HTTPAUTH_USED`](https://github.com/curl/curl/blob/curl-8_12_0/docs/libcurl/opts/CURLINFO_HTTPAUTH_USED.md) - `libcurl` >= 8.7.9 - Bitmask indicating the authentication method that was used in the previous HTTP request. - [`CURLINFO_PROXYAUTH_USED`](https://github.com/curl/curl/blob/curl-8_12_0/docs/libcurl/opts/CURLINFO_PROXYAUTH_USED.md) - `libcurl` >= 8.12.0 - Bitmask indicating the authentication method that was used in the previous request done over an HTTP proxy. ```php curl_getinfo($ch); ``` ```php [ // ... "used_proxy" => 0, "httpauth_used" => 0, "proxyauth_used" => 0, ] ``` This also updates the `Caddyfile` for curl tests to add a new route that supports HTTP basic auth. --- ext/curl/curl.stub.php | 19 ++++++ ext/curl/curl_arginfo.h | 11 +++- ext/curl/interface.c | 13 ++++ ext/curl/tests/Caddyfile | 5 ++ ..._getinfo_CURLINFO_HTTPAUTH_USED-caddy.phpt | 33 ++++++++++ .../curl_getinfo_CURLINFO_HTTPAUTH_USED.phpt | 66 +++++++++++++++++++ .../curl_getinfo_CURLINFO_USED_PROXY.phpt | 38 +++++++++++ 7 files changed, 184 insertions(+), 1 deletion(-) create mode 100644 ext/curl/tests/curl_getinfo_CURLINFO_HTTPAUTH_USED-caddy.phpt create mode 100644 ext/curl/tests/curl_getinfo_CURLINFO_HTTPAUTH_USED.phpt create mode 100644 ext/curl/tests/curl_getinfo_CURLINFO_USED_PROXY.phpt diff --git a/ext/curl/curl.stub.php b/ext/curl/curl.stub.php index 9eb8bd5b49e87..c9abe237339b5 100644 --- a/ext/curl/curl.stub.php +++ b/ext/curl/curl.stub.php @@ -1000,6 +1000,18 @@ */ const CURLINFO_CAINFO = UNKNOWN; #endif +#if LIBCURL_VERSION_NUM >= 0x080c00 /* Available since 8.12.0 */ +/** + * @var int + * @cvalue CURLINFO_HTTPAUTH_USED + */ +const CURLINFO_HTTPAUTH_USED = UNKNOWN; +/** + * @var int + * @cvalue CURLINFO_PROXYAUTH_USED + */ +const CURLINFO_PROXYAUTH_USED = UNKNOWN; +#endif /* Other */ /** @@ -3054,6 +3066,13 @@ * @cvalue CURLINFO_TOTAL_TIME_T */ const CURLINFO_TOTAL_TIME_T = UNKNOWN; +#if LIBCURL_VERSION_NUM >= 0x080700 /* Available since 8.7.0 */ +/** + * @var int + * @cvalue CURLINFO_USED_PROXY + */ +const CURLINFO_USED_PROXY = UNKNOWN; +#endif #if LIBCURL_VERSION_NUM >= 0x080a00 /* Available since 8.10.0 */ /** * @var int diff --git a/ext/curl/curl_arginfo.h b/ext/curl/curl_arginfo.h index e873e9e9f3277..6a81d1e92c88f 100644 --- a/ext/curl/curl_arginfo.h +++ b/ext/curl/curl_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 7d3cd96f8725c59be46817487bb8d06e04384269 */ + * Stub hash: 48fc95503f4f8cc96575ff6f31fdd1e4cdc5969e */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_curl_close, 0, 1, IS_VOID, 0) ZEND_ARG_OBJ_INFO(0, handle, CurlHandle, 0) @@ -429,6 +429,12 @@ static void register_curl_symbols(int module_number) #endif #if LIBCURL_VERSION_NUM >= 0x075400 /* Available since 7.84.0 */ REGISTER_LONG_CONSTANT("CURLINFO_CAINFO", CURLINFO_CAINFO, CONST_PERSISTENT); +#endif +#if LIBCURL_VERSION_NUM >= 0x080c00 /* Available since 8.12.0 */ + REGISTER_LONG_CONSTANT("CURLINFO_HTTPAUTH_USED", CURLINFO_HTTPAUTH_USED, CONST_PERSISTENT); +#endif +#if LIBCURL_VERSION_NUM >= 0x080c00 /* Available since 8.12.0 */ + REGISTER_LONG_CONSTANT("CURLINFO_PROXYAUTH_USED", CURLINFO_PROXYAUTH_USED, CONST_PERSISTENT); #endif REGISTER_LONG_CONSTANT("CURLMSG_DONE", CURLMSG_DONE, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("CURLVERSION_NOW", CURLVERSION_NOW, CONST_PERSISTENT); @@ -811,6 +817,9 @@ static void register_curl_symbols(int module_number) REGISTER_LONG_CONSTANT("CURLINFO_REDIRECT_TIME_T", CURLINFO_REDIRECT_TIME_T, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("CURLINFO_STARTTRANSFER_TIME_T", CURLINFO_STARTTRANSFER_TIME_T, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("CURLINFO_TOTAL_TIME_T", CURLINFO_TOTAL_TIME_T, CONST_PERSISTENT); +#if LIBCURL_VERSION_NUM >= 0x080700 /* Available since 8.7.0 */ + REGISTER_LONG_CONSTANT("CURLINFO_USED_PROXY", CURLINFO_USED_PROXY, CONST_PERSISTENT); +#endif #if LIBCURL_VERSION_NUM >= 0x080a00 /* Available since 8.10.0 */ REGISTER_LONG_CONSTANT("CURLINFO_POSTTRANSFER_TIME_T", CURLINFO_POSTTRANSFER_TIME_T, CONST_PERSISTENT); #endif diff --git a/ext/curl/interface.c b/ext/curl/interface.c index 690f2ccc609c9..311b2f7cc8a59 100644 --- a/ext/curl/interface.c +++ b/ext/curl/interface.c @@ -2662,6 +2662,19 @@ PHP_FUNCTION(curl_getinfo) if (curl_easy_getinfo(ch->cp, CURLINFO_CAINFO, &s_code) == CURLE_OK) { CAAS("cainfo", s_code); } +#endif +#if LIBCURL_VERSION_NUM >= 0x080700 /* Available since 8.7.0 */ + if (curl_easy_getinfo(ch->cp, CURLINFO_USED_PROXY, &l_code) == CURLE_OK) { + CAAL("used_proxy", l_code); + } +#endif +#if LIBCURL_VERSION_NUM >= 0x080c00 /* Available since 8.12.0 */ + if (curl_easy_getinfo(ch->cp, CURLINFO_HTTPAUTH_USED, &l_code) == CURLE_OK) { + CAAL("httpauth_used", l_code); + } + if (curl_easy_getinfo(ch->cp, CURLINFO_PROXYAUTH_USED, &l_code) == CURLE_OK) { + CAAL("proxyauth_used", l_code); + } #endif } else { switch (option) { diff --git a/ext/curl/tests/Caddyfile b/ext/curl/tests/Caddyfile index 28deb40926fc0..1c9432bdb0ba2 100644 --- a/ext/curl/tests/Caddyfile +++ b/ext/curl/tests/Caddyfile @@ -11,3 +11,8 @@ respond / "Caddy is up and running" respond /serverpush "main response" respond /serverpush/pushed "pushed response" push /serverpush /serverpush/pushed + +basicauth /http-basic-auth { + # bcrypt password hash for "password", calculated with 'caddy hash-password' + user $2a$14$yUKl9SGqVTAAqPTzLup.DefsbXXx3kfreNnzpJOUHcIrKnr5lgef2 +} diff --git a/ext/curl/tests/curl_getinfo_CURLINFO_HTTPAUTH_USED-caddy.phpt b/ext/curl/tests/curl_getinfo_CURLINFO_HTTPAUTH_USED-caddy.phpt new file mode 100644 index 0000000000000..91e1b8d6151f4 --- /dev/null +++ b/ext/curl/tests/curl_getinfo_CURLINFO_HTTPAUTH_USED-caddy.phpt @@ -0,0 +1,33 @@ +--TEST-- +curl_getinfo - CURLINFO_HTTPAUTH_USED - online test +--EXTENSIONS-- +curl +--SKIPIF-- += 8.12.0"); +include 'skipif-nocaddy.inc'; +?> +--FILE-- + +--EXPECT-- +bool(true) +bool(true) diff --git a/ext/curl/tests/curl_getinfo_CURLINFO_HTTPAUTH_USED.phpt b/ext/curl/tests/curl_getinfo_CURLINFO_HTTPAUTH_USED.phpt new file mode 100644 index 0000000000000..ea004d3dc9eb4 --- /dev/null +++ b/ext/curl/tests/curl_getinfo_CURLINFO_HTTPAUTH_USED.phpt @@ -0,0 +1,66 @@ +--TEST-- +curl_getinfo - CURLINFO_HTTPAUTH_USED +--EXTENSIONS-- +curl +--SKIPIF-- += 8.12.0"); +?> +--FILE-- + +--EXPECT-- +httpauth_used and proxyauth_used empty +bool(true) +bool(true) +bool(true) +bool(true) +httpauth_used and proxyauth_used empty after request +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +httpauth_used set after request +int(0) diff --git a/ext/curl/tests/curl_getinfo_CURLINFO_USED_PROXY.phpt b/ext/curl/tests/curl_getinfo_CURLINFO_USED_PROXY.phpt new file mode 100644 index 0000000000000..7020a70f5247d --- /dev/null +++ b/ext/curl/tests/curl_getinfo_CURLINFO_USED_PROXY.phpt @@ -0,0 +1,38 @@ +--TEST-- +curl_getinfo - CURLINFO_USED_PROXY +--EXTENSIONS-- +curl +--SKIPIF-- += 8.7.0"); +?> +--FILE-- + +--EXPECT-- +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) From 395c3fbe9f4a23abc7f461b53fc2fbc0eaeeba2d Mon Sep 17 00:00:00 2001 From: Ayesh Karunaratne Date: Mon, 17 Feb 2025 17:46:26 +0700 Subject: [PATCH 3/3] UPGRADING: Add `CURLINFO_USED_PROXY`, `HTTPAUTH_USED`, and `PROXYAUTH_USED` Follow-up to GH-17816. --- NEWS | 2 ++ UPGRADING | 17 +++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/NEWS b/NEWS index b30f82a0775c6..384565082cf92 100644 --- a/NEWS +++ b/NEWS @@ -28,6 +28,8 @@ PHP NEWS - Curl: . Added curl_multi_get_handles(). (timwolla) . Added curl_share_init_persistent(). (enorris) + . Added CURLINFO_USED_PROXY, CURLINFO_HTTPAUTH_USED, and CURLINFO_PROXYAUTH_USED + support to curl_getinfo. (Ayesh Karunaratne) - Date: . Fix undefined behaviour problems regarding integer overflow in extreme edge diff --git a/UPGRADING b/UPGRADING index 3a906de901e1d..4a89f3ea00970 100644 --- a/UPGRADING +++ b/UPGRADING @@ -95,6 +95,18 @@ PHP 8.5 UPGRADE NOTES . Added support for share handles that are persisted across multiple PHP requests, safely allowing for more effective connection reuse. RFC: https://wiki.php.net/rfc/curl_share_persistence_improvement + . Added support for CURLINFO_USED_PROXY (libcurl >= 8.7.0), + CURLINFO_HTTPAUTH_USED, and CURLINFO_PROXYAUTH_USED + (libcurl >= 8.12.0) to the curl_getinfo() function. + When curl_getinfo() returns an array, the same information + is available as "used_proxy", "httpauth_used", and "proxyauth_used" + keys. + CURLINFO_USED_PROXY gets zero set if no proxy was used in the + previous transfer or a non-zero value if a proxy was used. + CURLINFO_HTTPAUTH_USED and CURLINFO_PROXYAUTH_USED get bitmasks + indicating the http and proxy authentication methods that were + used in the previous request. See CURLAUTH_* constants for + possible values. - DOM: . Added Dom\Element::$outerHTML. @@ -265,6 +277,11 @@ PHP 8.5 UPGRADE NOTES - Core: . PHP_BUILD_DATE. +- Curl: + . CURLINFO_USED_PROXY. + . CURLINFO_HTTPAUTH_USED. + . CURLINFO_PROXYAUTH_USED. + - POSIX: . POSIX_SC_OPEN_MAX.