diff --git a/apache2/msc_util.c b/apache2/msc_util.c index 11c10371..99429fce 100644 --- a/apache2/msc_util.c +++ b/apache2/msc_util.c @@ -51,6 +51,29 @@ #define S_ISUID 04000 #endif /* defined(WIN32 || NETWARE) */ +/* Base64 tables used in decodeBase64Ext */ +static const char b64_pad = '='; + +static const short b64_reverse_t[256] = { + -2, -2, -2, -2, -2, -2, -2, -2, -2, -1, -1, -2, -2, -1, -2, -2, + -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, + -1, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 62, -2, -2, -2, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -2, -2, -2, -2, -2, -2, + -2, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -2, -2, -2, -2, -2, + -2, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -2, -2, -2, -2, -2, + -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, + -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, + -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, + -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, + -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, + -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, + -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, + -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2 +}; + + /** * */ @@ -66,6 +89,72 @@ int parse_boolean(const char *input) { return -1; } +/* \brief Decode Base64 data with special chars +* +* \param plain_text Pointer to plain text data +* \param input Pointer to input data +* \param input_len Input data length +* +* \retval 0 On failure +* \retval string length On Success +*/ +int decode_base64_ext(char *plain_text, const char *input, int input_len) +{ + const char *encoded = input; + int i = 0, j = 0, k = 0; + int ch = 0; + + while ((ch = *encoded++) != '\0' && input_len-- > 0) { + if (ch == b64_pad) { + if (*encoded != '=' && (i % 4) == 1) { + return 0; + } + continue; + } + + ch = b64_reverse_t[ch]; + if (ch < 0 || ch == -1) { + continue; + } else if (ch == -2) { + return 0; + } + switch(i % 4) { + case 0: + plain_text[j] = ch << 2; + break; + case 1: + plain_text[j++] |= ch >> 4; + plain_text[j] = (ch & 0x0f) << 4; + break; + case 2: + plain_text[j++] |= ch >>2; + plain_text[j] = (ch & 0x03) << 6; + break; + case 3: + plain_text[j++] |= ch; + break; + } + i++; + } + + k = j; + if (ch == b64_pad) { + switch(i % 4) { + case 1: + return 0; + case 2: + k++; + case 3: + plain_text[k] = 0; + } + } + + plain_text[j] = '\0'; + + return j; +} + + /** * Parses a string that contains a name-value pair in the form "name=value". * IMP1 It does not check for whitespace between tokens. diff --git a/apache2/msc_util.h b/apache2/msc_util.h index 53ccb002..c7be2591 100644 --- a/apache2/msc_util.h +++ b/apache2/msc_util.h @@ -90,6 +90,8 @@ char DSOLOCAL *log_escape_nul(apr_pool_t *mp, const unsigned char *text, unsigne char DSOLOCAL *_log_escape(apr_pool_t *p, const unsigned char *input, unsigned long int input_length, int escape_quotes, int escape_colon); +int DSOLOCAL decode_base64_ext(char *plain_text, const char *input, int input_len); + int DSOLOCAL js_decode_nonstrict_inplace(unsigned char *input, long int input_len); int DSOLOCAL urldecode_uni_nonstrict_inplace_ex(unsigned char *input, long int input_length, int * changed); diff --git a/apache2/re_tfns.c b/apache2/re_tfns.c index 2446a83a..034afe87 100644 --- a/apache2/re_tfns.c +++ b/apache2/re_tfns.c @@ -48,7 +48,6 @@ static const short b64_reverse_t[256] = { -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2 }; - /* lowercase */ static int msre_fn_lowercase_execute(apr_pool_t *mptmp, unsigned char *input, @@ -596,73 +595,6 @@ static int msre_fn_parityOdd7bit_execute(apr_pool_t *mptmp, unsigned char *input return changed; } -/* -* \brief Decode Base64 data with special chars -* -* \param plain_text Pointer to plain text data -* \param input Pointer to input data -* \param input_len Input data length -* -* \retval 0 On failure -* \retval string length On Success -*/ -int decode_base64_ext(char *plain_text, const char *input, int input_len) -{ - const char *encoded = input; - int i = 0, j = 0, k = 0; - int ch = 0; - - while ((ch = *encoded++) != '\0' && input_len-- > 0) { - if (ch == b64_pad) { - if (*encoded != '=' && (i % 4) == 1) { - return 0; - } - continue; - } - - ch = b64_reverse_t[ch]; - if (ch < 0 || ch == -1) { - continue; - } else if (ch == -2) { - return 0; - } - - switch(i % 4) { - case 0: - plain_text[j] = ch << 2; - break; - case 1: - plain_text[j++] |= ch >> 4; - plain_text[j] = (ch & 0x0f) << 4; - break; - case 2: - plain_text[j++] |= ch >>2; - plain_text[j] = (ch & 0x03) << 6; - break; - case 3: - plain_text[j++] |= ch; - break; - } - i++; - } - - k = j; - if (ch == b64_pad) { - switch(i % 4) { - case 1: - return 0; - case 2: - k++; - case 3: - plain_text[k] = 0; - } - } - - plain_text[j] = '\0'; - - return j; -} - /* * \brief Base64 transformation function based on RFC2045 * @@ -684,7 +616,6 @@ static int msre_fn_decodeBase64Ext_execute(apr_pool_t *mptmp, unsigned char *inp return *rval_len ? 1 : 0; } - /* ------------------------------------------------------------------------------ */ /** @@ -894,5 +825,4 @@ void msre_engine_register_default_tfns(msre_engine *engine) { "decodeBase64Ext", msre_fn_decodeBase64Ext_execute ); - }