From 294136b75411893c57db9438b1a69493adc08c9c Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 27 Feb 2025 23:26:54 +0100 Subject: [PATCH] lib: replace while(ISBLANK()) loops with Curl_str_passblanks() - replace several ISSPACE() with ISBLANK(), since the former also skips CR and LF which in most cases should not occur where this macro is used - after this commit, there is no ISSPACE() user left in libcurl code, but unfortunately tool and test code use the macro so it cannot be removed. Closes #16520 --- lib/altsvc.c | 12 ++++-------- lib/content_encoding.c | 2 +- lib/cookie.c | 5 ++--- lib/curl_fnmatch.c | 2 +- lib/ftplistparser.c | 5 ++--- lib/headers.c | 10 +++++----- lib/hsts.c | 25 ++++++++++--------------- lib/http.c | 13 +++++-------- lib/http_aws_sigv4.c | 31 ++++++++++++++----------------- lib/http_digest.c | 4 ++-- lib/http_negotiate.c | 4 ++-- lib/http_ntlm.c | 5 ++--- lib/http_proxy.c | 9 ++++----- lib/netrc.c | 13 ++++++------- lib/noproxy.c | 7 +++---- lib/rtsp.c | 11 ++++------- lib/strparse.c | 7 +++++++ lib/strparse.h | 1 + lib/strtoofft.c | 4 +--- lib/urlapi.c | 6 +----- 20 files changed, 77 insertions(+), 99 deletions(-) diff --git a/lib/altsvc.c b/lib/altsvc.c index b63cd7beac..d478a874d1 100644 --- a/lib/altsvc.c +++ b/lib/altsvc.c @@ -233,14 +233,10 @@ static CURLcode altsvc_load(struct altsvcinfo *asi, const char *file) struct dynbuf buf; Curl_dyn_init(&buf, MAX_ALTSVC_LINE); while(Curl_get_line(&buf, fp)) { - char *lineptr = Curl_dyn_ptr(&buf); - while(ISBLANK(*lineptr)) - lineptr++; - if(*lineptr == '#') - /* skip commented lines */ - continue; - - altsvc_add(asi, lineptr); + const char *lineptr = Curl_dyn_ptr(&buf); + Curl_str_passblanks(&lineptr); + if(Curl_str_single(&lineptr, '#')) + altsvc_add(asi, lineptr); } Curl_dyn_free(&buf); /* free the line buffer */ fclose(fp); diff --git a/lib/content_encoding.c b/lib/content_encoding.c index e39ac3ebad..d329a1b56e 100644 --- a/lib/content_encoding.c +++ b/lib/content_encoding.c @@ -758,7 +758,7 @@ CURLcode Curl_build_unencoding_stack(struct Curl_easy *data, name = enclist; for(namelen = 0; *enclist && *enclist != ','; enclist++) - if(!ISSPACE(*enclist)) + if(*enclist > ' ') namelen = enclist - name + 1; if(namelen) { diff --git a/lib/cookie.c b/lib/cookie.c index 519fcdc4af..5a84d7f133 100644 --- a/lib/cookie.c +++ b/lib/cookie.c @@ -1210,14 +1210,13 @@ struct CookieInfo *Curl_cookie_init(struct Curl_easy *data, struct dynbuf buf; Curl_dyn_init(&buf, MAX_COOKIE_LINE); while(Curl_get_line(&buf, fp)) { - char *lineptr = Curl_dyn_ptr(&buf); + const char *lineptr = Curl_dyn_ptr(&buf); bool headerline = FALSE; if(checkprefix("Set-Cookie:", lineptr)) { /* This is a cookie line, get it! */ lineptr += 11; headerline = TRUE; - while(ISBLANK(*lineptr)) - lineptr++; + Curl_str_passblanks(&lineptr); } Curl_cookie_add(data, ci, headerline, TRUE, lineptr, NULL, NULL, TRUE); diff --git a/lib/curl_fnmatch.c b/lib/curl_fnmatch.c index ffac8048f6..58e3f776b9 100644 --- a/lib/curl_fnmatch.c +++ b/lib/curl_fnmatch.c @@ -319,7 +319,7 @@ static int loop(const unsigned char *pattern, const unsigned char *string, else if(charset[CURLFNM_PRINT]) found = ISPRINT(*s); else if(charset[CURLFNM_SPACE]) - found = ISSPACE(*s); + found = ISBLANK(*s); else if(charset[CURLFNM_UPPER]) found = ISUPPER(*s); else if(charset[CURLFNM_LOWER]) diff --git a/lib/ftplistparser.c b/lib/ftplistparser.c index 8ca46998f5..9f60cf931c 100644 --- a/lib/ftplistparser.c +++ b/lib/ftplistparser.c @@ -443,11 +443,10 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb, else if(c == '\n') { mem[parser->item_length - 1] = 0; if(!strncmp("total ", mem, 6)) { - char *endptr = mem + 6; + const char *endptr = mem + 6; /* here we can deal with directory size, pass the leading whitespace and then the digits */ - while(ISBLANK(*endptr)) - endptr++; + Curl_str_passblanks(&endptr); while(ISDIGIT(*endptr)) endptr++; if(*endptr) { diff --git a/lib/headers.c b/lib/headers.c index 411515dfe1..380e3a2c99 100644 --- a/lib/headers.c +++ b/lib/headers.c @@ -29,6 +29,7 @@ #include "strcase.h" #include "sendf.h" #include "headers.h" +#include "strparse.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" @@ -208,14 +209,13 @@ static CURLcode namevalue(char *header, size_t hlen, unsigned int type, else return CURLE_BAD_FUNCTION_ARGUMENT; - /* skip all leading space letters */ - while(ISBLANK(*header)) - header++; + /* skip all leading blank letters */ + Curl_str_passblanks((const char **)&header); *value = header; /* skip all trailing space letters */ - while((end > header) && ISSPACE(*end)) + while((end > header) && ISBLANK(*end)) *end-- = 0; /* nul terminate */ return CURLE_OK; } @@ -235,7 +235,7 @@ static CURLcode unfold_value(struct Curl_easy *data, const char *value, oalloc = olen + offset + 1; /* skip all trailing space letters */ - while(vlen && ISSPACE(value[vlen - 1])) + while(vlen && ISBLANK(value[vlen - 1])) vlen--; /* save only one leading space */ diff --git a/lib/hsts.c b/lib/hsts.c index 9ea4789e77..7bad29f83e 100644 --- a/lib/hsts.c +++ b/lib/hsts.c @@ -154,8 +154,7 @@ CURLcode Curl_hsts_parse(struct hsts *h, const char *hostname, return CURLE_OK; do { - while(ISBLANK(*p)) - p++; + Curl_str_passblanks(&p); if(strncasecompare("max-age", p, 7)) { bool quoted = FALSE; int rc; @@ -164,17 +163,14 @@ CURLcode Curl_hsts_parse(struct hsts *h, const char *hostname, return CURLE_BAD_FUNCTION_ARGUMENT; p += 7; - while(ISBLANK(*p)) - p++; - if(*p++ != '=') + Curl_str_passblanks(&p); + if(Curl_str_single(&p, '=')) return CURLE_BAD_FUNCTION_ARGUMENT; - while(ISBLANK(*p)) - p++; + Curl_str_passblanks(&p); - if(*p == '\"') { - p++; + if(!Curl_str_single(&p, '\"')) quoted = TRUE; - } + rc = Curl_str_number(&p, &expires, TIME_T_MAX); if(rc == STRE_OVERFLOW) expires = CURL_OFF_T_MAX; @@ -202,8 +198,7 @@ CURLcode Curl_hsts_parse(struct hsts *h, const char *hostname, p++; } - while(ISBLANK(*p)) - p++; + Curl_str_passblanks(&p); if(*p == ';') p++; } while(*p); @@ -533,9 +528,9 @@ static CURLcode hsts_load(struct hsts *h, const char *file) struct dynbuf buf; Curl_dyn_init(&buf, MAX_HSTS_LINE); while(Curl_get_line(&buf, fp)) { - char *lineptr = Curl_dyn_ptr(&buf); - while(ISBLANK(*lineptr)) - lineptr++; + const char *lineptr = Curl_dyn_ptr(&buf); + Curl_str_passblanks(&lineptr); + /* * Skip empty or commented lines, since we know the line will have a * trailing newline from Curl_get_line we can treat length 1 as empty. diff --git a/lib/http.c b/lib/http.c index b273059d2d..944c35d63c 100644 --- a/lib/http.c +++ b/lib/http.c @@ -1073,8 +1073,7 @@ CURLcode Curl_http_input_auth(struct Curl_easy *data, bool proxy, auth++; else break; - while(ISBLANK(*auth)) - auth++; + Curl_str_passblanks(&auth); } #else (void) proxy; @@ -3880,8 +3879,7 @@ static CURLcode http_rw_hd(struct Curl_easy *data, */ const char *p = hd; - while(ISBLANK(*p)) - p++; + Curl_str_passblanks(&p); if(!strncmp(p, "HTTP/", 5)) { p += 5; switch(*p) { @@ -3895,7 +3893,7 @@ static CURLcode http_rw_hd(struct Curl_easy *data, k->httpcode = (p[0] - '0') * 100 + (p[1] - '0') * 10 + (p[2] - '0'); p += 3; - if(ISSPACE(*p)) + if(ISBLANK(*p)) fine_statusline = TRUE; } } @@ -3915,7 +3913,7 @@ static CURLcode http_rw_hd(struct Curl_easy *data, k->httpcode = (p[0] - '0') * 100 + (p[1] - '0') * 10 + (p[2] - '0'); p += 3; - if(!ISSPACE(*p)) + if(!ISBLANK(*p)) break; fine_statusline = TRUE; } @@ -4473,8 +4471,7 @@ CURLcode Curl_http_req_to_h2(struct dynhds *h2_headers, scheme = Curl_checkheaders(data, STRCONST(HTTP_PSEUDO_SCHEME)); if(scheme) { scheme += sizeof(HTTP_PSEUDO_SCHEME); - while(ISBLANK(*scheme)) - scheme++; + Curl_str_passblanks(&scheme); infof(data, "set pseudo header %s to %s", HTTP_PSEUDO_SCHEME, scheme); } else { diff --git a/lib/http_aws_sigv4.c b/lib/http_aws_sigv4.c index 4ed55f0cee..345ac0910f 100644 --- a/lib/http_aws_sigv4.c +++ b/lib/http_aws_sigv4.c @@ -83,7 +83,7 @@ static void trim_headers(struct curl_slist *head) { struct curl_slist *l; for(l = head; l; l = l->next) { - char *value; /* to read from */ + const char *value; /* to read from */ char *store; size_t colon = strcspn(l->data, ":"); Curl_strntolower(l->data, l->data, colon); @@ -92,11 +92,10 @@ static void trim_headers(struct curl_slist *head) if(!*value) continue; ++value; - store = value; + store = (char *)value; /* skip leading whitespace */ - while(ISBLANK(*value)) - value++; + Curl_str_passblanks(&value); while(*value) { int space = 0; @@ -234,7 +233,7 @@ static CURLcode make_headers(struct Curl_easy *data, sep = strchr(l->data, ';'); if(!sep || (*sep == ':' && !*(sep + 1))) continue; - for(ptr = sep + 1; ISSPACE(*ptr); ++ptr) + for(ptr = sep + 1; ISBLANK(*ptr); ++ptr) ; if(!*ptr && ptr != sep + 1) /* a value of whitespace only */ continue; @@ -261,16 +260,15 @@ static CURLcode make_headers(struct Curl_easy *data, *date_header = aprintf("%s: %s\r\n", date_hdr_key, timestamp); } else { - char *value; - char *endp; + const char *value; + const char *endp; value = strchr(*date_header, ':'); if(!value) { *date_header = NULL; goto fail; } ++value; - while(ISBLANK(*value)) - ++value; + Curl_str_passblanks(&value); endp = value; while(*endp && ISALNUM(*endp)) ++endp; @@ -334,14 +332,14 @@ fail: SHA256_HEX_LENGTH) /* try to parse a payload hash from the content-sha256 header */ -static char *parse_content_sha_hdr(struct Curl_easy *data, - const char *provider1, - size_t plen, - size_t *value_len) +static const char *parse_content_sha_hdr(struct Curl_easy *data, + const char *provider1, + size_t plen, + size_t *value_len) { char key[CONTENT_SHA256_KEY_LEN]; size_t key_len; - char *value; + const char *value; size_t len; key_len = msnprintf(key, sizeof(key), "x-%.*s-content-sha256", @@ -356,8 +354,7 @@ static char *parse_content_sha_hdr(struct Curl_easy *data, return NULL; ++value; - while(ISBLANK(*value)) - ++value; + Curl_str_passblanks(&value); len = strlen(value); while(len > 0 && ISBLANK(value[len-1])) @@ -593,7 +590,7 @@ CURLcode Curl_output_aws_sigv4(struct Curl_easy *data, bool proxy) char *date_header = NULL; Curl_HttpReq httpreq; const char *method = NULL; - char *payload_hash = NULL; + const char *payload_hash = NULL; size_t payload_hash_len = 0; unsigned char sha_hash[CURL_SHA256_DIGEST_LENGTH]; char sha_hex[SHA256_HEX_LENGTH]; diff --git a/lib/http_digest.c b/lib/http_digest.c index 3c81640f20..6b27a19a7e 100644 --- a/lib/http_digest.c +++ b/lib/http_digest.c @@ -30,6 +30,7 @@ #include "strcase.h" #include "vauth/vauth.h" #include "http_digest.h" +#include "strparse.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" @@ -62,8 +63,7 @@ CURLcode Curl_input_digest(struct Curl_easy *data, return CURLE_BAD_CONTENT_ENCODING; header += strlen("Digest"); - while(ISBLANK(*header)) - header++; + Curl_str_passblanks(&header); return Curl_auth_decode_digest_http_message(header, digest); } diff --git a/lib/http_negotiate.c b/lib/http_negotiate.c index b686b8ebc6..dd90a4e137 100644 --- a/lib/http_negotiate.c +++ b/lib/http_negotiate.c @@ -32,6 +32,7 @@ #include "http_negotiate.h" #include "vauth/vauth.h" #include "vtls/vtls.h" +#include "strparse.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" @@ -86,8 +87,7 @@ CURLcode Curl_input_negotiate(struct Curl_easy *data, struct connectdata *conn, /* Obtain the input token, if any */ header += strlen("Negotiate"); - while(ISBLANK(*header)) - header++; + Curl_str_passblanks(&header); len = strlen(header); neg_ctx->havenegdata = len != 0; diff --git a/lib/http_ntlm.c b/lib/http_ntlm.c index 2eee92742a..a2d342a7a0 100644 --- a/lib/http_ntlm.c +++ b/lib/http_ntlm.c @@ -41,6 +41,7 @@ #include "curl_base64.h" #include "vauth/vauth.h" #include "url.h" +#include "strparse.h" /* SSL backend-specific #if branches in this file must be kept in the order documented in curl_ntlm_core. */ @@ -70,9 +71,7 @@ CURLcode Curl_input_ntlm(struct Curl_easy *data, if(checkprefix("NTLM", header)) { header += strlen("NTLM"); - while(ISSPACE(*header)) - header++; - + Curl_str_passblanks(&header); if(*header) { unsigned char *hdr; size_t hdrlen; diff --git a/lib/http_proxy.c b/lib/http_proxy.c index 0ccb826edb..0cacf4cef3 100644 --- a/lib/http_proxy.c +++ b/lib/http_proxy.c @@ -43,6 +43,7 @@ #include "transfer.h" #include "multiif.h" #include "vauth/vauth.h" +#include "strparse.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" @@ -60,7 +61,7 @@ static CURLcode dynhds_add_custom(struct Curl_easy *data, struct dynhds *hds) { struct connectdata *conn = data->conn; - char *ptr; + const char *ptr; struct curl_slist *h[2]; struct curl_slist *headers; int numlists = 1; /* by default */ @@ -108,8 +109,7 @@ static CURLcode dynhds_add_custom(struct Curl_easy *data, name = headers->data; namelen = ptr - headers->data; ptr++; /* pass the colon */ - while(ISSPACE(*ptr)) - ptr++; + Curl_str_passblanks(&ptr); if(*ptr) { value = ptr; valuelen = strlen(value); @@ -131,8 +131,7 @@ static CURLcode dynhds_add_custom(struct Curl_easy *data, name = headers->data; namelen = ptr - headers->data; ptr++; /* pass the semicolon */ - while(ISSPACE(*ptr)) - ptr++; + Curl_str_passblanks(&ptr); if(!*ptr) { /* quirk #2, send an empty header */ value = ""; diff --git a/lib/netrc.c b/lib/netrc.c index 00aca78ece..83c6f42ac2 100644 --- a/lib/netrc.c +++ b/lib/netrc.c @@ -39,6 +39,7 @@ #include "netrc.h" #include "strcase.h" #include "curl_get_line.h" +#include "strparse.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" @@ -85,8 +86,7 @@ static NETRCcode file2memory(const char *filename, struct dynbuf *filebuf) CURLcode result; const char *line = Curl_dyn_ptr(&linebuf); /* skip comments on load */ - while(ISBLANK(*line)) - line++; + Curl_str_passblanks(&line); if(*line == '#') continue; result = Curl_dyn_add(filebuf, line); @@ -138,13 +138,12 @@ static NETRCcode parsenetrc(struct store_netrc *store, netrcbuffer = Curl_dyn_ptr(filebuf); while(!done) { - char *tok = netrcbuffer; + const char *tok = netrcbuffer; while(tok && !done) { - char *tok_end; + const char *tok_end; bool quoted; Curl_dyn_reset(&token); - while(ISBLANK(*tok)) - tok++; + Curl_str_passblanks(&tok); /* tok is first non-space letter */ if(state == MACDEF) { if((*tok == '\n') || (*tok == '\r')) @@ -162,7 +161,7 @@ static NETRCcode parsenetrc(struct store_netrc *store, if(!quoted) { size_t len = 0; CURLcode result; - while(!ISSPACE(*tok_end)) { + while(*tok_end > ' ') { tok_end++; len++; } diff --git a/lib/noproxy.c b/lib/noproxy.c index 23dd46ba74..d8cf1ddd74 100644 --- a/lib/noproxy.c +++ b/lib/noproxy.c @@ -29,6 +29,7 @@ #include "inet_pton.h" #include "strcase.h" #include "noproxy.h" +#include "strparse.h" #ifdef HAVE_NETINET_IN_H #include @@ -177,8 +178,7 @@ bool Curl_check_noproxy(const char *name, const char *no_proxy) bool match = FALSE; /* pass blanks */ - while(ISBLANK(*p)) - p++; + Curl_str_passblanks(&p); token = p; /* pass over the pattern */ @@ -247,8 +247,7 @@ bool Curl_check_noproxy(const char *name, const char *no_proxy) return TRUE; } /* if(tokenlen) */ /* pass blanks after pattern */ - while(ISBLANK(*p)) - p++; + Curl_str_passblanks(&p); /* if not a comma, this ends the loop */ if(*p != ',') break; diff --git a/lib/rtsp.c b/lib/rtsp.c index 7ff7274cb9..5ce8b001b2 100644 --- a/lib/rtsp.c +++ b/lib/rtsp.c @@ -929,8 +929,7 @@ CURLcode Curl_rtsp_parseheader(struct Curl_easy *data, const char *header) curl_off_t CSeq = 0; struct RTSP *rtsp = data->req.p.rtsp; const char *p = &header[5]; - while(ISBLANK(*p)) - p++; + Curl_str_passblanks(&p); if(Curl_str_number(&p, &CSeq, LONG_MAX)) { failf(data, "Unable to read the CSeq header: [%s]", header); return CURLE_RTSP_CSEQ_ERROR; @@ -944,8 +943,7 @@ CURLcode Curl_rtsp_parseheader(struct Curl_easy *data, const char *header) /* Find the first non-space letter */ start = header + 8; - while(ISBLANK(*start)) - start++; + Curl_str_passblanks(&start); if(!*start) { failf(data, "Got a blank Session ID"); @@ -959,7 +957,7 @@ CURLcode Curl_rtsp_parseheader(struct Curl_easy *data, const char *header) * gstreamer does url-encoded session ID's not covered by the standard. */ end = start; - while(*end && *end != ';' && !ISSPACE(*end)) + while((*end > ' ') && (*end != ';')) end++; idlen = end - start; @@ -1003,8 +1001,7 @@ CURLcode rtsp_parse_transport(struct Curl_easy *data, const char *transport) const char *start, *end; start = transport; while(start && *start) { - while(ISBLANK(*start) ) - start++; + Curl_str_passblanks(&start); end = strchr(start, ';'); if(checkprefix("interleaved=", start)) { curl_off_t chan1, chan2, chan; diff --git a/lib/strparse.c b/lib/strparse.c index a78c384906..db31cd7125 100644 --- a/lib/strparse.c +++ b/lib/strparse.c @@ -283,3 +283,10 @@ void Curl_str_trimblanks(struct Curl_str *out) while(out->len && ISBLANK(out->str[out->len - 1])) out->len--; } + +/* increase the pointer until it has moved over all blanks */ +void Curl_str_passblanks(const char **linep) +{ + while(ISBLANK(**linep)) + (*linep)++; /* move over it */ +} diff --git a/lib/strparse.h b/lib/strparse.h index e9109c55c2..8b4d1b68e9 100644 --- a/lib/strparse.h +++ b/lib/strparse.h @@ -97,5 +97,6 @@ int Curl_str_nudge(struct Curl_str *str, size_t num); int Curl_str_cspn(const char **linep, struct Curl_str *out, const char *cspn); void Curl_str_trimblanks(struct Curl_str *out); +void Curl_str_passblanks(const char **linep); #endif /* HEADER_CURL_STRPARSE_H */ diff --git a/lib/strtoofft.c b/lib/strtoofft.c index f347e2b6fe..6da60cd5e5 100644 --- a/lib/strtoofft.c +++ b/lib/strtoofft.c @@ -39,9 +39,7 @@ CURLofft curlx_strtoofft(const char *str, char **endp, int base, *num = 0; /* clear by default */ DEBUGASSERT((base == 10) || (base == 16)); - while(ISBLANK(*str)) - str++; - + Curl_str_passblanks(&str); rc = base == 10 ? Curl_str_number(&str, &number, CURL_OFF_T_MAX) : Curl_str_hex(&str, &number, CURL_OFF_T_MAX); diff --git a/lib/urlapi.c b/lib/urlapi.c index 060ccec151..06adda1127 100644 --- a/lib/urlapi.c +++ b/lib/urlapi.c @@ -128,10 +128,6 @@ static const char *find_host_sep(const char *url) /* convert CURLcode to CURLUcode */ #define cc2cu(x) ((x) == CURLE_TOO_LARGE ? CURLUE_TOO_LARGE : \ CURLUE_OUT_OF_MEMORY) -/* - * Decide whether a character in a URL must be escaped. - */ -#define urlchar_needs_escaping(c) (!(ISCNTRL(c) || ISSPACE(c) || ISGRAPH(c))) static const char hexdigits[] = "0123456789abcdef"; /* urlencode_str() writes data into an output dynbuf and URL-encodes the @@ -167,7 +163,7 @@ static CURLUcode urlencode_str(struct dynbuf *o, const char *url, else result = Curl_dyn_addn(o, "+", 1); } - else if(urlchar_needs_escaping(*iptr)) { + else if((*iptr < ' ') || (*iptr >= 0x7f)) { char out[3]={'%'}; out[1] = hexdigits[*iptr >> 4]; out[2] = hexdigits[*iptr & 0xf]; -- 2.47.3