From a5f5687368a5f95415d58d37e8dfb10c6b6d44c5 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 23 Nov 2021 14:16:38 +0100 Subject: [PATCH] urlapi: make Curl_is_absolute_url always use MAX_SCHEME_LEN Instad of having all callers pass in the maximum length, always use it. The passed in length is instead used only as the length of the target buffer for to storing the scheme name in, if used. Added the scheme max length restriction to the curl_url_set.3 man page. Follow-up to 45bcb2eaa78c79 Closes #8047 --- docs/libcurl/curl_url_set.3 | 3 ++- lib/transfer.c | 2 +- lib/url.c | 2 +- lib/urlapi-int.h | 4 +--- lib/urlapi.c | 20 ++++++++++++-------- 5 files changed, 17 insertions(+), 14 deletions(-) diff --git a/docs/libcurl/curl_url_set.3 b/docs/libcurl/curl_url_set.3 index 704171a75..3a871cd17 100644 --- a/docs/libcurl/curl_url_set.3 +++ b/docs/libcurl/curl_url_set.3 @@ -58,7 +58,8 @@ Pass a pointer to a null-terminated string to the \fIurl\fP parameter. The string must point to a correctly formatted "RFC 3986+" URL or be a NULL pointer. .IP CURLUPART_SCHEME -Scheme cannot be URL decoded on set. +Scheme cannot be URL decoded on set. libcurl only accepts setting schemes up +to 40 bytes long. .IP CURLUPART_USER .IP CURLUPART_PASSWORD .IP CURLUPART_OPTIONS diff --git a/lib/transfer.c b/lib/transfer.c index 05fec7998..22704fa15 100644 --- a/lib/transfer.c +++ b/lib/transfer.c @@ -1631,7 +1631,7 @@ CURLcode Curl_follow(struct Curl_easy *data, if((type != FOLLOW_RETRY) && (data->req.httpcode != 401) && (data->req.httpcode != 407) && - Curl_is_absolute_url(newurl, NULL, MAX_SCHEME_LEN)) + Curl_is_absolute_url(newurl, NULL, 0)) /* If this is not redirect due to a 401 or 407 response and an absolute URL: don't allow a custom port number */ disallowport = TRUE; diff --git a/lib/url.c b/lib/url.c index 9f446817f..72a028574 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1948,7 +1948,7 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data, return CURLE_OUT_OF_MEMORY; if(data->set.str[STRING_DEFAULT_PROTOCOL] && - !Curl_is_absolute_url(data->state.url, NULL, MAX_SCHEME_LEN)) { + !Curl_is_absolute_url(data->state.url, NULL, 0)) { char *url = aprintf("%s://%s", data->set.str[STRING_DEFAULT_PROTOCOL], data->state.url); if(!url) diff --git a/lib/urlapi-int.h b/lib/urlapi-int.h index 425723309..bd6b60175 100644 --- a/lib/urlapi-int.h +++ b/lib/urlapi-int.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2021, 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 @@ -22,8 +22,6 @@ * ***************************************************************************/ #include "curl_setup.h" -/* scheme is not URL encoded, the longest libcurl supported ones are... */ -#define MAX_SCHEME_LEN 40 bool Curl_is_absolute_url(const char *url, char *scheme, size_t buflen); diff --git a/lib/urlapi.c b/lib/urlapi.c index ff157c743..6963a805b 100644 --- a/lib/urlapi.c +++ b/lib/urlapi.c @@ -50,6 +50,9 @@ ((str)[1] == ':' || (str)[1] == '|') && \ ((str)[2] == '/' || (str)[2] == '\\' || (str)[2] == 0)) +/* scheme is not URL encoded, the longest libcurl supported ones are... */ +#define MAX_SCHEME_LEN 40 + /* Internal representation of CURLU. Point to URL-encoded strings. */ struct Curl_URL { char *scheme; @@ -228,21 +231,22 @@ static void strcpy_url(char *output, const char *url, bool relative) } /* - * Returns true if the given URL is absolute (as opposed to relative) within - * the buffer size. Returns the scheme in the buffer if TRUE and 'buf' is - * non-NULL. + * Returns true if the given URL is absolute (as opposed to relative). Returns + * the scheme in the buffer if TRUE and 'buf' is non-NULL. The buflen must + * be larger than MAX_SCHEME_LEN if buf is set. */ bool Curl_is_absolute_url(const char *url, char *buf, size_t buflen) { size_t i; - - if(buf && buflen) + DEBUGASSERT(!buf || (buflen > MAX_SCHEME_LEN)); + (void)buflen; /* only used in debug-builds */ + if(buf) buf[0] = 0; /* always leave a defined value in buf */ #ifdef WIN32 if(STARTS_WITH_DRIVE_PREFIX(url)) return FALSE; #endif - for(i = 0; i < buflen; ++i) { + for(i = 0; i < MAX_SCHEME_LEN; ++i) { char s = url[i]; if(s && (ISALNUM(s) || (s == '+') || (s == '-') || (s == '.') )) { /* RFC 3986 3.1 explains: @@ -817,7 +821,7 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags) hostname = &path[urllen + 1]; hostname[0] = 0; - if(Curl_is_absolute_url(url, schemebuf, sizeof(schemebuf) - 1)) { + if(Curl_is_absolute_url(url, schemebuf, sizeof(schemebuf))) { url_has_scheme = TRUE; schemelen = strlen(schemebuf); } @@ -1530,7 +1534,7 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what, char *redired_url; CURLU *handle2; - if(Curl_is_absolute_url(part, NULL, MAX_SCHEME_LEN)) { + if(Curl_is_absolute_url(part, NULL, 0)) { handle2 = curl_url(); if(!handle2) return CURLUE_OUT_OF_MEMORY;