From 7d84c19bec7482a9f470c29ffa9390cb5b38adc7 Mon Sep 17 00:00:00 2001 From: Srivardhan Hebbar Date: Mon, 7 Dec 2015 18:41:53 +0900 Subject: [PATCH] eina: Adding API for base64 decode. Summary: Added eina_str_base64_decode API. Signed-off-by: Srivardhan Hebbar Reviewers: cedric, jpeg Reviewed By: jpeg Subscribers: jpeg Differential Revision: https://phab.enlightenment.org/D3381 @feature --- src/lib/eina/eina_str.c | 76 +++++++++++++++++++++++++++++++++++++++++ src/lib/eina/eina_str.h | 13 +++++++ 2 files changed, 89 insertions(+) diff --git a/src/lib/eina/eina_str.c b/src/lib/eina/eina_str.c index 4ff23e9c3a..86852975ba 100644 --- a/src/lib/eina/eina_str.c +++ b/src/lib/eina/eina_str.c @@ -299,6 +299,11 @@ eina_str_split_full_helper(const char *str, return str_array; } +static inline Eina_Bool is_base64(unsigned char c) +{ + return (isalnum(c) || (c == '+') || (c == '/')); +} + /** * @endcond */ @@ -779,3 +784,74 @@ eina_str_base64_encode(const unsigned char *src, unsigned int len) return dest; } + +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,(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; +} diff --git a/src/lib/eina/eina_str.h b/src/lib/eina/eina_str.h index c47ddb464c..3caba1fa82 100644 --- a/src/lib/eina/eina_str.h +++ b/src/lib/eina/eina_str.h @@ -395,6 +395,19 @@ EAPI char *eina_strftime(const char *format, const struct tm *tm); */ EAPI char *eina_str_base64_encode(const unsigned char *src, unsigned int len); +/** + * @brief base64 decoding function. + * @param src The string to be decoded. + * @param decoded_str_len The length of the decoded string. + * @return the base64 decoded string. + * + * This will create a NULL terminated string which is base64 decode of the src. + * The caller has to free the returned string using free(). + * + * @since 1.17.0 + */ +EAPI unsigned char * eina_str_base64_decode(const char * src, int *decoded_str_len); + #include "eina_inline_str.x" /**