This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The nmh Mail Handling System".
The branch, master has been updated via f423b06bf5ab4a966b17857f027a46e74447f438 (commit) from 393c9290adc27e6d85b780c2434f51f95ea6df5b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- http://git.savannah.gnu.org/cgit/nmh.git/commit/?id=f423b06bf5ab4a966b17857f027a46e74447f438 commit f423b06bf5ab4a966b17857f027a46e74447f438 Author: David Levine <levin...@acm.org> Date: Thu Mar 22 21:06:47 2012 -0500 Added function escape_display_name() to double quote, if not already, a fullname that contains any of the special characters listed in RFC 5322, and escape unescaped, embedded double quotes. With this change, nmh should work with no special configuration on Cygwin, even if the user's fullname is of the form server\name. diff --git a/MACHINES b/MACHINES index ab0d2cb..8bae084 100644 --- a/MACHINES +++ b/MACHINES @@ -47,12 +47,6 @@ Libs category. And libncurses10 or later in the Lib category. You may notice a few (three) compile warnings: they can be ignored. -If send, post, and whom fail, the cause might be a \ in your username. -To avoid this, either add a Signature profile entry (see the -mh-profile(5) man page) or set/export your SIGNATURE environment -variable. The value can be just the short form of your username, such -as that displayed by "id -nu". - -------------------------------------- HPUX: diff --git a/Makefile.am b/Makefile.am index 14d1dd1..c8006a9 100644 --- a/Makefile.am +++ b/Makefile.am @@ -369,7 +369,7 @@ uip_viamail_SOURCES = uip/viamail.c uip/mhmisc.c uip/mhoutsbr.c uip/sendsbr.c \ uip/annosbr.c uip/distsbr.c test_getfullname_SOURCES = test/getfullname.c -test_getfullname_LDADD = +test_getfullname_LDADD = sbr/libmh.a test_getfqdn_SOURCES = test/getfqdn.c test_getfqdn_LDADD = @@ -452,7 +452,7 @@ sbr_libmh_a_SOURCES = sbr/addrsbr.c sbr/ambigsw.c sbr/atooi.c sbr/brkstring.c \ sbr/context_replace.c sbr/context_save.c \ sbr/copy.c sbr/copyip.c sbr/cpydata.c \ sbr/cpydgst.c sbr/crawl_folders.c sbr/discard.c \ - sbr/done.c sbr/dtime.c \ + sbr/done.c sbr/dtime.c sbr/escape_display_name.c \ sbr/error.c sbr/ext_hook.c sbr/fdcompare.c \ sbr/folder_addmsg.c sbr/folder_delmsgs.c \ sbr/folder_free.c sbr/folder_pack.c \ diff --git a/h/prototypes.h b/h/prototypes.h index 38357a8..b4c0048 100644 --- a/h/prototypes.h +++ b/h/prototypes.h @@ -47,6 +47,7 @@ void cpydgst (int, int, char *, char *); int decode_rfc2047 (char *, char *, size_t); void discard (FILE *); int default_done (int); +void escape_display_name (char *); int ext_hook(char *, char *, char *); int fdcompare (int, int); int folder_addmsg (struct msgs **, char *, int, int, int, int, char *); diff --git a/sbr/escape_display_name.c b/sbr/escape_display_name.c new file mode 100644 index 0000000..0918942 --- /dev/null +++ b/sbr/escape_display_name.c @@ -0,0 +1,63 @@ +#include <sys/types.h> +#include <h/utils.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> + +/* Escape a display name, hopefully per RFC 5322. + The argument is assumed to be a pointer to a character array of + one-byte characters with enough space to handle the additional + characters. */ +void +escape_display_name (char *name) { + /* Quote and escape name that contains any specials, as necessary. */ + if (strpbrk("\"(),.:;<>@[\\]", name)) { + size_t len = strlen(name); + char *destp, *srcp; + size_t destpos, srcpos; + /* E.g., 2 characters, "", would require 7, "\"\""\0. */ + char *tmp = malloc (2*len+3); + + for (destp = tmp, srcp = name, destpos = 0, srcpos = 0; + *srcp; + ++destp, ++srcp, ++destpos, ++srcpos) { + if (srcpos == 0) { + /* Insert initial double quote, if needed. */ + if (*srcp != '"') { + *destp++ = '"'; + ++destpos; + } + } else { + /* Escape embedded, unescaped ". */ + if (*srcp == '"' && srcpos < len - 1 && *(srcp-1) != '\\') { + *destp++ = '\\'; + ++destpos; + } + } + + *destp = *srcp; + + /* End of name. */ + if (srcpos == len - 1) { + /* Insert final double quote, if needed. */ + if (*srcp != '"') { + *++destp = '"'; + ++destpos; + } + + *++destp = '\0'; + ++destpos; + } + } + + if (strcmp (tmp, "\"")) { + /* assert (strlen(tmp) + 1 == destpos); */ + strncpy (name, tmp, destpos); + } else { + /* Handle just " as special case here instead of above. */ + strcpy (name, "\"\\\"\""); + } + + free (tmp); + } +} diff --git a/sbr/mts.c b/sbr/mts.c index c529156..556d740 100644 --- a/sbr/mts.c +++ b/sbr/mts.c @@ -395,16 +395,10 @@ getuserinfo (void) else if ((cp = context_find("Signature"))) strncpy (fullname, cp, sizeof(fullname)); - if (strchr(fullname, '.')) { /* quote any .'s */ - char tmp[BUFSIZ]; - - /* should quote "'s too */ - snprintf (tmp, sizeof(tmp), "\"%s\"", fullname); - strncpy (fullname, tmp, sizeof(fullname)); - } - fullname[sizeof(fullname) - 1] = '\0'; + escape_display_name(fullname); + localmbox[0] = '\0'; return; diff --git a/test/format/test-myname b/test/format/test-myname index 2b48c2f..d9dca2d 100755 --- a/test/format/test-myname +++ b/test/format/test-myname @@ -31,4 +31,25 @@ export SIGNATURE="Some Random Name 2" run_test "${MH_LIB_DIR}/ap -format %(myname) ignore" \ "${SIGNATURE}" "SIGNATURE Environment test" +#### Test escaping of display names. +escape="${MH_OBJ_DIR}/test/getfullname" +run_test "$escape "'user' 'user' 'no escape' +run_test "$escape "'first.last' '"first.last"' 'escape' +run_test "$escape "'"first.last"' '"first.last"' 'already escaped' +run_test "$escape "'embedded"quote' '"embedded\"quote"' 'embedded quote' +run_test "$escape "'"' '"\""' 'special "' +run_test "$escape "'(' '"("' 'special (' +run_test "$escape "')' '")"' 'special )' +#### We stop at the first comma so this one gets eliminated: +run_test "$escape "',' '' 'special ,' +run_test "$escape "'.' '"."' 'special .' +run_test "$escape "':' '":"' 'special :' +run_test "$escape "';' '";"' 'special ;' +run_test "$escape "'<' '"<"' 'special <' +run_test "$escape "'>' '">"' 'special >' +run_test "$escape "'@' '"@"' 'special @' +run_test "$escape "'[' '"["' 'special [' +run_test "$escape "'\\' '"\\"' 'special \\' +run_test "$escape "']' '"]"' 'special ]' + exit $failed diff --git a/test/getfullname.c b/test/getfullname.c index d8ff101..ec83939 100644 --- a/test/getfullname.c +++ b/test/getfullname.c @@ -14,52 +14,47 @@ #include <sys/types.h> #include <pwd.h> +extern void escape_display_name (char *); + int main(int argc, char *argv[]) { struct passwd *pwd; - char name[BUFSIZ], *p; - - if (argc > 1) { - fprintf (stderr, "usage: %s\n", argv[0]); - } - - pwd = getpwuid(getuid()); - - if (! pwd) { - fprintf(stderr, "Unable to retrieve user info for " - "userid %ld\n", (long) getuid()); - exit(1); + char buf[BUFSIZ], *p; + char *name = buf; + + if (argc < 2) { + pwd = getpwuid(getuid()); + + if (! pwd) { + fprintf(stderr, "Unable to retrieve user info for " + "userid %ld\n", (long) getuid()); + exit(1); + } + + strncpy(buf, pwd->pw_gecos, sizeof(buf)); + buf[sizeof(buf) - 1] = '\0'; + } else if (argc == 2) { + name = argv[1]; + } else if (argc > 2) { + fprintf (stderr, "usage: %s [name]\n", argv[0]); + return 1; } /* * Perform the same processing that getuserinfo() does. */ - strncpy(name, pwd->pw_gecos, sizeof(name)); - - name[sizeof(name) - 1] = '\0'; - /* - * Stop at the first comma + * Stop at the first comma. */ - if ((p = strchr(name, ','))) *p = '\0'; /* - * Quote the entire string if it has a "." in it + * Quote the entire string if it has a special character in it. */ - - if (strchr(name, '.')) { - char tmp[BUFSIZ]; - - snprintf(tmp, sizeof(tmp), "\"%s\"", name); - strncpy(name, tmp, sizeof(name)); - - name[sizeof(name) - 2] = '"'; - name[sizeof(name) - 1] = '\0'; - } + escape_display_name (name); printf("%s\n", name); ----------------------------------------------------------------------- Summary of changes: MACHINES | 6 ---- Makefile.am | 4 +- h/prototypes.h | 1 + sbr/escape_display_name.c | 63 +++++++++++++++++++++++++++++++++++++++++++++ sbr/mts.c | 10 +----- test/format/test-myname | 21 +++++++++++++++ test/getfullname.c | 53 +++++++++++++++++-------------------- 7 files changed, 113 insertions(+), 45 deletions(-) create mode 100644 sbr/escape_display_name.c hooks/post-receive -- The nmh Mail Handling System _______________________________________________ Nmh-commits mailing list Nmh-commits@nongnu.org https://lists.nongnu.org/mailman/listinfo/nmh-commits