summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2010-04-08 11:45:06 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2010-04-08 11:45:06 +0300
commit7287e840118d680efe1795e053500c999a950ade (patch)
treede3410b78f6eff36135fd1acab54ada7ec8331d2
parentb2c1b1ff400a604fa41c168351630bac3238177e (diff)
downloadmailutils-7287e840118d680efe1795e053500c999a950ade.tar.gz
mailutils-7287e840118d680efe1795e053500c999a950ade.tar.bz2
Improve MIME parameter parsing.
* mailbox/mimehdr.c (_header_get_param): Improve error checking. Allow for optional whitespace around the '='. * mailbox/rfc2047.c (mu_rfc2047_decode): tocode=NULL is OK.
-rw-r--r--mailbox/mimehdr.c66
-rw-r--r--mailbox/rfc2047.c2
2 files changed, 51 insertions, 17 deletions
diff --git a/mailbox/mimehdr.c b/mailbox/mimehdr.c
index 848842b26..0c04c23f9 100644
--- a/mailbox/mimehdr.c
+++ b/mailbox/mimehdr.c
@@ -84,7 +84,11 @@
RFCs.
ENOMEM , if unable to allocate memory.
*/
-
+
+/* Internal flag used by _header_get_param to delay increasing
+ estimated continuation index. */
+#define _MU_MIMEHDR_INCR_CIND 0x8000
+
int
_header_get_param (const char *field_body,
const char *disp,
@@ -117,7 +121,7 @@ _header_get_param (const char *field_body,
while (p && *p)
{
- char *v, *e;
+ char *v, *e, *ep, *cp;
size_t len, escaped_chars = 0;
if (*p != ';')
@@ -128,9 +132,10 @@ _header_get_param (const char *field_body,
/* walk upto start of param */
p = mu_str_skip_class (p + 1, MU_CTYPE_SPACE);
- if ((v = strchr (p, '=')) == NULL)
+ if ((ep = strchr (p, '=')) == NULL)
break;
- v++;
+ /* Allow for optional whitespace after '=' */
+ v = mu_str_skip_class (ep + 1, MU_CTYPE_SPACE);
/* Find end of the parameter */
if (*v == '"')
{
@@ -171,18 +176,15 @@ _header_get_param (const char *field_body,
continue;
}
- res = 0; /* Indicate success */
-
- if (p[param_len] == '*')
+ cp = p + param_len;
+
+ if (*cp == '*')
{
- char *cp = p + param_len + 1;
-
+ cp++;
/* It is a parameter value continuation (RFC 2231, Section 3)
or parameter value character set and language information
(ibid., Section 4). */
- if (*cp == '=')
- flags |= MU_MIMEHDR_CSINFO;
- else if (mu_isdigit (*cp))
+ if (mu_isdigit (*cp))
{
/* See if the index is OK */
@@ -194,16 +196,48 @@ _header_get_param (const char *field_body,
flags |= MU_MIMEHDR_CSINFO;
end++;
}
- if (*end != '=' || n != cind)
+ if (n != cind)
{
res = MU_ERR_PARSE;
break;
}
- /* Everything OK, increase the estimation */
- flags |= MU_MIMEHDR_MULTILINE;
- cind++;
+ /* Everything OK, mark this as a multiline (continued)
+ parameter. We also need to increment the estimation,
+ but it cannot be done right now because its value is
+ used below to decide whether to do flag cleanup
+ on error. So we set _MU_MIMEHDR_INCR_CIND flag instead
+ and increment cind later. */
+ flags |= (MU_MIMEHDR_MULTILINE|_MU_MIMEHDR_INCR_CIND);
+ /* And point cp to the last character: there are more
+ checks ahead. */
+ cp = end;
}
+ else
+ flags |= MU_MIMEHDR_CSINFO;
}
+ /* Allow for optional whitespace before '=' */
+ cp = mu_str_skip_class (cp, MU_CTYPE_SPACE);
+ /* cp must now point to the equals sign */
+ if (cp != ep)
+ {
+ /* Clean up everything, unless we're in the middle of a
+ parameter continuation. */
+ if (cind == 0)
+ flags = 0;
+
+ /* Try next parameter */
+ p = strchr (e, ';');
+ continue;
+ }
+
+ if (flags & _MU_MIMEHDR_INCR_CIND)
+ {
+ /* Increase the estimation. */
+ flags &= ~_MU_MIMEHDR_INCR_CIND;
+ cind++;
+ }
+
+ res = 0; /* Indicate success */
/* Prepare P for the next iteration */
p = e;
diff --git a/mailbox/rfc2047.c b/mailbox/rfc2047.c
index bf23b7e1f..540f80e68 100644
--- a/mailbox/rfc2047.c
+++ b/mailbox/rfc2047.c
@@ -92,7 +92,7 @@ mu_rfc2047_decode (const char *tocode, const char *input, char **ptostr)
} \
} while (0)
- if (!tocode || !input)
+ if (!input)
return EINVAL;
if (!ptostr)
return MU_ERR_OUT_PTR_NULL;

Return to:

Send suggestions and report system problems to the System administrator.