X-Git-Url: http://git.marmaro.de/?a=blobdiff_plain;f=uip%2Fmhparse.c;h=67717890cb31595feaf961b5c98b663948b53177;hb=a139e1ddbbe5e7fe89d7eb4a5dc16d4b9698960a;hp=8d3397ef120638b5761e6e9e38504de2cfb0de84;hpb=d2f12554a254e814dcdafb3828fc0d9936154eef;p=mmh diff --git a/uip/mhparse.c b/uip/mhparse.c index 8d3397e..6771789 100644 --- a/uip/mhparse.c +++ b/uip/mhparse.c @@ -127,8 +127,8 @@ CT parse_mime (char *); */ static CT get_content (FILE *, char *, int); static int add_header (CT, char *, char *); -static int get_ctinfo (char *, CT); -static int get_comment (CT, char **, int); +static int get_ctinfo (unsigned char *, CT); +static int get_comment (CT, unsigned char **, int); static int InitGeneric (CT); static int InitText (CT); static int InitMultiPart (CT); @@ -209,7 +209,8 @@ pidcheck (int status) fflush (stdout); fflush (stderr); - return done (1); + done (1); + return 1; } @@ -377,7 +378,8 @@ get_content (FILE *in, char *file, int toplevel) /* Get MIME-Version field */ if (!mh_strcasecmp (hp->name, VRSN_FIELD)) { int ucmp; - char c, *cp, *dp; + char c; + unsigned char *cp, *dp; if (ct->c_vrsn) { advise (NULL, "message %s has multiple %s: fields", @@ -444,7 +446,8 @@ get_content (FILE *in, char *file, int toplevel) } else if (!mh_strcasecmp (hp->name, ENCODING_FIELD)) { /* Get Content-Transfer-Encoding field */ - char c, *cp, *dp; + char c; + unsigned char *cp, *dp; struct str2init *s2i; /* @@ -485,7 +488,8 @@ get_content (FILE *in, char *file, int toplevel) } else if (!mh_strcasecmp (hp->name, MD5_FIELD)) { /* Get Content-MD5 field */ - char *cp, *dp, *ep; + unsigned char *cp, *dp; + char *ep; if (!checksw) goto next_header; @@ -611,10 +615,11 @@ add_header (CT ct, char *name, char *value) */ static int -get_ctinfo (char *cp, CT ct) +get_ctinfo (unsigned char *cp, CT ct) { int i; - char *dp, **ap, **ep; + unsigned char *dp; + char **ap, **ep; char c; CI ci; @@ -708,7 +713,8 @@ magic_skip: */ ep = (ap = ci->ci_attrs) + NPARMS; while (*cp == ';') { - char *vp, *up; + char *vp; + unsigned char *up; if (ap >= ep) { advise (NULL, @@ -812,10 +818,11 @@ bad_quote: static int -get_comment (CT ct, char **ap, int istype) +get_comment (CT ct, unsigned char **ap, int istype) { int i; - char *bp, *cp; + char *bp; + unsigned char *cp; char c, buffer[BUFSIZ], *dp; CI ci; @@ -956,7 +963,8 @@ InitMultiPart (CT ct) { int inout; long last, pos; - char *cp, *dp, **ap, **ep; + unsigned char *cp, *dp; + char **ap, **ep; char *bp, buffer[BUFSIZ]; struct multipart *m; struct k2v *kv; @@ -1112,7 +1120,7 @@ last_part: char partnam[BUFSIZ]; if (ct->c_partno) { - snprintf (partnam, sizeof(partnum), "%s.", ct->c_partno); + snprintf (partnam, sizeof(partnam), "%s.", ct->c_partno); pp = partnam + strlen (partnam); } else { pp = partnam; @@ -1568,7 +1576,8 @@ openBase64 (CT ct, char **file) int fd, len, skip; unsigned long bits; unsigned char value, *b, *b1, *b2, *b3; - char *cp, *ep, buffer[BUFSIZ]; + unsigned char *cp, *ep; + char buffer[BUFSIZ]; /* sbeck -- handle prefixes */ CI ci; CE ce; @@ -1779,7 +1788,7 @@ static int openQuoted (CT ct, char **file) { int cc, digested, len, quoted; - char *cp, *ep; + unsigned char *cp, *ep; char buffer[BUFSIZ]; unsigned char mask; CE ce; @@ -1850,8 +1859,6 @@ openQuoted (CT ct, char **file) fseek (ct->c_fp, ct->c_begin, SEEK_SET); while (len > 0) { - char *dp; - if (fgets (buffer, sizeof(buffer) - 1, ct->c_fp) == NULL) { content_error (NULL, ct, "premature eof"); goto clean_up; @@ -1867,79 +1874,67 @@ openQuoted (CT ct, char **file) *++ep = '\n', ep++; for (; cp < ep; cp++) { - if (quoted) { - if (quoted > 1) { - if (!isxdigit (*cp)) { -invalid_hex: - dp = "expecting hexidecimal-digit"; - goto invalid_encoding; - } + if (quoted > 0) { + /* in an escape sequence */ + if (quoted == 1) { + /* at byte 1 of an escape sequence */ + mask = hex2nib[*cp & 0x7f]; + /* next is byte 2 */ + quoted = 2; + } else { + /* at byte 2 of an escape sequence */ mask <<= 4; mask |= hex2nib[*cp & 0x7f]; putc (mask, ce->ce_fp); if (digested) MD5Update (&mdContext, &mask, 1); - } else { - switch (*cp) { - case ':': - putc (*cp, ce->ce_fp); - if (digested) - MD5Update (&mdContext, (unsigned char *) ":", 1); - break; - - default: - if (!isxdigit (*cp)) - goto invalid_hex; - mask = hex2nib[*cp & 0x7f]; - quoted = 2; - continue; + if (ferror (ce->ce_fp)) { + content_error (ce->ce_file, ct, "error writing to"); + goto clean_up; } + /* finished escape sequence; next may be literal or a new + * escape sequence */ + quoted = 0; } - - if (ferror (ce->ce_fp)) { - content_error (ce->ce_file, ct, "error writing to"); - goto clean_up; - } - quoted = 0; + /* on to next byte */ continue; } - switch (*cp) { - default: - if (*cp < '!' || *cp > '~') { - int i; - dp = "expecting character in range [!..~]"; - -invalid_encoding: - i = strlen (invo_name) + 2; - content_error (NULL, ct, - "invalid QUOTED-PRINTABLE encoding -- %s,\n%*.*sbut got char 0x%x", - dp, i, i, "", *cp); - goto clean_up; - } - /* and fall...*/ - case ' ': - case '\t': - case '\n': - putc (*cp, ce->ce_fp); - if (digested) { - if (*cp == '\n') - MD5Update (&mdContext, (unsigned char *) "\r\n",2); - else - MD5Update (&mdContext, (unsigned char *) cp, 1); + /* not in an escape sequence */ + if (*cp == '=') { + /* starting an escape sequence, or invalid '='? */ + if (cp + 1 < ep && cp[1] == '\n') { + /* "=\n" soft line break, eat the \n */ + cp++; + continue; } - if (ferror (ce->ce_fp)) { - content_error (ce->ce_file, ct, "error writing to"); - goto clean_up; + if (cp + 1 >= ep || cp + 2 >= ep) { + /* We don't have 2 bytes left, so this is an invalid + * escape sequence; just show the raw bytes (below). */ + } else if (isxdigit (cp[1]) && isxdigit (cp[2])) { + /* Next 2 bytes are hex digits, making this a valid escape + * sequence; let's decode it (above). */ + quoted = 1; + continue; + } else { + /* One or both of the next 2 is out of range, making this + * an invalid escape sequence; just show the raw bytes + * (below). */ } - break; + } - case '=': - if (*++cp != '\n') { - quoted = 1; - cp--; + /* Just show the raw byte. */ + putc (*cp, ce->ce_fp); + if (digested) { + if (*cp == '\n') { + MD5Update (&mdContext, (unsigned char *) "\r\n",2); + } else { + MD5Update (&mdContext, (unsigned char *) cp, 1); } - break; + } + if (ferror (ce->ce_fp)) { + content_error (ce->ce_file, ct, "error writing to"); + goto clean_up; } } } @@ -2675,7 +2670,7 @@ invalid_digest: while (*cp) cp++; fprintf (stderr, "invalid MD5 digest (got %d octets)\n", - cp - bp); + (int)(cp - bp)); } return NOTOK;