From 7305ca63e2b408a1fe9dc1c59f4e833bea942ee4 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 1 Feb 2023 00:17:28 +0100 Subject: [PATCH] urlapi: avoid Curl_dyn_addf() for hex outputs 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 | 2 +- lib/urlapi.c | 19 +++++++++++-------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/lib/curl_ctype.h b/lib/curl_ctype.h index 215b177678..1d1d60c28d 100644 --- a/lib/curl_ctype.h +++ b/lib/curl_ctype.h @@ -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)) diff --git a/lib/urlapi.c b/lib/urlapi.c index ef9ec4169f..f22adc7afd 100644 --- a/lib/urlapi.c +++ b/lib/urlapi.c @@ -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; } -- 2.47.2