]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
urlapi: support CURLU_URLENCODE for curl_url_get()
authorDaniel Stenberg <daniel@haxx.se>
Wed, 8 Jun 2022 14:32:46 +0000 (16:32 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Wed, 8 Jun 2022 14:32:46 +0000 (16:32 +0200)
lib/urlapi.c

index 2a36de6a58f2b73f56f16431eab50211063516cd..4010f0ac758cbca04f7009b02cb5fd257437143a 100644 (file)
@@ -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