summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDan Fandrich <dan@coneharvesters.com>2023-02-04 16:05:35 -0800
committerDaniel Stenberg <daniel@haxx.se>2023-02-07 08:20:04 +0100
commit349c5391f2121ee0338dcf5a61dafde7bc83be57 (patch)
tree4d87c540ce1b54a85ea23088f537994d863ea768 /src
parenta0adda4b47d653cd079df22b9a749279678ada04 (diff)
downloadcurl-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.c25
-rw-r--r--src/tool_operhlp.c109
-rw-r--r--src/tool_operhlp.h2
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 */