wClipboard/posix: decode percent-encoding

Nothing really interesting here, it's exactly what it says on the tin.
The percent-encoding is specified by RFC 3986. And we take care to
detect invalid encodings.
This commit is contained in:
ilammy 2017-04-09 02:29:51 +03:00
parent 64e1073044
commit 50038bb725

View File

@ -98,9 +98,74 @@ static void free_posix_file(void* the_file)
free(file);
}
static unsigned char hex_to_dec(char c, BOOL* valid)
{
if (('0' <= c) && (c <= '9'))
return (c - '0');
if (('a' <= c) && (c <= 'f'))
return (c - 'a') + 10;
if (('A' <= c) && (c <= 'F'))
return (c - 'A') + 10;
*valid = FALSE;
return 0;
}
static BOOL decode_percent_encoded_byte(const char* str, const char* end, char* value)
{
BOOL valid = TRUE;
if ((end < str) || (end - str < strlen("%20")))
return FALSE;
*value = 0;
*value |= hex_to_dec(str[1], &valid);
*value <<= 4;
*value |= hex_to_dec(str[2], &valid);
return valid;
}
static char* decode_percent_encoded_string(const char* str, size_t len)
{
/* TBD: decode percent-encoded URI into a fresh null-terminated string */
char* buffer = NULL;
char* next = NULL;
const char* cur = str;
const char* lim = str + len;
/* Percent decoding shrinks data length, so len bytes will be enough. */
buffer = calloc(len + 1, sizeof(char));
if (!buffer)
return NULL;
next = buffer;
while (cur < lim)
{
if (*cur != '%')
{
*next++ = *cur++;
}
else
{
if (!decode_percent_encoded_byte(cur, lim, next))
{
WLog_ERR(TAG, "invalid percent encoding");
goto error;
}
cur += strlen("%20");
next += 1;
}
}
return buffer;
error:
free(buffer);
return NULL;
}