From 63694769caa96f36675293e45a01e91cbe3175b4 Mon Sep 17 00:00:00 2001 From: Pierre Habouzit Date: Sun, 5 Nov 2006 23:18:42 +0100 Subject: [PATCH] simplify parse_parameters tokenizer Signed-off-by: Pierre Habouzit --- lib-mime/rfc822parse.c | 187 +++++++++++++++++------------------------ 1 file changed, 77 insertions(+), 110 deletions(-) diff --git a/lib-mime/rfc822parse.c b/lib-mime/rfc822parse.c index fb498b7..e9b171a 100644 --- a/lib-mime/rfc822parse.c +++ b/lib-mime/rfc822parse.c @@ -180,131 +180,99 @@ int mutt_check_encoding(const char *s) return ENCOTHER; } -static PARAMETER *parse_parameters(const char *s) +int mutt_check_mime_type(const char *s) { - PARAMETER *head = 0, *cur = 0, *new; - char buffer[LONG_STRING]; - const char *p; - size_t i; - - debug_print (2, ("`%s'\n", s)); - - while (*s) { - if ((p = strpbrk (s, "=;")) == NULL) { - debug_print (1, ("malformed parameter: %s\n", s)); - goto bail; +#define COMPARE(tok, value) \ + if (!ascii_strncasecmp(tok, s, sizeof(tok) - 1)) { \ + return value; \ } + COMPARE("text", TYPETEXT); + COMPARE("multipart", TYPEMULTIPART); + COMPARE("application", TYPEAPPLICATION); + COMPARE("message", TYPEMESSAGE); + COMPARE("image", TYPEIMAGE); + COMPARE("audio", TYPEAUDIO); + COMPARE("video", TYPEVIDEO); + COMPARE("model", TYPEMODEL); + COMPARE("*", TYPEANY); + COMPARE(".*", TYPEANY); +#undef COMPARE - /* if we hit a ; now the parameter has no value, just skip it */ - if (*p != ';') { - i = p - s; - - new = parameter_new(); - - new->attribute = p_dupstr(s, i); + return TYPEOTHER; +} - /* remove whitespace from the end of the attribute name */ - while (ISSPACE (new->attribute[--i])) - new->attribute[i] = 0; +static PARAMETER *parse_parameters(const char *s) +{ + PARAMETER *res = NULL; + PARAMETER **list = &res; - s = vskipspaces(p + 1); /* skip over the = */ + while (*s) { + const char *p; + PARAMETER *new; + int i; - if (*s == '"') { - int state_ascii = 1; + s = skipspaces(s); + if (*s == '=') /* parameters are fucked up, go away */ + break; - s++; - for (i = 0; *s && i < sizeof (buffer) - 1; i++, s++) { - if (!option (OPTSTRICTMIME)) { - /* As iso-2022-* has a characer of '"' with non-ascii state, - * ignore it. */ - if (*s == 0x1b && i < sizeof (buffer) - 2) { - if (s[1] == '(' && (s[2] == 'B' || s[2] == 'J')) - state_ascii = 1; - else - state_ascii = 0; - } - } - if (state_ascii && *s == '"') + p = strpbrk(s, "=;"); + if (!p) break; - if (*s == '\\') { - /* Quote the next character */ - buffer[i] = s[1]; - if (!*++s) - break; - } - else - buffer[i] = *s; + + if (*p == ';') { + /* if we hit a ; now the parameter has no value, just skip it */ + s = p + 1; + continue; } - buffer[i] = 0; - if (*s) - s++; /* skip over the " */ - } - else { - for (i = 0; *s && *s != ' ' && *s != ';' && i < sizeof (buffer) - 1; - i++, s++) - buffer[i] = *s; - buffer[i] = 0; - } - new->value = m_strdup(buffer); + i = p - s; + new = parameter_new(); + new->attribute = p_dupstr(s, i); - debug_print (2, ("`%s' = `%s'\n", new->attribute ? new->attribute : "", - new->value ? new->value : "")); + while (--i >= 0 && ISSPACE(new->attribute[i])) { + new->attribute[i] = '\0'; + } + s = skipspaces(p + 1); /* skip over the = */ + + if (*s == '"') { + char buffer[LONG_STRING]; + int state_ascii = 1; + + s++; + for (i = 0; *s && i < ssizeof(buffer) - 1; i++, s++) { + if (!option(OPTSTRICTMIME)) { + /* As iso-2022-* has a characer of '"' with non-ascii state, + * ignore it. */ + if (*s == 0x1b && i < ssizeof(buffer) - 2) { + state_ascii = s[1] == '(' && (s[2] == 'B' || s[2] == 'J'); + } + } + if (state_ascii && *s == '"') + break; + + if (*s == '\\') { + buffer[i] = *++s; + } else { + buffer[i] = *s; + } + } - /* Add this parameter to the list */ - if (head) { - cur->next = new; - cur = cur->next; - } - else - head = cur = new; - } - else { - debug_print (1, ("parameter with no value: %s\n", s)); - s = p; - } + new->value = p_dupstr(buffer, i); + } else { + for (p = s; *p && *p != ' ' && *p != ';'; p++); + new->value = p_dupstr(s, p - s); + } - /* Find the next parameter */ - if (*s != ';' && (s = strchr (s, ';')) == NULL) - break; /* no more parameters */ + *list = new; + list = &new->next; - do { - /* Move past any leading whitespace */ - s = vskipspaces(s + 1); + s = strchr(s, ';'); /* Find the next parameter */ + if (!s) + break; /* no more parameters */ } - while (*s == ';'); /* skip empty parameters */ - } - -bail: - rfc2231_decode_parameters (&head); - return (head); -} - -int mutt_check_mime_type (const char *s) -{ - if (ascii_strcasecmp ("text", s) == 0) - return TYPETEXT; - else if (ascii_strcasecmp ("multipart", s) == 0) - return TYPEMULTIPART; - else if (ascii_strcasecmp ("application", s) == 0) - return TYPEAPPLICATION; - else if (ascii_strcasecmp ("message", s) == 0) - return TYPEMESSAGE; - else if (ascii_strcasecmp ("image", s) == 0) - return TYPEIMAGE; - else if (ascii_strcasecmp ("audio", s) == 0) - return TYPEAUDIO; - else if (ascii_strcasecmp ("video", s) == 0) - return TYPEVIDEO; - else if (ascii_strcasecmp ("model", s) == 0) - return TYPEMODEL; - else if (ascii_strcasecmp ("*", s) == 0) - return TYPEANY; - else if (ascii_strcasecmp (".*", s) == 0) - return TYPEANY; - else - return TYPEOTHER; + rfc2231_decode_parameters(&res); + return res; } void mutt_parse_content_type (char *s, BODY * ct) @@ -374,7 +342,6 @@ void mutt_parse_content_type (char *s, BODY * ct) mutt_get_first_charset (AssumedCharset), &ct->parameter); } - } static void parse_content_disposition (char *s, BODY * ct) -- 2.20.1