escape: hex decode with a lookup-table
Makes the decoding 2.8 times faster in my tests. Closes #10376
This commit is contained in:
parent
1ca483a40c
commit
f1f8acb3b9
51
lib/escape.c
51
lib/escape.c
@ -115,6 +115,16 @@ char *curl_easy_escape(struct Curl_easy *data, const char *string,
|
||||
return Curl_dyn_ptr(&d);
|
||||
}
|
||||
|
||||
static const unsigned char hextable[] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, /* 0x30 - 0x3f */
|
||||
0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x40 - 0x4f */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x50 - 0x5f */
|
||||
0, 10, 11, 12, 13, 14, 15 /* 0x60 - 0x66 */
|
||||
};
|
||||
|
||||
/* the input is a single hex digit */
|
||||
#define onehex2dec(x) hextable[x - '0']
|
||||
|
||||
/*
|
||||
* Curl_urldecode() URL decodes the given string.
|
||||
*
|
||||
@ -137,54 +147,47 @@ CURLcode Curl_urldecode(const char *string, size_t length,
|
||||
{
|
||||
size_t alloc;
|
||||
char *ns;
|
||||
size_t strindex = 0;
|
||||
unsigned long hex;
|
||||
|
||||
DEBUGASSERT(string);
|
||||
DEBUGASSERT(ctrl >= REJECT_NADA); /* crash on TRUE/FALSE */
|
||||
|
||||
alloc = (length?length:strlen(string)) + 1;
|
||||
ns = malloc(alloc);
|
||||
alloc = (length?length:strlen(string));
|
||||
ns = malloc(alloc + 1);
|
||||
|
||||
if(!ns)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
while(--alloc > 0) {
|
||||
/* store output string */
|
||||
*ostring = ns;
|
||||
|
||||
while(alloc) {
|
||||
unsigned char in = *string;
|
||||
if(('%' == in) && (alloc > 2) &&
|
||||
ISXDIGIT(string[1]) && ISXDIGIT(string[2])) {
|
||||
/* this is two hexadecimal digits following a '%' */
|
||||
char hexstr[3];
|
||||
char *ptr;
|
||||
hexstr[0] = string[1];
|
||||
hexstr[1] = string[2];
|
||||
hexstr[2] = 0;
|
||||
in = (unsigned char)(onehex2dec(string[1]) << 4) | onehex2dec(string[2]);
|
||||
|
||||
hex = strtoul(hexstr, &ptr, 16);
|
||||
|
||||
in = curlx_ultouc(hex); /* this long is never bigger than 255 anyway */
|
||||
|
||||
string += 2;
|
||||
alloc -= 2;
|
||||
string += 3;
|
||||
alloc -= 3;
|
||||
}
|
||||
else {
|
||||
string++;
|
||||
alloc--;
|
||||
}
|
||||
|
||||
if(((ctrl == REJECT_CTRL) && (in < 0x20)) ||
|
||||
((ctrl == REJECT_ZERO) && (in == 0))) {
|
||||
free(ns);
|
||||
Curl_safefree(*ostring);
|
||||
return CURLE_URL_MALFORMAT;
|
||||
}
|
||||
|
||||
ns[strindex++] = in;
|
||||
string++;
|
||||
*ns++ = in;
|
||||
}
|
||||
ns[strindex] = 0; /* terminate it */
|
||||
*ns = 0; /* terminate it */
|
||||
|
||||
if(olen)
|
||||
/* store output size */
|
||||
*olen = strindex;
|
||||
|
||||
/* store output string */
|
||||
*ostring = ns;
|
||||
*olen = ns - *ostring;
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user