*/
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);
fflush (stdout);
fflush (stderr);
- return done (1);
+ done (1);
+ return 1;
}
/* 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",
}
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;
/*
}
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;
*/
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;
*/
ep = (ap = ci->ci_attrs) + NPARMS;
while (*cp == ';') {
- char *vp, *up;
+ char *vp;
+ unsigned char *up;
if (ap >= ep) {
advise (NULL,
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;
{
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;
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;
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;
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;
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;
*++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;
}
}
}
while (*cp)
cp++;
fprintf (stderr, "invalid MD5 digest (got %d octets)\n",
- cp - bp);
+ (int)(cp - bp));
}
return NOTOK;