Back to index

enigmail  1.4.3
Defines | Functions
mimehdrs2.cpp File Reference
#include <ctype.h>
#include "nspr.h"
#include "nsCOMPtr.h"
#include "msgCore.h"
#include "plstr.h"
#include "nsMailHeaders.h"
#include "mimehdrs2.h"
#include "enigmail.h"

Go to the source code of this file.

Defines

#define MOZILLA_INTERNAL_API
#define HEX_ESCAPE   '%'
#define UNHEX(C)

Functions

static PRInt32 __nsUnescapeCount (char *str)
static char * __nsUnescape (char *str)
EMBool MimeHeaders_IsAsciiSpace (PRUnichar aChar)
char * MimeHeaders_get_parameter (const char *header_value, const char *parm_name, char **charset, char **language)
char * MIME_StripContinuations (char *original)

Define Documentation

#define HEX_ESCAPE   '%'

Definition at line 53 of file mimehdrs2.cpp.

Definition at line 41 of file mimehdrs2.cpp.

#define UNHEX (   C)
Value:
((C >= '0' && C <= '9') ? C - '0' : \
     ((C >= 'A' && C <= 'F') ? C - 'A' + 10 : \
     ((C >= 'a' && C <= 'f') ? C - 'a' + 10 : 0)))

Definition at line 55 of file mimehdrs2.cpp.


Function Documentation

static char* __nsUnescape ( char *  str) [static]

Definition at line 105 of file mimehdrs2.cpp.

{
       __nsUnescapeCount(str);
       return str;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PRInt32 __nsUnescapeCount ( char *  str) [static]

Definition at line 61 of file mimehdrs2.cpp.

{
    register char *src = str;
    register char *dst = str;
    static const char hexChars[] = "0123456789ABCDEFabcdef";

    char c1[] = " ";
    char c2[] = " ";
    char* const pc1 = c1;
    char* const pc2 = c2;

    while (*src)
    {
        c1[0] = *(src+1);
        if (*(src+1) == '\0')
            c2[0] = '\0';
        else
            c2[0] = *(src+2);

        if (*src != HEX_ESCAPE || PL_strpbrk(pc1, hexChars) == 0 ||
                                  PL_strpbrk(pc2, hexChars) == 0 )
              *dst++ = *src++;
        else
              {
              src++; /* walk over escape */
              if (*src)
            {
              *dst = UNHEX(*src) << 4;
              src++;
            }
              if (*src)
            {
              *dst = (*dst + UNHEX(*src));
              src++;
            }
              dst++;
        }
    }

    *dst = 0;
    return (int)(dst - str);

} /* NET_UnEscapeCnt */

Here is the caller graph for this function:

char* MIME_StripContinuations ( char *  original)

Definition at line 310 of file mimehdrs2.cpp.

{
       char *p1, *p2;

       /* If we were given a null string, return it as is */
       if (!original) return NULL;

       /* Start source and dest pointers at the beginning */
       p1 = p2 = original;

       while(*p2)
       {
              /* p2 runs ahead at (CR and/or LF) */
              if ((p2[0] == '\r') || (p2[0] == '\n'))
              {
            p2++;
              } else {
            *p1++ = *p2++;
        }
       }
       *p1 = '\0';

       return original;
}

Here is the caller graph for this function:

char* MimeHeaders_get_parameter ( const char *  header_value,
const char *  parm_name,
char **  charset,
char **  language 
)

Definition at line 118 of file mimehdrs2.cpp.

{
  const char *str;
  char *s = NULL; /* parm value to be returned */
  PRInt32 parm_len;
  if (!header_value || !parm_name || !*header_value || !*parm_name)
       return 0;

  /* The format of these header lines is
        <token> [ ';' <token> '=' <token-or-quoted-string> ]*
   */

  if (charset) *charset = NULL;
  if (language) *language = NULL;

  str = header_value;
  parm_len = strlen(parm_name);

  /* Skip forward to first ';' */
  for (; *str && *str != ';' && *str != ','; str++)
       ;
  if (*str)
       str++;
  /* Skip over following whitespace */
  for (; *str && MimeHeaders_IsAsciiSpace(*str); str++)
       ;
  if (!*str)
       return 0;

  while (*str)
       {
         const char *token_start = str;
         const char *token_end = 0;
         const char *value_start = str;
         const char *value_end = 0;

         PR_ASSERT(!MimeHeaders_IsAsciiSpace(*str)); /* should be after whitespace already */

         /* Skip forward to the end of this token. */
         for (; *str && !MimeHeaders_IsAsciiSpace(*str) && *str != '=' && *str != ';'; str++)
              ;
         token_end = str;

         /* Skip over whitespace, '=', and whitespace */
         while (MimeHeaders_IsAsciiSpace (*str)) str++;
         if (*str == '=') str++;
         while (MimeHeaders_IsAsciiSpace (*str)) str++;

         if (*str != '"')
              {
                /* The value is a token, not a quoted string. */
                value_start = str;
                for (value_end = str;
                        *value_end && !MimeHeaders_IsAsciiSpace (*value_end) && *value_end != ';';
                        value_end++)
                     ;
                str = value_end;
              }
         else
              {
                /* The value is a quoted string. */
                str++;
                value_start = str;
                for (value_end = str; *value_end; value_end++)
                     {
                       if (*value_end == '\\')
                            value_end++;
                       else if (*value_end == '"')
                            break;
                     }
                str = value_end+1;
              }

         /* See if this is the parameter we're looking for.
               If so, copy it and return.
          */
         if (token_end - token_start == parm_len &&
                !PL_strncasecmp(token_start, parm_name, parm_len))
              {
                s = (char *) PR_MALLOC ((value_end - value_start) + 1);
                if (! s) return 0;  /* MIME_OUT_OF_MEMORY */
                memcpy (s, value_start, value_end - value_start);
                s [value_end - value_start] = 0;
                /* if the parameter spans across multiple lines we have to strip out the
                      line continuatio -- jht 4/29/98 */
                MIME_StripContinuations(s);
                return s;
              }
         else if (token_end - token_start > parm_len &&
                        !PL_strncasecmp(token_start, parm_name, parm_len) &&
                        *(token_start+parm_len) == '*')
         {
                /* RFC2231 - The legitimate parm format can be:
                      title*=us-ascii'en-us'This%20is%20weired.
                         or
                      title*0*=us-ascii'en'This%20is%20weired.%20We
                      title*1*=have%20to%20support%20this.
                      title*3="Else..."
                         or
                      title*0="Hey, what you think you are doing?"
                      title*1="There is no charset and language info."
                 */
                const char *cp = token_start+parm_len+1; /* 1st char pass '*' */
                EMBool needUnescape = *(token_end-1) == '*';
                if ((*cp == '0' && needUnescape) || (token_end-token_start == parm_len+1))
                {
                       const char *s_quote1 = PL_strchr(value_start, 0x27);
                       const char *s_quote2 = (char *) (s_quote1 ? PL_strchr(s_quote1+1, 0x27) : NULL);
                       PR_ASSERT(s_quote1 && s_quote2);
                       if (charset && s_quote1 > value_start && s_quote1 < value_end)
                       {
                              *charset = (char *) PR_MALLOC(s_quote1-value_start+1);
                              if (*charset)
                              {
                                     memcpy(*charset, value_start, s_quote1-value_start);
                                     *(*charset+(s_quote1-value_start)) = 0;
                              }
                       }
                       if (language && s_quote1 && s_quote2 && s_quote2 > s_quote1+1 &&
                              s_quote2 < value_end)
                       {
                              *language = (char *) PR_MALLOC(s_quote2-(s_quote1+1)+1);
                              if (*language)
                              {
                                     memcpy(*language, s_quote1+1, s_quote2-(s_quote1+1));
                                     *(*language+(s_quote2-(s_quote1+1))) = 0;
                              }
                       }
                       if (s_quote2 && s_quote2+1 < value_end)
                       {
                              PR_ASSERT(!s);
                              s = (char *) PR_MALLOC(value_end-(s_quote2+1)+1);
                              if (s)
                              {
                                     memcpy(s, s_quote2+1, value_end-(s_quote2+1));
                                     *(s+(value_end-(s_quote2+1))) = 0;
                                     if (needUnescape)
                                     {
                                            __nsUnescape(s);
                                            if (token_end-token_start == parm_len+1)
                                                   return s; /* we done; this is the simple case of
                                                                         encoding charset and language info
                                                                       */
                                     }
                              }
                       }
                }
                else if (IS_DIGIT(*cp))
                {
                       PRInt32 len = 0;
                       char *ns = NULL;
                       if (s)
                       {
                              len = strlen(s);
                              ns = (char *) PR_Realloc(s, len+(value_end-value_start)+1);
                              if (!ns)
                    {
                                     PR_FREEIF(s);
                    }
                              else if (ns != s)
                                     s = ns;
                       }
                       else if (*cp == '0') /* must be; otherwise something is wrong */
                       {
                              s = (char *) PR_MALLOC(value_end-value_start+1);
                       }
                       /* else {} something is really wrong; out of memory */
                       if (s)
                       {
                              memcpy(s+len, value_start, value_end-value_start);
                              *(s+len+(value_end-value_start)) = 0;
                              if (needUnescape)
                                     __nsUnescape(s+len);
                       }
                }
         }

         /* str now points after the end of the value.
               skip over whitespace, ';', whitespace. */
         while (MimeHeaders_IsAsciiSpace (*str)) str++;
         if (*str == ';') str++;
         while (MimeHeaders_IsAsciiSpace (*str)) str++;
       }
  return s;
}

Here is the call graph for this function:

Here is the caller graph for this function:

EMBool MimeHeaders_IsAsciiSpace ( PRUnichar  aChar)

Definition at line 112 of file mimehdrs2.cpp.

                                                 {
  return ((aChar == ' ') || (aChar == '\r') ||
          (aChar == '\n') || (aChar == '\t'));
}

Here is the caller graph for this function: