From 596383ca7165a4ec3a1774941bf7b90d4c2d1256 Mon Sep 17 00:00:00 2001 From: Viktor Szakats Date: Thu, 14 Aug 2025 16:45:15 +0200 Subject: [PATCH 01/18] GHA/linux: try improving valgrind job times with cmake Make the: - mbedTLS valgrind job finish under 14m, vs 15m before. - OpenSSL -O3 valgrind job finish in 14m30, vs 16m17. - OpenSSL libssh2 valgrind job finish in 16m, vs 17m30. - long valgrind rustls job finish 1 minute earlier, in return for spending 30s more on the other rustls job. Keep using autotools for the less slow valgrind job to test this combo. Closes #18290 --- .github/workflows/linux.yml | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 7f1ea5a5eb..9c5248449b 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -103,7 +103,12 @@ jobs: - name: 'mbedtls valgrind' install_packages: libnghttp2-dev libidn2-dev libldap-dev valgrind install_steps: mbedtls - configure: LDFLAGS=-Wl,-rpath,/home/runner/mbedtls/lib --with-mbedtls=/home/runner/mbedtls --enable-debug + generate: >- + -DCURL_USE_MBEDTLS=ON -DENABLE_DEBUG=ON + -DMBEDTLS_INCLUDE_DIR=/home/runner/mbedtls/include + -DMBEDTLS_LIBRARY=/home/runner/mbedtls/lib/libmbedtls.a + -DMBEDX509_LIBRARY=/home/runner/mbedtls/lib/libmbedx509.a + -DMBEDCRYPTO_LIBRARY=/home/runner/mbedtls/lib/libmbedcrypto.a - name: 'mbedtls clang' install_packages: libnghttp2-dev libldap-dev clang @@ -145,7 +150,7 @@ jobs: - name: 'openssl libssh2 sync-resolver valgrind' install_packages: zlib1g-dev libidn2-dev libssh2-1-dev libnghttp2-dev libldap-dev valgrind - configure: --with-openssl --enable-debug --disable-threaded-resolver --with-libssh2 + generate: -DENABLE_DEBUG=ON -DENABLE_THREADED_RESOLVER=OFF -DCURL_USE_LIBSSH2=ON - name: 'openssl' install_packages: zlib1g-dev @@ -160,7 +165,8 @@ jobs: - name: 'openssl -O3 libssh valgrind' install_packages: zlib1g-dev libssh-dev valgrind - configure: CFLAGS=-O3 --with-openssl --enable-debug --with-libssh + CFLAGS: -O3 + generate: -DENABLE_DEBUG=ON -DCURL_USE_LIBSSH=ON - name: 'openssl clang krb5 openldap static' install_steps: openldap-static @@ -260,12 +266,12 @@ jobs: - name: 'rustls valgrind' install_packages: libnghttp2-dev libldap-dev valgrind install_steps: rust rustls - configure: --with-rustls --enable-ech --enable-debug + generate: -DCURL_USE_RUSTLS=ON -DUSE_ECH=ON -DENABLE_DEBUG=ON - name: 'rustls' install_packages: libnghttp2-dev libldap-dev install_steps: rust rustls skiprun pytest - generate: -DCURL_USE_RUSTLS=ON -DUSE_ECH=ON -DENABLE_DEBUG=ON + configure: --with-rustls --enable-ech --enable-debug - name: 'IntelC openssl' install_packages: zlib1g-dev libssl-dev From 35a3b256f329cadd9248cca646cf82bf3d70b68c Mon Sep 17 00:00:00 2001 From: Viktor Szakats Date: Thu, 14 Aug 2025 20:28:14 +0200 Subject: [PATCH 02/18] GHA/linux: skip building examples in valgrind jobs To make these long jobs finish a little bit faster. 10s in total for 5 cmake jobs, 11s for 1 autotools job. Closes #18291 --- .github/workflows/linux.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 9c5248449b..b479b46e4c 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -706,7 +706,7 @@ jobs: ../.github/scripts/randcurl.pl 60 ../bld/src/curl - name: 'build examples' - if: ${{ matrix.build.make-custom-target != 'tidy' }} + if: ${{ !contains(matrix.build.install_packages, 'valgrind') && matrix.build.make-custom-target != 'tidy' }} run: | if [ "${MATRIX_BUILD}" = 'cmake' ]; then ${MATRIX_MAKE_PREFIX} cmake --build bld --verbose --target curl-examples-build From 9fc30567bf1a07bfe32df069a49bb7313fc1a73c Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 15 Aug 2025 09:29:47 +0200 Subject: [PATCH 03/18] RELEASE-NOTES: synced --- RELEASE-NOTES | 49 +++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 9aa5003d0a..ce492391b9 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -3,8 +3,8 @@ curl and libcurl 8.15.1 Public curl releases: 270 Command line options: 272 curl_easy_setopt() options: 308 - Public functions in libcurl: 97 - Contributors: 3486 + Public functions in libcurl: 98 + Contributors: 3488 This release includes the following changes: @@ -15,6 +15,7 @@ This release includes the following changes: o curl: make --retry-delay and --retry-max-time accept decimal seconds [112] o hostip: cache negative name resolves [175] o ip happy eyeballing: keep attempts running [80] + o mbedtls: bump minimum version required to 3.2.0 [180] o multi: add curl_multi_get_offt [56] o multi: add CURLMOPT_NETWORK_CHANGED to signal network changed [84] o netrc: use the NETRC environment variable (first) if set [70] @@ -22,6 +23,7 @@ This release includes the following changes: o tls: make default TLS version be minimum 1.2 [71] o tool_getparam: add support for `--longopt=value` [69] o vquic: drop msh3 [8] + o websocket: support CURLOPT_READFUNCTION [193] o writeout: add %time{} [74] This release includes the following bugfixes: @@ -50,6 +52,7 @@ This release includes the following bugfixes: o cmake: fix `ENABLE_UNIX_SOCKETS=OFF` with pre-fill enabled on unix o cmake: fix to disable Schannel and SSPI for non-Windows targets o cmake: fix to restrict `SystemConfiguration` to macOS [139] + o cmake: improve error message for invalid HTTP/3 MultiSSL configs [187] o cmake: keep websockets disabled if HTTP is disabled o cmake: make `runtests` targets build the curl tool [32] o cmake: make the ExternalProject test work [183] @@ -62,6 +65,7 @@ This release includes the following bugfixes: o connectdata: remove primary+secondary ip_quadruple [126] o connection: terminate after goaway [62] o contrithanks: fix for BSD `sed` tool [98] + o cookie: don't treat the leading slash as trailing [185] o curl-config: remove X prefix use [138] o curl/system.h: fix for GCC 3.3.x and older [38] o curl: make the URL indexes 64 bit [117] @@ -84,6 +88,7 @@ This release includes the following bugfixes: o CURLOPT: bump remaining macros to `long` [147] o CURLOPT: drop redundant `long` casts [55] o CURLOPT: replace `(long)` cast with `L` suffix for `CURLHSTS_*` macros + o CURLOPT_HTTP_VERSION: mention new default value [179] o delta: fix warnings, fix for non-GNU `date` tool [99] o DEPRECATE.md: drop support for Windows XP/2003 [31] o DEPRECATE.md: remove leftover "nothing" [57] @@ -94,6 +99,8 @@ This release includes the following bugfixes: o doh: rename symbols to avoid collision with mingw-w64 headers [66] o easy handle: check validity on external calls [28] o examples: drop long cast for `CURLALTSVC_*` + o examples: remove base64 encoded chunks from examples [189] + o examples: remove href_extractor.c [186] o gnutls: some small cleanups [41] o hmac: return error if init fails [2] o hostip: do DNS cache pruning in milliseconds [132] @@ -109,6 +116,7 @@ This release includes the following bugfixes: o libtests: update format strings to avoid casts, drop some macros [109] o libtests: use `FMT_SOCKET_T`, drop more casts [136] o managen: reset text mode at end of table marker [145] + o mbedtls: check for feature macros instead of version [166] o memanalyze: fix warnings [22] o memory: make function overrides work reliably in unity builds [93] o multi event: remove only announced [25] @@ -122,13 +130,17 @@ This release includes the following bugfixes: o openssl: check SSL_write() length on retries [152] o openssl: clear errors after a failed `d2i_X509()` [161] o openssl: output unescaped utf8 x509 issuer/subject DNs [169] + o openssl: save and restore OpenSSL error queue in two functions [172] o openssl: some small cleanups [42] o openssl: split cert_stuff into smaller sub functions [72] o parallel-max: bump the max value to 65535 [86] + o processhelp.pm: fix to use the correct null device on Windows [164] o pytest: add SOCKS tests and scoring [9] o pytest: increase server KeepAliveTimeout [26] o pytest: relax error check on test_07_22 [16] + o resolving: dns error tracing [196] o runtests: add `--ci` option, show `Env:` only when non-empty [134] + o runtests: assume `Time::HiRes`, drop Perl Win32 dependency [163] o schannel: add an error message for client cert not found [165] o schannel: assume `CERT_CHAIN_REVOCATION_CHECK_CHAIN` [114] o schannel: drop fallbacks for 4 macros [121] @@ -163,6 +175,7 @@ This release includes the following bugfixes: o tidy-up: move literal to the right side of comparisons [65] o tidy-up: prefer `ifdef`/`ifndef` for single checks [64] o tls: CURLINFO_TLS_SSL_PTR testing [79] + o TODO: remove session export item [194] o tool_cb_wrt: stop alloc/free for every chunk windows console output [140] o tool_operate: avoid superfluous strdup'ing output [1] o tool_operate: use the correct config pointer [115] @@ -171,6 +184,7 @@ This release includes the following bugfixes: o tool_urlglob: polish, cleanups, improvements [141] o unit-tests: build the unitprotos.h from here [73] o unit2604: avoid `UNCONST()` [135] + o URL-SYNTAX.md: drop link to codepoints.net to pass linkcheck [190] o urlapi: allow more path characters "raw" when asked to URL encode [146] o urldata: reduce two long struct fields to unsigned short [174] o vquic-tls: fix SSL backend type for QUIC connections using gnutls [29] @@ -210,16 +224,17 @@ advice from friends like these: adamse on github, Ahmad Gani, Alice Lee Poetics, Ammar Faizi, Anthony Hu, Berthin Torres Callañaupa, Caolán McNamara, Cole Leavitt, d1r3ct0r, - Dan Fandrich, Daniel Böhmer, Daniel Stenberg, David Zhuang, devgs on github, - Dominik Tomecki, Eshan Kelkar, Harry Sintonen, IoannisGS on github, - Jeroen Ooms, Kai Pastor, Karthik Das, kkmuffme on github, - letshack9707 on hackerone, lf- on github, LoRd_MuldeR, Michał Petryka, - nevakrien on github, Oxan van Leeuwen, Paul Gilmartin, Petar Popovic, - Philippe Antoine, Pino Toscano, Qriist, Qriist on github, Ray Satiro, - renovate[bot], rm-rmonaghan on github, Roberto Hidalgo, Schrijvers Luc, + Dan Fandrich, Daniel Böhmer, Daniel Engberg, Daniel Stenberg, David Zhuang, + devgs on github, Dominik Tomecki, Eshan Kelkar, Google Big Sleep, + Harry Sintonen, IoannisGS on github, Jelle Raaijmakers, Jeroen Ooms, + Kai Pastor, Karthik Das, kkmuffme on github, letshack9707 on hackerone, + lf- on github, LoRd_MuldeR, Michał Petryka, nevakrien on github, + Oxan van Leeuwen, Paul Gilmartin, Petar Popovic, Philippe Antoine, + Pino Toscano, Qriist, Qriist on github, Ray Satiro, renovate[bot], + rm-rmonaghan on github, Roberto Hidalgo, Samuel Henrique, Schrijvers Luc, Sergio Durigan Junior, Stefan Eissing, Tal Regev, Todd Gamblin, Viktor Szakats, Waldemar Kornewald, yaoy6 on github, ウさん - (47 contributors) + (51 contributors) References to bug reports and discussions on issues: @@ -383,13 +398,27 @@ References to bug reports and discussions on issues: [160] = https://curl.se/bug/?i=18177 [161] = https://curl.se/bug/?i=18190 [162] = https://curl.se/bug/?i=18230 + [163] = https://curl.se/bug/?i=18287 + [164] = https://curl.se/bug/?i=18282 [165] = https://curl.se/bug/?i=18124 + [166] = https://curl.se/bug/?i=18271 [168] = https://curl.se/bug/?i=18170 [169] = https://curl.se/bug/?i=18171 + [172] = https://curl.se/bug/?i=18190 [173] = https://curl.se/bug/?i=18123 [174] = https://curl.se/bug/?i=18173 [175] = https://curl.se/bug/?i=18157 [176] = https://curl.se/bug/?i=17974 [178] = https://curl.se/bug/?i=18216 + [179] = https://curl.se/bug/?i=18272 + [180] = https://curl.se/bug/?i=18254 [183] = https://curl.se/bug/?i=18208 [184] = https://curl.se/bug/?i=18206 + [185] = https://curl.se/bug/?i=18266 + [186] = https://curl.se/bug/?i=18264 + [187] = https://curl.se/bug/?i=18246 + [189] = https://curl.se/bug/?i=18260 + [190] = https://curl.se/bug/?i=18259 + [193] = https://curl.se/bug/?i=17683 + [194] = https://curl.se/bug/?i=18243 + [196] = https://curl.se/bug/?i=18247 From ecf12d44641d1211200d06391e8bb16bde008f93 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 14 Aug 2025 16:27:06 +0200 Subject: [PATCH 04/18] docs/examples: remove spurious trailing backslashes Unnecessary clutter Follow-up to d06b49d8b2d42d477f7e785960 Closes #18289 --- docs/examples/cacertinmem.c | 28 +++++++++---------- docs/examples/usercertinmem.c | 52 +++++++++++++++++------------------ 2 files changed, 40 insertions(+), 40 deletions(-) diff --git a/docs/examples/cacertinmem.c b/docs/examples/cacertinmem.c index 3a409dc5bd..9b39667aff 100644 --- a/docs/examples/cacertinmem.c +++ b/docs/examples/cacertinmem.c @@ -49,22 +49,22 @@ static CURLcode sslctx_function(CURL *curl, void *sslctx, void *pointer) /* replace the XXX with the actual CA certificates */ static const char mypem[] = "-----BEGIN CERTIFICATE-----\n" - "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ - "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ - "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ - "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ - "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ - "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ - "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" "-----END CERTIFICATE-----\n" "-----BEGIN CERTIFICATE-----\n" - "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ - "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ - "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ - "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ - "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ - "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ - "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" "-----END CERTIFICATE-----\n"; BIO *cbio = BIO_new_mem_buf(mypem, sizeof(mypem)); diff --git a/docs/examples/usercertinmem.c b/docs/examples/usercertinmem.c index 49722ca30f..536b65b490 100644 --- a/docs/examples/usercertinmem.c +++ b/docs/examples/usercertinmem.c @@ -61,36 +61,36 @@ static CURLcode sslctx_function(CURL *curl, void *sslctx, void *pointer) const char *mypem = /* replace the XXX with the actual CA certificate */ - "-----BEGIN CERTIFICATE-----\n"\ - "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ - "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ - "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ - "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ - "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ - "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ - "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ - "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ + "-----BEGIN CERTIFICATE-----\n" + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" "-----END CERTIFICATE-----\n"; /* replace the XXX with the actual RSA key */ const char *mykey = - "-----BEGIN RSA PRIVATE KEY-----\n"\ - "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ - "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ - "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ - "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ - "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ - "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ - "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ - "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ - "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ - "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ - "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ - "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ - "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ - "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ - "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ - "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\ + "-----BEGIN RSA PRIVATE KEY-----\n" + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" "-----END RSA PRIVATE KEY-----\n"; (void)curl; /* avoid warnings */ From b2294996b6fc59833e9fcfcef7f0790eb8da3572 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 12 Aug 2025 11:24:32 +0200 Subject: [PATCH 05/18] CURLOPT_SSL_CTX_*: replace the base64 with XXXX - they are fake anyway - these ones look more obvious fake and in need of replacement - avoids the risk that they might decode to something of value Closes #18261 --- docs/libcurl/opts/CURLOPT_SSL_CTX_DATA.md | 15 +++++++-------- docs/libcurl/opts/CURLOPT_SSL_CTX_FUNCTION.md | 15 +++++++-------- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/docs/libcurl/opts/CURLOPT_SSL_CTX_DATA.md b/docs/libcurl/opts/CURLOPT_SSL_CTX_DATA.md index 81edea682d..6dc81a0867 100644 --- a/docs/libcurl/opts/CURLOPT_SSL_CTX_DATA.md +++ b/docs/libcurl/opts/CURLOPT_SSL_CTX_DATA.md @@ -83,15 +83,14 @@ int main(void) { CURL *ch; CURLcode rv; - char *mypem = /* example CA cert PEM - shortened */ + char *mypem = /* CA cert in PEM format, replace the XXXs */ "-----BEGIN CERTIFICATE-----\n" - "MIIHPTCCBSWgAwIBAgIBADANBgkqhkiG9w0BAQQFADB5MRAwDgYDVQQKEwdSb290\n" - "IENBMR4wHAYDVQQLExVodHRwOi8vd3d3LmNhY2VydC5vcmcxIjAgBgNVBAMTGUNB\n" - "IENlcnQgU2lnbmluZyBBdXRob3JpdHkxITAfBgkqhkiG9w0BCQEWEnN1cHBvcnRA\n" - "Y2FjZXJ0Lm9yZzAeFw0wMzAzMzAxMjI5NDlaFw0zMzAzMjkxMjI5NDlaMHkxEDAO\n" - "GCSNe9FINSkYQKyTYOGWhlC0elnYjyELn8+CkcY7v2vcB5G5l1YjqrZslMZIBjzk\n" - "zk6q5PYvCdxTby78dOs6Y5nCpqyJvKeyRKANihDjbPIky/qbn3BHLt4Ui9SyIAmW\n" - "omTxJBzcoTWcFbLUvFUufQb1nA5V9FrWk9p2rSVzTMVD\n" + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" "-----END CERTIFICATE-----\n"; curl_global_init(CURL_GLOBAL_ALL); diff --git a/docs/libcurl/opts/CURLOPT_SSL_CTX_FUNCTION.md b/docs/libcurl/opts/CURLOPT_SSL_CTX_FUNCTION.md index ebf4c2ec3e..0c873f5d17 100644 --- a/docs/libcurl/opts/CURLOPT_SSL_CTX_FUNCTION.md +++ b/docs/libcurl/opts/CURLOPT_SSL_CTX_FUNCTION.md @@ -134,15 +134,14 @@ int main(void) { CURL *ch; CURLcode rv; - char *mypem = /* example CA cert PEM - shortened */ + char *mypem = /* CA cert in PEM format, replace the XXXs */ "-----BEGIN CERTIFICATE-----\n" - "MIIHPTCCBSWgAwIBAgIBADANBgkqhkiG9w0BAQQFADB5MRAwDgYDVQQKEwdSb290\n" - "IENBMR4wHAYDVQQLExVodHRwOi8vd3d3LmNhY2VydC5vcmcxIjAgBgNVBAMTGUNB\n" - "IENlcnQgU2lnbmluZyBBdXRob3JpdHkxITAfBgkqhkiG9w0BCQEWEnN1cHBvcnRA\n" - "Y2FjZXJ0Lm9yZzAeFw0wMzAzMzAxMjI5NDlaFw0zMzAzMjkxMjI5NDlaMHkxEDAO\n" - "GCSNe9FINSkYQKyTYOGWhlC0elnYjyELn8+CkcY7v2vcB5G5l1YjqrZslMZIBjzk\n" - "zk6q5PYvCdxTby78dOs6Y5nCpqyJvKeyRKANihDjbPIky/qbn3BHLt4Ui9SyIAmW\n" - "omTxJBzcoTWcFbLUvFUufQb1nA5V9FrWk9p2rSVzTMVD\n" + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" "-----END CERTIFICATE-----\n"; curl_global_init(CURL_GLOBAL_ALL); From c5f76b8096e05a73b0ecebf359b95703c5b8a2ab Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 15 Aug 2025 09:23:33 +0200 Subject: [PATCH 06/18] sendf: getting less data than "max allowed" is okay Easily triggered when doing an FTP ranged download with the end range larger than the file size. A regression since 30de937bda0 (shipped in curl 8.9.0) Add test 2307 to verify. Reported-by: kupavcevdenis on github Fixes #18283 Closes #18295 --- lib/sendf.c | 4 +-- tests/data/Makefile.am | 4 +-- tests/data/test2307 | 60 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 4 deletions(-) create mode 100644 tests/data/test2307 diff --git a/lib/sendf.c b/lib/sendf.c index 6bd4b1bfba..43b30ecc7f 100644 --- a/lib/sendf.c +++ b/lib/sendf.c @@ -293,9 +293,9 @@ static CURLcode cw_download_write(struct Curl_easy *data, } if((type & CLIENTWRITE_EOS) && !data->req.no_body && - (data->req.maxdownload > data->req.bytecount)) { + (data->req.size > data->req.bytecount)) { failf(data, "end of response with %" FMT_OFF_T " bytes missing", - data->req.maxdownload - data->req.bytecount); + data->req.size - data->req.bytecount); return CURLE_PARTIAL_FILE; } } diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am index 1c0258e17c..184a54e92e 100644 --- a/tests/data/Makefile.am +++ b/tests/data/Makefile.am @@ -256,8 +256,8 @@ test2100 test2101 test2102 test2103 test2104 \ \ test2200 test2201 test2202 test2203 test2204 test2205 \ \ -test2300 test2301 test2302 test2303 test2304 test2306 \ -test2308 test2309 \ +test2300 test2301 test2302 test2303 test2304 test2306 test2307 test2308 \ +test2309 \ \ test2400 test2401 test2402 test2403 test2404 test2405 test2406 \ \ diff --git a/tests/data/test2307 b/tests/data/test2307 new file mode 100644 index 0000000000..cbb581a4ab --- /dev/null +++ b/tests/data/test2307 @@ -0,0 +1,60 @@ + + + +FTP +EPSV +RETR +Range + + +# Server-side + + +0123456789abcdef +0123456789abcdef +0123456789abcdef +0123456789abcdef + + +0123456789abcdef +0123456789abcdef +0123456789abcdef +012345678 + + +64 + + + +# Client-side + + +ftp + + +FTP retrieve a byte-range with end larger than file + + +-r 4-1000 ftp://%HOSTIP:%FTPPORT/%TESTNUMBER + + + +# Verify data after the test has been "shot" + + +QUIT + + +USER anonymous +PASS ftp@example.com +PWD +EPSV +TYPE I +SIZE %TESTNUMBER +REST 4 +RETR %TESTNUMBER +ABOR +QUIT + + + From a5f0ab7995bbb6e269feb3a516f804a65c753705 Mon Sep 17 00:00:00 2001 From: Stefan Eissing Date: Thu, 14 Aug 2025 14:12:54 +0200 Subject: [PATCH 07/18] openssl: auto-pause on verify callback retry When an application install its own OpenSSL verify callback and that callback invokes `SSL_set_retry_verify()`, the transfer is automatically paused and does not progress the connect attempt any further until unpaused via `curl_easy_pause(). Added test758 to verify. Ref: #18284 Original PR by @Natris Bug: https://curl.se/mail/lib-2025-08/0012.html Closes #18288 --- docs/libcurl/opts/CURLOPT_SSL_CTX_FUNCTION.md | 4 +- lib/multi.c | 42 +- lib/vtls/openssl.c | 3 +- tests/data/Makefile.am | 2 +- tests/data/test758 | 53 ++ tests/libtest/Makefile.inc | 2 +- tests/libtest/lib758.c | 515 ++++++++++++++++++ 7 files changed, 599 insertions(+), 22 deletions(-) create mode 100644 tests/data/test758 create mode 100644 tests/libtest/lib758.c diff --git a/docs/libcurl/opts/CURLOPT_SSL_CTX_FUNCTION.md b/docs/libcurl/opts/CURLOPT_SSL_CTX_FUNCTION.md index 0c873f5d17..75e1dc8edb 100644 --- a/docs/libcurl/opts/CURLOPT_SSL_CTX_FUNCTION.md +++ b/docs/libcurl/opts/CURLOPT_SSL_CTX_FUNCTION.md @@ -60,7 +60,9 @@ callbacks to add additional validation code for certificates, and even to change the actual URI of an HTTPS request. For OpenSSL, asynchronous certificate verification via *SSL_set_retry_verify* -is supported. (Added in 8.3.0) +is supported. When *SSL_set_retry_verify* is set, the transfer is paused. +When verification should continue, call curl_easy_pause(3) to unpause +the transfer. (Added in 8.3.0, Pausing added in 8.16.0) The CURLOPT_SSL_CTX_FUNCTION(3) callback allows the application to reach in and modify SSL details in the connection without libcurl itself knowing diff --git a/lib/multi.c b/lib/multi.c index d38155cd9b..1c09b14b6b 100644 --- a/lib/multi.c +++ b/lib/multi.c @@ -1026,9 +1026,13 @@ CURLMcode Curl_multi_pollset(struct Curl_easy *data, case MSTATE_CONNECTING: case MSTATE_TUNNELING: - result = mstate_connecting_pollset(data, ps); - if(!result) - result = Curl_conn_adjust_pollset(data, data->conn, ps); + if(!Curl_xfer_recv_is_paused(data)) { + result = mstate_connecting_pollset(data, ps); + if(!result) + result = Curl_conn_adjust_pollset(data, data->conn, ps); + } + else + expect_sockets = FALSE; break; case MSTATE_PROTOCONNECT: @@ -2434,22 +2438,24 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, case MSTATE_CONNECTING: /* awaiting a completion of an asynch TCP connect */ DEBUGASSERT(data->conn); - result = Curl_conn_connect(data, FIRSTSOCKET, FALSE, &connected); - if(connected && !result) { - if(!data->conn->bits.reuse && - Curl_conn_is_multiplex(data->conn, FIRSTSOCKET)) { - /* new connection, can multiplex, wake pending handles */ - process_pending_handles(data->multi); + if(!Curl_xfer_recv_is_paused(data)) { + result = Curl_conn_connect(data, FIRSTSOCKET, FALSE, &connected); + if(connected && !result) { + if(!data->conn->bits.reuse && + Curl_conn_is_multiplex(data->conn, FIRSTSOCKET)) { + /* new connection, can multiplex, wake pending handles */ + process_pending_handles(data->multi); + } + rc = CURLM_CALL_MULTI_PERFORM; + multistate(data, MSTATE_PROTOCONNECT); + } + else if(result) { + /* failure detected */ + multi_posttransfer(data); + multi_done(data, result, TRUE); + stream_error = TRUE; + break; } - rc = CURLM_CALL_MULTI_PERFORM; - multistate(data, MSTATE_PROTOCONNECT); - } - else if(result) { - /* failure detected */ - multi_posttransfer(data); - multi_done(data, result, TRUE); - stream_error = TRUE; - break; } break; diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c index c4c2981108..e25c57304d 100644 --- a/lib/vtls/openssl.c +++ b/lib/vtls/openssl.c @@ -61,6 +61,7 @@ #include "../vauth/vauth.h" #include "keylog.h" #include "hostcheck.h" +#include "../transfer.h" #include "../multiif.h" #include "../curlx/strparse.h" #include "../strdup.h" @@ -4602,7 +4603,7 @@ static CURLcode ossl_connect_step2(struct Curl_cfilter *cf, #ifdef SSL_ERROR_WANT_RETRY_VERIFY if(SSL_ERROR_WANT_RETRY_VERIFY == detail) { CURL_TRC_CF(data, cf, "SSL_connect() -> want retry_verify"); - connssl->io_need = CURL_SSL_IO_NEED_RECV; + Curl_xfer_pause_recv(data, TRUE); return CURLE_AGAIN; } #endif diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am index 184a54e92e..950cb2544c 100644 --- a/tests/data/Makefile.am +++ b/tests/data/Makefile.am @@ -108,7 +108,7 @@ test718 test719 test720 test721 test722 test723 test724 test725 test726 \ test727 test728 test729 test730 test731 test732 test733 test734 test735 \ test736 test737 test738 test739 test740 test741 test742 test743 test744 \ test745 test746 test747 test748 test749 test750 test751 test752 test753 \ -test754 test755 test756 test757 \ +test754 test755 test756 test757 test758 \ test780 test781 test782 test783 test784 test785 test786 test787 test788 \ test789 test790 test791 test792 test793 test794 test796 test797 \ \ diff --git a/tests/data/test758 b/tests/data/test758 new file mode 100644 index 0000000000..a807ae9c85 --- /dev/null +++ b/tests/data/test758 @@ -0,0 +1,53 @@ + + + +multi +HTTPS + + + +# Server-side + + +HTTP/1.1 200 OK +Date: Tue, 09 Nov 2010 14:49:00 GMT +Server: test-server/fake +Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT +ETag: "21025-dc7-39462498" +Accept-Ranges: bytes +Content-Length: 6007 +Connection: close +Content-Type: text/html +Funny-head: yesyes + +-foo- +%repeat[1000 x foobar]% + + + + +OpenSSL + + +# Client-side + + +https + + +lib%TESTNUMBER + + +multi_socket interface transfer with callbacks returning error + + +https://localhost:%HTTPSPORT/file%TESTNUMBER + + + +# Verify data after the test has been "shot" + + + + + diff --git a/tests/libtest/Makefile.inc b/tests/libtest/Makefile.inc index 5e14621087..6f51040c1a 100644 --- a/tests/libtest/Makefile.inc +++ b/tests/libtest/Makefile.inc @@ -71,7 +71,7 @@ TESTS_C = \ lib661.c lib666.c lib667.c lib668.c \ lib670.c lib674.c lib676.c lib677.c lib678.c \ lib694.c lib695.c \ - lib751.c lib753.c \ + lib751.c lib753.c lib758.c \ lib757.c \ lib1156.c \ lib1301.c lib1308.c \ diff --git a/tests/libtest/lib758.c b/tests/libtest/lib758.c new file mode 100644 index 0000000000..dfcbaebb31 --- /dev/null +++ b/tests/libtest/lib758.c @@ -0,0 +1,515 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * SPDX-License-Identifier: curl + * + ***************************************************************************/ + +/* + * The purpose of this test is to make sure that if CURLMOPT_SOCKETFUNCTION or + * CURLMOPT_TIMERFUNCTION returns error, the associated transfer should be + * aborted correctly. + */ + +#include "first.h" + +#include "testtrace.h" +#include "memdebug.h" + +#ifdef USE_OPENSSL + +#include +#include + +#if ((OPENSSL_VERSION_NUMBER >= 0x30000000L) && \ + !defined(LIBRESSL_VERSION_NUMBER) && \ + !defined(OPENSSL_IS_BORINGSSL)) +#define T578_ENABLED +#endif +#endif + +#ifdef T578_ENABLED + +static struct t758_ctx { + int socket_calls; + int max_socket_calls; + int timer_calls; + int max_timer_calls; + int fake_async_cert_verification_pending; + int fake_async_cert_verification_finished; + int number_of_cert_verify_callbacks; + char buf[1024]; +} t758_ctx; + +static const char *t758_tag(void) +{ + curl_msnprintf(t758_ctx.buf, sizeof(t758_ctx.buf), + "[T758-%d-%d] [%d/%d]", + t758_ctx.max_socket_calls, t758_ctx.max_timer_calls, + t758_ctx.socket_calls, t758_ctx.timer_calls); + return t758_ctx.buf; +} + +static void t758_msg(const char *msg) +{ + curl_mfprintf(stderr, "%s %s\n", t758_tag(), msg); +} + + +struct t758_Sockets { + curl_socket_t *sockets; + int count; /* number of sockets actually stored in array */ + int max_count; /* max number of sockets that fit in allocated array */ +}; + +struct t758_ReadWriteSockets { + struct t758_Sockets read, write; +}; + +/** + * Remove a file descriptor from a sockets array. + */ +static void t758_removeFd(struct t758_Sockets *sockets, curl_socket_t fd, + int mention) +{ + int i; + + if(mention) + curl_mfprintf(stderr, "%s remove socket fd %" FMT_SOCKET_T "\n", + t758_tag(), fd); + + for(i = 0; i < sockets->count; ++i) { + if(sockets->sockets[i] == fd) { + if(i < sockets->count - 1) + memmove(&sockets->sockets[i], &sockets->sockets[i + 1], + sizeof(curl_socket_t) * (sockets->count - (i + 1))); + --sockets->count; + } + } +} + +/** + * Add a file descriptor to a sockets array. + * Return 0 on success, 1 on error. + */ +static int t758_addFd(struct t758_Sockets *sockets, curl_socket_t fd, + const char *what) +{ + /** + * To ensure we only have each file descriptor once, we remove it then add + * it again. + */ + curl_mfprintf(stderr, "%s add socket fd %" FMT_SOCKET_T " for %s\n", + t758_tag(), fd, what); + t758_removeFd(sockets, fd, 0); + /* + * Allocate array storage when required. + */ + if(!sockets->sockets) { + sockets->sockets = malloc(sizeof(curl_socket_t) * 20U); + if(!sockets->sockets) + return 1; + sockets->max_count = 20; + } + else if(sockets->count + 1 > sockets->max_count) { + curl_socket_t *ptr = realloc(sockets->sockets, sizeof(curl_socket_t) * + (sockets->max_count + 20)); + if(!ptr) + /* cleanup in test_cleanup */ + return 1; + sockets->sockets = ptr; + sockets->max_count += 20; + } + /* + * Add file descriptor to array. + */ + sockets->sockets[sockets->count] = fd; + ++sockets->count; + return 0; +} + +/** + * Callback invoked by curl to poll reading / writing of a socket. + */ +static int t758_curlSocketCallback(CURL *easy, curl_socket_t s, int action, + void *userp, void *socketp) +{ + struct t758_ReadWriteSockets *sockets = userp; + + (void)easy; + (void)socketp; + + t758_ctx.socket_calls++; + t758_msg("-> CURLMOPT_SOCKETFUNCTION"); + if(t758_ctx.socket_calls == t758_ctx.max_socket_calls) { + t758_msg("<- CURLMOPT_SOCKETFUNCTION returns error"); + return -1; + } + + if(action == CURL_POLL_IN || action == CURL_POLL_INOUT) + if(t758_addFd(&sockets->read, s, "read")) + return -1; /* bail out */ + + if(action == CURL_POLL_OUT || action == CURL_POLL_INOUT) + if(t758_addFd(&sockets->write, s, "write")) + return -1; + + if(action == CURL_POLL_REMOVE) { + t758_removeFd(&sockets->read, s, 1); + t758_removeFd(&sockets->write, s, 0); + } + + return 0; +} + +/** + * Callback invoked by curl to set a timeout. + */ +static int t758_curlTimerCallback(CURLM *multi, long timeout_ms, void *userp) +{ + struct curltime *timeout = userp; + + (void)multi; /* unused */ + t758_ctx.timer_calls++; + t758_msg("-> CURLMOPT_TIMERFUNCTION"); + if(t758_ctx.timer_calls == t758_ctx.max_timer_calls) { + t758_msg("<- CURLMOPT_TIMERFUNCTION returns error"); + return -1; + } + if(timeout_ms != -1) { + *timeout = curlx_now(); + timeout->tv_usec += (int)timeout_ms * 1000; + } + else { + timeout->tv_sec = -1; + } + return 0; +} + +static int t758_cert_verify_callback(X509_STORE_CTX *ctx, void *arg) +{ + SSL * ssl; + (void)arg; /* unused */ + ssl = (SSL *)X509_STORE_CTX_get_ex_data(ctx, + SSL_get_ex_data_X509_STORE_CTX_idx()); + t758_ctx.number_of_cert_verify_callbacks++; + if(!t758_ctx.fake_async_cert_verification_pending) { + t758_ctx.fake_async_cert_verification_pending = 1; + t758_msg(" initial t758_cert_verify_callback"); + return SSL_set_retry_verify(ssl); + } + else if(t758_ctx.fake_async_cert_verification_finished) { + t758_msg(" final t758_cert_verify_callback"); + return 1; /* success */ + } + else { + t758_msg(" pending t758_cert_verify_callback"); + return SSL_set_retry_verify(ssl); + } +} + +static CURLcode +t758_set_ssl_ctx_callback(CURL *curl, void *ssl_ctx, void *clientp) +{ + SSL_CTX *ctx = (SSL_CTX *) ssl_ctx; + (void)curl; /* unused */ + SSL_CTX_set_cert_verify_callback(ctx, t758_cert_verify_callback, clientp); + return CURLE_OK; +} + +/** + * Check for curl completion. + */ +static int t758_checkForCompletion(CURLM *curl, int *success) +{ + int result = 0; + *success = 0; + while(1) { + int numMessages; + CURLMsg *message = curl_multi_info_read(curl, &numMessages); + if(!message) + break; + if(message->msg == CURLMSG_DONE) { + result = 1; + if(message->data.result == CURLE_OK) + *success = 1; + else + *success = 0; + } + else { + curl_mfprintf(stderr, "%s got an unexpected message from curl: %i\n", + t758_tag(), message->msg); + result = 1; + *success = 0; + } + } + return result; +} + +static ssize_t t758_getMicroSecondTimeout(struct curltime *timeout) +{ + struct curltime now; + ssize_t result; + now = curlx_now(); + result = (ssize_t)((timeout->tv_sec - now.tv_sec) * 1000000 + + timeout->tv_usec - now.tv_usec); + if(result < 0) + result = 0; + + return result; +} + +/** + * Update a fd_set with all of the sockets in use. + */ +static void t758_updateFdSet(struct t758_Sockets *sockets, fd_set* fdset, + curl_socket_t *maxFd) +{ + int i; + for(i = 0; i < sockets->count; ++i) { +#ifdef __DJGPP__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Warith-conversion" +#endif + FD_SET(sockets->sockets[i], fdset); +#ifdef __DJGPP__ +#pragma GCC diagnostic pop +#endif + if(*maxFd < sockets->sockets[i] + 1) { + *maxFd = sockets->sockets[i] + 1; + } + } +} + +static CURLMcode t758_saction(CURLM *curl, curl_socket_t s, + int evBitmask, const char *info) +{ + int numhandles = 0; + CURLMcode result = curl_multi_socket_action(curl, s, evBitmask, &numhandles); + if(result != CURLM_OK) { + curl_mfprintf(stderr, "%s Curl error on %s (%i) %s\n", + t758_tag(), info, result, curl_multi_strerror(result)); + } + return result; +} + +/** + * Invoke curl when a file descriptor is set. + */ +static CURLMcode t758_checkFdSet(CURLM *curl, struct t758_Sockets *sockets, + fd_set *fdset, int evBitmask, + const char *name) +{ + int i; + CURLMcode result = CURLM_OK; + for(i = 0; i < sockets->count; ++i) { + if(FD_ISSET(sockets->sockets[i], fdset)) { + result = t758_saction(curl, sockets->sockets[i], evBitmask, name); + if(result) + break; + } + } + return result; +} + +static CURLcode t758_one(const char *URL, int timer_fail_at, + int socket_fail_at) +{ + CURLcode res = CURLE_OK; + CURL *curl = NULL; CURLM *m = NULL; + struct t758_ReadWriteSockets sockets = {{NULL, 0, 0}, {NULL, 0, 0}}; + int success = 0; + struct curltime timeout = {0}; + timeout.tv_sec = (time_t)-1; + + /* set the limits */ + memset(&t758_ctx, 0, sizeof(t758_ctx)); + t758_ctx.max_timer_calls = timer_fail_at; + t758_ctx.max_socket_calls = socket_fail_at; + + t758_msg("start"); + start_test_timing(); + + if(curl_global_sslset(CURLSSLBACKEND_OPENSSL, NULL, NULL) != CURLSSLSET_OK) { + t758_msg("could not set OpenSSL as backend"); + res = CURLE_FAILED_INIT; + return res; + } + + res_global_init(CURL_GLOBAL_ALL); + if(res != CURLE_OK) + return res; + + curl_global_trace("all"); + + + easy_init(curl); + debug_config.nohex = TRUE; + debug_config.tracetime = TRUE; + test_setopt(curl, CURLOPT_DEBUGDATA, &debug_config); + easy_setopt(curl, CURLOPT_DEBUGFUNCTION, libtest_debug_cb); + easy_setopt(curl, CURLOPT_VERBOSE, 1L); + + /* specify target */ + easy_setopt(curl, CURLOPT_URL, URL); + + /* go verbose */ + easy_setopt(curl, CURLOPT_VERBOSE, 1L); + + easy_setopt(curl, CURLOPT_SSL_CTX_FUNCTION, t758_set_ssl_ctx_callback); + + multi_init(m); + + multi_setopt(m, CURLMOPT_SOCKETFUNCTION, t758_curlSocketCallback); + multi_setopt(m, CURLMOPT_SOCKETDATA, &sockets); + + multi_setopt(m, CURLMOPT_TIMERFUNCTION, t758_curlTimerCallback); + multi_setopt(m, CURLMOPT_TIMERDATA, &timeout); + + multi_add_handle(m, curl); + + if(t758_saction(m, CURL_SOCKET_TIMEOUT, 0, "timeout")) { + res = TEST_ERR_MAJOR_BAD; + goto test_cleanup; + } + while(!t758_checkForCompletion(m, &success)) { + fd_set readSet, writeSet; + curl_socket_t maxFd = 0; + struct timeval tv = {0}; + tv.tv_sec = 10; + + if(t758_ctx.fake_async_cert_verification_pending && + !t758_ctx.fake_async_cert_verification_finished) { + if(sockets.read.count || sockets.write.count) { + t758_msg("during verification there should be no sockets scheduled"); + res = TEST_ERR_MAJOR_BAD; + goto test_cleanup; + } + if(t758_ctx.number_of_cert_verify_callbacks != 1) { + t758_msg("expecting exactly one cert verify callback here"); + res = TEST_ERR_MAJOR_BAD; + goto test_cleanup; + } + t758_ctx.fake_async_cert_verification_finished = 1; + if(t758_saction(m, CURL_SOCKET_TIMEOUT, 0, "timeout")) { + t758_msg("spurious retry cert action"); + res = TEST_ERR_MAJOR_BAD; + goto test_cleanup; + } + curl_easy_pause(curl, CURLPAUSE_CONT); + if(t758_saction(m, CURL_SOCKET_TIMEOUT, 0, "timeout")) { + t758_msg("unblocking transfer after cert verification finished"); + res = TEST_ERR_MAJOR_BAD; + goto test_cleanup; + } + if(t758_ctx.number_of_cert_verify_callbacks != 2) { + t758_msg("this should have triggered the callback again, right?"); + res = TEST_ERR_MAJOR_BAD; + goto test_cleanup; + } + t758_msg("TEST: all fine?"); + } + FD_ZERO(&readSet); + FD_ZERO(&writeSet); + t758_updateFdSet(&sockets.read, &readSet, &maxFd); + t758_updateFdSet(&sockets.write, &writeSet, &maxFd); + + if(timeout.tv_sec != (time_t)-1) { + int usTimeout = curlx_sztosi(t758_getMicroSecondTimeout(&timeout)); + tv.tv_sec = usTimeout / 1000000; + tv.tv_usec = usTimeout % 1000000; + } + else if(maxFd <= 0) { + tv.tv_sec = 0; + tv.tv_usec = 100000; + } + + select_test((int)maxFd, &readSet, &writeSet, NULL, &tv); + + /* Check the sockets for reading / writing */ + if(t758_checkFdSet(m, &sockets.read, &readSet, CURL_CSELECT_IN, + "read")) { + res = TEST_ERR_MAJOR_BAD; + goto test_cleanup; + } + if(t758_checkFdSet(m, &sockets.write, &writeSet, CURL_CSELECT_OUT, + "write")) { + res = TEST_ERR_MAJOR_BAD; + goto test_cleanup; + } + + if(timeout.tv_sec != (time_t)-1 && + t758_getMicroSecondTimeout(&timeout) == 0) { + /* Curl's timer has elapsed. */ + if(t758_saction(m, CURL_SOCKET_TIMEOUT, 0, "timeout")) { + res = TEST_ERR_BAD_TIMEOUT; + goto test_cleanup; + } + } + + abort_on_test_timeout(); + } + if(success && t758_ctx.number_of_cert_verify_callbacks != 2) { + t758_msg("unexpected invocations of cert verify callback"); + res = TEST_ERR_MAJOR_BAD; + goto test_cleanup; + } + + if(!success) { + t758_msg("Error getting file."); + res = TEST_ERR_MAJOR_BAD; + } + +test_cleanup: + + /* proper cleanup sequence */ + t758_msg("cleanup"); + curl_multi_remove_handle(m, curl); + curl_easy_cleanup(curl); + curl_multi_cleanup(m); + curl_global_cleanup(); + + /* free local memory */ + free(sockets.read.sockets); + free(sockets.write.sockets); + t758_msg("done"); + + return res; +} + +static CURLcode test_lib758(const char *URL) +{ + CURLcode rc; + /* rerun the same transfer multiple times and make it fail in different + callback calls */ + rc = t758_one(URL, 0, 0); /* no callback fails */ + if(rc) + curl_mfprintf(stderr, "%s FAILED: %d\n", t758_tag(), rc); + + return rc; +} + +#else /* T578_ENABLED */ +static CURLcode test_lib758(const char *URL) +{ + (void)URL; + return CURLE_OK; +} +#endif From de89b86046ee8030c042cb1c01799c262ef47606 Mon Sep 17 00:00:00 2001 From: xfangfang <2553041586@qq.com> Date: Sat, 16 Aug 2025 18:15:42 +0800 Subject: [PATCH 08/18] cookie: remove expired cookies before listing Closes #18299 --- lib/cookie.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/cookie.c b/lib/cookie.c index b72dd99bce..99b5e43d64 100644 --- a/lib/cookie.c +++ b/lib/cookie.c @@ -1615,6 +1615,9 @@ static struct curl_slist *cookie_list(struct Curl_easy *data) if(!data->cookies || (data->cookies->numcookies == 0)) return NULL; + /* at first, remove expired cookies */ + remove_expired(data->cookies); + for(i = 0; i < COOKIE_HASH_SIZE; i++) { for(n = Curl_llist_head(&data->cookies->cookielist[i]); n; n = Curl_node_next(n)) { From 0ba8e7f9db9adf21f1550e72754ce1c65e40a2cd Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 17 Aug 2025 22:24:10 +0200 Subject: [PATCH 09/18] test1549: verify CURLOPT_COOKIEFILE after expired cookies Verifies #18299 (de89b86046ee) Closes #18303 --- tests/data/Makefile.am | 10 ++--- tests/data/test1549 | 59 +++++++++++++++++++++++++++++ tests/libtest/Makefile.inc | 2 +- tests/libtest/lib1549.c | 76 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 141 insertions(+), 6 deletions(-) create mode 100644 tests/data/test1549 create mode 100644 tests/libtest/lib1549.c diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am index 950cb2544c..71fc94860d 100644 --- a/tests/data/Makefile.am +++ b/tests/data/Makefile.am @@ -203,11 +203,11 @@ test1516 test1517 test1518 test1519 test1520 test1521 test1522 test1523 \ test1524 test1525 test1526 test1527 test1528 test1529 test1530 test1531 \ test1532 test1533 test1534 test1535 test1536 test1537 test1538 test1539 \ test1540 test1541 test1542 test1543 test1544 test1545 test1546 test1547 \ -test1548 \ -test1550 test1551 test1552 test1553 test1554 test1555 test1556 test1557 \ -test1558 test1559 test1560 test1561 test1562 test1563 test1564 test1565 \ -test1566 test1567 test1568 test1569 test1570 test1571 test1572 test1573 \ -test1574 test1575 test1576 test1577 test1578 test1579 test1580 test1581 \ +test1548 test1549 test1550 test1551 test1552 test1553 test1554 test1555 \ +test1556 test1557 test1558 test1559 test1560 test1561 test1562 test1563 \ +test1564 test1565 test1566 test1567 test1568 test1569 test1570 test1571 \ +test1572 test1573 test1574 test1575 test1576 test1577 test1578 test1579 \ +test1580 test1581 \ \ test1590 test1591 test1592 test1593 test1594 test1595 test1596 test1597 \ test1598 test1599 test1600 test1601 test1602 test1603 test1604 test1605 \ diff --git a/tests/data/test1549 b/tests/data/test1549 new file mode 100644 index 0000000000..bc821e5eba --- /dev/null +++ b/tests/data/test1549 @@ -0,0 +1,59 @@ + + + +HTTP +cookies + + + +# +# Server-side + + +HTTP/1.1 200 OK +Content-Length: 6 +Content-Type: text/plain +Set-Cookie: c1=123; Path=/; Expires=Thu, 12 Feb 2000 00:00:00 GMT +Set-Cookie: c2=456; Path=/; Expires=Thu, 12 Feb 2000 00:00:00 GMT; + +hello + + + +# +# Client-side + + +http + + +http +cookies + + +Receive expired cookies and CURLINFO_COOKIELIST + + +lib%TESTNUMBER + + +http://%HOSTIP:%HTTPPORT/%TESTNUMBER + + + +# +# Verify data after the test has been "shot" + + +GET /%TESTNUMBER HTTP/1.1 +Host: %HOSTIP:%HTTPPORT +Accept: */* + + + +URL: http://%HOSTIP:%HTTPPORT/%TESTNUMBER +0 cookies +Test ended with result 0 + + + diff --git a/tests/libtest/Makefile.inc b/tests/libtest/Makefile.inc index 6f51040c1a..40ec0d1559 100644 --- a/tests/libtest/Makefile.inc +++ b/tests/libtest/Makefile.inc @@ -82,7 +82,7 @@ TESTS_C = \ lib1522.c lib1523.c lib1525.c lib1526.c lib1527.c lib1528.c \ lib1529.c lib1530.c lib1531.c lib1532.c lib1533.c lib1534.c lib1535.c \ lib1536.c lib1537.c lib1538.c lib1540.c lib1541.c lib1542.c \ - lib1545.c lib1550.c lib1551.c \ + lib1545.c lib1549.c lib1550.c lib1551.c \ lib1552.c lib1553.c lib1554.c lib1555.c lib1556.c lib1557.c lib1558.c \ lib1559.c lib1560.c lib1564.c lib1565.c \ lib1567.c lib1568.c lib1569.c lib1571.c \ diff --git a/tests/libtest/lib1549.c b/tests/libtest/lib1549.c new file mode 100644 index 0000000000..b7bf010612 --- /dev/null +++ b/tests/libtest/lib1549.c @@ -0,0 +1,76 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * SPDX-License-Identifier: curl + * + ***************************************************************************/ +#include "first.h" + +#include "testtrace.h" +#include "memdebug.h" + +static CURLcode test_lib1549(const char *URL) +{ + CURLcode res; + CURL *curl; + + if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { + curl_mfprintf(stderr, "curl_global_init() failed\n"); + return TEST_ERR_MAJOR_BAD; + } + + curl = curl_easy_init(); + if(!curl) { + curl_mfprintf(stderr, "curl_easy_init() failed\n"); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + test_setopt(curl, CURLOPT_URL, URL); + test_setopt(curl, CURLOPT_HEADER, 1L); + test_setopt(curl, CURLOPT_COOKIEFILE, ""); + + res = curl_easy_perform(curl); + + if(!res) { + /* extract all known cookies */ + struct curl_slist *cookies = NULL; + int num = 0; + res = curl_easy_getinfo(curl, CURLINFO_COOKIELIST, &cookies); + if(!res && cookies) { + /* a linked list of cookies in cookie file format */ + struct curl_slist *each = cookies; + while(each) { + printf("%s\n", each->data); + each = each->next; + num++; + } + /* we must free these cookies when we are done */ + curl_slist_free_all(cookies); + } + fprintf(stderr, "%d cookies\n", num); + } +test_cleanup: + + curl_easy_cleanup(curl); + curl_global_cleanup(); + + return res; +} From 435069fcd94d5706919fe7a8967bb4f0fe769acb Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 17 Aug 2025 22:56:48 +0200 Subject: [PATCH 10/18] RELEASE-NOTES: synced --- RELEASE-NOTES | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/RELEASE-NOTES b/RELEASE-NOTES index ce492391b9..770daed1de 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -4,7 +4,7 @@ curl and libcurl 8.15.1 Command line options: 272 curl_easy_setopt() options: 308 Public functions in libcurl: 98 - Contributors: 3488 + Contributors: 3490 This release includes the following changes: @@ -66,6 +66,7 @@ This release includes the following bugfixes: o connection: terminate after goaway [62] o contrithanks: fix for BSD `sed` tool [98] o cookie: don't treat the leading slash as trailing [185] + o cookie: remove expired cookies before listing [158] o curl-config: remove X prefix use [138] o curl/system.h: fix for GCC 3.3.x and older [38] o curl: make the URL indexes 64 bit [117] @@ -89,6 +90,7 @@ This release includes the following bugfixes: o CURLOPT: drop redundant `long` casts [55] o CURLOPT: replace `(long)` cast with `L` suffix for `CURLHSTS_*` macros o CURLOPT_HTTP_VERSION: mention new default value [179] + o CURLOPT_SSL_CTX_*: replace the base64 with XXXX [171] o delta: fix warnings, fix for non-GNU `date` tool [99] o DEPRECATE.md: drop support for Windows XP/2003 [31] o DEPRECATE.md: remove leftover "nothing" [57] @@ -127,6 +129,7 @@ This release includes the following bugfixes: o multi: replace remaining EXPIRE_RUN_NOW [67] o multissl: initialize when requesting a random number [30] o ngtcp2: extend callback tables for nghttp3 1.11.0 and ngtcp2 1.14.0 [47] + o openssl: auto-pause on verify callback retry [167] o openssl: check SSL_write() length on retries [152] o openssl: clear errors after a failed `d2i_X509()` [161] o openssl: output unescaped utf8 x509 issuer/subject DNs [169] @@ -151,6 +154,7 @@ This release includes the following bugfixes: o schannel: use if(result) like the code style says [125] o scripts: enable strict warnings in Perl where missing, fix fallouts [63] o scripts: fix two Perl uninitialized value warnings [60] + o sendf: getting less data than "max allowed" is okay [170] o servers: convert two macros to scoped static const strings [89] o setopt: refactor out the booleans from setopt_long to setopt_bool [83] o setopt: split out cookielist() and cookiefile() [130] @@ -227,14 +231,15 @@ advice from friends like these: Dan Fandrich, Daniel Böhmer, Daniel Engberg, Daniel Stenberg, David Zhuang, devgs on github, Dominik Tomecki, Eshan Kelkar, Google Big Sleep, Harry Sintonen, IoannisGS on github, Jelle Raaijmakers, Jeroen Ooms, - Kai Pastor, Karthik Das, kkmuffme on github, letshack9707 on hackerone, - lf- on github, LoRd_MuldeR, Michał Petryka, nevakrien on github, - Oxan van Leeuwen, Paul Gilmartin, Petar Popovic, Philippe Antoine, - Pino Toscano, Qriist, Qriist on github, Ray Satiro, renovate[bot], - rm-rmonaghan on github, Roberto Hidalgo, Samuel Henrique, Schrijvers Luc, - Sergio Durigan Junior, Stefan Eissing, Tal Regev, Todd Gamblin, - Viktor Szakats, Waldemar Kornewald, yaoy6 on github, ウさん - (51 contributors) + Kai Pastor, Karthik Das, kkmuffme on github, kupavcevdenis on github, + letshack9707 on hackerone, lf- on github, LoRd_MuldeR, Michał Petryka, + nevakrien on github, Oxan van Leeuwen, Paul Gilmartin, Petar Popovic, + Philippe Antoine, Pino Toscano, Qriist, Qriist on github, Ray Satiro, + renovate[bot], rm-rmonaghan on github, Roberto Hidalgo, Samuel Henrique, + Schrijvers Luc, Sergio Durigan Junior, Stefan Eissing, Tal Regev, + Todd Gamblin, Viktor Szakats, Waldemar Kornewald, xfangfang, yaoy6 on github, + ウさん + (53 contributors) References to bug reports and discussions on issues: @@ -394,6 +399,7 @@ References to bug reports and discussions on issues: [154] = https://curl.se/bug/?i=18241 [155] = https://curl.se/bug/?i=18238 [156] = https://curl.se/bug/?i=18195 + [158] = https://curl.se/bug/?i=18299 [159] = https://curl.se/bug/?i=18232 [160] = https://curl.se/bug/?i=18177 [161] = https://curl.se/bug/?i=18190 @@ -402,8 +408,11 @@ References to bug reports and discussions on issues: [164] = https://curl.se/bug/?i=18282 [165] = https://curl.se/bug/?i=18124 [166] = https://curl.se/bug/?i=18271 + [167] = https://curl.se/mail/lib-2025-08/0012.html [168] = https://curl.se/bug/?i=18170 [169] = https://curl.se/bug/?i=18171 + [170] = https://curl.se/bug/?i=18283 + [171] = https://curl.se/bug/?i=18261 [172] = https://curl.se/bug/?i=18190 [173] = https://curl.se/bug/?i=18123 [174] = https://curl.se/bug/?i=18173 From e4406860346b546cda6bcacd30d5db07c8efce0b Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 18 Aug 2025 09:32:21 +0200 Subject: [PATCH 11/18] ftp: use 'conn' instead of 'data->conn' In the ftp_state_use_port function, as we already use that local variable for all other conn accesses. Closes #18304 --- lib/ftp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ftp.c b/lib/ftp.c index f088054b2d..dde651a53e 100644 --- a/lib/ftp.c +++ b/lib/ftp.c @@ -1256,7 +1256,7 @@ out: !Curl_conn_is_ssl(conn, SECONDARYSOCKET)) { result = Curl_ssl_cfilter_add(data, conn, SECONDARYSOCKET); } - data->conn->bits.do_more = FALSE; + conn->bits.do_more = FALSE; Curl_pgrsTime(data, TIMER_STARTACCEPT); Curl_expire(data, (data->set.accepttimeout > 0) ? data->set.accepttimeout: DEFAULT_ACCEPT_TIMEOUT, From 294ebba56588754f226c8ab49e85dd457b5a1df4 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 18 Aug 2025 09:41:00 +0200 Subject: [PATCH 12/18] bufq: simplify condition 'result' is always CURLE_AGAIN here Pointed out by CodeSonar Closes #18305 --- lib/bufq.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/bufq.c b/lib/bufq.c index 9919707b4c..c97640a63c 100644 --- a/lib/bufq.c +++ b/lib/bufq.c @@ -537,7 +537,8 @@ CURLcode Curl_bufq_write_pass(struct bufq *q, if(result != CURLE_AGAIN) /* real error, fail */ return result; - if((result == CURLE_AGAIN) && *pwritten) + /* result == CURLE_AGAIN */ + if(*pwritten) /* we did write successfully before */ result = CURLE_OK; return result; From a19bd4321030c6ea18e3bbec411dfd49961a1f71 Mon Sep 17 00:00:00 2001 From: Viktor Szakats Date: Mon, 18 Aug 2025 10:19:45 +0200 Subject: [PATCH 13/18] cmake: honor `CMAKE_C_FLAGS` in test 1119 and 1167 `CMAKE_C_FLAGS` is not set by curl, but may contain custom options required for a successful compiler run, when invoked by these tests. One such case is when configuring Visual Studio or clang-cl via compiler options, instead of envs. Cherry-picked from #18301 Closes #18307 --- tests/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 014fe0db87..0593b513ee 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -104,6 +104,7 @@ if(MSVC OR CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Cl if(APPLE AND CMAKE_OSX_SYSROOT) string(APPEND CURL_CPP " -isysroot ${CMAKE_OSX_SYSROOT}") endif() + string(APPEND CURL_CPP " ${CMAKE_C_FLAGS}") # Add header directories, like autotools builds do. get_property(_include_dirs TARGET ${LIB_SELECTED} PROPERTY INCLUDE_DIRECTORIES) foreach(_include_dir IN LISTS _include_dirs) From 11bb681ce8f3c98ce17d1b07629f4b679af01ed3 Mon Sep 17 00:00:00 2001 From: Viktor Szakats Date: Mon, 18 Aug 2025 11:18:09 +0200 Subject: [PATCH 14/18] GHA/windows: tidy up running find in two build steps Cherry-picked from #18301 --- .github/workflows/windows.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index f6d029ddb0..796534c014 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -551,7 +551,7 @@ jobs: - name: 'curl version' timeout-minutes: 1 run: | - PATH=/usr/bin find . \( -name '*.exe' -o -name '*.dll' -o -name '*.a' \) -exec file '{}' \; + /usr/bin/find . \( -name '*.exe' -o -name '*.dll' -o -name '*.a' \) -exec file '{}' \; PATH="$PWD/bld/lib:$PATH" bld/src/curl.exe --disable --version @@ -871,7 +871,7 @@ jobs: - name: 'curl version' timeout-minutes: 1 run: | - PATH=/usr/bin find . \( -name '*.exe' -o -name '*.dll' -o -name '*.lib' -o -name '*.pdb' \) -exec file '{}' \; + /usr/bin/find . \( -name '*.exe' -o -name '*.dll' -o -name '*.lib' -o -name '*.pdb' \) -exec file '{}' \; if [ "${MATRIX_PLAT}" != 'uwp' ]; then # Missing: ucrtbased.dll, VCRUNTIME140D.dll, VCRUNTIME140D_APP.dll PATH="$PWD/bld/lib/${MATRIX_TYPE}:$PATH" "bld/src/${MATRIX_TYPE}/curl.exe" --disable --version From fc4ae23cc22a12d283a291c5986270fef88b9120 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 18 Aug 2025 09:54:50 +0200 Subject: [PATCH 15/18] asyn-thrdd: fix Curl_async_pollset without socketpair - remove a superfluous if() - edit the #ifdef to only do the timeout checks when socketpair support is missing, as that code flow could not be reached otherways anyway CodeSonar pointed out possible issue that led me to see this. Closes #18306 --- lib/asyn-thrdd.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/lib/asyn-thrdd.c b/lib/asyn-thrdd.c index 509ec427a8..7884dc166a 100644 --- a/lib/asyn-thrdd.c +++ b/lib/asyn-thrdd.c @@ -655,12 +655,9 @@ CURLcode Curl_async_pollset(struct Curl_easy *data, struct easy_pollset *ps) return result; #ifndef CURL_DISABLE_SOCKETPAIR - if(thrdd->addr) { - /* return read fd to client for polling the DNS resolution status */ - result = Curl_pollset_add_in(data, ps, thrdd->addr->sock_pair[0]); - } - else -#endif + /* return read fd to client for polling the DNS resolution status */ + result = Curl_pollset_add_in(data, ps, thrdd->addr->sock_pair[0]); +#else { timediff_t milli; timediff_t ms = curlx_timediff(curlx_now(), thrdd->addr->start); @@ -674,7 +671,7 @@ CURLcode Curl_async_pollset(struct Curl_easy *data, struct easy_pollset *ps) milli = 200; Curl_expire(data, milli, EXPIRE_ASYNC_NAME); } - +#endif return result; } From 7dafe10db2f0b104317e6640670b4cd973a4e3da Mon Sep 17 00:00:00 2001 From: David Zhuang Date: Tue, 5 Aug 2025 17:45:06 -0700 Subject: [PATCH 16/18] ngtcp2: use custom mem funcs Pass curl's memory functions to the nghttp3 and ngtcp2 functions that allow them. This allows custom memory functions passed by the curl user to be used in nghttp3 and ngtcp2. Closes #18196 --- lib/vquic/curl_ngtcp2.c | 4 +-- lib/vquic/curl_osslq.c | 2 +- lib/vquic/vquic.c | 56 +++++++++++++++++++++++++++++++++++++++++ lib/vquic/vquic_int.h | 9 +++++++ 4 files changed, 68 insertions(+), 3 deletions(-) diff --git a/lib/vquic/curl_ngtcp2.c b/lib/vquic/curl_ngtcp2.c index 6467025137..575ebb9022 100644 --- a/lib/vquic/curl_ngtcp2.c +++ b/lib/vquic/curl_ngtcp2.c @@ -1212,7 +1212,7 @@ static CURLcode init_ngh3_conn(struct Curl_cfilter *cf, rc = nghttp3_conn_client_new(&ctx->h3conn, &ngh3_callbacks, &ctx->h3settings, - nghttp3_mem_default(), + Curl_nghttp3_mem(), cf); if(rc) { failf(data, "error creating nghttp3 connection instance"); @@ -2475,7 +2475,7 @@ static const struct alpn_spec ALPN_SPEC_H3 = { &ctx->connected_path, NGTCP2_PROTO_VER_V1, &ng_callbacks, &ctx->settings, &ctx->transport_params, - NULL, cf); + Curl_ngtcp2_mem(), cf); if(rc) return CURLE_QUIC_CONNECT_ERROR; diff --git a/lib/vquic/curl_osslq.c b/lib/vquic/curl_osslq.c index fa2c0a2899..3dd9753a72 100644 --- a/lib/vquic/curl_osslq.c +++ b/lib/vquic/curl_osslq.c @@ -1106,7 +1106,7 @@ static CURLcode cf_osslq_h3conn_init(struct cf_osslq_ctx *ctx, SSL *conn, rc = nghttp3_conn_client_new(&h3->conn, &ngh3_callbacks, &h3->settings, - nghttp3_mem_default(), + Curl_nghttp3_mem(), user_data); if(rc) { result = CURLE_OUT_OF_MEMORY; diff --git a/lib/vquic/vquic.c b/lib/vquic/vquic.c index f8ce34129b..43a2c95021 100644 --- a/lib/vquic/vquic.c +++ b/lib/vquic/vquic.c @@ -724,6 +724,62 @@ CURLcode Curl_conn_may_http3(struct Curl_easy *data, return CURLE_OK; } +#if defined(USE_NGTCP2) || defined(USE_NGHTTP3) + +static void *Curl_ngtcp2_malloc(size_t size, void *user_data) +{ + (void)user_data; + return Curl_cmalloc(size); +} + +static void Curl_ngtcp2_free(void *ptr, void *user_data) +{ + (void)user_data; + Curl_cfree(ptr); +} + +static void *Curl_ngtcp2_calloc(size_t nmemb, size_t size, void *user_data) +{ + (void)user_data; + return Curl_ccalloc(nmemb, size); +} + +static void *Curl_ngtcp2_realloc(void *ptr, size_t size, void *user_data) +{ + (void)user_data; + return Curl_crealloc(ptr, size); +} + +#ifdef USE_NGTCP2 +static struct ngtcp2_mem curl_ngtcp2_mem = { + NULL, + Curl_ngtcp2_malloc, + Curl_ngtcp2_free, + Curl_ngtcp2_calloc, + Curl_ngtcp2_realloc +}; +struct ngtcp2_mem *Curl_ngtcp2_mem(void) +{ + return &curl_ngtcp2_mem; +} +#endif + +#ifdef USE_NGHTTP3 +static struct nghttp3_mem curl_nghttp3_mem = { + NULL, + Curl_ngtcp2_malloc, + Curl_ngtcp2_free, + Curl_ngtcp2_calloc, + Curl_ngtcp2_realloc +}; +struct nghttp3_mem *Curl_nghttp3_mem(void) +{ + return &curl_nghttp3_mem; +} +#endif + +#endif /* USE_NGTCP2 || USE_NGHTTP3 */ + #else /* CURL_DISABLE_HTTP || !USE_HTTP3 */ CURLcode Curl_conn_may_http3(struct Curl_easy *data, diff --git a/lib/vquic/vquic_int.h b/lib/vquic/vquic_int.h index d271368d29..38189beb70 100644 --- a/lib/vquic/vquic_int.h +++ b/lib/vquic/vquic_int.h @@ -91,4 +91,13 @@ CURLcode vquic_recv_packets(struct Curl_cfilter *cf, #endif /* !USE_HTTP3 */ +#ifdef USE_NGTCP2 +struct ngtcp2_mem; +struct ngtcp2_mem *Curl_ngtcp2_mem(void); +#endif +#ifdef USE_NGHTTP3 +struct nghttp3_mem; +struct nghttp3_mem *Curl_nghttp3_mem(void); +#endif + #endif /* HEADER_CURL_VQUIC_QUIC_INT_H */ From a477789c4344d8231265d739f37787d026086333 Mon Sep 17 00:00:00 2001 From: Viktor Szakats Date: Sun, 17 Aug 2025 10:46:22 +0200 Subject: [PATCH 17/18] GHA/windows: switch from MSBuild to Ninja for MSVC jobs running tests This patch fixes flakiness caused by MSBuild scanning the runtests.pl output for regex patterns. When finding a hit, it returns an error code to cmake, making the build test CI step fail. This happens rarely after an earlier mitigation tweaking outputs, but, as expected, it did not resolve it completely. MSBuild doesn't have an option to disable this behavior. To fix, this patch migrates the two affected jobs from MSBuild to Ninja. To align with existing multi-config logic, it uses the `Ninja Multi-Config` generator, which hasn't been tested before in CI. Switching to Ninja was not trivial. Visual Studio to this day relies on an MS-DOS batch file stored at an unstable location (containing spaces and parenthesis), to initialize its environment. Without this env, `cl.exe` is unable to find its own components. GHA does not initialize it (even if it did, it could only default to a single specific target). CMake helps with this when using a Visual Studio generator, but doesn't when using Ninja. (On local machines the VS installer adds a couple of Start menu items for launching pre-configured command prompts.) Ref: https://learn.microsoft.com/cpp/build/building-on-the-command-line The MS-DOS batches don't integrate well with CI envs and even less so with shell scripts. To avoid it, this patch uses manual configuration. Also without using environment variables, to make it easy to use and easy to debug and trace in logs. Configuring Visual Studio is relatively stable across releases and hasn't changed a whole lot in the last 2 decades, but still may need more maintenance compared to llvm, or pretty much any other toolchain out there. On the upside, it allows to manually select compiler version, SDK version, cross-combinations, and allows choosing clang-cl. The configuration aims to find the latest of these automatically. Some traps that had to be avoided: - need to switch to MS-DOS short names to avoid spaces in the VS component paths. - need to switch to forward slashes to avoid confusing downstream tools with backslashes. - need to pass either MSYS2 for Windows-style path depending on setting. - need to use a trick to retrieve the oddly named `ProgramFiles(x86)` Windows env from shell script. - need to match VS version (2022) and edition (Enterprise), found on GHA runners. - need to pass the CMake generator via env so that the space in the name doesn't trip the shell when passed via a variable. - trash and unexpected dirs when detecting SDK/toolchain versions. - need to pass `-external:W0` to the C compiler to avoid MSVC warning: `D9007: '/external:I' requires '/external:W'; option ignored` - using cmake options only, to make it run without relying on envs and work out-of-the-box when running subsequent cmake sessions. - some others discovered while making work clang-cl locally in cross-builds. Ninja also improves performance in most cases (though wasn't a goal here). After this patch configure is significantly faster (1.5-2x), builds are a tiny bit faster, except examples which was twice as fast with MSBuild. Disk space use is 10% lower. MSBuild builds remain tested in AppVeyor CI and the UWP job. Before: https://github.com/curl/curl/actions/runs/17025737223/job/48260856051 After: https://github.com/curl/curl/actions/runs/17027981486/job/48266133301 Fixes: ``` === Start of file stderr1635 % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 100 4 100 4 0 0 449 0 --:--:-- --:--:-- --:--:-- 500 curl : (22) The requested URL returned error : 429 [D:\a\curl\curl\bld\tests\test-ci.vcxproj] CUSTOMBUILD : warning : Problem : HTTP error. Will retry in 1 second. 1 retry left. [D:\a\curl\curl\bld\tests\test-ci.vcxproj] [...] C:\Program Files\Microsoft Visual Studio\2022\Enterprise\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets(254,5): error MSB8066: Custom build for 'D:\a\curl\curl\bld\CMakeFiles\621f80ddbb0fa48179f056ca77842ff0\test-ci.rule;D:\a\curl\curl\tests\CMakeLists.txt' exited with code -1. [D:\a\curl\curl\bld\tests\test-ci.vcxproj] Error: Process completed with exit code 1. ``` Ref: https://github.com/curl/curl/actions/runs/16966304797/job/48091058271?pr=18287#step:13:3471 Bug: https://github.com/curl/curl/discussions/14854#discussioncomment-14104166 Ref: a19bd4321030c6ea18e3bbec411dfd49961a1f71 #18307 Follow-up to 9463769f2e2dba9eeff554a88e5df5195d2c774b #16583 Closes #18301 --- .github/workflows/windows.yml | 56 ++++++++++++++++++++++++++++++----- 1 file changed, 49 insertions(+), 7 deletions(-) diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 796534c014..af05bb92c8 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -821,16 +821,58 @@ jobs: [ -f "${MINGW_PREFIX}/include/zconf.h" ] && sed -i -E 's|(# +define +Z_HAVE_UNISTD_H)|/*\1*/|g' "${MINGW_PREFIX}/include/zconf.h" # Patch MSYS2 zconf.h for MSVC for _chkprefill in '' ${MATRIX_CHKPREFILL}; do options='' + cflags='' + rcflags='' + ldflags='' if [ "${MATRIX_PLAT}" = 'uwp' ]; then options+=' -DCMAKE_SYSTEM_NAME=WindowsStore -DCMAKE_SYSTEM_VERSION=10.0' - cflags='-DWINAPI_FAMILY=WINAPI_FAMILY_PC_APP' - ldflags='-OPT:NOREF -OPT:NOICF -APPCONTAINER:NO' + cflags+=' -DWINAPI_FAMILY=WINAPI_FAMILY_PC_APP' + ldflags+=' -OPT:NOREF -OPT:NOICF -APPCONTAINER:NO' vsglobals=';AppxPackage=false;WindowsAppContainer=false' fi - [ "${MATRIX_ARCH}" = 'arm64' ] && options+=' -A ARM64' - [ "${MATRIX_ARCH}" = 'x64' ] && options+=' -A x64' - [ "${MATRIX_ARCH}" = 'x86' ] && options+=' -A Win32' - [ "${TFLAGS}" = 'skiprun' ] && options+=' -D_CURL_SKIP_BUILD_CERTS=ON' + if [ "${TFLAGS}" = 'skiprun' ]; then + [ "${MATRIX_ARCH}" = 'arm64' ] && options+=' -A ARM64' + [ "${MATRIX_ARCH}" = 'x64' ] && options+=' -A x64' + [ "${MATRIX_ARCH}" = 'x86' ] && options+=' -A Win32' + options+=" -DCMAKE_VS_GLOBALS=TrackFileAccess=false${vsglobals}" + options+=' -D_CURL_SKIP_BUILD_CERTS=ON' + unset CMAKE_GENERATOR + else + # Use Ninja when running tests to avoid MSBuild heuristics picking + # up "error messages" in the test log output and making the job fail. + # Officially this requires the vcvarsall.bat MS-DOS batch file (as of + # VS2022). Since it integrates badly with CI steps and shell scripts + # scripts, reproduce the necessary build configuration manually, and + # without envs. + [[ "$(uname -s)" = *'ARM64'* ]] && MSVC_HOST='arm64' || MSVC_HOST='x64' # x86 + MSVC_ROOTD="$(cygpath --mixed --short-name "$PROGRAMFILES/Microsoft Visual Studio")" # to avoid spaces in directory names + MSVC_ROOTU="$(/usr/bin/find "$(cygpath --unix "$MSVC_ROOTD/2022/Enterprise/vc/tools/msvc")" -mindepth 1 -maxdepth 1 -type d -name '*.*' | sort | tail -n 1)" + MSVC_ROOTW="$(cygpath --mixed "$MSVC_ROOTU")" + MSVC_ROOTU="$(cygpath --unix "$MSVC_ROOTW")" + MSVC_BINU="$MSVC_ROOTU/bin/Host$MSVC_HOST/$MATRIX_ARCH" + MSDK_ROOTW="$(cygpath --mixed --short-name "$(printenv 'ProgramFiles(x86)')/Windows Kits")/10" + MSDK_ROOTU="$(cygpath --unix "$MSDK_ROOTW")" + MSDK_VER="$(basename "$(/usr/bin/find "$MSDK_ROOTU/lib" -mindepth 1 -maxdepth 1 -type d -name '*.*' | sort | tail -n 1)")" + MSDK_LIBW="$MSDK_ROOTW/lib/$MSDK_VER" + MSDK_INCW="$MSDK_ROOTW/include/$MSDK_VER" + MSDK_BINU="$MSDK_ROOTU/bin/$MSDK_VER/$MSVC_HOST" + cflags+=" -external:W0" + cflags+=" -external:I$MSVC_ROOTW/include" + cflags+=" -external:I$MSDK_INCW/shared" + cflags+=" -external:I$MSDK_INCW/ucrt" + cflags+=" -external:I$MSDK_INCW/um" + cflags+=" -external:I$MSDK_INCW/km" + rcflags+=" -I$MSDK_INCW/shared" + rcflags+=" -I$MSDK_INCW/um" + ldflags+=" -libpath:$MSVC_ROOTW/lib/$MATRIX_ARCH" + ldflags+=" -libpath:$MSDK_LIBW/ucrt/$MATRIX_ARCH" + ldflags+=" -libpath:$MSDK_LIBW/um/$MATRIX_ARCH" + ldflags+=" -libpath:$MSDK_LIBW/km/$MATRIX_ARCH" + options+=" -DCMAKE_RC_COMPILER=$MSDK_BINU/rc.exe" + options+=" -DCMAKE_MT=$MSDK_BINU/mt.exe" + options+=" -DCMAKE_C_COMPILER=$MSVC_BINU/cl.exe" + export CMAKE_GENERATOR='Ninja Multi-Config' # pass it via env to avoid space issues + fi [ "${_chkprefill}" = '_chkprefill' ] && options+=' -D_CURL_PREFILL=OFF' if [ -n "${MATRIX_INSTALL_VCPKG}" ]; then options+=" -DCMAKE_TOOLCHAIN_FILE=$VCPKG_INSTALLATION_ROOT/scripts/buildsystems/vcpkg.cmake" @@ -840,9 +882,9 @@ jobs: fi cmake -B "bld${_chkprefill}" ${options} \ -DCMAKE_C_FLAGS="${cflags}" \ + -DCMAKE_RC_FLAGS="${rcflags}" \ -DCMAKE_EXE_LINKER_FLAGS="-INCREMENTAL:NO ${ldflags}" \ -DCMAKE_SHARED_LINKER_FLAGS="-INCREMENTAL:NO ${ldflags}" \ - -DCMAKE_VS_GLOBALS="TrackFileAccess=false${vsglobals}" \ -DCMAKE_UNITY_BUILD=ON \ -DCURL_WERROR=ON \ -DLIBPSL_INCLUDE_DIR="${MINGW_PREFIX}/include" \ From 0ea1e50d00ec5ff5a5899f355eae86a20c2d7391 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 17 Aug 2025 11:31:33 +0000 Subject: [PATCH 18/18] GHA: update vmactions/omnios-vm digest to c31844c Closes #18302 --- .github/workflows/non-native.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/non-native.yml b/.github/workflows/non-native.yml index 91431c922b..c584803fd6 100644 --- a/.github/workflows/non-native.yml +++ b/.github/workflows/non-native.yml @@ -248,7 +248,7 @@ jobs: with: persist-credentials: false - name: 'autotools' - uses: vmactions/omnios-vm@8eba2a9217262f275d4566751a92d6ef2f433d00 # v1 + uses: vmactions/omnios-vm@c31844c7abe722cd7c97df82cab1f1fab1e5339f # v1 with: usesh: true # https://pkg.omnios.org/r151052/core/en/index.shtml