diff options
author | Stefan Eissing <stefan.eissing@greenbytes.de> | 2021-11-22 12:47:56 +0100 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2021-11-22 22:41:11 +0100 |
commit | 45bcb2eaa78c790966f678c17482e70cca6593db (patch) | |
tree | 045be63d1c53d11d6d078a1d59a475f975109251 /lib | |
parent | 18270893abdb19f0ca170c118f8a2847dbd304be (diff) | |
download | curl-45bcb2eaa78c790966f678c17482e70cca6593db.tar.gz |
urlapi: cleanup scheme parsing
Makea Curl_is_absolute_url() always leave a defined 'buf' and avoids
copying on urls that do not start with a scheme.
Closes #8043
Diffstat (limited to 'lib')
-rw-r--r-- | lib/urlapi.c | 38 |
1 files changed, 22 insertions, 16 deletions
diff --git a/lib/urlapi.c b/lib/urlapi.c index 6d116b61b..b0bce2e7d 100644 --- a/lib/urlapi.c +++ b/lib/urlapi.c @@ -235,26 +235,32 @@ static void strcpy_url(char *output, const char *url, bool relative) bool Curl_is_absolute_url(const char *url, char *buf, size_t buflen) { size_t i; + + if(buf && buflen) + 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 && url[i]; ++i) { + for(i = 0; i < buflen; ++i) { char s = url[i]; - if((s == ':') && (url[i + 1] == '/')) { - if(buf) - buf[i] = 0; - return TRUE; + if(s && (ISALNUM(s) || (s == '+') || (s == '-') || (s == '.') )) { + /* RFC 3986 3.1 explains: + scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) + */ } - /* RFC 3986 3.1 explains: - scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) - */ - else if(ISALNUM(s) || (s == '+') || (s == '-') || (s == '.') ) { - if(buf) - buf[i] = (char)TOLOWER(s); - } - else + else { break; + } + } + if(i && (url[i] == ':') && (url[i + 1] == '/')) { + if(buf) { + buf[i] = 0; + while(i--) { + buf[i] = (char)TOLOWER(url[i]); + } + } + return TRUE; } return FALSE; } @@ -811,13 +817,13 @@ 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))) { + if(Curl_is_absolute_url(url, schemebuf, sizeof(schemebuf) - 1)) { url_has_scheme = TRUE; schemelen = strlen(schemebuf); } /* handle the file: scheme */ - if(url_has_scheme && strcasecompare(schemebuf, "file")) { + if(url_has_scheme && !strcmp(schemebuf, "file")) { /* path has been allocated large enough to hold this */ strcpy(path, &url[5]); @@ -1520,7 +1526,7 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what, char *redired_url; CURLU *handle2; - if(Curl_is_absolute_url(part, NULL, MAX_SCHEME_LEN + 1)) { + if(Curl_is_absolute_url(part, NULL, MAX_SCHEME_LEN)) { handle2 = curl_url(); if(!handle2) return CURLUE_OUT_OF_MEMORY; |