Daniel Stenberg [Tue, 17 Mar 2026 12:23:30 +0000 (13:23 +0100)]
strerr: correct the strerror_s() return code condition
In curlx_strerror on Windows, the condition checks `!strerror_s(...)`
(true on success) and therefore always evaluates the fallback block.
Even when strerror_s successfully produced a valid errno message.
Viktor Szakats [Fri, 13 Mar 2026 15:34:57 +0000 (16:34 +0100)]
configure: fix `--with-ngtcp2=<path>` option for crypto libs
ngtcp2 1.14.0 added module dependencies to `ngtcp2_crypto_*.pc` files.
This broke certain build cases in curl, because configure was is
querying pkg-config modules by setting `PKG_CONFIG_LIBDIR` to the
directory specified via `--with-*=` options, including `--with-ngtcp2=`.
Setting `PKG_CONFIG_LIBDIR` tells pkg-config (and pkgconf) to ignore
system locations. This caused that `ngtcp2_crypto_gnutls.pc` could no
longer find its indirect dependencies, if those were present at system
locations (where they typically are). Another fallout was BoringSSL,
because it does not provide `openssl.pc` on its own, and successful
detection relied on finding a non-BoringSSL copy, typically at a system
location (also fixed in ngtcp2 main branch).
Fix `ngtcp2_crypto_*` detections to not touch `PKG_CONFIG_LIBDIR` and
instead prepend `<path>` set via `--with-ngtcp2=` to `PKG_CONFIG_PATH`.
This ensures to pick up any dependent modules from system locations.
Note the side-effect is that potentially undesired modules may be
detected this way from system locations, i.e. it makes this particular
detection less "hermetic" than the rest used in curl configure.
(Configurations using a bare `--with-ngtcp2` with no path were not
affected, and served as a workaround before this patch. It remains a
valid way of configuration after.)
Both `pkgconf` and `pkg-config` use this logic to calculate their search
directory list:
```pseudo
search = {}
if PKG_CONFIG_PATH is set
search += PKG_CONFIG_PATH
endif
if PKG_CONFIG_LIBDIR is set (even if empty)
search += PKG_CONFIG_LIBDIR
else
search += built-in-pkg-config-dirs
endif
```
Refs:
https://github.com/curl/curl/pull/18028/commits (earlier attempt. Failed due to using `PKG_CONFIG_DIR` instead of the correct `PKG_CONFIG_PATH`)
https://github.com/curl/curl/pull/18028/commits/c0874ce8242d42a1ae1d570d6b70b8360da56482
https://man.archlinux.org/man/pkgconf.1.en
https://manpages.debian.org/unstable/pkgconf/pkgconf.1.en.html
https://manpages.debian.org/unstable/pkg-config/pkg-config.1.en.html
https://github.com/ngtcp2/ngtcp2/commit/10e27fd63cc7dd87236ab15de4a02eca6801e234
Flavio Amieiro [Wed, 4 Mar 2026 02:37:49 +0000 (23:37 -0300)]
curl_ctype.h: fix spelling in a couple of locally used macros
The `ISLOWHEXALHA` and `ISUPHEXALHA` macros were introduced in commit f65f750 and seem to be only referenced locally by the `ISXDIGIT` macro.
Judging by the `ISALPHA` macro defined in the same file, it seems like
the intention was to spell them as `IS.*HEXALPHA`.
I noticed this while reading through the code and decided to open a PR,
even if it is only a tiny change, just because I was already looking at
it and it might be useful. If there is any reason not to merge this,
please do close the PR.
Viktor Szakats [Mon, 16 Mar 2026 19:00:44 +0000 (20:00 +0100)]
HTTP3.md: minor improvements
- document building curl with CMake.
- mention all supported forks in the OpenSSL section. Delete dedicated
quictls section.
- add TLS-backend pkgconfig dir to `PKG_CONFIG_PATH` for correctness.
OpenSSL-based ones often work without this, by finding system
`openssl.pc`. For GnuTLS and wolfSSL this has a lesser chance. Best to
point to them explicitly. (configure may technically be able to do
this automatically, but it isn't implemented.)
- use `--with-ngtcp2=<path>` again, where possible.
GnuTLS is the exception, pending fix in #20910.
Same for BoringSSL, but not documented in `HTTP3.md`.
- replace `<somewhereN>` with `/path/to/depname` for clarity.
- move `LDFLAGS` after `./configure` for curl, to match dep builds.
- move `--with-ngtcp2` next to the TLS-backend option.
Viktor Szakats [Sun, 15 Mar 2026 14:07:35 +0000 (15:07 +0100)]
GHA/http3-linux: add CI reproducer for `--with-ngtcp2=<path>` regression
Configure LibreSSL autotools job with `--with-ngtcp=<path>` instead of
adding ngtcp2 to `PKG_CONFIG_PATH`. To test this way of configuration in
CI and test for the regression reported in #20889.
Turns out this way of configuration isn't affected by the detection
issue in this particular case.
It also works for other backends except for these two, subject to
separate fixes:
- BoringSSL fix: https://github.com/ngtcp2/ngtcp2/pull/2070
- GnuTLS fix and BoringSSL workaround: #20920
Viktor Szakats [Mon, 16 Mar 2026 12:36:17 +0000 (13:36 +0100)]
build: drop `openssl` module dependency for BoringSSL from `libcurl.pc`
BoringSSL does not provide pc files, as of v0.20260211.0 (and its latest
main branch.) It also did not provide them in the past.
Its sibling fork, AWS-LC does provide them since v1.18.0 (2023-12-04):
https://github.com/aws/aws-lc/commit/7e6aef83ecf7bec3a0c6d38e38c64ac079647c78
https://github.com/aws/aws-lc/pull/1310
Introduce internal variable `OPENSSL_IS_AWSLC` to make this possible.
Viktor Szakats [Mon, 16 Mar 2026 17:39:53 +0000 (18:39 +0100)]
curl-wolfssl.m4: fix to use the correct value for pkg-config directory
Before this patch the `$withval` variable may have contained `yes` or
other unrelated values, instead of the wolfSSL directory configured via
`--with-wolfssl=`.
Fixing:
```
checking for wolfssl options with pkg-config... found
configure: pkg-config --exists wolfssl trace:
---- begin
PKG_CONFIG_PATH: |/home/runner/wolfssl/build/lib/pkgconfig:/home/runner/nghttp3/build/lib/pkgconfig:/home/runner/ngtcp2/build/lib/pkgconfig:/home/runner/nghttp2/build/lib/pkgconfig|
PKG_CONFIG_LIBDIR: |yes/lib/pkgconfig| <=============== 'yes' used as base directory
trying path: /home/runner/wolfssl/build/lib/pkgconfig for wolfssl
---- end
```
Ref: https://github.com/curl/curl/actions/runs/23146424326/job/67235762794?pr=20920#step:18:245
Daniel Stenberg [Mon, 16 Mar 2026 13:51:52 +0000 (14:51 +0100)]
tool_cb_wrt: fix no-clobber error handling
When saving a file with --no-clobber, make sure the existing file name
remains set when creating the name fails. In a retry scenario, it comes
back and uses that variable again.
Viktor Szakats [Fri, 6 Mar 2026 14:43:59 +0000 (15:43 +0100)]
cmake: rework binutils ld hack to not read `LOCATION` property
Instead hook up the upstream target name as-is to the local wrapper
target.
To:
- make the hack work regardless of how the upstream target was created.
- make it work the same way in `curl-config.cmake`.
Before this patch it had no guard for `IMPORTED` targets even though
`find_dependencies()` is not guaranteed to create the target expected
if it already existed and was potentially created differently.
Viktor Szakats [Sat, 28 Feb 2026 23:54:09 +0000 (00:54 +0100)]
build: include curlx headers directly in src and tests
To include what's actually used.
Also:
- drop unused includes.
- scope includes where possible.
- drop `curlx/curlx.h` umbrella header.
- config2setopts: include `netinet/in.h` for Cygwin/MSYS2.
Previously included by chance via an unused curlx include.
Viktor Szakats [Thu, 5 Feb 2026 14:24:22 +0000 (15:24 +0100)]
mk-ca-bundle.pl: make generated timestamps deterministic
With default invocation, make generated file timestamps deterministic
by looking up (via the GitHub API) the last commit that modified
`certdata.txt`, along with its commit timestamp.
Also:
- show the URL used to download `certdata.txt` from.
- make `ca-bundle.crt` timestamp match `certdata.txt`'s.
Viktor Szakats [Fri, 6 Mar 2026 14:50:09 +0000 (15:50 +0100)]
cmake: resolve imported targets recursively when generating `libcurl.pc`
To allow simplifying the binutils ld hack, by chaining the original
imported target to curl's local duplicate target. Also to allow linking
to dependencies' native imported targets via their CMake Configs, which
will always be hooked up to a `CURL::` interface, and may also be
chained upstream.
Fixing (seen on Linux with simplified binutils hack via #20839):
```
Requires:
Requires.private: libzstd openssl zlib
Libs: -L${libdir} -lcurl
-Libs.private: -lcrypto -lssl -lz -lzstd
+Libs.private: -lOpenSSL::Crypto -lZLIB::ZLIB -lcrypto -lssl -lz -lzstd
Cflags: -I${includedir}
Cflags.private: -DCURL_STATICLIB
Error: Process completed with exit code
```
Ref: https://github.com/curl/curl/actions/runs/22768301699/job/66041980258?pr=20839
Note this makes it possible to run into an infinite loop because CMake
allows cyclic dependencies. It isn't added by curl's CMake script nor by
any dependencies as defined by default, but may happen in theory with
custom-created targets. In such case CMake automatically stops with
an error at 1000 iterations. I find it overkill to add custom protection
for it.
Cherry-picked from #20814
Cherry-picked from #20839
Viktor Szakats [Tue, 10 Mar 2026 00:03:13 +0000 (01:03 +0100)]
curl_get_line: fix potential infinite loop when filename is a directory
Fix potential inifinite loop reading file content with `Curl_get_line()`
when a filename passed via these options are pointing to a directory
entry (on non-Windows):
Fix by checking for this condition and silently skipping such filename
without attempting to read content. Add test 1713 to verify.
Mention in cookie documentation as an accepted case, also show a verbose
message when a directory is detected. Extend test 46 to verify if such
failure lets the logic continue to the next cookie file.
Viktor Szakats [Sun, 15 Mar 2026 14:07:35 +0000 (15:07 +0100)]
configure: add option to trace pkg-config detection details
To aid debugging cases when dependency detection acts unexpectedly.
Sprung from spending days trying to figure out behavior of ngtcp2 crypto
modules and their dependencies.
You can enable by setting env `CURL_TRACE_PKG_CONFIG` to a non-empty
value. When enabled, details are logged for both successful and
unsuccessful detections. Logging of unsuccessful ones is automatically
enabled when `CURL_CI` env is set, which is the case for all CI jobs.
It works by asking for `--debug` output and grepping for lines that seem
useful for this purpose. Output is different for classic pkg-config and
pkgconf, and may depending on tool version. Also append `--print-errors`
output if any.
Examples (with pkgconf):
Fail, before:
```
checking for libngtcp2_crypto_boringssl options with pkg-config... no
configure: error: --with-ngtcp2 was specified but could not find ngtcp2_crypto_boringssl pkg-config file.
```
Fail, after:
```
checking for libngtcp2_crypto_boringssl options with pkg-config... no
configure: pkg-config --exists libngtcp2_crypto_boringssl trace:
---- begin
trying path: /home/runner/nghttp3/build/lib/pkgconfig for libngtcp2_crypto_boringssl
trying path: /home/runner/ngtcp2-boringssl/build/lib/pkgconfig for libngtcp2_crypto_boringssl
trying path: /home/runner/nghttp3/build/lib/pkgconfig for libngtcp2
trying path: /home/runner/ngtcp2-boringssl/build/lib/pkgconfig for libngtcp2
trying path: /home/runner/nghttp3/build/lib/pkgconfig for openssl
trying path: /home/runner/ngtcp2-boringssl/build/lib/pkgconfig for openssl
trying path: /home/runner/nghttp2/build/lib/pkgconfig for openssl
==== error:
Package openssl was not found in the pkg-config search path.
Perhaps you should add the directory containing `openssl.pc'
to the PKG_CONFIG_PATH environment variable
Package 'openssl', required by 'libngtcp2_crypto_boringssl', not found
---- end
configure: error: --with-ngtcp2 was specified but could not find ngtcp2_crypto_boringssl pkg-config file.
```
Success, after:
```
checking for libngtcp2_crypto_boringssl options with pkg-config... found
configure: pkg-config --exists libngtcp2_crypto_boringssl trace:
---- begin
trying path: /home/runner/awslc/build/lib/pkgconfig for libngtcp2_crypto_boringssl
trying path: /home/runner/nghttp3/build/lib/pkgconfig for libngtcp2_crypto_boringssl
trying path: /home/runner/nghttp2/build/lib/pkgconfig for libngtcp2_crypto_boringssl
trying path: /home/runner/ngtcp2/build/lib/pkgconfig for libngtcp2_crypto_boringssl
trying path: /home/runner/awslc/build/lib/pkgconfig for libngtcp2
trying path: /home/runner/nghttp3/build/lib/pkgconfig for libngtcp2
trying path: /home/runner/nghttp2/build/lib/pkgconfig for libngtcp2
trying path: /home/runner/ngtcp2/build/lib/pkgconfig for libngtcp2
trying path: /home/runner/awslc/build/lib/pkgconfig for openssl
trying path: /home/runner/awslc/build/lib/pkgconfig for libssl
trying path: /home/runner/awslc/build/lib/pkgconfig for libcrypto
---- end
```
More examples:
https://github.com/curl/curl/pull/20926#issuecomment-4064259935
If there is an externally enablable, built-in feature like this in
classic pkg-config or pkgconf, I could not find it.
Also:
- GHA/http3-linux: set `CURL_TRACE_PKG_CONFIG` to log detection details.
H3 builds are prone to hard-to-debug dependency issues.
Stefan Eissing [Thu, 12 Mar 2026 12:11:38 +0000 (13:11 +0100)]
protocol source, all about protocols and uri schemes
Add protocol.h and protocol.c containing all about libcurl's
known URI schemes and their protocol handlers (so they exist).
Moves the scheme definitions from the various sources files into
protocol.c. Schemes are known and used, even of the protocol
handler is not build or just not implemented at all.
Stefan Eissing [Thu, 12 Mar 2026 10:18:32 +0000 (11:18 +0100)]
lib: keepon improving
Improve the name, type and handling of `data->req.keepon`:
- Rename `keepon` to `io_flags`
- make `io_flags` and `uint8_t` and reposition in struct
- Rename `KEEP_*` defines to `REQ_IO_*`, move to request.h
- Replace all direct bit tests to `CURL_REQ_WANT_*` use
- Replace all direct bit manipulations with new macros
Stefan Eissing [Fri, 13 Mar 2026 12:34:46 +0000 (13:34 +0100)]
urldata: import port types and conn destination format
Convert more `int port` to `uint16_t` port types. Reshuffle ports in
connectdata to save some bytes. Change `conn->destination` format to
- make it more readable and thus usable in tracing
- add the IPv6 scope_id only when not default (global)
and make it resemble more the textual format for IPv6
(e.g. suffix '%<scope_id>')
Stefan Eissing [Fri, 13 Mar 2026 13:29:13 +0000 (14:29 +0100)]
urldata: connection bit ipv6_ip is wrong
Eliminate `conn->bits.ipv6_ip`
The bit was only correct for the first transfer using a connection. Use
`data->state.up.hostname` instead in places that need the URL hostname
in its original form.
Fix parseurlandfillconn() to not modify `data->state.up.hostname` before
copying the connection's hostname, but modify the copy instead, leaving
the URL hostname intact.
Daniel Stenberg [Fri, 13 Mar 2026 09:29:05 +0000 (10:29 +0100)]
GHA: make typos ignore RELEASE-NOTES
The file is almost entirely made up by first-lines of previous git
commits, and we usually push it without a PR cycle, making it annoying
to trigger on typos later as they then show in independent PRs by other
people.
Daniel Stenberg [Thu, 12 Mar 2026 13:39:59 +0000 (14:39 +0100)]
badwords: only check comments and strings in source code
- when scanning source code, this now only checks source code comments
and double-quote strings. No more finding bad words as part of code
- this allows the full scan to be done in a single invocation
- detects source code or markdown by file name extension
- moved the whitelist words config into the single `badwords.txt` file,
no more having them separately (see top of file for syntax)
- all whitelisted words are checked case insensitively now
- removed support for whitelisting words on a specific line number. We
did not use it and it is too fragile
Removing the actual code from getting scanned made the script take an
additional 0.5 seconds on my machine.
Scanning 1525 files now takes a little under 1.7 seconds for me.
- tool_writeout: add comment saying silencing is a no-op for llvm/clang.
For `strftime()` it is a GCC-specific, as of llvm/clang v22.1.0.
Follow-up to f07a98ae113b832a8748ba66e1554a7f14c6897e #20366
- unit1652: drop always-false `!defined(__clang__)` guard. Pointed-out-by: Orgad Shaneh
Ref: #20902
Follow-up to 7e814c8717939393d4436d75f5f0c3ffa98c8c53 #16062
- a logic error made it not loop and thus only match if the searched string
was first
- it no longer matches a substring
Adjusted test 1 to use multiple values in the Connection: response
header. Adjusted test 1542 to have a "Connection: close-not" which
should not match.
Viktor Szakats [Wed, 11 Mar 2026 09:17:10 +0000 (10:17 +0100)]
badwords: rework exceptions, fix many of them
Also:
- support per-directory and per-upper-directory whitelist entries.
- convert badlist input grep tweak into the above format.
(except for 'And' which had just a few hits.)
- fix many code exceptions, but do not enforce.
(there also remain about 350 'will' uses in lib)
- fix badwords in example code, drop exceptions.
- badwords-all: convert to Perl.
To make it usable from CMake.
- FAQ: reword to not use 'will'. Drop exception.
Stefan Eissing [Wed, 11 Mar 2026 13:43:14 +0000 (14:43 +0100)]
pingpong: cleanup timeleft handling
- Move `RESP_TIMEOUT` from urldata.h to pingpong.h as
`PINGPONG_TIMEOUT_MS`.
- Rename `Curl_pp_state_timeout()` to `Curl_pp_state_timeleft_ms()` as
the function returns the time left, not the timout..
- Update implementation comments and variable names
Stefan Eissing [Wed, 11 Mar 2026 14:25:45 +0000 (15:25 +0100)]
connection_check, simplified
The protocol handler method `connection_check` allowed to variable
operations to trigger with variable result bits. Only the `CONNCHECK_ISDEAD`
and `CONNRESULT_DEAD` were in use. Transform the function into
`connection_is_dead` without extra parameter and a bool result.
- Remove defines for `CONNCHECK_*` and `CONNRESULT_*`
- Rename protocol function in handler comments
- Change RTSP implementation (only protocol that uses this)
Vladimír Marek [Wed, 11 Mar 2026 09:46:51 +0000 (10:46 +0100)]
hostip: clear the sockaddr_in6 structure before use
On Solaris this was causing intermittent issues when the private
structure member __sin6_src_id had unexpectedly some value. connect(2)
would then fail with EADDRNOTAVAIL.
Felipe Mesquita [Thu, 5 Mar 2026 13:40:16 +0000 (10:40 -0300)]
badwords: avoid 'simply'
It's mostly a filler word. I've read through each use of it in the code
base and did minor rephrasings when "simply" carried some meaning. The
overwhelming majority of cases, removing it improved the text
significantly. Inspired by #20793.
Daniel Stenberg [Mon, 9 Mar 2026 12:32:14 +0000 (13:32 +0100)]
badwords: move into ./scripts, speed up
- 'badwords' is now a target in Makefile.am
- change badwords.txt to specify plain "words" instead of regexes so the
script can build single regexes when scanning, which makes the script
perform much faster (~6 times faster)