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
# 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
.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
.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
# check charset conversion
msgfile=`mhpath new`
-cat >"$msgfile" <<EOF
+cat >"$msgfile" <<'EOF'
From: foo@example.edu
To: bar@example.edu
Subject: test display with charset conversion
4 =F7 2 =3D 2
EOF
-cat >"$expected" <<EOF
+cat >"$expected" <<'EOF'
Date: Sun, 18 Dec 2005 00:52:39 +0100
To: bar@example.edu
From: foo@example.edu
# check expansion of %{charset} by itself
msgfile=`mhpath new`
-cat >"$msgfile" <<EOF
+cat >"$msgfile" <<'EOF'
From: foo@example.edu
To: bar@example.edu
Subject: test display with %{charset} expansion
4 =F7 2 =3D 2
EOF
-cat >"$expected" <<EOF
+cat >"$expected" <<'EOF'
Date: Sun, 18 Dec 2005 00:52:39 +0100
To: bar@example.edu
From: foo@example.edu
# check expansion of empty %{charset} by itself
msgfile=`mhpath new`
-cat >"$msgfile" <<EOF
+cat >"$msgfile" <<'EOF'
From: foo@example.edu
To: bar@example.edu
Subject: test display with empty %{charset} expansion
4 =F7 2 =3D 2
EOF
-cat >"$expected" <<EOF
+cat >"$expected" <<'EOF'
Date: Sun, 18 Dec 2005 00:52:39 +0100
To: bar@example.edu
From: foo@example.edu
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" <<EOF
+cat >"$expected" <<'EOF'
Date: Sun, 18 Dec 2005 00:52:39 +0100
To: bar@example.edu
From: foo@example.edu
check "$expected" "$actual"
# check expansion of empty embedded %{charset} with no text following
-cat >"$expected" <<EOF
+cat >"$expected" <<'EOF'
Date: Sun, 18 Dec 2005 00:52:39 +0100
To: bar@example.edu
From: foo@example.edu
mv -f "$MH.new" "$MH"
# check expansion of embedded %{charset} with text following
-cat >"$expected" <<EOF
+cat >"$expected" <<'EOF'
Date: Sun, 18 Dec 2005 00:52:39 +0100
To: bar@example.edu
From: foo@example.edu
check "$expected" "$actual"
# check expansion of empty embedded %{charset} with text following
-cat >"$expected" <<EOF
+cat >"$expected" <<'EOF'
Date: Sun, 18 Dec 2005 00:52:39 +0100
To: bar@example.edu
From: foo@example.edu
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" <<EOF
+cat >"$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
4 =F7 2 =3D 2
EOF
-cat >"$expected" <<EOF
+cat >"$expected" <<'EOF'
Date: Sun, 18 Dec 2005 00:52:39 +0100
To: bar@example.edu
From: foo@example.edu
MIME-Version: 1.0
--I %{unknown} file
+file
EOF
run_prog mhshow -nopause last >"$actual" 2>&1
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);
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:
/*
- * 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;
}