diff options
author | Dan Fandrich <dan@coneharvesters.com> | 2023-02-04 16:05:35 -0800 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2023-02-07 08:20:04 +0100 |
commit | 349c5391f2121ee0338dcf5a61dafde7bc83be57 (patch) | |
tree | 4d87c540ce1b54a85ea23088f537994d863ea768 /src | |
parent | a0adda4b47d653cd079df22b9a749279678ada04 (diff) | |
download | curl-349c5391f2121ee0338dcf5a61dafde7bc83be57.tar.gz |
tool_operate: Fix error codes on bad URL & OOM
curl would erroneously report CURLE_OUT_OF_MEMORY in some cases instead
of CURLE_URL_MALFORMAT. In other cases, it would erroneously return
CURLE_URL_MALFORMAT instead of CURLE_OUT_OF_MEMORY. Add a test case to
test the former condition.
Fixes #10130
Closes #10414
Diffstat (limited to 'src')
-rw-r--r-- | src/tool_operate.c | 25 | ||||
-rw-r--r-- | src/tool_operhlp.c | 109 | ||||
-rw-r--r-- | src/tool_operhlp.h | 2 |
3 files changed, 86 insertions, 50 deletions
diff --git a/src/tool_operate.c b/src/tool_operate.c index 2fccfda67..ae17586d8 100644 --- a/src/tool_operate.c +++ b/src/tool_operate.c @@ -1209,21 +1209,26 @@ static CURLcode single_transfer(struct GlobalConfig *global, CURLU *uh = curl_url(); if(uh) { char *updated; - if(curl_url_set(uh, CURLUPART_URL, per->this_url, - CURLU_GUESS_SCHEME)) { - result = CURLE_FAILED_INIT; + CURLUcode uerr; + uerr = curl_url_set(uh, CURLUPART_URL, per->this_url, + CURLU_GUESS_SCHEME); + if(uerr) { + result = urlerr_cvt(uerr); errorf(global, "(%d) Could not parse the URL, " "failed to set query\n", result); config->synthetic_error = TRUE; } - else if(curl_url_set(uh, CURLUPART_QUERY, q, CURLU_APPENDQUERY) || - curl_url_get(uh, CURLUPART_URL, &updated, - CURLU_GUESS_SCHEME)) { - result = CURLE_OUT_OF_MEMORY; - } else { - Curl_safefree(per->this_url); /* free previous URL */ - per->this_url = updated; /* use our new URL instead! */ + uerr = curl_url_set(uh, CURLUPART_QUERY, q, CURLU_APPENDQUERY); + if(!uerr) + uerr = curl_url_get(uh, CURLUPART_URL, &updated, + CURLU_GUESS_SCHEME); + if(uerr) + result = urlerr_cvt(uerr); + else { + Curl_safefree(per->this_url); /* free previous URL */ + per->this_url = updated; /* use our new URL instead! */ + } } curl_url_cleanup(uh); if(result) diff --git a/src/tool_operhlp.c b/src/tool_operhlp.c index f6ae04d78..02039413c 100644 --- a/src/tool_operhlp.c +++ b/src/tool_operhlp.c @@ -71,22 +71,43 @@ bool stdin_upload(const char *uploadfile) !strcmp(uploadfile, ".")) ? TRUE : FALSE; } +/* Convert a CURLUcode into a CURLcode */ +CURLcode urlerr_cvt(CURLUcode ucode) +{ + if(ucode == CURLUE_OUT_OF_MEMORY) + return CURLE_OUT_OF_MEMORY; + else if(ucode == CURLUE_UNSUPPORTED_SCHEME) + return CURLE_UNSUPPORTED_PROTOCOL; + else if(ucode == CURLUE_LACKS_IDN) + return CURLE_NOT_BUILT_IN; + else if(ucode == CURLUE_BAD_HANDLE) + return CURLE_BAD_FUNCTION_ARGUMENT; + return CURLE_URL_MALFORMAT; +} + /* * Adds the file name to the URL if it doesn't already have one. * url will be freed before return if the returned pointer is different */ CURLcode add_file_name_to_url(CURL *curl, char **inurlp, const char *filename) { - CURLcode result = CURLE_OUT_OF_MEMORY; + CURLcode result = CURLE_URL_MALFORMAT; + CURLUcode uerr; CURLU *uh = curl_url(); char *path = NULL; if(uh) { char *ptr; - if(curl_url_set(uh, CURLUPART_URL, *inurlp, - CURLU_GUESS_SCHEME|CURLU_NON_SUPPORT_SCHEME)) + uerr = curl_url_set(uh, CURLUPART_URL, *inurlp, + CURLU_GUESS_SCHEME|CURLU_NON_SUPPORT_SCHEME); + if(uerr) { + result = urlerr_cvt(uerr); goto fail; - if(curl_url_get(uh, CURLUPART_PATH, &path, 0)) + } + uerr = curl_url_get(uh, CURLUPART_PATH, &path, 0); + if(uerr) { + result = urlerr_cvt(uerr); goto fail; + } ptr = strrchr(path, '/'); if(!ptr || !*++ptr) { @@ -111,7 +132,6 @@ CURLcode add_file_name_to_url(CURL *curl, char **inurlp, const char *filename) if(encfile) { char *newpath; char *newurl; - CURLUcode uerr; if(ptr) /* there is a trailing slash on the path */ newpath = aprintf("%s%s", path, encfile); @@ -125,10 +145,15 @@ CURLcode add_file_name_to_url(CURL *curl, char **inurlp, const char *filename) goto fail; uerr = curl_url_set(uh, CURLUPART_PATH, newpath, 0); free(newpath); - if(uerr) + if(uerr) { + result = urlerr_cvt(uerr); goto fail; - if(curl_url_get(uh, CURLUPART_URL, &newurl, CURLU_DEFAULT_SCHEME)) + } + uerr = curl_url_get(uh, CURLUPART_URL, &newurl, CURLU_DEFAULT_SCHEME); + if(uerr) { + result = urlerr_cvt(uerr); goto fail; + } free(*inurlp); *inurlp = newurl; result = CURLE_OK; @@ -153,32 +178,35 @@ CURLcode get_url_file_name(char **filename, const char *url) const char *pc, *pc2; CURLU *uh = curl_url(); char *path = NULL; + CURLUcode uerr; if(!uh) return CURLE_OUT_OF_MEMORY; *filename = NULL; - if(!curl_url_set(uh, CURLUPART_URL, url, CURLU_GUESS_SCHEME) && - !curl_url_get(uh, CURLUPART_PATH, &path, 0)) { - curl_url_cleanup(uh); + uerr = curl_url_set(uh, CURLUPART_URL, url, CURLU_GUESS_SCHEME); + if(!uerr) { + uerr = curl_url_get(uh, CURLUPART_PATH, &path, 0); + if(!uerr) { + curl_url_cleanup(uh); - pc = strrchr(path, '/'); - pc2 = strrchr(pc ? pc + 1 : path, '\\'); - if(pc2) - pc = pc2; + 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 = ""; + 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; + *filename = strdup(pc); + curl_free(path); + if(!*filename) + return CURLE_OUT_OF_MEMORY; #if defined(MSDOS) || defined(WIN32) { @@ -191,25 +219,26 @@ CURLcode get_url_file_name(char **filename, const char *url) } #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 *alt = aprintf("%s/%s", tdir, *filename); - Curl_safefree(*filename); - *filename = alt; - 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; + return urlerr_cvt(uerr); } diff --git a/src/tool_operhlp.h b/src/tool_operhlp.h index 1f2c19c66..1d56fa040 100644 --- a/src/tool_operhlp.h +++ b/src/tool_operhlp.h @@ -37,4 +37,6 @@ CURLcode add_file_name_to_url(CURL *curl, char **inurlp, const char *filename); CURLcode get_url_file_name(char **filename, const char *url); +CURLcode urlerr_cvt(CURLUcode ucode); + #endif /* HEADER_CURL_TOOL_OPERHLP_H */ |