summaryrefslogtreecommitdiff
path: root/lib/urlapi.c
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2022-06-08 16:32:46 +0200
committerDaniel Stenberg <daniel@haxx.se>2022-06-08 16:32:46 +0200
commitc3fc406ebb56c113d4ebdce54dcbad34db848056 (patch)
tree29de5b199bb1a2605aa561d6dc3415d873628f3b /lib/urlapi.c
parentdb8cfdc8f7a6e52b11ebeb3b482af1fe69e90051 (diff)
downloadcurl-c3fc406ebb56c113d4ebdce54dcbad34db848056.tar.gz
urlapi: support CURLU_URLENCODE for curl_url_get()
Diffstat (limited to 'lib/urlapi.c')
-rw-r--r--lib/urlapi.c21
1 files changed, 20 insertions, 1 deletions
diff --git a/lib/urlapi.c b/lib/urlapi.c
index 2a36de6a5..4010f0ac7 100644
--- a/lib/urlapi.c
+++ b/lib/urlapi.c
@@ -175,14 +175,17 @@ static size_t strlen_url(const char *url, bool relative)
* the source URL accordingly.
* URL encoding should be skipped for host names, otherwise IDN resolution
* will fail.
+ *
+ * Returns TRUE if something was updated.
*/
-static void strcpy_url(char *output, const char *url, bool relative)
+static bool strcpy_url(char *output, const char *url, bool relative)
{
/* we must add this with whitespace-replacing */
bool left = TRUE;
const unsigned char *iptr;
char *optr = output;
const unsigned char *host_sep = (const unsigned char *) url;
+ bool changed = FALSE;
if(!relative)
host_sep = (const unsigned char *) find_host_sep(url);
@@ -204,6 +207,7 @@ static void strcpy_url(char *output, const char *url, bool relative)
}
else
*optr++='+'; /* add a '+' here */
+ changed = TRUE;
continue;
}
@@ -212,6 +216,7 @@ static void strcpy_url(char *output, const char *url, bool relative)
if(urlchar_needs_escaping(*iptr)) {
msnprintf(optr, 4, "%%%02x", *iptr);
+ changed = TRUE;
optr += 3;
}
else
@@ -219,6 +224,7 @@ static void strcpy_url(char *output, const char *url, bool relative)
}
*optr = 0; /* null-terminate output buffer */
+ return changed;
}
/*
@@ -1436,6 +1442,19 @@ CURLUcode curl_url_get(CURLU *u, CURLUPart what,
}
*part = decoded;
}
+ if(urlencode) {
+ /* worst case output length is 3x the original! */
+ char *newp = malloc(strlen(*part) * 3);
+ if(!newp)
+ return CURLUE_OUT_OF_MEMORY;
+ if(strcpy_url(newp, *part, TRUE)) { /* consider it relative */
+ free(*part);
+ *part = newp;
+ }
+ else
+ free(newp);
+ }
+
return CURLUE_OK;
}
else