]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
urlapi: avoid Curl_dyn_addf() for hex outputs
authorDaniel Stenberg <daniel@haxx.se>
Tue, 31 Jan 2023 23:17:28 +0000 (00:17 +0100)
committerDaniel Stenberg <daniel@haxx.se>
Wed, 1 Feb 2023 22:05:51 +0000 (23:05 +0100)
Inspired by the recent fixes to escape.c, we should avoid calling
Curl_dyn_addf() in loops, perhaps in particular when adding something so
simple as %HH codes - for performance reasons. This change makes the
same thing for the URL parser's two URL-encoding loops.

Closes #10384

lib/curl_ctype.h
lib/urlapi.c

index 215b1776786582f762dceb766d74a433b26e9a0c..1d1d60c28d15183ac781b8cd2996a92111782d0c 100644 (file)
@@ -27,7 +27,7 @@
 #define ISLOWHEXALHA(x) (((x) >= 'a') && ((x) <= 'f'))
 #define ISUPHEXALHA(x) (((x) >= 'A') && ((x) <= 'F'))
 
-#define ISLOWCNTRL(x) ((x) >= 0 && ((x) <= 0x1f))
+#define ISLOWCNTRL(x) ((unsigned char)(x) <= 0x1f)
 #define IS7F(x) ((x) == 0x7f)
 
 #define ISLOWPRINT(x) (((x) >= 9) && ((x) <= 0x0d))
index ef9ec4169f6b2c7761ec3a3297cb2368514a6078..f22adc7afd17f07ff0a864443b10bbfe69a92ec0 100644 (file)
@@ -117,14 +117,11 @@ static const char *find_host_sep(const char *url)
 }
 
 /*
- * Decide in an encoding-independent manner whether a character in a URL must
- * be escaped. This is used in urlencode_str().
+ * Decide whether a character in a URL must be escaped.
  */
-static bool urlchar_needs_escaping(int c)
-{
-  return !(ISCNTRL(c) || ISSPACE(c) || ISGRAPH(c));
-}
+#define urlchar_needs_escaping(c) (!(ISCNTRL(c) || ISSPACE(c) || ISGRAPH(c)))
 
+static const char hexdigits[] = "0123456789abcdef";
 /* urlencode_str() writes data into an output dynbuf and URL-encodes the
  * spaces in the source URL accordingly.
  *
@@ -168,7 +165,10 @@ static CURLUcode urlencode_str(struct dynbuf *o, const char *url,
       left = FALSE;
 
     if(urlchar_needs_escaping(*iptr)) {
-      if(Curl_dyn_addf(o, "%%%02x", *iptr))
+      char out[3]={'%'};
+      out[1] = hexdigits[*iptr>>4];
+      out[2] = hexdigits[*iptr & 0xf];
+      if(Curl_dyn_addn(o, out, 3))
         return CURLUE_OUT_OF_MEMORY;
     }
     else {
@@ -1836,7 +1836,10 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
             return CURLUE_OUT_OF_MEMORY;
         }
         else {
-          result = Curl_dyn_addf(&enc, "%%%02x", *i);
+          char out[3]={'%'};
+          out[1] = hexdigits[*i>>4];
+          out[2] = hexdigits[*i & 0xf];
+          result = Curl_dyn_addn(&enc, out, 3);
           if(result)
             return CURLUE_OUT_OF_MEMORY;
         }