From: HenrikHolst Date: Fri, 4 Feb 2022 19:41:35 +0000 (+0100) Subject: http: make Curl_compareheader() take string length arguments too X-Git-Tag: curl-7_82_0~114 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4028892f14669937cb47d8a165e059503107812a;p=thirdparty%2Fcurl.git http: make Curl_compareheader() take string length arguments too Also add STRCONST, a macro that returns a string literal and it's length for functions that take "string,len" Removes unnecesary calls to strlen(). Closes #8391 --- diff --git a/lib/curl_setup.h b/lib/curl_setup.h index c1161ab6c5..25c667477e 100644 --- a/lib/curl_setup.h +++ b/lib/curl_setup.h @@ -772,6 +772,11 @@ endings either CRLF or LF so 't' is appropriate. #define CURLMAX(x,y) ((x)>(y)?(x):(y)) #define CURLMIN(x,y) ((x)<(y)?(x):(y)) +/* A convenience macro to provide both the string literal and the length of + the string literal in one go, useful for functions that take "string,len" + as their argument */ +#define STRCONST(x) x,sizeof(x)-1 + /* Some versions of the Android SDK is missing the declaration */ #if defined(HAVE_GETPWUID_R) && defined(HAVE_DECL_GETPWUID_R_MISSING) struct passwd; diff --git a/lib/http.c b/lib/http.c index 1c898a78b9..94cccf7961 100644 --- a/lib/http.c +++ b/lib/http.c @@ -1416,18 +1416,22 @@ CURLcode Curl_buffer_send(struct dynbuf *in, bool Curl_compareheader(const char *headerline, /* line to check */ const char *header, /* header keyword _with_ colon */ - const char *content) /* content string to find */ + const size_t hlen, /* len of the keyword in bytes */ + const char *content, /* content string to find */ + const size_t clen) /* len of the content in bytes */ { /* RFC2616, section 4.2 says: "Each header field consists of a name followed * by a colon (":") and the field value. Field names are case-insensitive. * The field value MAY be preceded by any amount of LWS, though a single SP * is preferred." */ - size_t hlen = strlen(header); - size_t clen; size_t len; const char *start; const char *end; + DEBUGASSERT(hlen); + DEBUGASSERT(clen); + DEBUGASSERT(header); + DEBUGASSERT(content); if(!strncasecompare(headerline, header, hlen)) return FALSE; /* doesn't start with header */ @@ -1451,7 +1455,6 @@ Curl_compareheader(const char *headerline, /* line to check */ } len = end-start; /* length of the content part of the input line */ - clen = strlen(content); /* length of the word to find */ /* find the content string in the rest of the line */ for(; len >= clen; len--, start++) { @@ -1707,7 +1710,7 @@ static CURLcode expect100(struct Curl_easy *data, const char *ptr = Curl_checkheaders(data, "Expect"); if(ptr) { data->state.expect100header = - Curl_compareheader(ptr, "Expect:", "100-continue"); + Curl_compareheader(ptr, STRCONST("Expect:"), STRCONST("100-continue")); } else { result = Curl_dyn_add(req, "Expect: 100-continue\r\n"); @@ -2325,7 +2328,8 @@ CURLcode Curl_http_body(struct Curl_easy *data, struct connectdata *conn, if(ptr) { /* Some kind of TE is requested, check if 'chunked' is chosen */ data->req.upload_chunky = - Curl_compareheader(ptr, "Transfer-Encoding:", "chunked"); + Curl_compareheader(ptr, + STRCONST("Transfer-Encoding:"), STRCONST("chunked")); } else { if((conn->handler->protocol & PROTO_FAMILY_HTTP) && @@ -2475,7 +2479,7 @@ CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn, ptr = Curl_checkheaders(data, "Expect"); if(ptr) { data->state.expect100header = - Curl_compareheader(ptr, "Expect:", "100-continue"); + Curl_compareheader(ptr, STRCONST("Expect:"), STRCONST("100-continue")); } else if(http->postsize > EXPECT_100_THRESHOLD || http->postsize < 0) { result = expect100(data, conn, r); @@ -2548,7 +2552,7 @@ CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn, ptr = Curl_checkheaders(data, "Expect"); if(ptr) { data->state.expect100header = - Curl_compareheader(ptr, "Expect:", "100-continue"); + Curl_compareheader(ptr, STRCONST("Expect:"), STRCONST("100-continue")); } else if(http->postsize > EXPECT_100_THRESHOLD || http->postsize < 0) { result = expect100(data, conn, r); @@ -3393,7 +3397,9 @@ CURLcode Curl_http_header(struct Curl_easy *data, struct connectdata *conn, #ifndef CURL_DISABLE_PROXY else if((conn->httpversion == 10) && conn->bits.httpproxy && - Curl_compareheader(headp, "Proxy-Connection:", "keep-alive")) { + Curl_compareheader(headp, + STRCONST("Proxy-Connection:"), + STRCONST("keep-alive"))) { /* * When a HTTP/1.0 reply comes when using a proxy, the * 'Proxy-Connection: keep-alive' line tells us the @@ -3405,7 +3411,9 @@ CURLcode Curl_http_header(struct Curl_easy *data, struct connectdata *conn, } else if((conn->httpversion == 11) && conn->bits.httpproxy && - Curl_compareheader(headp, "Proxy-Connection:", "close")) { + Curl_compareheader(headp, + STRCONST("Proxy-Connection:"), + STRCONST("close"))) { /* * We get a HTTP/1.1 response from a proxy and it says it'll * close down after this transfer. @@ -3415,7 +3423,9 @@ CURLcode Curl_http_header(struct Curl_easy *data, struct connectdata *conn, } #endif else if((conn->httpversion == 10) && - Curl_compareheader(headp, "Connection:", "keep-alive")) { + Curl_compareheader(headp, + STRCONST("Connection:"), + STRCONST("keep-alive"))) { /* * A HTTP/1.0 reply with the 'Connection: keep-alive' line * tells us the connection will be kept alive for our @@ -3425,7 +3435,8 @@ CURLcode Curl_http_header(struct Curl_easy *data, struct connectdata *conn, connkeep(conn, "Connection keep-alive"); infof(data, "HTTP/1.0 connection set to keep alive!"); } - else if(Curl_compareheader(headp, "Connection:", "close")) { + else if(Curl_compareheader(headp, + STRCONST("Connection:"), STRCONST("close"))) { /* * [RFC 2616, section 8.1.2.1] * "Connection: close" is HTTP/1.1 language and means that diff --git a/lib/http.h b/lib/http.h index b4aaba2a26..0fa016cfef 100644 --- a/lib/http.h +++ b/lib/http.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2021, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2022, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -47,7 +47,9 @@ extern const struct Curl_handler Curl_handler_https; /* Header specific functions */ bool Curl_compareheader(const char *headerline, /* line to check */ const char *header, /* header keyword _with_ colon */ - const char *content); /* content string to find */ + const size_t hlen, /* len of the keyword in bytes */ + const char *content, /* content string to find */ + const size_t clen); /* len of the content in bytes */ char *Curl_copy_header_value(const char *header); diff --git a/lib/http_proxy.c b/lib/http_proxy.c index 2793459cd5..90f1bd9d92 100644 --- a/lib/http_proxy.c +++ b/lib/http_proxy.c @@ -589,7 +589,8 @@ static CURLcode CONNECT(struct Curl_easy *data, strlen("Content-Length:"), NULL, 10, &s->cl); } } - else if(Curl_compareheader(linep, "Connection:", "close")) + else if(Curl_compareheader(linep, + STRCONST("Connection:"), STRCONST("close"))) s->close_connection = TRUE; else if(checkprefix("Transfer-Encoding:", linep)) { if(k->httpcode/100 == 2) { @@ -600,14 +601,17 @@ static CURLcode CONNECT(struct Curl_easy *data, "CONNECT %03d response", k->httpcode); } else if(Curl_compareheader(linep, - "Transfer-Encoding:", "chunked")) { + STRCONST("Transfer-Encoding:"), + STRCONST("chunked"))) { infof(data, "CONNECT responded chunked"); s->chunked_encoding = TRUE; /* init our chunky engine */ Curl_httpchunk_init(data); } } - else if(Curl_compareheader(linep, "Proxy-Connection:", "close")) + else if(Curl_compareheader(linep, + STRCONST("Proxy-Connection:"), + STRCONST("close"))) s->close_connection = TRUE; else if(2 == sscanf(linep, "HTTP/1.%d %d", &subversion,