diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/mbox-util.c | 32 | ||||
-rw-r--r-- | common/mbox-util.h | 2 | ||||
-rw-r--r-- | common/t-mbox-util.c | 95 |
3 files changed, 120 insertions, 9 deletions
diff --git a/common/mbox-util.c b/common/mbox-util.c index 76255ba38..a9086a3f5 100644 --- a/common/mbox-util.c +++ b/common/mbox-util.c @@ -173,11 +173,12 @@ is_valid_mailbox (const char *name) /* Return the mailbox (local-part@domain) form a standard user id. - All plain ASCII characters in the result are converted to - lowercase. Caller must free the result. Returns NULL if no valid - mailbox was found (or we are out of memory). */ + * All plain ASCII characters in the result are converted to + * lowercase. If SUBADDRESS is 1, '+' denoted sub-addresses are not + * included in the result. Caller must free the result. Returns NULL + * if no valid mailbox was found (or we are out of memory). */ char * -mailbox_from_userid (const char *userid) +mailbox_from_userid (const char *userid, int subaddress) { const char *s, *s_end; size_t len; @@ -226,6 +227,29 @@ mailbox_from_userid (const char *userid) else errno = EINVAL; + if (result && subaddress == 1) + { + char *atsign, *plus; + + if ((atsign = strchr (result, '@'))) + { + /* We consider a subaddress only if there is a single '+' + * in the local part and the '+' is not the first or last + * character. */ + *atsign = 0; + if ((plus = strchr (result, '+')) + && !strchr (plus+1, '+') + && result != plus + && plus[1] ) + { + *atsign = '@'; + memmove (plus, atsign, strlen (atsign)+1); + } + else + *atsign = '@'; + } + } + return result? ascii_strlwr (result): NULL; } diff --git a/common/mbox-util.h b/common/mbox-util.h index 7355ceef5..10ff2c4a0 100644 --- a/common/mbox-util.h +++ b/common/mbox-util.h @@ -22,7 +22,7 @@ int has_invalid_email_chars (const void *buffer, size_t length); int is_valid_mailbox (const char *name); int is_valid_mailbox_mem (const void *buffer, size_t length); -char *mailbox_from_userid (const char *userid); +char *mailbox_from_userid (const char *userid, int subaddress); int is_valid_user_id (const char *uid); int is_valid_domain_name (const char *string); diff --git a/common/t-mbox-util.c b/common/t-mbox-util.c index e9cf41215..ae717f96f 100644 --- a/common/t-mbox-util.c +++ b/common/t-mbox-util.c @@ -83,7 +83,86 @@ run_mbox_test (void) for (idx=0; testtbl[idx].userid; idx++) { - char *mbox = mailbox_from_userid (testtbl[idx].userid); + char *mbox = mailbox_from_userid (testtbl[idx].userid, 0); + + if (!testtbl[idx].mbox) + { + if (mbox) + fail (idx); + } + else if (!mbox) + fail (idx); + else if (strcmp (mbox, testtbl[idx].mbox)) + fail (idx); + + xfree (mbox); + } +} + + +static void +run_mbox_no_sub_test (void) +{ + static struct + { + const char *userid; + const char *mbox; + } testtbl[] = + { + { "[email protected]", "[email protected]" }, + { "Werner Koch <[email protected]>", "[email protected]" }, + { "<[email protected]>", "[email protected]" }, + { "[email protected]", "[email protected]" }, + { "[email protected] ", NULL }, + { " [email protected]", NULL }, + { "Werner Koch (test) <[email protected]>", "[email protected]" }, + { "Werner Koch <[email protected]> (test)", "[email protected]" }, + { "Werner Koch <[email protected] (test)", NULL }, + { "Werner Koch <[email protected] >", NULL }, + { "Werner Koch <[email protected]", NULL }, + { "", NULL }, + { "@", NULL }, + { "bar <>", NULL }, + { "<[email protected]>", "[email protected]" }, + { "<[email protected]>", "[email protected]" }, + { "<[email protected]>", "[email protected]" }, + { "<[email protected]>", "[email protected]" }, + { "<[email protected]>", "[email protected]" }, + { "<[email protected].>", NULL }, + { "<[email protected]>", NULL }, + { "<foo@.>", NULL }, + { "<@example.org>", NULL }, + { "<foo@@example.org>", NULL }, + { "<@[email protected]>", NULL }, + { "<[email protected]> ()", "[email protected]" }, + { "<fo()[email protected]> ()", "fo()[email protected]" }, + { "<fo()[email protected]> ()", "fo()[email protected]" }, + { "fo()[email protected]", NULL}, + { "[email protected]", "[email protected]" }, + { "[email protected]", "[email protected]" }, + { "[email protected]", "[email protected]" }, + { "[email protected]", "[email protected]" }, + { "[email protected]", "[email protected]" }, + { "[email protected]", "[email protected]" }, + { "[email protected]", "[email protected]" }, + { "[email protected]", "[email protected]" }, + { "[email protected]", "[email protected]" }, + { "[email protected]", "[email protected]" }, + { "[email protected]", "[email protected]" }, + { "[email protected]", "[email protected]" }, + { "[email protected]", "[email protected]" }, + { "[email protected]", "[email protected]" }, + { "[email protected]", "[email protected]" }, + { "[email protected]", "[email protected]" }, + + { NULL, NULL } + }; + int idx; + + for (idx=0; testtbl[idx].userid; idx++) + { + char *mbox = mailbox_from_userid (testtbl[idx].userid, 1); if (!testtbl[idx].mbox) { @@ -151,7 +230,7 @@ run_dns_test (void) static void -run_filter (void) +run_filter (int no_sub) { char buf[4096]; int c; @@ -172,7 +251,7 @@ run_filter (void) } count1++; trim_spaces (buf); - mbox = mailbox_from_userid (buf); + mbox = mailbox_from_userid (buf, no_sub); if (mbox) { printf ("%s\n", mbox); @@ -190,6 +269,7 @@ main (int argc, char **argv) { int last_argc = -1; int opt_filter = 0; + int opt_no_sub = 0; if (argc) { argc--; argv++; } @@ -208,6 +288,7 @@ main (int argc, char **argv) " --verbose Print timings etc.\n" " --debug Flyswatter\n" " --filter Filter mboxes from input lines\n" + " --no-sub Ignore '+'-sub-addresses\n" , stdout); exit (0); } @@ -227,6 +308,11 @@ main (int argc, char **argv) opt_filter = 1; argc--; argv++; } + else if (!strcmp (*argv, "--no-sub")) + { + opt_no_sub = 1; + argc--; argv++; + } else if (!strncmp (*argv, "--", 2)) { fprintf (stderr, PGM ": unknown option '%s'\n", *argv); @@ -235,10 +321,11 @@ main (int argc, char **argv) } if (opt_filter) - run_filter (); + run_filter (opt_no_sub); else { run_mbox_test (); + run_mbox_no_sub_test (); run_dns_test (); } |