From: Ken Hornstein Date: Sat, 22 Feb 2014 05:07:55 +0000 (-0500) Subject: It compiles now! And actually sort of works, but still a LOT more X-Git-Url: https://diplodocus.org/git/nmh/commitdiff_plain/e14b80c187fdcd00920eed669a8333d7c12a4dd8?ds=sidebyside It compiles now! And actually sort of works, but still a LOT more that needs to be done before it is complete. --- diff --git a/sbr/utils.c b/sbr/utils.c index 99207e32..989a9c8b 100644 --- a/sbr/utils.c +++ b/sbr/utils.c @@ -363,6 +363,9 @@ nmh_init(const char *argv0, int read_context) { int contains8bit(const char *start, const char *end) { + if (! start) + return 0; + while (*start != '\0' && (!end || (start < end))) if (! isascii((unsigned char) *start++)) return 1; diff --git a/uip/mhbuildsbr.c b/uip/mhbuildsbr.c index 6798bba5..0075c2b2 100644 --- a/uip/mhbuildsbr.c +++ b/uip/mhbuildsbr.c @@ -1127,7 +1127,7 @@ compose_content (CT ct) if (!ce->ce_file) { pid_t child_id; int i, xstdout, len, buflen; - char *bp, **ap, *cp; + char *bp, *cp; char *vec[4], buffer[BUFSIZ]; FILE *out; CI ci = &ct->c_ctinfo; diff --git a/uip/mhfixmsg.c b/uip/mhfixmsg.c index a5787ff2..9f317acd 100644 --- a/uip/mhfixmsg.c +++ b/uip/mhfixmsg.c @@ -1214,7 +1214,6 @@ build_multipart_alt (CT first_alt, CT new_part, int type, int subtype) { CT ct; struct part *p; struct multipart *m; - char *cp; const struct str2init *ctinit; if ((ct = (CT) calloc (1, sizeof *ct)) == NULL) @@ -1314,14 +1313,8 @@ build_multipart_alt (CT first_alt, CT new_part, int type, int subtype) { ct->c_ctinfo.ci_subtype = add (subtypename, NULL); } - name = concat (" ", typename, "/", subtypename, boundary_indicator, - boundary, NULL); - if ((cp = strstr (name, boundary_indicator))) { - ct->c_ctinfo.ci_attrs[0] = name; - ct->c_ctinfo.ci_attrs[1] = NULL; - /* ci_values don't get free'd, so point into ci_attrs. */ - ct->c_ctinfo.ci_values[0] = cp + strlen (boundary_indicator); - } + add_param(&ct->c_ctinfo.ci_first_pm, &ct->c_ctinfo.ci_last_pm, + "boundary", boundary); p = (struct part *) mh_xmalloc (sizeof *p); p->mp_next = (struct part *) mh_xmalloc (sizeof *p->mp_next); @@ -1762,19 +1755,22 @@ content_codeset (CT ct) { const char *const charset = "charset"; char *default_codeset = NULL; CI ctinfo = &ct->c_ctinfo; - char **ap, **vp; char **src_codeset = NULL; + PM pm; - for (ap = ctinfo->ci_attrs, vp = ctinfo->ci_values; *ap; ++ap, ++vp) { - if (! strcasecmp (*ap, charset)) { - src_codeset = vp; + for (pm = ctinfo->ci_first_pm; pm; pm = pm->pm_next) { + if (! strcasecmp (pm->pm_name, charset)) { + src_codeset = &pm->pm_value; break; } } /* RFC 2045, Sec. 5.2: default to us-ascii. */ - if (src_codeset == NULL) src_codeset = &default_codeset; - if (*src_codeset == NULL) *src_codeset = "US-ASCII"; + if (src_codeset == NULL) { + src_codeset = &default_codeset; + if (*src_codeset == NULL) + *src_codeset = "US-ASCII"; + } return *src_codeset; } diff --git a/uip/mhparse.c b/uip/mhparse.c index 043effdc..602ca40a 100644 --- a/uip/mhparse.c +++ b/uip/mhparse.c @@ -138,6 +138,7 @@ static int openURL (CT, char **); static size_t param_len(PM, int, size_t, int *); static size_t encode_param(PM, char *, size_t, size_t, size_t, int); static size_t normal_param(PM, char *, size_t, size_t, size_t); +static int get_dispo (char *, CT); struct str2init str2cts[] = { { "application", CT_APPLICATION, InitApplication }, @@ -513,7 +514,8 @@ get_content (FILE *in, char *file, int toplevel) } else if (!strcasecmp (hp->name, DISPO_FIELD)) { /* Get Content-Disposition field */ - ct->c_dispo = add (hp->value, ct->c_dispo); + if (get_dispo(hp->value, ct) == NOTOK) + goto out; } next_header: @@ -679,7 +681,6 @@ extract_name_value (char *name_suffix, char *value) { int get_ctinfo (char *cp, CT ct, int magic) { - int i; char *dp; char c; CI ci; @@ -922,8 +923,67 @@ magic_skip: } else advise (NULL, - "extraneous information in message %s's %s: field\n%*.*s(%s)", - ct->c_file, TYPE_FIELD, i, i, "", cp); + "extraneous information in message %s's %s: field\n%*s(%s)", + ct->c_file, TYPE_FIELD, strlen(invo_name) + 2, "", cp); + } + + return OK; +} + + +/* + * Parse out a Content-Disposition header. A lot of this is cribbed from + * get_ctinfo(). + */ +static int +get_dispo (char *cp, CT ct) +{ + char *dp; + char c; + int status; + + /* Save the whole copy of the Content-Disposition header */ + + ct->c_dispo = add(cp, NULL); + + while (isspace ((unsigned char) *cp)) /* trim leading spaces */ + cp++; + + /* change newlines to spaces */ + for (dp = strchr(cp, '\n'); dp; dp = strchr(dp, '\n')) + *dp++ = ' '; + + /* trim trailing spaces */ + for (dp = cp + strlen (cp) - 1; dp >= cp; dp--) + if (!isspace ((unsigned char) *dp)) + break; + *++dp = '\0'; + + if (debugsw) + fprintf (stderr, "%s: %s\n", DISPO_FIELD, cp); + + if (*cp == '(' && get_comment (ct->c_file, DISPO_FIELD, &cp, NULL) == NOTOK) + return NOTOK; + + for (dp = cp; istoken (*dp); dp++) + continue; + c = *dp, *dp = '\0'; + ct->c_dispo_type = add (cp, NULL); /* store disposition type */ + *dp = c, cp = dp; + + if (*cp == '(' && get_comment (ct->c_file, DISPO_FIELD, &cp, NULL) == NOTOK) + return NOTOK; + + if ((status = parse_header_attrs (ct->c_file, DISPO_FIELD, &cp, + &ct->c_dispo_first, &ct->c_dispo_last, + NULL)) != OK) { + return status == NOTOK ? NOTOK : OK; + } + + if (*cp) { + advise (NULL, + "extraneous information in message %s's %s: field\n%*s(%s)", + ct->c_file, DISPO_FIELD, strlen(invo_name) + 2, "", cp); } return OK; @@ -3286,7 +3346,7 @@ parse_header_attrs (const char *filename, const char *fieldname, /* Now store the attribute value. */ - pm->pm_value = vp = pm->pm_name + (dp - cp); + vp = pm->pm_name + (dp - cp); if (*dp == '"') { for (cp = ++dp, dp = vp;;) { @@ -3321,6 +3381,7 @@ bad_quote: continue; *dp = '\0'; } + pm->pm_value = getcpy(vp); if (!*vp) { advise (NULL, "invalid parameter in message %s's %s: " @@ -3361,7 +3422,7 @@ char * output_params(size_t initialwidth, PM params, int *offsetout) { char *paramout = NULL; - char line[CPERLIN * 2], *p, *q; + char line[CPERLIN * 2], *q; int curlen, index, eightbit, encode, i; size_t valoff; @@ -3667,7 +3728,7 @@ static size_t normal_param(PM pm, char *output, size_t len, size_t valuelen, size_t valueoff) { - size_t outlen = 0, n; + size_t outlen = 0; char *endptr = output + len, *p; *output++ = '='; @@ -3715,7 +3776,7 @@ add_param(PM *first, PM *last, const char *name, const char *value) memset(pm, 0, sizeof(*pm)); pm->pm_name = getcpy(name); - pm->pm_value = getcpy(name); + pm->pm_value = getcpy(value); if (*first) { (*last)->pm_next = pm; diff --git a/uip/mhshowsbr.c b/uip/mhshowsbr.c index fe0e3304..61b00573 100644 --- a/uip/mhshowsbr.c +++ b/uip/mhshowsbr.c @@ -336,11 +336,12 @@ show_content_aux (CT ct, int serial, int alternate, char *cp, char *cracked) case 'a': /* insert parameters from Content-Type field */ { - char **ap, **ep; + PM pm; char *s = ""; - for (ap = ci->ci_attrs, ep = ci->ci_values; *ap; ap++, ep++) { - snprintf (bp, buflen, "%s%s=\"%s\"", s, *ap, *ep); + for (pm = ci->ci_first_pm; pm; pm = pm->pm_next) { + snprintf (bp, buflen, "%s%s=\"%s\"", s, pm->pm_name, + pm->pm_value); len = strlen (bp); bp += len; buflen -= len; @@ -843,11 +844,12 @@ show_multi_aux (CT ct, int serial, int alternate, char *cp) case 'a': /* insert parameters from Content-Type field */ { - char **ap, **ep; + PM pm; char *s = ""; - for (ap = ci->ci_attrs, ep = ci->ci_values; *ap; ap++, ep++) { - snprintf (bp, buflen, "%s%s=\"%s\"", s, *ap, *ep); + for (pm = ci->ci_first_pm; pm; pm = pm->pm_next) { + snprintf (bp, buflen, "%s%s=\"%s\"", s, pm->pm_name, + pm->pm_value); len = strlen (bp); bp += len; buflen -= len; diff --git a/uip/mhstoresbr.c b/uip/mhstoresbr.c index 7b1dbd51..799bdb42 100644 --- a/uip/mhstoresbr.c +++ b/uip/mhstoresbr.c @@ -193,8 +193,8 @@ store_generic (CT ct) static int store_application (CT ct) { - char **ap, **ep; CI ci = &ct->c_ctinfo; + PM pm; /* Check if the content specifies a filename */ if (autosw) @@ -208,10 +208,10 @@ store_application (CT ct) if (!ct->c_storeproc && ct->c_subtype == APPLICATION_OCTETS) { int tarP = 0, zP = 0, gzP = 0; - for (ap = ci->ci_attrs, ep = ci->ci_values; *ap; ap++, ep++) { + for (pm = ci->ci_first_pm; pm; pm = pm->pm_next) { /* check for "type=tar" attribute */ - if (!strcasecmp (*ap, "type")) { - if (strcasecmp (*ep, "tar")) + if (!strcasecmp (pm->pm_name, "type")) { + if (strcasecmp (pm->pm_value, "tar")) break; tarP = 1; @@ -219,14 +219,18 @@ store_application (CT ct) } /* check for "conversions=compress" attribute */ - if ((!strcasecmp (*ap, "conversions") || !strcasecmp (*ap, "x-conversions")) - && (!strcasecmp (*ep, "compress") || !strcasecmp (*ep, "x-compress"))) { + if ((!strcasecmp (pm->pm_name, "conversions") || + !strcasecmp (pm->pm_name, "x-conversions")) + && (!strcasecmp (pm->pm_value, "compress") || + !strcasecmp (pm->pm_value, "x-compress"))) { zP = 1; continue; } /* check for "conversions=gzip" attribute */ - if ((!strcasecmp (*ap, "conversions") || !strcasecmp (*ap, "x-conversions")) - && (!strcasecmp (*ep, "gzip") || !strcasecmp (*ep, "x-gzip"))) { + if ((!strcasecmp (pm->pm_name, "conversions") || + !strcasecmp (pm->pm_name, "x-conversions")) + && (!strcasecmp (pm->pm_value, "gzip") || + !strcasecmp (pm->pm_value, "x-gzip"))) { gzP = 1; continue; } @@ -961,12 +965,12 @@ parse_format_string (CT ct, char *cp, char *buffer, int buflen, char *dir) buflen--; continue; } else { - char **ap, **ep; + PM pm; char *s = ""; - for (ap = ci->ci_attrs, ep = ci->ci_values; - *ap; ap++, ep++) { - snprintf (bp, buflen, "%s%s=\"%s\"", s, *ap, *ep); + for (pm = ci->ci_first_pm; pm; pm = pm->pm_next) { + snprintf (bp, buflen, "%s%s=\"%s\"", s, + pm->pm_name, pm->pm_value); len = strlen (bp); bp += len; buflen -= len; @@ -1038,8 +1042,9 @@ raw: static void get_storeproc (CT ct) { - char **ap, **ep, *cp; + char *cp; CI ci; + PM pm; /* * If the storeproc has already been defined, @@ -1054,28 +1059,20 @@ get_storeproc (CT ct) * use that (RFC-2183). */ if (ct->c_dispo) { - char *cp = strchr (ct->c_dispo, ';'); - CI ci = calloc (1, sizeof *ci); - int status; int found_filename = 0; - if (cp && parse_header_attrs (ct->c_file, strlen (invo_name) + 2, &cp, - ci, &status) == OK) { - for (ap = ci->ci_attrs, ep = ci->ci_values; *ap; ap++, ep++) { - if (! strcasecmp (*ap, "filename") - && *(cp = *ep) != '/' + for (pm = ct->c_dispo_first; pm; pm = pm->pm_next) { + if (! strcasecmp (pm->pm_name, "filename") + && *(cp = pm->pm_value) != '/' && *cp != '.' && *cp != '|' && *cp != '!' && !strchr (cp, '%')) { - ct->c_storeproc = add (cp, NULL); - found_filename = 1; - } - free (*ap); + ct->c_storeproc = add (cp, NULL); + found_filename = 1; } } - free (ci); if (found_filename) return; } @@ -1085,9 +1082,9 @@ get_storeproc (CT ct) * the storeproc. */ ci = &ct->c_ctinfo; - for (ap = ci->ci_attrs, ep = ci->ci_values; *ap; ap++, ep++) { - if (! strcasecmp (*ap, "name") - && *(cp = *ep) != '/' + for (pm = ci->ci_first_pm; pm; pm = pm->pm_next) { + if (! strcasecmp (pm->pm_name, "name") + && *(cp = pm->pm_value) != '/' && *cp != '.' && *cp != '|' && *cp != '!'