X-Git-Url: https://diplodocus.org/git/nmh/blobdiff_plain/a8d183948d18b1fba94a305072bfd3c15f93da03..44c4d3d460b88cb285e10fd40d0d69b16a69a6b8:/uip/mhparse.c diff --git a/uip/mhparse.c b/uip/mhparse.c index 69660a91..904c1237 100644 --- a/uip/mhparse.c +++ b/uip/mhparse.c @@ -13,6 +13,7 @@ #include #include #include +#include "mhmisc.h" #include #include "../sbr/m_mktemp.h" #include "mhfree.h" @@ -33,19 +34,19 @@ int checksw = 0; /* check Content-MD5 field */ * 3) Suppress the warning about extraneous trailing ';' in header parameter * lists. */ -int skip_mp_cte_check; -int suppress_bogus_mp_content_warning; -int bogus_mp_content; -int suppress_extraneous_trailing_semicolon_warning; +bool skip_mp_cte_check; +bool suppress_bogus_mp_content_warning; +bool bogus_mp_content; +bool suppress_extraneous_trailing_semicolon_warning; /* * By default, suppress warning about multiple MIME-Version header fields. */ -int suppress_multiple_mime_version_warning = 1; +bool suppress_multiple_mime_version_warning = true; /* list of preferred type/subtype pairs, for -prefer */ -char *preferred_types[NPREFS], - *preferred_subtypes[NPREFS]; +char *preferred_types[NPREFS]; +char *preferred_subtypes[NPREFS]; int npreferred; @@ -106,11 +107,6 @@ static struct k2v EncodingType[] = { }; -/* mhmisc.c */ -int part_ok (CT); -int type_ok (CT, int); -void content_error (char *, CT, char *, ...); - /* * static prototypes */ @@ -173,7 +169,7 @@ struct str2init str2ces[] = { /* * NOTE WELL: si_key MUST NOT have value of NOTOK * - * si_key is 1 if access method is anonymous. + * si_val is 1 if access method is anonymous. */ struct str2init str2methods[] = { { "afs", 1, InitFile }, @@ -202,7 +198,7 @@ parse_mime (char *file) size_t n; struct stat statbuf; - bogus_mp_content = 0; + bogus_mp_content = false; /* * Check if file is actually standard input @@ -295,22 +291,23 @@ get_content (FILE *in, char *file, int toplevel) char *np, *vp; CT ct; HF hp; - m_getfld_state_t gstate = 0; + m_getfld_state_t gstate; /* allocate the content structure */ NEW0(ct); ct->c_fp = in; - ct->c_file = add (file, NULL); + ct->c_file = mh_xstrdup(FENDNULL(file)); ct->c_begin = ftell (ct->c_fp) + 1; /* * Parse the header fields for this * content into a linked list. */ - m_getfld_track_filepos (&gstate, in); + gstate = m_getfld_state_init(in); + m_getfld_track_filepos2(&gstate); for (compnum = 1;;) { int bufsz = sizeof buf; - switch (state = m_getfld (&gstate, name, buf, &bufsz, in)) { + switch (state = m_getfld2(&gstate, name, buf, &bufsz)) { case FLD: case FLDPLUS: compnum++; @@ -322,7 +319,7 @@ get_content (FILE *in, char *file, int toplevel) /* if necessary, get rest of field */ while (state == FLDPLUS) { bufsz = sizeof buf; - state = m_getfld (&gstate, name, buf, &bufsz, in); + state = m_getfld2(&gstate, name, buf, &bufsz); vp = add (buf, vp); /* add to previous value */ } @@ -334,12 +331,25 @@ get_content (FILE *in, char *file, int toplevel) continue; case BODY: + /* There are two cases. The unusual one is when there is no + * blank line between the headers and the body. This is + * indicated by the name of the header starting with `:'. + * + * For both cases, normal first, `1' is the desired c_begin + * file position for the start of the body, and `2' is the + * file position when buf is returned. + * + * f o o : b a r \n \n b o d y \n bufsz = 6 + * 1 2 move -5 + * f o o : b a r \n b o d y \n bufsz = 4 + * 1 2 move -4 + * + * For the normal case, bufsz includes the + * header-terminating `\n', even though it is not in buf, + * but bufsz isn't affected when it's missing in the unusual + * case. */ if (name[0] == ':') { - /* Special case: no blank line between header and body. The - file position indicator is on the newline at the end of the - line, but it needs to be one prior to the beginning of the - line. So subtract the length of the line, bufsz, plus 1. */ - ct->c_begin = ftell (in) - (bufsz + 1); + ct->c_begin = ftell(in) - bufsz; } else { ct->c_begin = ftell (in) - (bufsz - 1); } @@ -377,7 +387,7 @@ get_content (FILE *in, char *file, int toplevel) char c, *cp, *dp; char *vrsn; - vrsn = add (hp->value, NULL); + vrsn = mh_xstrdup(FENDNULL(hp->value)); /* Now, cleanup this field */ cp = vrsn; @@ -460,7 +470,7 @@ get_content (FILE *in, char *file, int toplevel) } /* get copy of this field */ - ct->c_celine = cp = add (hp->value, NULL); + ct->c_celine = cp = mh_xstrdup(FENDNULL(hp->value)); while (isspace ((unsigned char) *cp)) cp++; @@ -498,7 +508,7 @@ get_content (FILE *in, char *file, int toplevel) goto next_header; } - ep = cp = add (hp->value, NULL); /* get a copy */ + ep = cp = mh_xstrdup(FENDNULL(hp->value)); /* get a copy */ while (isspace ((unsigned char) *cp)) cp++; @@ -628,7 +638,7 @@ get_ctinfo (char *cp, CT ct, int magic) ci = &ct->c_ctinfo; /* store copy of Content-Type line */ - cp = ct->c_ctline = add (cp, NULL); + cp = ct->c_ctline = mh_xstrdup(FENDNULL(cp)); while (isspace ((unsigned char) *cp)) /* trim leading spaces */ cp++; @@ -851,8 +861,8 @@ magic_skip: } } else - inform("extraneous information in message %s's %s: field\n%*s(%s)", - ct->c_file, TYPE_FIELD, strlen(invo_name) + 2, "", cp); + inform("extraneous information in message %s's %s: field\n" + " (%s)", ct->c_file, TYPE_FIELD, cp); } return OK; @@ -877,7 +887,7 @@ get_dispo (char *cp, CT ct, int buildflag) * time. */ - dispoheader = cp = add(cp, NULL); + dispoheader = cp = mh_xstrdup(FENDNULL(cp)); while (isspace ((unsigned char) *cp)) /* trim leading spaces */ cp++; @@ -920,8 +930,8 @@ get_dispo (char *cp, CT ct, int buildflag) return NOTOK; } } else if (*cp) { - inform("extraneous information in message %s's %s: field\n%*s(%s)", - ct->c_file, DISPO_FIELD, strlen(invo_name) + 2, "", cp); + inform("extraneous information in message %s's %s: field\n (%s)", + ct->c_file, DISPO_FIELD, cp); } if (buildflag) @@ -1213,7 +1223,7 @@ end_part: if (! suppress_bogus_mp_content_warning) { inform("bogus multipart content in message %s", ct->c_file); } - bogus_mp_content = 1; + bogus_mp_content = true; if (!inout && part) { p = part->mp_part; @@ -1422,7 +1432,7 @@ InitMessage (CT ct) /* scan for parameters "id", "number", and "total" */ for (pm = ci->ci_first_pm; pm; pm = pm->pm_next) { if (!strcasecmp (pm->pm_name, "id")) { - p->pm_partid = add (pm->pm_value, NULL); + p->pm_partid = mh_xstrdup(FENDNULL(pm->pm_value)); continue; } if (!strcasecmp (pm->pm_name, "number")) { @@ -1827,7 +1837,10 @@ openBase64 (CT ct, char **file) *cp = '\0'; if (decodeBase64 (buffer, &decoded, &decoded_len, ct->c_type == CT_TEXT, - ct->c_digested ? digest : NULL) == OK) { + ct->c_digested ? digest : NULL) != OK) + goto clean_up; + + { size_t i; unsigned char *decoded_p = decoded; for (i = 0; i < decoded_len; ++i) { @@ -1841,7 +1854,7 @@ openBase64 (CT ct, char **file) if (ct->c_digested) { if (memcmp(digest, ct->c_digest, - sizeof(digest) / sizeof(digest[0]))) { + sizeof digest)) { content_error (NULL, ct, "content integrity suspect (digest mismatch) -- continuing"); } else { @@ -1850,8 +1863,6 @@ openBase64 (CT ct, char **file) } } } - } else { - goto clean_up; } fseek (ct->c_fp, 0L, SEEK_SET); @@ -2093,12 +2104,11 @@ openQuoted (CT ct, char **file) MD5Final (digest, &mdContext); if (memcmp((char *) digest, (char *) ct->c_digest, - sizeof(digest) / sizeof(digest[0]))) + sizeof digest)) content_error (NULL, ct, "content integrity suspect (digest mismatch) -- continuing"); - else - if (debugsw) - fprintf (stderr, "content integrity confirmed\n"); + else if (debugsw) + fprintf (stderr, "content integrity confirmed\n"); } fseek (ce->ce_fp, 0L, SEEK_SET); @@ -2200,7 +2210,7 @@ open7Bit (CT ct, char **file) len = 0; fprintf (ce->ce_fp, "%s: %s/%s", TYPE_FIELD, ci->ci_type, ci->ci_subtype); - len += strlen (TYPE_FIELD) + 2 + strlen (ci->ci_type) + len += LEN(TYPE_FIELD) + 2 + strlen (ci->ci_type) + 1 + strlen (ci->ci_subtype); buffer = output_params(len, ci->ci_first_pm, &len, 0); @@ -2316,7 +2326,7 @@ openExternal (CT ct, CT cb, CE ce, char **file, int *fd) goto ready_already; } - if (find_cache (ct, rcachesw, (int *) 0, cb->c_id, + if (find_cache(ct, rcachesw, NULL, cb->c_id, cachefile, sizeof(cachefile)) != NOTOK) { if ((ce->ce_fp = fopen (cachefile, "r"))) { ce->ce_file = mh_xstrdup(cachefile); @@ -2326,7 +2336,7 @@ openExternal (CT ct, CT cb, CE ce, char **file, int *fd) admonish (cachefile, "unable to fopen for reading"); } - *fd = fileno (ce->ce_fp); + *fd = ce->ce_fp ? fileno (ce->ce_fp) : -1; return OK; ready_already: @@ -2402,12 +2412,10 @@ openFile (CT ct, char **file) if (ferror (gp)) { admonish (ce->ce_file, "error reading"); (void) m_unlink (cachefile); - } - else - if (ferror (fp)) { - admonish (cachefile, "error writing"); - (void) m_unlink (cachefile); - } + } else if (ferror (fp)) { + admonish (cachefile, "error writing"); + (void) m_unlink (cachefile); + } fclose (fp); } umask (mask); @@ -2613,12 +2621,10 @@ openFTP (CT ct, char **file) if (ferror (gp)) { admonish (ce->ce_file, "error reading"); (void) m_unlink (cachefile); - } - else - if (ferror (fp)) { - admonish (cachefile, "error writing"); - (void) m_unlink (cachefile); - } + } else if (ferror (fp)) { + admonish (cachefile, "error writing"); + (void) m_unlink (cachefile); + } fclose (fp); } umask (mask); @@ -2883,7 +2889,7 @@ openURL (CT ct, char **file) fseeko(ce->ce_fp, 0, SEEK_SET); *file = ce->ce_file; - return fd; + return fileno(ce->ce_fp); } @@ -2898,7 +2904,7 @@ readDigest (CT ct, char *cp) size_t len; if (decodeBase64 (cp, &digest, &len, 0, NULL) == OK) { - const size_t maxlen = sizeof ct->c_digest / sizeof ct->c_digest[0]; + const size_t maxlen = sizeof ct->c_digest; if (strlen ((char *) digest) <= maxlen) { memcpy (ct->c_digest, digest, maxlen); @@ -3291,9 +3297,9 @@ parse_header_attrs (const char *filename, const char *fieldname, for (up = dp; isspace ((unsigned char) *dp);) dp++; if (dp == cp || *dp != '=') { - inform("invalid parameter in message %s's %s: " - "field\n%*sparameter %s (error detected at offset %d)", - filename, fieldname, strlen(invo_name) + 2, "",cp, dp - cp); + inform("invalid parameter in message %s's %s: field\n" + " parameter %s (error detected at offset %ld)", + filename, fieldname, cp, (long)(dp - cp)); return NOTOK; } @@ -3324,9 +3330,8 @@ parse_header_attrs (const char *filename, const char *fieldname, if (isdigit((unsigned char) *vp)) index = *vp - '0' + index * 10; else { - inform("invalid parameter index in message %s's " - "%s: field\n%*s(parameter %s)", filename, - fieldname, strlen(invo_name) + 2, "", cp); + inform("invalid parameter index in message %s's %s: field" + "\n (parameter %s)", filename, fieldname, cp); return NOTOK; } } else { @@ -3368,9 +3373,8 @@ parse_header_attrs (const char *filename, const char *fieldname, } vp++; } else { - inform("missing charset in message %s's %s: " - "field\n%*s(parameter %s)", filename, fieldname, - strlen(invo_name) + 2, "", nameptr); + inform("missing charset in message %s's %s: field\n" + " (parameter %s)", filename, fieldname, nameptr); free(nameptr); return NOTOK; } @@ -3391,9 +3395,8 @@ parse_header_attrs (const char *filename, const char *fieldname, } vp++; } else { - inform("missing language tag in message %s's %s: " - "field\n%*s(parameter %s)", filename, fieldname, - strlen(invo_name) + 2, "", nameptr); + inform("missing language tag in message %s's %s: field\n" + " (parameter %s)", filename, fieldname, nameptr); free(nameptr); mh_xfree(charset); return NOTOK; @@ -3415,10 +3418,8 @@ parse_header_attrs (const char *filename, const char *fieldname, !isxdigit((unsigned char) *(vp + 1)) || *(vp + 2) == '\0' || !isxdigit((unsigned char) *(vp + 2))) { - inform("invalid encoded sequence in message " - "%s's %s: field\n%*s(parameter %s)", - filename, fieldname, strlen(invo_name) + 2, - "", nameptr); + inform("invalid encoded sequence in message %s's %s: field\n" + " (parameter %s)", filename, fieldname, nameptr); free(nameptr); mh_xfree(charset); mh_xfree(lang); @@ -3458,9 +3459,8 @@ parse_header_attrs (const char *filename, const char *fieldname, switch (*cp++) { case '\0': bad_quote: - inform("invalid quoted-string in message %s's %s: " - "field\n%*s(parameter %s)", filename, - fieldname, strlen(invo_name) + 2, "", nameptr); + inform("invalid quoted-string in message %s's %s: field\n" + " (parameter %s)", filename, fieldname, nameptr); free(nameptr); mh_xfree(charset); mh_xfree(lang); @@ -3544,10 +3544,9 @@ bad_quote: } else { for (sp2 = pp->sechead; sp2 != NULL; sp2 = sp2->next) { if (sp2->index == sp->index) { - inform("duplicate index (%d) in message " - "%s's %s: field\n%*s(parameter %s)", sp->index, - filename, fieldname, strlen(invo_name) + 2, "", - nameptr); + inform("duplicate index (%d) in message %s's %s: field" + "\n (parameter %s)", sp->index, filename, + fieldname, nameptr); return NOTOK; } if (sp2->index < sp->index && @@ -3559,10 +3558,9 @@ bad_quote: } if (sp2 == NULL) { - inform("Internal error: cannot insert partial " - "param in message %s's %s: field\n%*s(parameter %s)", - filename, fieldname, strlen(invo_name) + 2, "", - nameptr); + inform("Internal error: cannot insert partial param " + "in message %s's %s: field\n (parameter %s)", + filename, fieldname, nameptr); return NOTOK; } } @@ -3602,10 +3600,9 @@ bad_quote: int pindex = 0; for (sp = pp->sechead; sp != NULL; sp = sp->next) { if (sp->index != pindex++) { - inform("missing section %d for parameter in " - "message %s's %s: field\n%*s(parameter %s)", pindex - 1, - filename, fieldname, strlen(invo_name) + 2, "", - pp->name); + inform("missing section %d for parameter in message " + "%s's %s: field\n (parameter %s)", pindex - 1, + filename, fieldname, pp->name); return NOTOK; } tlen += sp->len;