Re: [PATCH 0/3] test-suite fixes for upcoming curl 8.18.0
- From
Jeff King <peff@peff.net>
- Date
- Dec 19, 2025, 08:04 UTC
- Message-ID
- <20251219080409.GC3784564@coredump.intra.peff.net>
- In-Reply-To
- <sn7p46s1-4o20-q05n-173r-s6716s8145q6@unkk.fr>
On Thu, Dec 18, 2025 at 05:49:27PM +0100, Daniel Stenberg wrote:
Show 12 quoted lines
> On Thu, 18 Dec 2025, Daniel Stenberg wrote: > > > > [3/3]: t5563: relax whitespace assumptions for unfolded headers > > > I did not fully consider the impact this might have on users such as > > you. Allow me to rework that a little bit further and get the former > > white-space behavior back. Thanks! > > I just merged a fix [1] into curl that should restore the unfolding behavior > to match previous releases. It would be awesome if you could verify. > > [1] = https://github.com/curl/curl/commit/9941e7c95bf26f00fd87888a
Thanks, I took a look at it. Unfortunately I think it only gets us halfway there. It drops the extra space when folding this:
printf 'Foo: bar\r\n' printf ' \r\n' printf ' baz\r\n'
which will yield:
Foo: bar baz
and it fixes the first of Git's failing tests. But if we swap out the space for a tab like this:
printf 'Foo: bar\r\n' printf ' \r\n' printf '\tbaz\r\n'
then we get collapsed whitespace, but it's a tab. I.e.:
Foo: bar\tbaz
(where "\t" is a literal tab). I think that does violate the standard (which says it should become spaces). I think in most headers the grammar allows OWS/RWS fields that are spaces or tabs, so in theory it shouldn't matter. But I wouldn't be surprised if that causes some surprises in the real world.
Sadly the input buffer to http_parse_headers() is const, so we can't just write a space over the original tab. ;) But I think rather than walking back to preserve that final leading whitespace byte, we could just always add in our own space separately, like this:
diff --git a/lib/http.c b/lib/http.c index ea62219542..eaa8bf73c2 100644 --- a/lib/http.c +++ b/lib/http.c @@ -4388,6 +4388,7 @@ static CURLcode http_parse_headers(struct Curl_easy *data, { /* preserve the whole original header piece size */ size_t header_piece = consumed; + bool did_unfold = false; if(data->state.leading_unfold) { /* immediately after an unfold, keep only a single whitespace */ @@ -4398,17 +4399,18 @@ static CURLcode http_parse_headers(struct Curl_easy *data, blen--; } if(consumed) { - if(iblen > blen) { - /* take one step back */ - consumed++; - buf--; - blen++; - } data->state.leading_unfold = FALSE; /* done now */ + did_unfold = TRUE; } } if(consumed) { + if (did_unfold) { + result = curlx_dyn_addn(&data->state.headerb, " ", 1); + if(result) + return result; + } + result = curlx_dyn_addn(&data->state.headerb, buf, consumed); if(result) return result; -Peff