From 81884ccb464c69a8dba9de1b97af261a8a02b2c7 Mon Sep 17 00:00:00 2001 From: Pierre Habouzit Date: Wed, 1 Nov 2006 00:01:50 +0100 Subject: [PATCH] move some decoding functions right into the str module, with a bit more optimized arrays. --- base64.c | 19 ++++++++----------- handler.c | 34 ++++++---------------------------- lib-lib/str.c | 26 ++++++++++++++++++++++++++ lib-lib/str.h | 18 +++++++++++++++++- mime.h | 5 ----- rfc2047.c | 2 +- 6 files changed, 58 insertions(+), 46 deletions(-) diff --git a/base64.c b/base64.c index 69ae3a7..df55689 100644 --- a/base64.c +++ b/base64.c @@ -46,8 +46,6 @@ #include "mutt.h" #include "mime.h" -#define BAD -1 - /* raw bytes to null-terminated base 64 string */ void mutt_to_base64 (unsigned char *out, const unsigned char *in, size_t len, size_t olen) @@ -86,32 +84,31 @@ int mutt_from_base64 (char *out, const char *in) do { digit1 = in[0]; - if (digit1 > 127 || base64val (digit1) == BAD) + if (base64val(digit1) < 0) return -1; digit2 = in[1]; - if (digit2 > 127 || base64val (digit2) == BAD) + if (base64val(digit2) < 0) return -1; digit3 = in[2]; - if (digit3 > 127 || ((digit3 != '=') && (base64val (digit3) == BAD))) + if (digit3 != '=' && base64val(digit3) < 0) return -1; digit4 = in[3]; - if (digit4 > 127 || ((digit4 != '=') && (base64val (digit4) == BAD))) + if (digit4 != '=' && base64val(digit4) < 0) return -1; in += 4; /* digits are already sanity-checked */ - *out++ = (base64val (digit1) << 2) | (base64val (digit2) >> 4); + *out++ = (base64val(digit1) << 2) | (base64val(digit2) >> 4); len++; if (digit3 != '=') { - *out++ = ((base64val (digit2) << 4) & 0xf0) | (base64val (digit3) >> 2); + *out++ = ((base64val(digit2) << 4) & 0xf0) | (base64val(digit3) >> 2); len++; if (digit4 != '=') { - *out++ = ((base64val (digit3) << 6) & 0xc0) | base64val (digit4); + *out++ = ((base64val(digit3) << 6) & 0xc0) | base64val(digit4); len++; } } - } - while (*in && digit4 != '='); + } while (*in && digit4 != '='); return len; } diff --git a/handler.c b/handler.c index 1ed6c23..2bee349 100644 --- a/handler.c +++ b/handler.c @@ -44,29 +44,7 @@ typedef int handler_f (BODY *, STATE *); typedef handler_f *handler_t; -int Index_hex[128] = { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, - -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 -}; - -int Index_64[128] = { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, - -1, 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, -1, -1, -1, -1, -1, - -1, 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, -1, -1, -1, -1, -1 -}; - -void mutt_decode_xbit (STATE * s, long len, int istext, iconv_t cd) +static void mutt_decode_xbit (STATE * s, long len, int istext, iconv_t cd) { int c, ch; char bufi[BUFI_SIZE]; @@ -242,7 +220,7 @@ void mutt_decode_base64 (STATE * s, long len, int istext, iconv_t cd) for (i = 0; i < 4 && len > 0; len--) { if ((ch = fgetc (s->fpin)) == EOF) break; - if (ch >= 0 && ch < 128 && (base64val (ch) != -1 || ch == '=')) + if (base64val(ch) >= 0 || ch == '=') buf[i++] = ch; } if (i != 4) { @@ -250,8 +228,8 @@ void mutt_decode_base64 (STATE * s, long len, int istext, iconv_t cd) break; } - c1 = base64val (buf[0]); - c2 = base64val (buf[1]); + c1 = base64val(buf[0]); + c2 = base64val(buf[1]); ch = (c1 << 2) | (c2 >> 4); if (cr && ch != '\n') @@ -266,7 +244,7 @@ void mutt_decode_base64 (STATE * s, long len, int istext, iconv_t cd) if (buf[2] == '=') break; - c3 = base64val (buf[2]); + c3 = base64val(buf[2]); ch = ((c2 & 0xf) << 4) | (c3 >> 2); if (cr && ch != '\n') @@ -281,7 +259,7 @@ void mutt_decode_base64 (STATE * s, long len, int istext, iconv_t cd) if (buf[3] == '=') break; - c4 = base64val (buf[3]); + c4 = base64val(buf[3]); ch = ((c3 & 0x3) << 6) | c4; if (cr && ch != '\n') diff --git a/lib-lib/str.c b/lib-lib/str.c index 8b0c393..6bdc25c 100644 --- a/lib-lib/str.c +++ b/lib-lib/str.c @@ -20,6 +20,32 @@ #include "macros.h" #include "str.h" +#define XX 255 +unsigned char const __m_strdigits[128] = { + XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, + XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, + XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, XX, XX, XX, XX, XX, XX, + XX, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, XX, XX, XX, XX, XX, + XX, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, XX, XX, XX, XX, XX, +}; +#undef XX + +#define XX -1 +signed char const __m_b64digits[128] = { + XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, + XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, + XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, 62, XX, XX, XX, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, XX, XX, XX, XX, XX, XX, + XX, 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, XX, XX, XX, XX, XX, + XX, 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, XX, XX, XX, XX, XX +}; +#undef XX + ssize_t m_strcpy(char *dst, ssize_t n, const char *src) { ssize_t len = m_strlen(src); diff --git a/lib-lib/str.h b/lib-lib/str.h index 973e0be..01e6c62 100644 --- a/lib-lib/str.h +++ b/lib-lib/str.h @@ -33,7 +33,23 @@ #define SHORT_STRING 128 #define NONULL(x) (x?x:"") -# define ISSPACE(c) isspace((unsigned char)c) +#define ISSPACE(c) isspace((unsigned char)c) + +extern unsigned char const __m_strdigits[128]; +extern signed char const __m_b64digits[128]; + +/****************************************************************************/ +/* char related */ +/****************************************************************************/ + +static inline int hexval(int c) { + int v = __m_strdigits[c]; + return !(c & ~127) && v < 16 ? v : -1; +} + +static inline int base64val(int c) { + return (c & ~127) ? -1 : __m_b64digits[c]; +} /****************************************************************************/ /* length related */ diff --git a/mime.h b/mime.h index 6125e7a..d102594 100644 --- a/mime.h +++ b/mime.h @@ -42,14 +42,9 @@ enum { /* MIME encoding/decoding global vars */ #ifndef _SENDLIB_C -extern int Index_hex[]; -extern int Index_64[]; extern char B64Chars[]; #endif -#define hexval(c) Index_hex[(unsigned int)(c)] -#define base64val(c) Index_64[(unsigned int)(c)] - #define is_multipart(x) \ ((x)->type == TYPEMULTIPART \ || ((x)->type == TYPEMESSAGE && (!strcasecmp((x)->subtype, "rfc822") \ diff --git a/rfc2047.c b/rfc2047.c index 0b35cf7..d973d26 100644 --- a/rfc2047.c +++ b/rfc2047.c @@ -599,7 +599,7 @@ static int rfc2047_decode_word (char *d, const char *s, size_t len) for (; pp < pp1; pp++) { if (*pp == '=') break; - if ((*pp & ~127) || (c = base64val (*pp)) == -1) + if ((c = base64val(*pp)) < 0) continue; if (k + 6 >= 8) { k -= 2; -- 2.20.1