]> code.citadel.org Git - citadel.git/commitdiff
Handle email addresses with commas inside quotes,
authorArt Cancro <ajc@citadel.org>
Sun, 16 Oct 2005 04:12:55 +0000 (04:12 +0000)
committerArt Cancro <ajc@citadel.org>
Sun, 16 Oct 2005 04:12:55 +0000 (04:12 +0000)
without thinking that the comma is a separator between addresses

citadel/ChangeLog
citadel/database_sleepycat.c
citadel/msgbase.c
citadel/room_ops.c

index 8f5bfed9715bfcacde3f5a1c467ba7230f4f2417..4539e0c4cbb370f104fd32db6a57cf3fdb2cc91e 100644 (file)
@@ -1,3 +1,8 @@
+Sun Oct 16 00:11:16 EDT 2005 Art Cancro <ajc@uncensored.citadel.org>
+* Handle email addresses with commas inside quotes, such as
+  "Cancro, Art" <ajc@uncensored.citadel.org>
+  ...without thinking that the comma is a separator between addresses
+
 Thu Oct 13 00:02:23 EDT 2005 Art Cancro <ajc@uncensored.citadel.org>
 * citadel.c: don't crash when <.R>ead <U>serlist results in an empty
   list.  The ClientIPC API returns NULL if the search returned no results,
index eb1e37f11e03d17ca00a7bb9e95183275a0ff958..088ce54122f8447889385d322184da4c6e5a3589 100644 (file)
@@ -778,12 +778,18 @@ struct cdbdata *cdb_fetch(int cdb, void *key, int keylen)
 
 
 /*
- * Free a cdbdata item (ok, this is really no big deal, but we might need to do
- * more complex stuff with other database managers in the future).
+ * Free a cdbdata item.
+ *
+ * Note that we only free the 'ptr' portion if it is not NULL.  This allows
+ * other code to assume ownership of that memory simply by storing the
+ * pointer elsewhere and then setting 'ptr' to NULL.  cdb_free() will then
+ * avoid freeing it.
  */
 void cdb_free(struct cdbdata *cdb)
 {
-       free(cdb->ptr);
+       if (cdb->ptr) {
+               free(cdb->ptr);
+       }
        free(cdb);
 }
 
index 36c8cfddc9ad970b2a37016db92a55535a3515fa..e16d7cb5ebd83dd010b6d1a182dcff8b94370ab9 100644 (file)
@@ -382,8 +382,8 @@ void CtdlSetSeen(long *target_msgnums, int num_target_msgnums,
        /* Load the message list */
        cdbfr = cdb_fetch(CDB_MSGLISTS, &CC->room.QRnumber, sizeof(long));
        if (cdbfr != NULL) {
-               msglist = malloc(cdbfr->len);
-               memcpy(msglist, cdbfr->ptr, cdbfr->len);
+               msglist = (long *) cdbfr->ptr;
+               cdbfr->ptr = NULL;      /* CtdlSetSeen() now owns this memory */
                num_msgs = cdbfr->len / sizeof(long);
                cdb_free(cdbfr);
        } else {
@@ -543,8 +543,8 @@ int CtdlForEachMessage(int mode, long ref,
        /* Load the message list */
        cdbfr = cdb_fetch(CDB_MSGLISTS, &CC->room.QRnumber, sizeof(long));
        if (cdbfr != NULL) {
-               msglist = malloc(cdbfr->len);
-               memcpy(msglist, cdbfr->ptr, cdbfr->len);
+               msglist = (long *) cdbfr->ptr;
+               cdbfr->ptr = NULL;      /* CtdlForEachMessage() now owns this memory */
                num_msgs = cdbfr->len / sizeof(long);
                cdb_free(cdbfr);
        } else {
@@ -1798,12 +1798,9 @@ int CtdlSaveMsgPointerInRoom(char *roomname, long msgid, int do_repl_check,
                msglist = NULL;
                num_msgs = 0;
        } else {
-               msglist = malloc(cdbfr->len);
-               if (msglist == NULL) {
-                       lprintf(CTDL_ALERT, "ERROR malloc msglist!\n");
-               }
+               msglist = (long *) cdbfr->ptr;
+               cdbfr->ptr = NULL;      /* CtdlSaveMsgPointerInRoom() now owns this memory */
                num_msgs = cdbfr->len / sizeof(long);
-               memcpy(msglist, cdbfr->ptr, cdbfr->len);
                cdb_free(cdbfr);
        }
 
@@ -2659,10 +2656,11 @@ int CtdlCheckInternetMailPermission(struct ctdluser *who) {
  * Returns 0 if all addresses are ok, -1 if no addresses were specified,
  * or the number of addresses found invalid.
  */
-struct recptypes *validate_recipients(char *recipients) {
+struct recptypes *validate_recipients(char *supplied_recipients) {
        struct recptypes *ret;
-       char this_recp[SIZ];
-       char this_recp_cooked[SIZ];
+       char recipients[SIZ];
+       char this_recp[256];
+       char this_recp_cooked[256];
        char append[SIZ];
        int num_recps;
        int i, j;
@@ -2670,6 +2668,7 @@ struct recptypes *validate_recipients(char *recipients) {
        int invalid;
        struct ctdluser tempUS;
        struct ctdlroom tempQR;
+       int in_quotes = 0;
 
        /* Initialize */
        ret = (struct recptypes *) malloc(sizeof(struct recptypes));
@@ -2682,28 +2681,42 @@ struct recptypes *validate_recipients(char *recipients) {
        ret->num_error = 0;
        ret->num_room = 0;
 
-       if (recipients == NULL) {
-               num_recps = 0;
-       }
-       else if (strlen(recipients) == 0) {
-               num_recps = 0;
+       if (supplied_recipients == NULL) {
+               strcpy(recipients, "");
        }
        else {
-               /* Change all valid separator characters to commas */
-               for (i=0; i<strlen(recipients); ++i) {
-                       if ((recipients[i] == ';') || (recipients[i] == '|')) {
-                               recipients[i] = ',';
-                       }
-               }
+               safestrncpy(recipients, supplied_recipients, sizeof recipients);
+       }
 
-               /* Count 'em up */
-               num_recps = num_tokens(recipients, ',');
+       /* Change all valid separator characters to commas */
+       for (i=0; i<strlen(recipients); ++i) {
+               if ((recipients[i] == ';') || (recipients[i] == '|')) {
+                       recipients[i] = ',';
+               }
        }
 
-       if (num_recps > 0) for (i=0; i<num_recps; ++i) {
-               extract_token(this_recp, recipients, i, ',', sizeof this_recp);
+       /* Now start extracting recipients... */
+
+       while (strlen(recipients) > 0) {
+
+               for (i=0; i<=strlen(recipients); ++i) {
+                       if (recipients[i] == '\"') in_quotes = 1 - in_quotes;
+                       if ( ( (recipients[i] == ',') && (!in_quotes) ) || (recipients[i] == 0) ) {
+                               safestrncpy(this_recp, recipients, i+1);
+                               this_recp[i] = 0;
+                               if (recipients[i] == ',') {
+                                       strcpy(recipients, &recipients[i+1]);
+                               }
+                               else {
+                                       strcpy(recipients, "");
+                               }
+                               break;
+                       }
+               }
+
                striplt(this_recp);
-               lprintf(CTDL_DEBUG, "Evaluating recipient #%d <%s>\n", i, this_recp);
+               lprintf(CTDL_DEBUG, "Evaluating recipient #%d: %s\n", num_recps, this_recp);
+               ++num_recps;
                mailtype = alias(this_recp);
                mailtype = alias(this_recp);
                mailtype = alias(this_recp);
@@ -3117,9 +3130,9 @@ int CtdlDeleteMessages(char *room_name,           /* which room */
        cdbfr = cdb_fetch(CDB_MSGLISTS, &qrbuf.QRnumber, sizeof(long));
 
        if (cdbfr != NULL) {
-               msglist = malloc(cdbfr->len);
                dellist = malloc(cdbfr->len);
-               memcpy(msglist, cdbfr->ptr, cdbfr->len);
+               msglist = (long *) cdbfr->ptr;
+               cdbfr->ptr = NULL;      /* CtdlDeleteMessages() now owns this memory */
                num_msgs = cdbfr->len / sizeof(long);
                cdb_free(cdbfr);
        }
index 163d449117ae190dee400cb202f80be99077d00e..80fada02cd0ba74dbb11f610f163f882f11410a5 100644 (file)
@@ -824,8 +824,8 @@ void usergoto(char *where, int display_result, int transiently,
        get_mm();
         cdbfr = cdb_fetch(CDB_MSGLISTS, &CC->room.QRnumber, sizeof(long));
         if (cdbfr != NULL) {
-               msglist = malloc(cdbfr->len);
-               memcpy(msglist, cdbfr->ptr, cdbfr->len);
+               msglist = (long *) cdbfr->ptr;
+               cdbfr->ptr = NULL;      /* usergoto() now owns this memory */
                num_msgs = cdbfr->len / sizeof(long);
                cdb_free(cdbfr);
        }