forked from enlightenment/efl
eina: API for base64url decode.
Summary: eina_base64url_decode API. Signed-off-by: Srivardhan Hebbar <sri.hebbar@samsung.com> Reviewers: jpeg, cedric Differential Revision: https://phab.enlightenment.org/D3434
This commit is contained in:
parent
9f99213723
commit
1243b24f9b
|
@ -301,9 +301,12 @@ eina_str_split_full_helper(const char *str,
|
|||
return str_array;
|
||||
}
|
||||
|
||||
static inline Eina_Bool is_base64(unsigned char c)
|
||||
static inline Eina_Bool is_base64_char(unsigned char c, Eina_Bool is_base64url)
|
||||
{
|
||||
return (isalnum(c) || (c == '+') || (c == '/'));
|
||||
if (is_base64url)
|
||||
return (isalnum(c) || (c == '-') || (c == '_'));
|
||||
else
|
||||
return (isalnum(c) || (c == '+') || (c == '/'));
|
||||
}
|
||||
|
||||
static char *
|
||||
|
@ -366,6 +369,83 @@ eina_str_base64_encode_common(const unsigned char *src, unsigned int len, Eina_B
|
|||
return dest;
|
||||
}
|
||||
|
||||
static
|
||||
unsigned char *eina_str_base64_decode_common(const char * src, int *decoded_str_len, Eina_Bool is_base64url_decode)
|
||||
{
|
||||
unsigned char inarr[4], outarr[3];
|
||||
int i = 0, j = 0, k = 0, l = 0;
|
||||
int len;
|
||||
unsigned char *dest;
|
||||
const char *base64_table;
|
||||
|
||||
if (!src)
|
||||
goto error;
|
||||
|
||||
len = strlen(src);
|
||||
/* The encoded string length should be a multiple of 4. Else it is not a
|
||||
* valid encoded string.
|
||||
*/
|
||||
if (!is_base64url_decode && (len % 4))
|
||||
goto error;
|
||||
|
||||
/* This is the max size the destination string can have.
|
||||
*/
|
||||
dest = (unsigned char *)malloc(sizeof(unsigned char) * ((len * 3 / 4) + 1));
|
||||
if (!dest)
|
||||
goto error;
|
||||
|
||||
if (is_base64url_decode)
|
||||
base64_table = base64_table_url;
|
||||
else
|
||||
base64_table = base64_table_normal;
|
||||
|
||||
while (len-- && (src[k] != '=') && is_base64_char(src[k], is_base64url_decode))
|
||||
{
|
||||
inarr[i++] = src[k++];
|
||||
if (i == 4)
|
||||
{
|
||||
for (i = 0; i <4; i++)
|
||||
inarr[i] = strchr(base64_table,(int) inarr[i]) - base64_table;
|
||||
|
||||
outarr[0] = (inarr[0] << 2) + ((inarr[1] & 0x30) >> 4);
|
||||
outarr[1] = ((inarr[1] & 0xf) << 4) + ((inarr[2] & 0x3c) >> 2);
|
||||
outarr[2] = ((inarr[2] & 0x3) << 6) + inarr[3];
|
||||
|
||||
for (i = 0; (i < 3); i++)
|
||||
dest[l++] = outarr[i];
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (i)
|
||||
{
|
||||
for (j = i; j <4; j++)
|
||||
inarr[j] = 0;
|
||||
|
||||
for (j = 0; j <4; j++)
|
||||
inarr[j] = strchr(base64_table, (int) inarr[j]) - base64_table;
|
||||
|
||||
outarr[0] = (inarr[0] << 2) + ((inarr[1] & 0x30) >> 4);
|
||||
outarr[1] = ((inarr[1] & 0xf) << 4) + ((inarr[2] & 0x3c) >> 2);
|
||||
outarr[2] = ((inarr[2] & 0x3) << 6) + inarr[3];
|
||||
|
||||
for (j = 0; (j < i - 1); j++)
|
||||
dest[l++] = outarr[j];
|
||||
}
|
||||
|
||||
/* This is to prevent the applications from crashing. */
|
||||
dest[l] = '\0';
|
||||
|
||||
if (decoded_str_len)
|
||||
*decoded_str_len = l;
|
||||
return dest;
|
||||
|
||||
error:
|
||||
if (decoded_str_len)
|
||||
*decoded_str_len = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @endcond
|
||||
*/
|
||||
|
@ -810,70 +890,11 @@ eina_str_base64url_encode(const unsigned char *src, unsigned int len)
|
|||
EAPI
|
||||
unsigned char *eina_str_base64_decode(const char * src, int *decoded_str_len)
|
||||
{
|
||||
unsigned char inarr[4], outarr[3];
|
||||
int i = 0, j = 0, k = 0, l = 0;
|
||||
int len;
|
||||
unsigned char *dest;
|
||||
|
||||
if (!src)
|
||||
goto error;
|
||||
|
||||
len = strlen(src);
|
||||
/* The encoded string length should be a multiple of 4. Else it is not a
|
||||
* valid encoded string.
|
||||
*/
|
||||
if (len % 4)
|
||||
goto error;
|
||||
|
||||
/* This is the max size the destination string can have.
|
||||
*/
|
||||
dest = (unsigned char *)malloc(sizeof(unsigned char) * ((len * 3 / 4) + 1));
|
||||
if (!dest)
|
||||
goto error;
|
||||
|
||||
while (len-- && ( src[k] != '=') && is_base64(src[k]))
|
||||
{
|
||||
inarr[i++] = src[k++];
|
||||
if (i ==4)
|
||||
{
|
||||
for (i = 0; i <4; i++)
|
||||
inarr[i] = strchr(base64_table_normal,(int) inarr[i]) - base64_table_normal;
|
||||
|
||||
outarr[0] = (inarr[0] << 2) + ((inarr[1] & 0x30) >> 4);
|
||||
outarr[1] = ((inarr[1] & 0xf) << 4) + ((inarr[2] & 0x3c) >> 2);
|
||||
outarr[2] = ((inarr[2] & 0x3) << 6) + inarr[3];
|
||||
|
||||
for (i = 0; (i < 3); i++)
|
||||
dest[l++] = outarr[i];
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (i)
|
||||
{
|
||||
for (j = i; j <4; j++)
|
||||
inarr[j] = 0;
|
||||
|
||||
for (j = 0; j <4; j++)
|
||||
inarr[j] = strchr(base64_table_normal, (int) inarr[j]) - base64_table_normal;
|
||||
|
||||
outarr[0] = (inarr[0] << 2) + ((inarr[1] & 0x30) >> 4);
|
||||
outarr[1] = ((inarr[1] & 0xf) << 4) + ((inarr[2] & 0x3c) >> 2);
|
||||
outarr[2] = ((inarr[2] & 0x3) << 6) + inarr[3];
|
||||
|
||||
for (j = 0; (j < i - 1); j++)
|
||||
dest[l++] = outarr[j];
|
||||
}
|
||||
|
||||
/* This is to prevent the applications from crashing. */
|
||||
dest[l] = '\0';
|
||||
|
||||
if (decoded_str_len)
|
||||
*decoded_str_len = l;
|
||||
return dest;
|
||||
|
||||
error:
|
||||
if (decoded_str_len)
|
||||
*decoded_str_len = 0;
|
||||
return NULL;
|
||||
return eina_str_base64_decode_common(src, decoded_str_len, EINA_FALSE);
|
||||
}
|
||||
|
||||
EAPI
|
||||
unsigned char *eina_str_base64url_decode(const char * src, int *decoded_str_len)
|
||||
{
|
||||
return eina_str_base64_decode_common(src, decoded_str_len, EINA_TRUE);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue