On 2023-01-18 03:42, Ævar Arnfjörð Bjarmason wrote: > > On Wed, Jan 18 2023, Matthew John Cheetham via GitGitGadget wrote: > >> From: Matthew John Cheetham <mjcheetham@xxxxxxxxxxx> > >> + strbuf_add(&buf, ptr, size); >> + >> + /* Strip the CRLF that should be present at the end of each field */ >> + strbuf_trim_trailing_newline(&buf); >> + >> + /* Start of a new WWW-Authenticate header */ >> + if (skip_iprefix(buf.buf, "www-authenticate:", &val)) { >> + while (isspace(*val)) >> + val++; >> + >> + strvec_push(values, val); >> + http_auth.header_is_last_match = 1; >> + goto exit; >> [...] >> + if (http_auth.header_is_last_match && isspace(*buf.buf)) { >> + /* Trim leading whitespace from this continuation hdr line. */ >> + strbuf_ltrim(&buf); > > > The mixture of this isspace() loop and then strbuf_ltrim() seems odd, > why not stick with the strbuf API? > > I.e. after skip_iprefix() strbuf_splice() the start of the string away, > then use strbuf_ltrim() in the first "if" branch here? You mean like this? size_t size = st_mult(eltsize, nmemb); struct strvec *values = &http_auth.wwwauth_headers; struct strbuf buf = STRBUF_INIT; - const char *val; /* * Header lines may not come NULL-terminated from libcurl so we must @@ -216,11 +215,11 @@ static size_t fwrite_wwwauth(char *ptr, size_t eltsize, size_t nmemb, void *p) strbuf_trim_trailing_newline(&buf); /* Start of a new WWW-Authenticate header */ - if (skip_iprefix(buf.buf, "www-authenticate:", &val)) { - while (isspace(*val)) - val++; + if (istarts_with(buf.buf, "www-authenticate:")) { + strbuf_splice(&buf, 0, 17, NULL, 0); + strbuf_ltrim(&buf); - strvec_push(values, val); + strvec_push(values, buf.buf); http_auth.header_is_last_match = 1; goto exit; } I don't particularly like this given we're now introducing the 'magic' number 17 that's the length of `www-authenticate:`, plus `strbuf_splice` is doing a lot more work moving pieces of memory around rather than just producing a new starting pointer to the start of the value (skipping leading whitespace). > Likewise this is open-coding the "isspace" in strbuf_ltrim() for the > second "if". Maybe run the strbuf_ltrim() unconditionally, save away the > length before, and then: > > if (http_auth.header_is_last_match && prev_len != buf.len) { ... > > ? The suggestion of trimming and comparing lengths just makes a piece of code handling a little-known edge case less immediately obvious in its intent in my opinion. The current implementation of "if starts with a single space" matches the definition of continuation header lines, rather than re-piecing together this from "why are we trimming and comparing lengths?" Perf-wise the current implementation is only adding one extra `isspace` call which we're potentially about to do in a loop inside of `strbuf_ltrim` anyway. Plus, the common case will be a single space anyway. Thanks, Matthew