Viktor Szakats [Thu, 30 Jul 2026 12:20:59 +0000 (14:20 +0200)]
build: assume POSIX `select()` is available
This change effectively replaces an explicit compile-time #error with
a missing prototype error in environments not offering `select()`, and
saves curl-compatible systems from performing an explicit feature check.
Stefan Eissing [Wed, 29 Jul 2026 11:11:20 +0000 (13:11 +0200)]
apple-fast-udp: fix sendmsg_x partial results
When sending with sendmsg_x(), fix handling of last gso chunk being
smaller. Handle partial results correctly. Ignore SOCKEMSGSIZE by
reporting success which drops PMTUD probes into the void.
Viktor Szakats [Fri, 24 Jul 2026 22:11:21 +0000 (00:11 +0200)]
tidy-up: minor code fixes and improvements
- schannel: drop redundant parentheses.
- os400sys: drop redundant includes.
Follow-up to ebc5212dacd3db8f5315b5a2d676415848e936d5 #22374
- pytest: replace `()` with `[]` to match rest of tests.
- libtests: constify some local pointers.
- libtests: drop redundant `(long)` casts.
- lib650: use `CURL_CSTRLEN()`.
Follow-up to 59dc2bbe07c3b5889e0b380e5fa384d338d9d24e #22424
Viktor Szakats [Wed, 29 Jul 2026 21:30:51 +0000 (23:30 +0200)]
lib5004: fix memleak on OOM, check all slist append results (httpsig)
Detected by torture tests:
```
test 5004...[HTTP RFC 9421 B.2.6: Ed25519 POST with headers (RFC test vector)]
105 functions found, but only fail 25 (23.81%)
** MEMORY FAILURE
Leak detected: memory still allocated: 99 bytes
At 6000022c9408, there is 36 bytes.
allocated by /Users/runner/work/curl/curl/lib/slist.c:87
At 6000039c8e78, there is 31 bytes.
allocated by /Users/runner/work/curl/curl/lib/slist.c:87
At 6000037dd688, there is 16 bytes.
allocated by /Users/runner/work/curl/curl/lib/slist.c:62
At 6000037dd628, there is 16 bytes.
allocated by /Users/runner/work/curl/curl/lib/slist.c:62
LIMIT /Users/runner/work/curl/curl/lib/slist.c:62 malloc reached memlimit
5004: torture FAILED: function number 10 in test.
```
Ref: https://github.com/curl/curl/actions/runs/30497660391/job/90730128599?pr=22437#step:16:2331
Also:
- enable HTTPSIG in torture tests.
- NULL check all `curl_slist_append()` results.
- apply a NULL check to sibling test 5000 also.
Viktor Szakats [Thu, 30 Jul 2026 00:24:58 +0000 (02:24 +0200)]
build: fix HTTPSIG option for unsupported TLS backends
Show a warning and force-disable HTTPSIG when the TLS backend is not
OpenSSL or wolfSSL. Before this patch this resulted in a mismatched
feature list in configure and `curl -V`.
Also enable HTTPSIG in more CI jobs to cover unsupported ones, Windows
compilers, clang-tidy, cmake.
Viktor Szakats [Wed, 29 Jul 2026 23:46:15 +0000 (01:46 +0200)]
GHA: work around Homebrew `ca-certificates` install error
Working around:
```
==> Installing libngtcp2 dependency: ca-certificates
==> Pouring ca-certificates--2026-07-16.all.bottle.1.tar.gz
Warning: The post-install step did not complete successfully
[...]
Error: Process completed with exit code 1.
```
Dan Fandrich [Tue, 28 Jul 2026 23:27:38 +0000 (16:27 -0700)]
tests: fix cert comparison with old cryptography
The fallback path for cryptography < 42 was broken by commit e13362c2
that caused a comparison between offset-naive and offset-aware
datetimes. Use the positional form of tz in datetime.now() everywhere.
Viktor Szakats [Sat, 16 May 2026 10:08:00 +0000 (12:08 +0200)]
src: improve `curlx_memzero()` internal APIs
- delete zero-and-free wrapper macros. (not yet used)
To keep it simple.
- do NULL-check in `curlx_memzero()`.
To avoid noise at call sites.
- add `curlx_strzero()` for null-terminated strings, also with
NULL-check.
Stefan Eissing [Tue, 28 Jul 2026 12:27:13 +0000 (14:27 +0200)]
websocket: pause writing and meta data fix
When writing a decoded chunk of websocket data, always flush the writer
chain so that buffered data gets delivered before the ws meta data gets
updated.
Add client writer flags CURL_CW_FLAG_BLOWUP for writer types that may
significantly enlarge write sizes. This flag causes the pause writer to
be added and shrinks the write chunk sizes. We do not want that for
content decoders like WS that do not change the size.
Add test_20_13 to check that large frames are paused/unpaused correctly
with the matching meta data.
Fixes #22413 Reported-by: Hendrik Hübner
Closes #22416
Viktor Szakats [Wed, 15 Jul 2026 00:18:30 +0000 (02:18 +0200)]
scorecard: fix `max_upload` init value in `ul_parallel()`
"In `ul_parallel`, `max_parallel` is computed using
`self._download_parallel` instead of `self._upload_parallel`. This
causes the upload parallelism to incorrectly follow the download
parallel setting. It should use `self._upload_parallel` to be consistent
with how `uploads()` computes `max_parallel`."
Viktor Szakats [Wed, 15 Jul 2026 00:28:09 +0000 (02:28 +0200)]
dnsd: fix bounds check in `read_https_alpn_part()`
"The check `i > 256` permits `i == 256` to pass through. When `i` is
then cast to `uint8_t` in `blob_add(b, (uint8_t)i)`, the value wraps to
0, silently encoding a zero-length ALPN entry instead of rejecting it.
The condition should be `i > 255` (or equivalently `i >= 256`) to
correctly reject any length that does not fit in a single byte."
Dan Fandrich [Sat, 25 Jul 2026 20:34:38 +0000 (13:34 -0700)]
tests: target Python 3.8 as the minimum Python version
This version is already two releases out of support, but is "only" 7
years old so is probably still being used in the real world. Document
this version along with some other testing dependencies. Remove code
support for earlier versions. Disable ruff checks that need a newer
version.
Dan Fandrich [Sat, 25 Jul 2026 20:23:21 +0000 (13:23 -0700)]
tests: address mutable class vars and naive datetime in Python code
Mark Python mutable class variables with ClassVar, to denote that the
danger this can cause has been considered. Since any change made to
these in any object affects all other objects, this can cause locality
errors. However, as used in the test suite, they are are never modified
and so they are annotated as being intended.
Always set a timezone in datetime objects, as mixing naive and
timezone-aware object can cause errors.
Dan Fandrich [Sat, 25 Jul 2026 21:05:01 +0000 (14:05 -0700)]
tests: use simpler constructions in Python code
* call super() without arguments
* mark an unused variable as such
* simplify by using dict getter for default values
* use writelines() when possible
* use dedent to simplify some text formatting
* avoid items() on dict in a loop when unnecessary
* replace most Python format() calls with f-strings
* use capture_output in subprocess.run
Dan Fandrich [Sat, 25 Jul 2026 20:35:51 +0000 (13:35 -0700)]
tests: change whitespace and comments in Python test code
* remove an unneeded ruff warning disable
* remove coding: utf-8 from Python code; PEP 3120 makes UTF-8 the
default encoding
* remove unusable shebang lines from Python code
* remove empty print strings
* disable warnings when file objects are stored; these instances can't
be handled with context managers
* use more consistent whitespace in Python code, fixing flake8 warnings
* set the executable bit on scorecard.py, making it easier to run
These fix ruff rules EXE001, FURB105, UP009, SIM115.
Dan Fandrich [Sat, 25 Jul 2026 20:06:38 +0000 (13:06 -0700)]
tests: improve exception handling in Python test code
* Explicitly set "check" in subprocess.run() to raise an exception
automatically, where it was done manually before
* Use contextlib.suppress to ignore exceptions
* Use custom exceptions for test errors for clarity and flexibility.
* Replace IOError with OSError
Viktor Szakats [Wed, 22 Jul 2026 23:50:06 +0000 (01:50 +0200)]
tidy-up: use more `static`, `sizeof()`, `char[]`, double-const
- make `const` data `static`, where missing and possible.
- replace `strlen()` on literal or const strings with `sizeof()`.
While the latter is optimized by popular C compiler, e.g. MSVC only
does it with `/O2`.
- replace magic numbers with `sizeof()`, where missing.
- introduce `CURL_CSTRLEN()` macro for `sizeof(char[]) - 1`.
- use `CURL_CSTRLEN()` macro.
- move `const` before integer types, where missing.
- replace `char *var` with `var[]`, where missing and possible.
- use double const, where missing.
`static const char *` -> `static const char * const`.
- lib1514: constify pointers.
- unit3205: drop redundant cast, avoid another one.
- unit1666: map `OID()` macro to identical `STRCONST()`.
- Switch the Windows SSPI identity struct to SEC_WINNT_AUTH_IDENTITY_EX
to use !ntlm in PackageList to prevent NTLM from being offered.
- For GSS filter out NTLMSSP OID, and restrict via gss_set_neg_mechs()
to prevent NTLM from being offered.
- Extend the GSS-API debug stub layer to support the NTLM blocking logic
without a real Kerberos environment.
- Update test 2057 to check that negotiate auth is silently skipped with
no Authorization header when only NTLM stub credentials are available.
- Add SPNEGO NTLM blocking test 2093 which verifies that Kerberos
credentials still succeed when NTLM is blocked within SPNEGO.
- Suppress tests valgrind leak for MIT krb5 gss_display_status, since
the leak is in the library and not in curl.
To suppress the tests valgrind leak, the wildcard '...' bridges over an
anonymous frame inside libgssapi_krb5.so that valgrind reports as '???'.
Signed-off-by: Matthew John Cheetham <mjcheetham@outlook.com> Aided-by: Johannes Schindelin
Closes https://github.com/curl/curl/pull/21315
Closes https://github.com/curl/curl/pull/22410
Stefan Eissing [Mon, 27 Jul 2026 07:49:33 +0000 (09:49 +0200)]
conncache: conn upkeep/alive: move and enhance
- move `Curl_conn_seems_dead()` into conncache.c
- move `Curl_conn_upkeep()` into conncache.c
- when upkeep gives an error on a connection not in use,
terminate it
Viktor Szakats [Sun, 26 Jul 2026 14:57:51 +0000 (16:57 +0200)]
vquic: silence `-Wmissing-field-initializers` for nghttp3/ngtcp2 callback tables
To avoid a breakage in CI and curl-for-win builds on upstream updates
extending the callback lists. Each such breakage needed patching curl,
rolling these patches into curl-for-win, and doing it in near real-time,
to keep CI and builds working (and still causing some red CI jobs).
Bring calmness here by suppressing the warnings and allowing time to
extend the callback tables as/if needed and at a convenient moment.
Viktor Szakats [Sat, 25 Jul 2026 11:43:33 +0000 (13:43 +0200)]
runtests: fix `mode="warn"` tests passing unconditionally, fix test 1752
Fix test 1712 to pass curl C by setting `COLUMNS` to the highest
accepted value, and adjust expected results. To avoid envs with varying
lengths of `LOGDIR` affect the outcome.
Apply the same fix to test 459, though it wasn't affected in curl CI.
Also sync up test 433 `COLUMNS` value with these two tests for
consistency.
httpsig: add RFC 9421 HTTP Message Signatures support
Add support for signing outgoing HTTP requests per RFC 9421 using Ed25519 or HMAC-SHA256 algorithms.
New libcurl options:
- CURLOPT_HTTPSIG: signing algorithm ("ed25519" or "hmac-sha256")
- CURLOPT_HTTPSIG_KEY: path to hex-encoded key file
- CURLOPT_HTTPSIG_KEYID: key identifier for Signature-Input
- CURLOPT_HTTPSIG_HEADERS: space-separated components to sign
New CLI flags: --httpsig, --httpsig-key, --httpsig-keyid,
--httpsig-headers
The crypto layer follows the sha256.c multi-backend pattern with
implementations for OpenSSL (EVP_DigestSign) and wolfSSL
(wc_ed25519_sign_msg). HMAC-SHA256 uses the existing Curl_hmacit()
infrastructure which works on all backends.
Viktor Szakats [Sun, 28 Jun 2026 11:10:38 +0000 (13:10 +0200)]
tidy-up: drop redundant includes
`sys/types.h` and `sys/socket.h` (non-Win32). They are included via
`curl/curl.h` and `curl_setup.h`.
This drops `HAVE_SYS_TYPES_H` guards from the codebase. It's safe
because `sys/types.h` (POSIX) is already required unconditionally by
`curl/curl.h`. It remains used in feature checks by both autotools and
cmake; to be reviewed in a future step.
Viktor Szakats [Fri, 24 Jul 2026 18:26:01 +0000 (20:26 +0200)]
spacecheck: cap number of lines per file
To prevent merging large text files by accident.
Set the cap at 10k lines. The current line number top list is:
```
5577 configure.ac
5561 lib/vtls/openssl.c
5077 lib/http.c
4517 lib/ftp.c
4284 lib/multi.c
```
Stefan Eissing [Thu, 23 Jul 2026 12:17:13 +0000 (14:17 +0200)]
connect: connection close tweaks
- connclose/streamclose/connkeep() remove description string that was
never used anywhere. Add trace statements where reasons for closing
were not already traced and maybe not obvious.
- multi_remove_handle: only lookup former connection in pool when
transfer is set to connect only
- test1554: adapt expectations now that pool is less often locked
Stefan Eissing [Tue, 21 Jul 2026 11:28:59 +0000 (13:28 +0200)]
asyn-thrdd: retry link-local ipv6 if missing scope id
When the threaded resolver gets AAAA results that carry a link-local
address without scope-id, it now re-queues a query with AF_UNSPEC and
strips ipv4 addresses from that result. Whatever the resulting addresses
and scope-ids are, this becomes the result of the resolve.
Ross Burton [Thu, 23 Jul 2026 12:09:13 +0000 (13:09 +0100)]
configure: only check in the watt library if WATT_ROOT is set
Only look for gethostbyname in libwatt in $WATT_ROOT/lib if WATT_ROOT
has actually been set. This avoids configure trying to search in /lib,
which won't every succeed and can cause problems in cross builds which
check that host paths are not being searched.
Viktor Szakats [Fri, 10 Jul 2026 22:44:25 +0000 (00:44 +0200)]
tidy-up: miscellaneous
- CMake/CurlTests.c: sync indent with rest of file and most of code.
- cmake: sync term in `_CURL_PREFILL` description with rest of code.
- curl_setup.h: document function relying on `_CRT_SECURE_NO_WARNINGS`.
- tests/http/scorecard.py: typo in message.
- 'Quiche' -> 'quiche'.
- fix comment and formatting nits.
Stefan Eissing [Mon, 6 Jul 2026 10:59:45 +0000 (12:59 +0200)]
hardening: add API guards
Add call stacks to easy and multi instances. Record ongoing API calls
and callback invocations there to detect recursion and not allowed
invocations.
Define enums for easy, multi and callbacks in `api.h`. In `api.c` define
properties for these functions:
- can they recurse
- is the easy/multi handle destroyed during the call or should it be
good afterwards
- is the call allowed when a multi event callback is ongoing
- is the call allowed when a notification callback is ongoing
Entering a guard
- checks that passed CURL*/CURLM* are GOOD on entering
- checks that easy handle's `mid` is correct and it is known
for it in the multi.
- checks that call properties are obeyed (recursion, callback checks)
- checks that passed CURL*/CURLM* are GOOD on leaving, unless call is
known to kill it
Checks for ongoing callbacks inspect the whole call stack and catches
nested invocations (which our current flags can not).
Call stacks in easy/multi handle are fixed size and will deny recursion
when the limit is reached. The current limits are 7 for easy and 15 for
multi now.
Removes:
- multi->in_callback, check is done via call stack
- multi->in_ntfy_cb, check is done via call stack
The overhead in my tests seems minimal, if noticeable at all.