From: Daniel Stenberg Date: Mon, 10 Oct 2022 09:10:12 +0000 (+0200) Subject: curl/get_url_file_name: use libcurl URL parser X-Git-Tag: curl-7_86_0~90 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=671adfa4938dd2c54c5931fe788bd4e257e64eed;p=thirdparty%2Fcurl.git curl/get_url_file_name: use libcurl URL parser To avoid URL tricks, use the URL parser for this. This update changes curl's behavior slightly in that it will ignore the possible query part from the URL and only use the file name from the actual path from the URL. I consider it a bugfix. "curl -O localhost/name?giveme-giveme" will now save the output in the local file named 'name' Updated test 1210 to verify Assisted-by: Jay Satiro Closes #9684 --- diff --git a/src/tool_operhlp.c b/src/tool_operhlp.c index d311e8d9da..f41406f3ce 100644 --- a/src/tool_operhlp.c +++ b/src/tool_operhlp.c @@ -149,61 +149,65 @@ CURLcode add_file_name_to_url(CURL *curl, char **inurlp, const char *filename) CURLcode get_url_file_name(char **filename, const char *url) { const char *pc, *pc2; + CURLU *uh = curl_url(); + char *path = NULL; + + if(!uh) + return CURLE_OUT_OF_MEMORY; *filename = NULL; - /* Find and get the remote file name */ - pc = strstr(url, "://"); - if(pc) - pc += 3; - else - pc = url; - - pc2 = strrchr(pc, '\\'); - pc = strrchr(pc, '/'); - if(pc2 && (!pc || pc < pc2)) - pc = pc2; - - if(pc) - /* duplicate the string beyond the slash */ - pc++; - else - /* no slash => empty string */ - pc = ""; - - *filename = strdup(pc); - if(!*filename) - return CURLE_OUT_OF_MEMORY; + if(!curl_url_set(uh, CURLUPART_URL, url, CURLU_GUESS_SCHEME) && + !curl_url_get(uh, CURLUPART_PATH, &path, 0)) { + curl_url_cleanup(uh); + + pc = strrchr(path, '/'); + pc2 = strrchr(pc ? pc + 1 : path, '\\'); + if(pc2) + pc = pc2; + + if(pc) + /* duplicate the string beyond the slash */ + pc++; + else + /* no slash => empty string */ + pc = ""; + + *filename = strdup(pc); + curl_free(path); + if(!*filename) + return CURLE_OUT_OF_MEMORY; #if defined(MSDOS) || defined(WIN32) - { - char *sanitized; - SANITIZEcode sc = sanitize_file_name(&sanitized, *filename, 0); - Curl_safefree(*filename); - if(sc) - return CURLE_URL_MALFORMAT; - *filename = sanitized; - } + { + char *sanitized; + SANITIZEcode sc = sanitize_file_name(&sanitized, *filename, 0); + Curl_safefree(*filename); + if(sc) + return CURLE_URL_MALFORMAT; + *filename = sanitized; + } #endif /* MSDOS || WIN32 */ - /* in case we built debug enabled, we allow an environment variable - * named CURL_TESTDIR to prefix the given file name to put it into a - * specific directory - */ + /* in case we built debug enabled, we allow an environment variable + * named CURL_TESTDIR to prefix the given file name to put it into a + * specific directory + */ #ifdef DEBUGBUILD - { - char *tdir = curlx_getenv("CURL_TESTDIR"); - if(tdir) { - char buffer[512]; /* suitably large */ - msnprintf(buffer, sizeof(buffer), "%s/%s", tdir, *filename); - Curl_safefree(*filename); - *filename = strdup(buffer); /* clone the buffer */ - curl_free(tdir); - if(!*filename) - return CURLE_OUT_OF_MEMORY; + { + char *tdir = curlx_getenv("CURL_TESTDIR"); + if(tdir) { + char *alt = aprintf("%s/%s", tdir, *filename); + Curl_safefree(*filename); + *filename = alt; + curl_free(tdir); + if(!*filename) + return CURLE_OUT_OF_MEMORY; + } } - } #endif - - return CURLE_OK; + return CURLE_OK; + } + curl_url_cleanup(uh); + return CURLE_URL_MALFORMAT; } diff --git a/tests/data/test1210 b/tests/data/test1210 index 037eb16d8e..89cfe61eaf 100644 --- a/tests/data/test1210 +++ b/tests/data/test1210 @@ -39,7 +39,7 @@ HTTP GET with -J without Content-Disposition CURL_TESTDIR=%PWD/log -http://%HOSTIP:%HTTPPORT/%TESTNUMBER -J -O +http://%HOSTIP:%HTTPPORT/%TESTNUMBER?junk -J -O @@ -47,7 +47,7 @@ http://%HOSTIP:%HTTPPORT/%TESTNUMBER -J -O # Verify data after the test has been "shot" -GET /%TESTNUMBER HTTP/1.1 +GET /%TESTNUMBER?junk HTTP/1.1 Host: %HOSTIP:%HTTPPORT User-Agent: curl/%VERSION Accept: */*