From bcc8144b896a49738cd60cbbe8e4f8e6f70461ef Mon Sep 17 00:00:00 2001 From: Viktor Szakats Date: Sat, 28 Feb 2026 11:29:16 +0100 Subject: [PATCH 1/6] clang-tidy: silence more minor issues found by v22 Also one found manually in lib/curl_sha512_256.c. Follow-up to 7a08c5d820fcf237688562a237a05000214db789 #20762 Closes #20770 --- lib/curl_sha512_256.c | 8 ++++---- lib/openldap.c | 2 +- lib/vssh/libssh.c | 9 +++++---- lib/vssh/libssh2.c | 10 +++++----- lib/vtls/rustls.c | 2 +- 5 files changed, 16 insertions(+), 15 deletions(-) diff --git a/lib/curl_sha512_256.c b/lib/curl_sha512_256.c index fa568b6b04..2f51d2a4cd 100644 --- a/lib/curl_sha512_256.c +++ b/lib/curl_sha512_256.c @@ -727,10 +727,10 @@ static CURLcode Curl_sha512_256_finish(unsigned char *digest, void *context) /* Put in BE mode the leftmost part of the hash as the final digest. See FIPS PUB 180-4 section 6.7. */ - CURL_PUT_64BIT_BE(digest + 0 * SHA512_256_BYTES_IN_WORD, ctx->H[0]); - CURL_PUT_64BIT_BE(digest + 1 * SHA512_256_BYTES_IN_WORD, ctx->H[1]); - CURL_PUT_64BIT_BE(digest + 2 * SHA512_256_BYTES_IN_WORD, ctx->H[2]); - CURL_PUT_64BIT_BE(digest + 3 * SHA512_256_BYTES_IN_WORD, ctx->H[3]); + CURL_PUT_64BIT_BE(digest + (0 * SHA512_256_BYTES_IN_WORD), ctx->H[0]); + CURL_PUT_64BIT_BE(digest + (1 * SHA512_256_BYTES_IN_WORD), ctx->H[1]); + CURL_PUT_64BIT_BE(digest + (2 * SHA512_256_BYTES_IN_WORD), ctx->H[2]); + CURL_PUT_64BIT_BE(digest + (3 * SHA512_256_BYTES_IN_WORD), ctx->H[3]); /* Erase potentially sensitive data. */ memset(ctx, 0, sizeof(struct Curl_sha512_256ctx)); diff --git a/lib/openldap.c b/lib/openldap.c index 8dd984132c..95f7681caa 100644 --- a/lib/openldap.c +++ b/lib/openldap.c @@ -1247,7 +1247,7 @@ void Curl_ldap_version(char *buf, size_t bufsz) unsigned int patch = (unsigned int)(api.ldapai_vendor_version % 100); unsigned int major = (unsigned int)(api.ldapai_vendor_version / 10000); unsigned int minor = - (((unsigned int)api.ldapai_vendor_version - major * 10000) + (((unsigned int)api.ldapai_vendor_version - (major * 10000)) - patch) / 100; curl_msnprintf(buf, bufsz, "%s/%u.%u.%u", api.ldapai_vendor_name, major, minor, patch); diff --git a/lib/vssh/libssh.c b/lib/vssh/libssh.c index 53617773b5..7bd2101e52 100644 --- a/lib/vssh/libssh.c +++ b/lib/vssh/libssh.c @@ -1000,10 +1000,11 @@ static int myssh_in_UPLOAD_INIT(struct Curl_easy *data, if(!sshc->sftp_file) { int err = sftp_get_error(sshc->sftp_session); - if(((err == SSH_FX_NO_SUCH_FILE || err == SSH_FX_FAILURE || - err == SSH_FX_NO_SUCH_PATH)) && - (data->set.ftp_create_missing_dirs && - (strlen(sshp->path) > 1))) { + if((err == SSH_FX_NO_SUCH_FILE || + err == SSH_FX_FAILURE || + err == SSH_FX_NO_SUCH_PATH) && + data->set.ftp_create_missing_dirs && + (strlen(sshp->path) > 1)) { /* try to create the path remotely */ rc = 0; sshc->secondCreateDirs = 1; diff --git a/lib/vssh/libssh2.c b/lib/vssh/libssh2.c index db52d1e703..2d40e04fe4 100644 --- a/lib/vssh/libssh2.c +++ b/lib/vssh/libssh2.c @@ -967,11 +967,11 @@ static CURLcode sftp_upload_init(struct Curl_easy *data, sftp_libssh2_strerror(sftperr)); return sftp_libssh2_error_to_CURLE(sftperr); } - if(((sftperr == LIBSSH2_FX_NO_SUCH_FILE) || - (sftperr == LIBSSH2_FX_FAILURE) || - (sftperr == LIBSSH2_FX_NO_SUCH_PATH)) && - (data->set.ftp_create_missing_dirs && - (strlen(sshp->path) > 1))) { + if((sftperr == LIBSSH2_FX_NO_SUCH_FILE || + sftperr == LIBSSH2_FX_FAILURE || + sftperr == LIBSSH2_FX_NO_SUCH_PATH) && + data->set.ftp_create_missing_dirs && + (strlen(sshp->path) > 1)) { /* try to create the path remotely */ sshc->secondCreateDirs = 1; myssh_to(data, sshc, SSH_SFTP_CREATE_DIRS_INIT); diff --git a/lib/vtls/rustls.c b/lib/vtls/rustls.c index 63ee0349a1..061b444bce 100644 --- a/lib/vtls/rustls.c +++ b/lib/vtls/rustls.c @@ -577,7 +577,7 @@ init_config_builder(struct Curl_easy *data, } #endif /* USE_ECH */ - cipher_suites = curlx_malloc(sizeof(*cipher_suites) * (cipher_suites_len)); + cipher_suites = curlx_malloc(sizeof(*cipher_suites) * cipher_suites_len); if(!cipher_suites) { result = CURLE_OUT_OF_MEMORY; goto cleanup; From 35bbb2e830aeb8181bd4bf6b0ef68929217d97f0 Mon Sep 17 00:00:00 2001 From: Viktor Szakats Date: Sat, 28 Feb 2026 22:41:23 +0100 Subject: [PATCH 2/6] clang-tidy: fix issues found with build-fuzzing - curl_sha512_256: add missing, drop redundant, parentheses. - doh: drop redundant returns. - url: add missing parentheses. - vtls: fix unused const variables. - tests/unit: fix missing header with clang-tidy and !threaded-resolver. Follow-up to 57ff2d6c918d0bb444e5a8a53405217aec116b1b #20106 Closes #20774 --- lib/curl_sha512_256.c | 24 ++++++++++++------------ lib/doh.c | 2 -- lib/url.c | 8 ++++---- lib/vtls/vtls.c | 2 -- tests/unit/unit1607.c | 1 + tests/unit/unit1609.c | 1 + tests/unit/unit2600.c | 1 + 7 files changed, 19 insertions(+), 20 deletions(-) diff --git a/lib/curl_sha512_256.c b/lib/curl_sha512_256.c index 2f51d2a4cd..00f4d1071f 100644 --- a/lib/curl_sha512_256.c +++ b/lib/curl_sha512_256.c @@ -452,14 +452,14 @@ static void Curl_sha512_256_transform(uint64_t H[SHA512_256_HASH_SIZE_WORDS], /* Four 'Sigma' macro functions. See FIPS PUB 180-4 formulae 4.10, 4.11, 4.12, 4.13. */ -#define SIG0(x) \ - (Curl_rotr64((x), 28) ^ Curl_rotr64((x), 34) ^ Curl_rotr64((x), 39)) -#define SIG1(x) \ - (Curl_rotr64((x), 14) ^ Curl_rotr64((x), 18) ^ Curl_rotr64((x), 41)) -#define sig0(x) \ - (Curl_rotr64((x), 1) ^ Curl_rotr64((x), 8) ^ ((x) >> 7)) -#define sig1(x) \ - (Curl_rotr64((x), 19) ^ Curl_rotr64((x), 61) ^ ((x) >> 6)) +#define SIG0(x) \ + (Curl_rotr64(x, 28) ^ Curl_rotr64(x, 34) ^ Curl_rotr64(x, 39)) +#define SIG1(x) \ + (Curl_rotr64(x, 14) ^ Curl_rotr64(x, 18) ^ Curl_rotr64(x, 41)) +#define sig0(x) \ + (Curl_rotr64(x, 1) ^ Curl_rotr64(x, 8) ^ ((x) >> 7)) +#define sig1(x) \ + (Curl_rotr64(x, 19) ^ Curl_rotr64(x, 61) ^ ((x) >> 6)) if(1) { unsigned int t; @@ -520,8 +520,8 @@ static void Curl_sha512_256_transform(uint64_t H[SHA512_256_HASH_SIZE_WORDS], used. */ #define SHA2STEP64(vA, vB, vC, vD, vE, vF, vG, vH, kt, wt) \ do { \ - (vD) += ((vH) += SIG1((vE)) + Sha512_Ch((vE), (vF), (vG)) + (kt) + (wt)); \ - (vH) += SIG0((vA)) + Sha512_Maj((vA), (vB), (vC)); \ + (vD) += ((vH) += SIG1(vE) + Sha512_Ch(vE, vF, vG) + (kt) + (wt)); \ + (vH) += SIG0(vA) + Sha512_Maj(vA, vB, vC); \ } while(0) /* One step of SHA-512/256 computation with working variables rotation, @@ -530,7 +530,7 @@ static void Curl_sha512_256_transform(uint64_t H[SHA512_256_HASH_SIZE_WORDS], #define SHA2STEP64RV(vA, vB, vC, vD, vE, vF, vG, vH, kt, wt) \ do { \ uint64_t tmp_h_ = (vH); \ - SHA2STEP64((vA), (vB), (vC), (vD), (vE), (vF), (vG), tmp_h_, (kt), (wt)); \ + SHA2STEP64(vA, vB, vC, vD, vE, vF, vG, tmp_h_, kt, wt); \ (vH) = (vG); \ (vG) = (vF); \ (vF) = (vE); \ @@ -546,7 +546,7 @@ static void Curl_sha512_256_transform(uint64_t H[SHA512_256_HASH_SIZE_WORDS], Input data must be read in big-endian bytes order, see FIPS PUB 180-4 section 3.1.2. */ #define SHA512_GET_W_FROM_DATA(buf, t) \ - CURL_GET_64BIT_BE(((const uint8_t *)(buf)) + (t) * SHA512_256_BYTES_IN_WORD) + CURL_GET_64BIT_BE((const uint8_t *)(buf) + ((t) * SHA512_256_BYTES_IN_WORD)) /* During first 16 steps, before making any calculation on each step, the W element is read from the input data buffer as a big-endian value and diff --git a/lib/doh.c b/lib/doh.c index 283746cab3..7fe4a06058 100644 --- a/lib/doh.c +++ b/lib/doh.c @@ -201,7 +201,6 @@ static void doh_print_buf(struct Curl_easy *data, infof(data, "%s: len=%d, val=%s", prefix, (int)len, hexstr); else infof(data, "%s: len=%d (truncated)val=%s", prefix, (int)len, hexstr); - return; } #endif @@ -1191,7 +1190,6 @@ UNITTEST void doh_print_httpsrr(struct Curl_easy *data, } else infof(data, "HTTPS RR: no ipv6hints"); - return; } # endif #endif diff --git a/lib/url.c b/lib/url.c index 0e594681ea..495de2297c 100644 --- a/lib/url.c +++ b/lib/url.c @@ -953,7 +953,7 @@ static bool url_match_proxy_use(struct connectdata *conn, return TRUE; } #else -#define url_match_proxy_use(c, m) ((void)c, (void)m, TRUE) +#define url_match_proxy_use(c, m) ((void)(c), (void)(m), TRUE) #endif #ifndef CURL_DISABLE_HTTP @@ -1009,8 +1009,8 @@ static bool url_match_http_version(struct connectdata *conn, return TRUE; } #else -#define url_match_http_multiplex(c, m) ((void)c, (void)m, TRUE) -#define url_match_http_version(c, m) ((void)c, (void)m, TRUE) +#define url_match_http_multiplex(c, m) ((void)(c), (void)(m), TRUE) +#define url_match_http_version(c, m) ((void)(c), (void)(m), TRUE) #endif static bool url_match_proto_config(struct connectdata *conn, @@ -1178,7 +1178,7 @@ static bool url_match_auth_ntlm(struct connectdata *conn, return TRUE; } #else -#define url_match_auth_ntlm(c, m) ((void)c, (void)m, TRUE) +#define url_match_auth_ntlm(c, m) ((void)(c), (void)(m), TRUE) #endif #ifdef USE_SPNEGO diff --git a/lib/vtls/vtls.c b/lib/vtls/vtls.c index df9bc33a7b..f7201d18d6 100644 --- a/lib/vtls/vtls.c +++ b/lib/vtls/vtls.c @@ -136,7 +136,6 @@ static const struct alpn_spec ALPN_SPEC_H11 = { static const struct alpn_spec ALPN_SPEC_H10_H11 = { { ALPN_HTTP_1_0, ALPN_HTTP_1_1 }, 2 }; -#endif /* !CURL_DISABLE_HTTP || !CURL_DISABLE_PROXY */ #ifdef USE_HTTP2 static const struct alpn_spec ALPN_SPEC_H2 = { { ALPN_H2 }, 1 @@ -149,7 +148,6 @@ static const struct alpn_spec ALPN_SPEC_H11_H2 = { }; #endif /* USE_HTTP2 */ -#if !defined(CURL_DISABLE_HTTP) || !defined(CURL_DISABLE_PROXY) static const struct alpn_spec *alpn_get_spec(http_majors wanted, http_majors preferred, bool only_http_10, diff --git a/tests/unit/unit1607.c b/tests/unit/unit1607.c index 3072130cce..3265df484a 100644 --- a/tests/unit/unit1607.c +++ b/tests/unit/unit1607.c @@ -25,6 +25,7 @@ #include "urldata.h" #include "connect.h" +#include "curl_addrinfo.h" static CURLcode t1607_setup(void) { diff --git a/tests/unit/unit1609.c b/tests/unit/unit1609.c index 366b117abe..a862154176 100644 --- a/tests/unit/unit1609.c +++ b/tests/unit/unit1609.c @@ -25,6 +25,7 @@ #include "urldata.h" #include "connect.h" +#include "curl_addrinfo.h" static CURLcode t1609_setup(void) { diff --git a/tests/unit/unit2600.c b/tests/unit/unit2600.c index 97d4caed96..4bd12313e6 100644 --- a/tests/unit/unit2600.c +++ b/tests/unit/unit2600.c @@ -46,6 +46,7 @@ #include "cf-ip-happy.h" #include "multiif.h" #include "select.h" +#include "curl_addrinfo.h" #include "curl_trc.h" static CURLcode t2600_setup(CURL **easy) From 7a80082471e5983857c92900dc4858427994e236 Mon Sep 17 00:00:00 2001 From: Viktor Szakats Date: Sat, 28 Feb 2026 23:53:08 +0100 Subject: [PATCH 3/6] GHA/windows: bump clang-tidy job to clang v20 (from v18) Adds 50 seconds to the 5m long build step. Also more prerequisites to install, with no apparent effect on step time. Follow-up to 9b52d516bb8990107f20c9786e09dbb6961c30b2 #20732 Closes #20775 --- .github/workflows/windows.yml | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index f34f1f45b2..cc95548cad 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -677,10 +677,12 @@ jobs: include: - { build: 'autotools', compiler: 'gcc' } - { build: 'cmake' , compiler: 'gcc' } - - { build: 'cmake' , compiler: 'clang-tidy' } + - { build: 'cmake' , compiler: 'clang-tidy', install_packages: 'clang-20 clang-tidy-20' } steps: - name: 'install packages' - run: sudo apt-get -o Dpkg::Use-Pty=0 install gcc-mingw-w64-x86-64-win32 + env: + MATRIX_INSTALL_PACKAGES: '${{ matrix.install_packages }}' + run: sudo apt-get -o Dpkg::Use-Pty=0 install gcc-mingw-w64-x86-64-win32 ${MATRIX_INSTALL_PACKAGES} - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -694,10 +696,10 @@ jobs: run: | if [ "${MATRIX_BUILD}" = 'cmake' ]; then if [ "${MATRIX_COMPILER}" = 'clang-tidy' ]; then - options+=' -DCURL_CLANG_TIDY=ON' + options+=' -DCURL_CLANG_TIDY=ON -DCLANG_TIDY=/usr/bin/clang-tidy-20' options+=' -DENABLE_UNICODE=ON -DUSE_SSLS_EXPORT=ON' - options+=' -DCMAKE_C_COMPILER=clang' - options+=" -DCMAKE_RC_COMPILER=llvm-windres-$(clang -dumpversion | cut -d '.' -f 1)" + options+=' -DCMAKE_C_COMPILER=clang-20' + options+=" -DCMAKE_RC_COMPILER=llvm-windres-$(clang-20 -dumpversion | cut -d '.' -f 1)" else options+=" -DCMAKE_C_COMPILER=${TRIPLET}-gcc" fi From 1b35c9e1e3bb84336082a8fde12eeeafe6bfa3b2 Mon Sep 17 00:00:00 2001 From: Viktor Szakats Date: Sat, 28 Feb 2026 01:33:05 +0100 Subject: [PATCH 4/6] cmake: rename `testbins` target to `tt`, restore internal option To make it easy to type. The internal option is used in CI. Follow-up to aae361242f30eafacf46085ed731b1524bfd3be9 #20708 Closes #20768 --- RELEASE-NOTES | 2 +- docs/INSTALL-CMAKE.md | 4 ++-- tests/CMakeLists.txt | 10 +++++----- tests/certs/CMakeLists.txt | 6 +++++- tests/libtest/CMakeLists.txt | 2 +- tests/server/CMakeLists.txt | 2 +- tests/tunit/CMakeLists.txt | 2 +- tests/unit/CMakeLists.txt | 2 +- 8 files changed, 17 insertions(+), 13 deletions(-) diff --git a/RELEASE-NOTES b/RELEASE-NOTES index fe6ba29c95..838c105b57 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -63,7 +63,7 @@ This release includes the following bugfixes: o cmake: normalize uppercase hex winver (for display) [191] o cmake: omit `curl.rc` from curltool lib [209] o cmake: reference OpenSSL and ZLIB imported targets only when enabled [41] - o cmake: replace internal option with a new `testbins` target [220] + o cmake: replace internal option with a new `tt` (test tools) target [220] o cmake: silence potential unused var warnings in C++ test snippet [201] o cmake: silence silly Apple clang warnings in C89 mode, test in CI [14] o cmake: silence useless compiler warnings triggered by the FASTBuild generator [43] diff --git a/docs/INSTALL-CMAKE.md b/docs/INSTALL-CMAKE.md index 9ef9ba6aaa..9c92e4b4ca 100644 --- a/docs/INSTALL-CMAKE.md +++ b/docs/INSTALL-CMAKE.md @@ -552,12 +552,12 @@ Note: These variables are internal and subject to change. ## Useful build targets -- `testbins`: Build test binaries (servers, tools). - Individual targets: `curlinfo`, `libtests`, `servers`, `tunits`, `units` - `testdeps`: Build test dependencies (test binaries, test certificates). Test certificates: `build-certs` (clean with `clean-certs`) - `tests`: Run tests (`runtests.pl`). Customize via the `TFLAGS` environment variable, e.g. `TFLAGS=1621`. Other flavors: `test-am`, `test-ci`, `test-event`, `test-full`, `test-nonflaky`, `test-quiet`, `test-torture` +- `tt`: Build test binaries (servers, tools). + Individual targets: `curlinfo`, `libtests`, `servers`, `tunits`, `units` - `curl-pytest`: Run tests (pytest). Other flavor: `curl-test-ci` - `curl-examples`: Build examples diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 7edfaa7ed8..d751a69f2c 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -29,21 +29,21 @@ mark_as_advanced(TEST_NGHTTPX) # Consumed variables: TEST_NGHTTPX configure_file("config.in" "${CMAKE_CURRENT_BINARY_DIR}/config" @ONLY) -add_custom_target(testbins) +add_custom_target(tt) if(BUILD_CURL_EXE) - add_dependencies(testbins "curlinfo") + add_dependencies(tt "curlinfo") endif() if(CURL_BUILD_EVERYTHING) - set_target_properties(testbins PROPERTIES EXCLUDE_FROM_ALL FALSE) + set_target_properties(tt PROPERTIES EXCLUDE_FROM_ALL FALSE) endif() if(CURL_CLANG_TIDY) add_custom_target(tests-clang-tidy) - add_dependencies(testbins tests-clang-tidy) + add_dependencies(tt tests-clang-tidy) endif() add_custom_target(testdeps) -add_dependencies(testdeps "testbins") +add_dependencies(testdeps "tt") add_subdirectory(http) add_subdirectory(server) diff --git a/tests/certs/CMakeLists.txt b/tests/certs/CMakeLists.txt index 399483a738..d0e1f55b85 100644 --- a/tests/certs/CMakeLists.txt +++ b/tests/certs/CMakeLists.txt @@ -31,7 +31,11 @@ add_custom_command(OUTPUT ${GENERATEDCERTS} VERBATIM ) add_custom_target(build-certs DEPENDS ${GENERATEDCERTS}) -add_dependencies(testdeps build-certs) + +option(_CURL_SKIP_BUILD_CERTS "Skip building certs with testdeps" OFF) # Internal option to increase perf for build tests +if(NOT _CURL_SKIP_BUILD_CERTS) + add_dependencies(testdeps build-certs) +endif() add_custom_target(clean-certs COMMAND ${CMAKE_COMMAND} -E remove ${GENERATEDCERTS} diff --git a/tests/libtest/CMakeLists.txt b/tests/libtest/CMakeLists.txt index 60c8676568..7991a11486 100644 --- a/tests/libtest/CMakeLists.txt +++ b/tests/libtest/CMakeLists.txt @@ -52,7 +52,7 @@ add_custom_command(OUTPUT "${BUNDLE}.c" VERBATIM) add_executable(${BUNDLE} EXCLUDE_FROM_ALL "${BUNDLE}.c") -add_dependencies(testbins ${BUNDLE}) +add_dependencies(tt ${BUNDLE}) target_link_libraries(${BUNDLE} ${LIB_SELECTED} ${CURL_LIBS}) target_include_directories(${BUNDLE} PRIVATE "${PROJECT_BINARY_DIR}/lib" # for "curl_config.h" diff --git a/tests/server/CMakeLists.txt b/tests/server/CMakeLists.txt index 716724ab05..bf1431c7fc 100644 --- a/tests/server/CMakeLists.txt +++ b/tests/server/CMakeLists.txt @@ -39,7 +39,7 @@ add_custom_command(OUTPUT "${BUNDLE}.c" VERBATIM) add_executable(${BUNDLE} EXCLUDE_FROM_ALL "${BUNDLE}.c") -add_dependencies(testbins ${BUNDLE}) +add_dependencies(tt ${BUNDLE}) target_link_libraries(${BUNDLE} ${CURL_NETWORK_AND_TIME_LIBS}) target_include_directories(${BUNDLE} PRIVATE "${PROJECT_BINARY_DIR}/lib" # for "curl_config.h" diff --git a/tests/tunit/CMakeLists.txt b/tests/tunit/CMakeLists.txt index a10d240a08..c6ac279a66 100644 --- a/tests/tunit/CMakeLists.txt +++ b/tests/tunit/CMakeLists.txt @@ -39,7 +39,7 @@ add_custom_command(OUTPUT "${BUNDLE}.c" VERBATIM) add_executable(${BUNDLE} EXCLUDE_FROM_ALL "${BUNDLE}.c") -add_dependencies(testbins ${BUNDLE}) +add_dependencies(tt ${BUNDLE}) target_link_libraries(${BUNDLE} curltool ${LIB_SELECTED}) target_include_directories(${BUNDLE} PRIVATE "${PROJECT_BINARY_DIR}/lib" # for "curl_config.h" diff --git a/tests/unit/CMakeLists.txt b/tests/unit/CMakeLists.txt index 8d27fc0a5b..46710ce1ea 100644 --- a/tests/unit/CMakeLists.txt +++ b/tests/unit/CMakeLists.txt @@ -40,7 +40,7 @@ add_custom_command(OUTPUT "${BUNDLE}.c" add_executable(${BUNDLE} EXCLUDE_FROM_ALL "${BUNDLE}.c") add_dependencies(${BUNDLE} curlu-unitprotos) -add_dependencies(testbins ${BUNDLE}) +add_dependencies(tt ${BUNDLE}) target_link_libraries(${BUNDLE} curlu) target_include_directories(${BUNDLE} PRIVATE "${PROJECT_BINARY_DIR}/lib" # for "curl_config.h", "unitprotos.h" From f26a2917559394c9594b979eae4ff1b07a8f7b50 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sat, 28 Feb 2026 10:48:59 +0100 Subject: [PATCH 5/6] urlapi: typecast CURLU_URLDECODE to uint when toggling it off In this use case 'unsigned value &= ~DEFINE;' As otherwise the right side is treated as signed, which annoyingly triggers UBSan. Reported-by: xmoezzz on github Fixes #20753 --- lib/urlapi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/urlapi.c b/lib/urlapi.c index c59f239756..3c84fcba7f 100644 --- a/lib/urlapi.c +++ b/lib/urlapi.c @@ -1555,7 +1555,7 @@ CURLUcode curl_url_get(const CURLU *u, CURLUPart what, case CURLUPART_SCHEME: ptr = u->scheme; ifmissing = CURLUE_NO_SCHEME; - flags &= ~CURLU_URLDECODE; /* never for schemes */ + flags &= ~(unsigned int)CURLU_URLDECODE; /* never for schemes */ if((flags & CURLU_NO_GUESS_SCHEME) && u->guessed_scheme) return CURLUE_NO_SCHEME; break; @@ -1582,7 +1582,7 @@ CURLUcode curl_url_get(const CURLU *u, CURLUPart what, case CURLUPART_PORT: ptr = u->port; ifmissing = CURLUE_NO_PORT; - flags &= ~CURLU_URLDECODE; /* never for port */ + flags &= ~(unsigned int)CURLU_URLDECODE; /* never for port */ if(!ptr && (flags & CURLU_DEFAULT_PORT) && u->scheme) { /* there is no stored port number, but asked to deliver a default one for the scheme */ From f54d5ccad668e840a02271d92d62d05d04875617 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 1 Mar 2026 13:55:31 +0100 Subject: [PATCH 6/6] fixup Viktor's extra case --- lib/urlapi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/urlapi.c b/lib/urlapi.c index 3c84fcba7f..1de38f1f98 100644 --- a/lib/urlapi.c +++ b/lib/urlapi.c @@ -1274,7 +1274,7 @@ static CURLUcode redirect_url(const char *base, const char *relurl, if(!curlx_dyn_addn(&urlbuf, base, prelen) && !urlencode_str(&urlbuf, useurl, strlen(useurl), !host_changed, FALSE)) { uc = parseurl_and_replace(curlx_dyn_ptr(&urlbuf), u, - flags & ~CURLU_PATH_AS_IS); + flags & ~(unsigned int)CURLU_PATH_AS_IS); } else uc = CURLUE_OUT_OF_MEMORY;