From b27e828b938777b75cf627093e1c9c9d4af2cbd2 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 1 Apr 2026 15:44:02 +0200 Subject: [PATCH] url: init req.no_body in DO so that it works for h2 push req.no_body was only initialized in Curl_connect, while HTTP/2 server push adds a duplicated handle via Curl_multi_add_perform and calls Curl_init_do with conn==NULL, never invoking Curl_connect. Verify it by amending test 1620 Found by Codex Security Closes #21194 --- lib/url.c | 1 + tests/unit/unit1620.c | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/lib/url.c b/lib/url.c index db82b6a070..c377f0733b 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3514,6 +3514,7 @@ CURLcode Curl_init_do(struct Curl_easy *data, struct connectdata *conn) data->state.done = FALSE; /* *_done() is not called yet */ + data->req.no_body = data->set.opt_no_body; if(data->req.no_body) /* in HTTP lingo, no body means using the HEAD request... */ data->state.httpreq = HTTPREQ_HEAD; diff --git a/tests/unit/unit1620.c b/tests/unit/unit1620.c index af9363d75e..2b46d86290 100644 --- a/tests/unit/unit1620.c +++ b/tests/unit/unit1620.c @@ -72,6 +72,7 @@ static CURLcode test_unit1620(const char *arg) CURLcode result; struct Curl_easy *empty; + struct Curl_easy *dupe = NULL; enum dupstring i; bool connected = FALSE; @@ -95,6 +96,20 @@ static CURLcode test_unit1620(const char *arg) result = Curl_init_do(empty, empty->conn); fail_unless(result == CURLE_OK, "Curl_init_do() failed"); + result = curl_easy_setopt((CURL *)empty, CURLOPT_NOBODY, 1L); + fail_unless(result == CURLE_OK, "curl_easy_setopt(CURLOPT_NOBODY) failed"); + + dupe = (struct Curl_easy *)curl_easy_duphandle((CURL *)empty); + if(!dupe) + Curl_close(&empty); + abort_unless(dupe, "curl_easy_duphandle() failed"); + + result = Curl_init_do(dupe, NULL); + fail_unless(result == CURLE_OK, "Curl_init_do() on duplicate failed"); + fail_unless(dupe->req.no_body, "duplicate handle should keep no_body"); + fail_unless(dupe->state.httpreq == HTTPREQ_HEAD, + "duplicate handle should use HTTPREQ_HEAD"); + t1620_parse("hostname", "hostname", NULL, NULL); t1620_parse("user:password", "user", "password", NULL); t1620_parse("user:password;options", "user", "password", "options"); @@ -116,6 +131,9 @@ static CURLcode test_unit1620(const char *arg) fail_unless(empty->set.str[i] == NULL, "Curl_free() did not set to NULL"); } + result = Curl_close(&dupe); + fail_unless(result == CURLE_OK, "Curl_close() failed for duplicate"); + result = Curl_close(&empty); fail_unless(result == CURLE_OK, "Curl_close() failed");