Changeset 5473:00ce81d778bf

Show
Ignore:
Timestamp:
2008-07-10 16:30:00 (5 months ago)
Author:
Aron Griffis <agriffis@…>
Branch:
HEAD
Message:

Unify parser for message-ids

Rewrite mutt_extract_message_id and change mutt_parse_references to us it. The
parser in mutt_extract_message_id is looser than the old one in
mutt_parse_references; it just looks for <[\s>]+> and doesn't worry about
@-signs. Additionally it doesn't use strtok, so the input string can be const.

Closes #3090, #1935, #1116 (both the stated bug and the conversation following).

Signed-off-by: Aron Griffis <agriffis@…>

Files:
3 modified

Legend:

Unmodified
Added
Removed
  • parse.c

    r5395 r5473  
    9393{ 
    9494  LIST *t, *lst = NULL; 
    95   int m, n = 0; 
    96   char *o = NULL, *new, *at; 
    97  
    98   while ((s = strtok (s, " \t;")) != NULL) 
    99   { 
    100     /* 
    101      * some mail clients add other garbage besides message-ids, so do a quick 
    102      * check to make sure this looks like a valid message-id 
    103      * some idiotic clients also break their message-ids between lines, deal 
    104      * with that too (give up if it's more than two lines, though) 
    105      */ 
    106     t = NULL; 
    107     new = NULL; 
    108  
    109     if (*s == '<') 
    110     { 
    111       n = strlen (s); 
    112       if (s[n-1] != '>') 
    113       { 
    114         o = s; 
    115         s = NULL; 
    116         continue; 
    117       } 
    118  
    119       new = safe_strdup (s); 
    120     } 
    121     else if (o) 
    122     { 
    123       m = strlen (s); 
    124       if (s[m - 1] == '>') 
    125       { 
    126         new = safe_malloc (sizeof (char) * (n + m + 1)); 
    127         strcpy (new, o);        /* __STRCPY_CHECKED__ */ 
    128         strcpy (new + n, s);    /* __STRCPY_CHECKED__ */ 
    129       } 
    130     } 
    131     if (new) 
    132     { 
    133       /* make sure that this really does look like a message-id. 
    134        * it should have exactly one @, and if we're looking at 
    135        * an in-reply-to header, make sure that the part before 
    136        * the @ has more than eight characters or it's probably 
    137        * an email address 
    138        */ 
    139       if (!(at = strchr (new, '@')) || strchr (at + 1, '@') 
    140           || (in_reply_to && at - new <= 8)) 
    141         FREE (&new); 
    142       else 
    143       { 
    144         t = (LIST *) safe_malloc (sizeof (LIST)); 
    145         t->data = new; 
    146         t->next = lst; 
    147         lst = t; 
    148       } 
    149     } 
    150     o = NULL; 
    151     s = NULL; 
    152   } 
    153  
    154   return (lst); 
     95  char *m, *sp; 
     96 
     97  for (; (m = mutt_extract_message_id (s, &sp)) != NULL; s = NULL) 
     98  { 
     99    t = safe_malloc (sizeof (LIST)); 
     100    t->data = m; 
     101    t->next = lst; 
     102    lst = t; 
     103  } 
     104 
     105  return lst; 
    155106} 
    156107 
     
    926877} 
    927878 
    928 /* extract the first substring that looks like a message-id */ 
    929 char *mutt_extract_message_id (const char *s) 
    930 { 
    931   const char *p; 
    932   char *r; 
    933   size_t l; 
    934  
    935   if ((s = strchr (s, '<')) == NULL || (p = strchr (s, '>')) == NULL) 
    936     return (NULL); 
    937   l = (size_t)(p - s) + 1; 
    938   r = safe_malloc (l + 1); 
    939   memcpy (r, s, l); 
    940   r[l] = 0; 
    941   return (r); 
     879/* extract the first substring that looks like a message-id. 
     880 * call back with NULL for more (like strtok). 
     881 */ 
     882char *mutt_extract_message_id (const char *s, const char **saveptr) 
     883{ 
     884  const char *o, *onull, *p; 
     885  char *ret = NULL; 
     886 
     887  if (s) 
     888    p = s; 
     889  else if (saveptr) 
     890    p = *saveptr; 
     891 
     892  for (s = NULL, o = NULL, onull = NULL; 
     893       (p = strpbrk (p, "<> \t;")) != NULL; ++p) 
     894  { 
     895    if (*p == '<') 
     896    { 
     897      s = p;  
     898      o = onull = NULL; 
     899      continue; 
     900    } 
     901 
     902    if (!s) 
     903      continue; 
     904 
     905    if (*p == '>') 
     906    { 
     907      size_t olen = onull - o, slen = p - s + 1; 
     908      ret = safe_malloc (olen + slen + 1); 
     909      if (o) 
     910        memcpy (ret, o, olen); 
     911      memcpy (ret + olen, s, slen); 
     912      ret[olen + slen] = '\0'; 
     913      if (saveptr) 
     914        *saveptr = p + 1; /* next call starts after '>' */ 
     915      return ret; 
     916    } 
     917 
     918    /* some idiotic clients break their message-ids between lines */ 
     919    if (s == p)  
     920      /* step past another whitespace */ 
     921      s = p + 1; 
     922    else if (o) 
     923      /* more than two lines, give up */ 
     924      s = o = onull = NULL; 
     925    else 
     926    { 
     927      /* remember the first line, start looking for the second */ 
     928      o = s; 
     929      onull = p; 
     930      s = p + 1; 
     931    } 
     932  } 
     933 
     934  return NULL; 
    942935} 
    943936 
     
    11331126      /* We add a new "Message-ID:" when building a message */ 
    11341127      FREE (&e->message_id); 
    1135       e->message_id = mutt_extract_message_id (p); 
     1128      e->message_id = mutt_extract_message_id (p, NULL); 
    11361129      matched = 1; 
    11371130    } 
  • protos.h

    r5457 r5473  
    9191int quadoption (int); 
    9292 
    93 char* mutt_extract_message_id (const char *); 
     93char* mutt_extract_message_id (const char *, const char **); 
    9494 
    9595ADDRESS *mutt_default_from (void); 
  • send.c

    r5443 r5473  
    300300    else if (ascii_strncasecmp ("message-id:", uh->data, 11) == 0) 
    301301    { 
    302       char *tmp = mutt_extract_message_id (uh->data + 11); 
     302      char *tmp = mutt_extract_message_id (uh->data + 11, NULL); 
    303303      if (rfc822_valid_msgid (tmp) >= 0) 
    304304      {