From: David Levine Date: Thu, 20 Feb 2014 03:36:16 +0000 (-0600) Subject: Generalized %{charset} display string escape to any Content-Type X-Git-Url: https://diplodocus.org/git/nmh/commitdiff_plain/d6366b583c87d112858cf8226de77fca852eea87?ds=inline;hp=3ce8402113b0d2006074f721fdf748a92e614cb2 Generalized %{charset} display string escape to any Content-Type parameter. Also, always quote the expanded value, whether or not the escape was quoted in the profile. --- diff --git a/etc/mhn.defaults.sh b/etc/mhn.defaults.sh index b7cecd51..7e9ca564 100755 --- a/etc/mhn.defaults.sh +++ b/etc/mhn.defaults.sh @@ -27,11 +27,11 @@ trap "rm -f $TMP" 0 1 2 3 13 15 if [ ! -z "`$SEARCHPROG $SEARCHPATH w3m`" ]; then - echo 'mhfixmsg-format-text/html: charset="%{charset}"; '"\ + echo 'mhfixmsg-format-text/html: charset=%{charset}; '"\ "'w3m -dump -T text/html "${charset:+-I $charset}" -O utf-8 %F' >> $TMP elif [ ! -z "`$SEARCHPROG $SEARCHPATH lynx`" ]; then #### lynx indents with 3 spaces, remove them and any trailing spaces. - echo 'mhfixmsg-format-text/html: charset="%{charset}"; '"\ + echo 'mhfixmsg-format-text/html: charset=%{charset}; '"\ "'lynx -child -dump -force_html "${charset:+--assume_charset $charset}" %F | '"\ expand | sed -e 's/^ //' -e 's/ *$//'" >> $TMP elif [ ! -z "`$SEARCHPROG $SEARCHPATH elinks`" ]; then @@ -239,12 +239,12 @@ EOF # that another netscape is already running and certain things can't be done). PGM="`$SEARCHPROG $SEARCHPATH lynx`" if [ ! -z "$PGM" ]; then - echo 'mhshow-show-text/html: charset="%{charset}"; '"\ + echo 'mhshow-show-text/html: charset=%{charset}; '"\ %p$PGM"' -force-html "${charset:+--assume_charset $charset}" %F' >> $TMP else PGM="`$SEARCHPROG $SEARCHPATH w3m`" if [ ! -z "$PGM" ]; then - echo 'mhshow-show-text/html: charset="%{charset}"; '"\ + echo 'mhshow-show-text/html: charset=%{charset}; '"\ %p$PGM"' "${charset:+-I $charset}" -T text/html %F' >> $TMP fi fi diff --git a/man/mhshow.man b/man/mhshow.man index 40304b09..03ca5f82 100644 --- a/man/mhshow.man +++ b/man/mhshow.man @@ -224,9 +224,9 @@ The display string may contain the following escapes: .PP .RS 5 .nf -.ta \w'%F 'u +.ta \w'%F 'u %a Insert parameters from Content-Type field -%{charset} Insert the charset value from the Content-Type field +%{parameter} Insert the parameter value from the Content-Type field %e exclusive execution %f Insert filename containing content %F %e, %f, and stdin is terminal not content @@ -258,13 +258,15 @@ control-\\) will tell .B mhshow to wrap things up immediately. .PP -The {charset} escape is typically used in a command line argument that -should only be present if it has a non-null value. Shell parameter -expansion can construct the argument only when it is non-null, e.g., +The {parameter} escape is typically used in a command line argument +that should only be present if it has a non-null value. Its value +will be wrapped with single quotes if the escape is not so wrapped. +Shell parameter expansion can construct the argument only when it is +non-null, e.g., .PP .RS 5 .nf -mhshow-show-text/html: charset="%{charset}"; +mhshow-show-text/html: charset=%{charset}; w3m ${charset:+-I $charset} -T text/html %F .fi .RE diff --git a/test/mhshow/test-textcharset b/test/mhshow/test-textcharset index eafb6ad0..5d358d92 100755 --- a/test/mhshow/test-textcharset +++ b/test/mhshow/test-textcharset @@ -27,7 +27,7 @@ actual="$MH_TEST_DIR"/$$.actual # check charset conversion msgfile=`mhpath new` -cat >"$msgfile" <"$msgfile" <<'EOF' From: foo@example.edu To: bar@example.edu Subject: test display with charset conversion @@ -39,7 +39,7 @@ Date: Sun, 18 Dec 2005 00:52:39 +0100 4 =F7 2 =3D 2 EOF -cat >"$expected" <"$expected" <<'EOF' Date: Sun, 18 Dec 2005 00:52:39 +0100 To: bar@example.edu From: foo@example.edu @@ -60,7 +60,7 @@ EOF # check expansion of %{charset} by itself msgfile=`mhpath new` -cat >"$msgfile" <"$msgfile" <<'EOF' From: foo@example.edu To: bar@example.edu Subject: test display with %{charset} expansion @@ -72,7 +72,7 @@ Date: Sun, 18 Dec 2005 00:52:39 +0100 4 =F7 2 =3D 2 EOF -cat >"$expected" <"$expected" <<'EOF' Date: Sun, 18 Dec 2005 00:52:39 +0100 To: bar@example.edu From: foo@example.edu @@ -88,7 +88,7 @@ check "$expected" "$actual" # check expansion of empty %{charset} by itself msgfile=`mhpath new` -cat >"$msgfile" <"$msgfile" <<'EOF' From: foo@example.edu To: bar@example.edu Subject: test display with empty %{charset} expansion @@ -100,7 +100,7 @@ Date: Sun, 18 Dec 2005 00:52:39 +0100 4 =F7 2 =3D 2 EOF -cat >"$expected" <"$expected" <<'EOF' Date: Sun, 18 Dec 2005 00:52:39 +0100 To: bar@example.edu From: foo@example.edu @@ -117,11 +117,11 @@ check "$expected" "$actual" grep -v 'mhshow-show-text/plain:' "$MH" >"$MH.new" mv -f "$MH.new" "$MH" cat >>"$MH" <<'EOF' -mhshow-show-text/plain: charset="%{charset}"; echo ${charset:+-I $charset} +mhshow-show-text/plain: charset=%{charset}; echo ${charset:+-I $charset} EOF # check expansion of embedded %{charset} with no text following -cat >"$expected" <"$expected" <<'EOF' Date: Sun, 18 Dec 2005 00:52:39 +0100 To: bar@example.edu From: foo@example.edu @@ -136,7 +136,7 @@ run_prog mhshow -nopause prev >"$actual" 2>&1 check "$expected" "$actual" # check expansion of empty embedded %{charset} with no text following -cat >"$expected" <"$expected" <<'EOF' Date: Sun, 18 Dec 2005 00:52:39 +0100 To: bar@example.edu From: foo@example.edu @@ -154,7 +154,7 @@ sed -e 's%\(mhshow-show-text/plain:.*\)%\1 file%' "$MH" >"$MH.new" mv -f "$MH.new" "$MH" # check expansion of embedded %{charset} with text following -cat >"$expected" <"$expected" <<'EOF' Date: Sun, 18 Dec 2005 00:52:39 +0100 To: bar@example.edu From: foo@example.edu @@ -169,7 +169,7 @@ run_prog mhshow -nopause prev >"$actual" 2>&1 check "$expected" "$actual" # check expansion of empty embedded %{charset} with text following -cat >"$expected" <"$expected" <<'EOF' Date: Sun, 18 Dec 2005 00:52:39 +0100 To: bar@example.edu From: foo@example.edu @@ -183,12 +183,43 @@ EOF run_prog mhshow -nopause last >"$actual" 2>&1 check "$expected" "$actual" -sed -e 's/%{charset}/%{unknown}/' "$MH" >"$MH.new" +sed -e 's/charset/method/g' "$MH" >"$MH.new" mv -f "$MH.new" "$MH" -# check expansion of unknown parameter +# check parameter value quoting msgfile=`mhpath new` -cat >"$msgfile" <"$msgfile" <<'EOF' +From: foo@example.edu +To: bar@example.edu +Subject: test C-T parameter expansion quoting +MIME-Version: 1.0 +Content-Type: text/plain; method=$QUOTEME' +Content-Transfer-Encoding: quoted-printable +Date: Sun, 18 Dec 2005 00:52:39 +0100 + +4 =F7 2 =3D 2 +EOF + +cat >"$expected" <<'EOF' +Date: Sun, 18 Dec 2005 00:52:39 +0100 +To: bar@example.edu +From: foo@example.edu +Subject: test C-T parameter expansion quoting + +MIME-Version: 1.0 + +-I $QUOTEME' file +EOF + +run_prog mhshow -nopause last >"$actual" 2>&1 +check "$expected" "$actual" + +sed -e 's/method/unknown/g' "$MH" >"$MH.new" +mv -f "$MH.new" "$MH" + +# check that unknown parameter is not expanded +msgfile=`mhpath new` +cat >"$msgfile" <<'EOF' From: foo@example.edu To: bar@example.edu Subject: test display with unknown C-T parameter expansion @@ -200,7 +231,7 @@ Date: Sun, 18 Dec 2005 00:52:39 +0100 4 =F7 2 =3D 2 EOF -cat >"$expected" <"$expected" <<'EOF' Date: Sun, 18 Dec 2005 00:52:39 +0100 To: bar@example.edu From: foo@example.edu @@ -208,7 +239,7 @@ Subject: test display with unknown C-T parameter expansion MIME-Version: 1.0 --I %{unknown} file +file EOF run_prog mhshow -nopause last >"$actual" 2>&1 diff --git a/uip/mhshowsbr.c b/uip/mhshowsbr.c index bd44c859..cfc4d886 100644 --- a/uip/mhshowsbr.c +++ b/uip/mhshowsbr.c @@ -73,7 +73,7 @@ static int show_external (CT, int, int); static int parse_display_string (CT, char *, int *, int *, int *, int *, char *, char *, size_t, int multipart); static int convert_content_charset (CT, char **); -static int parameter_value (CI, const char *, const char *, const char **); +static const char *parameter_value (CI, const char *); static void intrser (int); @@ -939,60 +939,38 @@ parse_display_string (CT ct, char *cp, int *xstdin, int *xlist, int *xpause, goto raw; case '{' : { - static const char param[] = "charset"; - const char *value; - const int found = parameter_value (ci, param, cp, &value); + const char *closing_brace = strchr(cp, '}'); - if (found == OK) { - /* Because it'll get incremented in the next iteration, - just increment by 1 for the '{'. */ - cp += strlen(param) + 1; + if (closing_brace) { + const size_t param_len = closing_brace - cp - 1; + char *param = mh_xmalloc(param_len + 1); + const char *value; - /* cp pointed to the param and it's set in the - Content-Type header. */ - strncpy (bp, value, buflen); + (void) strncpy(param, cp + 1, param_len); + param[param_len] = '\0'; + value = parameter_value(ci, param); + free(param); - /* since we've quoted the file argument, set things up - * to look past it, to avoid problems with the quoting - * logic below. (I know, I should figure out what's - * broken with the quoting logic, but..) - */ - len = strlen(bp); - bp += len; - buflen -= len; - pp = bp; + cp += param_len + 1; /* Skip both braces, too. */ - break; - } else if (found == 1) { - /* cp points to the param and it's not set in the - Content-Type header, so skip it. */ - cp += strlen(param) + 1; - - if (*cp == '\0') { - break; + if (value) { + /* %{param} is set in the Content-Type header. + After the break below, quote it if necessary. */ + (void) strncpy(bp, value, buflen); } else { - if (*(cp + 1) == '\0') { - break; - } else { - ++cp; - /* Increment cp again so that the last - character of the %{} token isn't output - after falling thru below. */ - ++cp; - } + /* %{param} not found, so skip it completely. cp + was advanced above. */ + continue; } } else { - /* cp points to an unrecognized parameter. Output - it as-is, starting here with the "%{". */ - *bp++ = '%'; - *bp++ = '{'; - *bp = '\0'; - buflen -= 2; - continue; + /* This will get confused if there are multiple %{}'s, + but its real purpose is to avoid doing bad things + above if a closing brace wasn't found. */ + admonish(NULL, + "no closing brace for display string escape %s", + cp); } - - /* No parameter was found, so fall thru to default to - output the rest of the text as-is. */ + break; } default: @@ -1244,33 +1222,22 @@ convert_content_charset (CT ct, char **file) { /* - * Return values: - * NOTOK if cp doesn't point to {param} - * OK if cp points to {param} and that attribute exists, and returns - * its value - * 1 if cp points to {param} and that attribute doesn't exist + * If a Content-Type parameter named param exists, returns its value. + * Otherwise, returns NULL. */ -int -parameter_value (CI ci, const char *param, const char *cp, const char **value) { - int found = NOTOK; - char *braced_param = concat ("{", param, "}", NULL); - - if (! strncasecmp(cp, braced_param, strlen (braced_param))) { - char **ap, **ep; - - found = 1; - - for (ap = ci->ci_attrs, ep = ci->ci_values; *ap; ++ap, ++ep) { - if (!strcasecmp (*ap, param)) { - found = OK; - *value = *ep; - break; - } +static const char * +parameter_value (CI ci, const char *param) { + const char *value = NULL; + char **ap, **vp; + + for (ap = ci->ci_attrs, vp = ci->ci_values; *ap; ++ap, ++vp) { + if (! strcasecmp (*ap, param)) { + value = *vp; + break; } } - free (braced_param); - return found; + return value; }