]> diplodocus.org Git - nmh/commitdiff
Generalized %{charset} display string escape to any Content-Type
authorDavid Levine <levinedl@acm.org>
Thu, 20 Feb 2014 03:36:16 +0000 (21:36 -0600)
committerDavid Levine <levinedl@acm.org>
Thu, 20 Feb 2014 03:36:16 +0000 (21:36 -0600)
parameter.  Also, always quote the expanded value, whether or not
the escape was quoted in the profile.

etc/mhn.defaults.sh
man/mhshow.man
test/mhshow/test-textcharset
uip/mhshowsbr.c

index b7cecd51be069686f733d51193e3477d5345c1c8..7e9ca564d3709f8e0505d778f9b33a9a56892ea9 100755 (executable)
@@ -27,11 +27,11 @@ trap "rm -f $TMP" 0 1 2 3 13 15
 
 
 if [ ! -z "`$SEARCHPROG $SEARCHPATH w3m`" ]; then
 
 
 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.
 "'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
 "'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
 # 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
 %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
 %p$PGM"' "${charset:+-I $charset}" -T text/html %F' >> $TMP
   fi
 fi
index 40304b09d3e7b9c74cc025c2723c8706e6ce6f0a..03ca5f82d1b22b53a86ea36a8d778926a48bb153 100644 (file)
@@ -224,9 +224,9 @@ The display string may contain the following escapes:
 .PP
 .RS 5
 .nf
 .PP
 .RS 5
 .nf
-.ta \w'%F      'u
+.ta \w'%F        'u
 %a        Insert parameters from Content-Type field
 %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
 %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
 .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
 .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
   w3m ${charset:+-I $charset} -T text/html %F
 .fi
 .RE
index eafb6ad085d26a400b57cd3c475505e16e3e1ea0..5d358d929cb7b2a3e0c251c99eea110cc1bd3b11 100755 (executable)
@@ -27,7 +27,7 @@ actual="$MH_TEST_DIR"/$$.actual
 
 # check charset conversion
 msgfile=`mhpath new`
 
 # 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
 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
 
 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
 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`
 
 # 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
 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
 
 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
 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`
 
 # 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
 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
 
 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
 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'
 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
 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
 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
 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
 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
 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
 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
 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
 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"
 
 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"
 
 mv -f "$MH.new" "$MH"
 
-# check expansion of unknown parameter
+# check parameter value quoting
 msgfile=`mhpath new`
 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
 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
 
 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
 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
 
 
 MIME-Version: 1.0
 
--I %{unknown} file
+file
 EOF
 
 run_prog mhshow -nopause last >"$actual" 2>&1
 EOF
 
 run_prog mhshow -nopause last >"$actual" 2>&1
index bd44c85975d5e247a6774cff22a95a18645f655e..cfc4d8864a39c5dcd783177ee19ed04514075517 100644 (file)
@@ -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 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);
 
 
 static void intrser (int);
 
 
@@ -939,60 +939,38 @@ parse_display_string (CT ct, char *cp, int *xstdin, int *xlist, int *xpause,
                goto raw;
 
            case '{' : {
                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 {
                    } 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 {
                    }
                } 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:
            }
 
            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;
 }
 
 
 }