Back to index

lightning-sunbird  0.9+nobinonly
Defines | Functions | Variables
nsEscape.cpp File Reference
#include "nsEscape.h"
#include "nsMemory.h"
#include "nsCRT.h"
#include "nsReadableUtils.h"

Go to the source code of this file.

Defines

#define UNHEX(C)
#define IS_OK(C)   (netCharType[((unsigned int) (C))] & (flags))
#define HEX_ESCAPE   '%'
#define NO_NEED_ESC(C)   (EscapeChars[((unsigned int) (C))] & (flags))
#define ISHEX(c)   memchr(hexChars, c, sizeof(hexChars)-1)

Functions

static char * nsEscapeCount (const char *str, nsEscapeMask flags, size_t *out_len)
NS_COM char * nsEscape (const char *str, nsEscapeMask flags)
 Escape the given string according to mask.
NS_COM char * nsUnescape (char *str)
NS_COM PRInt32 nsUnescapeCount (char *str)
NS_COM char * nsEscapeHTML (const char *string)
NS_COM PRUnicharnsEscapeHTML2 (const PRUnichar *aSourceBuffer, PRInt32 aSourceBufferLen)
NS_COM PRBool NS_EscapeURL (const char *part, PRInt32 partLen, PRUint32 flags, nsACString &result)
 NS_EscapeURL.
NS_COM PRBool NS_UnescapeURL (const char *str, PRInt32 len, PRUint32 flags, nsACString &result)
 Expands URL escape sequences...

Variables

const int netCharType [256]
const int EscapeChars [256]

Define Documentation

#define HEX_ESCAPE   '%'

Definition at line 73 of file nsEscape.cpp.

#define IS_OK (   C)    (netCharType[((unsigned int) (C))] & (flags))

Definition at line 72 of file nsEscape.cpp.

#define ISHEX (   c)    memchr(hexChars, c, sizeof(hexChars)-1)

Definition at line 466 of file nsEscape.cpp.

#define NO_NEED_ESC (   C)    (EscapeChars[((unsigned int) (C))] & (flags))

Definition at line 355 of file nsEscape.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 66 of file nsEscape.cpp.


Function Documentation

NS_COM PRBool NS_EscapeURL ( const char *  str,
PRInt32  len,
PRUint32  flags,
nsACString &  result 
)

NS_EscapeURL.

Escapes invalid char's in an URL segment. Has no side-effect if the URL segment is already escaped. Otherwise, the escaped URL segment is appended to |result|.

Parameters:
strurl segment string
lenurl segment string length (-1 if unknown)
flagsurl segment type flag
resultresult buffer, untouched if part is already escaped
Returns:
TRUE if escaping was performed, FALSE otherwise.

Definition at line 385 of file nsEscape.cpp.

{
    if (!part) {
        NS_NOTREACHED("null pointer");
        return PR_FALSE;
    }

    int i = 0;
    static const char hexChars[] = "0123456789ABCDEF";
    if (partLen < 0)
        partLen = strlen(part);
    PRBool forced = (flags & esc_Forced);
    PRBool ignoreNonAscii = (flags & esc_OnlyASCII);
    PRBool ignoreAscii = (flags & esc_OnlyNonASCII);
    PRBool writing = (flags & esc_AlwaysCopy);
    PRBool colon = (flags & esc_Colon);

    register const unsigned char* src = (const unsigned char *) part;

    char tempBuffer[100];
    unsigned int tempBufferPos = 0;

    PRBool previousIsNonASCII = PR_FALSE;
    for (i = 0; i < partLen; i++)
    {
      unsigned char c = *src++;

      // if the char has not to be escaped or whatever follows % is 
      // a valid escaped string, just copy the char.
      //
      // Also the % will not be escaped until forced
      // See bugzilla bug 61269 for details why we changed this
      //
      // And, we will not escape non-ascii characters if requested.
      // On special request we will also escape the colon even when
      // not covered by the matrix.
      // ignoreAscii is not honored for control characters (C0 and DEL)
      //
      // And, we should escape the '|' character when it occurs after any
      // non-ASCII character as it may be part of a multi-byte character.
      if ((NO_NEED_ESC(c) || (c == HEX_ESCAPE && !forced)
                          || (c > 0x7f && ignoreNonAscii)
                          || (c > 0x1f && c < 0x7f && ignoreAscii))
          && !(c == ':' && colon)
          && !(previousIsNonASCII && c == '|' && !ignoreNonAscii))
      {
        if (writing)
          tempBuffer[tempBufferPos++] = c;
      }
      else /* do the escape magic */
      {
        if (!writing)
        {
          result.Append(part, i);
          writing = PR_TRUE;
        }
        tempBuffer[tempBufferPos++] = HEX_ESCAPE;
        tempBuffer[tempBufferPos++] = hexChars[c >> 4]; /* high nibble */
        tempBuffer[tempBufferPos++] = hexChars[c & 0x0f]; /* low nibble */
      }

      if (tempBufferPos >= sizeof(tempBuffer) - 4)
      {
        NS_ASSERTION(writing, "should be writing");
        tempBuffer[tempBufferPos] = '\0';
        result += tempBuffer;
        tempBufferPos = 0;
      }

      previousIsNonASCII = (c > 0x7f);
    }
    if (writing) {
      tempBuffer[tempBufferPos] = '\0';
      result += tempBuffer;
    }
    return writing;
}

Here is the caller graph for this function:

NS_COM PRBool NS_UnescapeURL ( const char *  str,
PRInt32  len,
PRUint32  flags,
nsACString &  result 
)

Expands URL escape sequences...

beware embedded null bytes!

Parameters:
strurl string to unescape
lenlength of |str|
flagsonly esc_OnlyNonASCII, esc_SkipControl and esc_AlwaysCopy are recognized
resultresult buffer, untouched if |str| is already unescaped
Returns:
TRUE if unescaping was performed, FALSE otherwise.

Definition at line 468 of file nsEscape.cpp.

{
    if (!str) {
        NS_NOTREACHED("null pointer");
        return PR_FALSE;
    }

    if (len < 0)
        len = strlen(str);

    PRBool ignoreNonAscii = (flags & esc_OnlyASCII);
    PRBool ignoreAscii = (flags & esc_OnlyNonASCII);
    PRBool writing = (flags & esc_AlwaysCopy);
    PRBool skipControl = (flags & esc_SkipControl); 

    static const char hexChars[] = "0123456789ABCDEFabcdef";

    const char *last = str;
    const char *p = str;

    for (int i=0; i<len; ++i, ++p) {
        //printf("%c [i=%d of len=%d]\n", *p, i, len);
        if (*p == HEX_ESCAPE && i < len-2) {
            unsigned char *p1 = ((unsigned char *) p) + 1;
            unsigned char *p2 = ((unsigned char *) p) + 2;
            if (ISHEX(*p1) && ISHEX(*p2) && 
                ((*p1 < '8' && !ignoreAscii) || (*p1 >= '8' && !ignoreNonAscii)) &&
                !(skipControl && 
                  (*p1 < '2' || (*p1 == '7' && (*p2 == 'f' || *p2 == 'F'))))) {
                //printf("- p1=%c p2=%c\n", *p1, *p2);
                writing = PR_TRUE;
                if (p > last) {
                    //printf("- p=%p, last=%p\n", p, last);
                    result.Append(last, p - last);
                    last = p;
                }
                char u = (UNHEX(*p1) << 4) + UNHEX(*p2);
                //printf("- u=%c\n", u);
                result.Append(u);
                i += 2;
                p += 2;
                last += 3;
            }
        }
    }
    if (writing && last < str + len)
        result.Append(last, str + len - last);

    return writing;
}

Here is the caller graph for this function:

NS_COM char* nsEscape ( const char *  str,
nsEscapeMask  mask 
)

Escape the given string according to mask.

Parameters:
strThe string to escape
maskHow to escape the string
Returns:
A newly allocated escaped string that must be free'd with nsCRT::free, or null on failure

Definition at line 159 of file nsEscape.cpp.

{
    if(!str)
        return NULL;
    return nsEscapeCount(str, flags, NULL);
}

Here is the call graph for this function:

static char* nsEscapeCount ( const char *  str,
nsEscapeMask  flags,
size_t *  out_len 
) [static]

Definition at line 76 of file nsEscape.cpp.

{
       if (!str)
              return 0;

    size_t i, len = 0, charsToEscape = 0;
    static const char hexChars[] = "0123456789ABCDEF";

       register const unsigned char* src = (const unsigned char *) str;
    while (*src)
       {
        len++;
        if (!IS_OK(*src++))
            charsToEscape++;
       }

    // calculate how much memory should be allocated
    // original length + 2 bytes for each escaped character + terminating '\0'
    // do the sum in steps to check for overflow
    size_t dstSize = len + 1 + charsToEscape;
    if (dstSize <= len)
       return 0;
    dstSize += charsToEscape;
    if (dstSize < len)
       return 0;

    // fail if we need more than 4GB
    // size_t is likely to be long unsigned int but nsMemory::Alloc(size_t)
    // calls NS_Alloc_P(size_t) which calls PR_Malloc(PRUint32), so there is
    // no chance to allocate more than 4GB using nsMemory::Alloc()
    if (dstSize > PR_UINT32_MAX)
        return 0;

       char* result = (char *)nsMemory::Alloc(dstSize);
    if (!result)
        return 0;

    register unsigned char* dst = (unsigned char *) result;
       src = (const unsigned char *) str;
       if (flags == url_XPAlphas)
       {
           for (i = 0; i < len; i++)
              {
                     unsigned char c = *src++;
                     if (IS_OK(c))
                            *dst++ = c;
                     else if (c == ' ')
                            *dst++ = '+'; /* convert spaces to pluses */
                     else 
                     {
                            *dst++ = HEX_ESCAPE;
                            *dst++ = hexChars[c >> 4];  /* high nibble */
                            *dst++ = hexChars[c & 0x0f];       /* low nibble */
                     }
              }
       }
       else
       {
           for (i = 0; i < len; i++)
              {
                     unsigned char c = *src++;
                     if (IS_OK(c))
                            *dst++ = c;
                     else 
                     {
                            *dst++ = HEX_ESCAPE;
                            *dst++ = hexChars[c >> 4];  /* high nibble */
                            *dst++ = hexChars[c & 0x0f];       /* low nibble */
                     }
              }
       }

    *dst = '\0';     /* tack on eos */
       if(out_len)
              *out_len = dst - (unsigned char *) result;
    return result;
}

Here is the call graph for this function:

NS_COM char* nsEscapeHTML ( const char *  string)

Definition at line 223 of file nsEscape.cpp.

{
       /* XXX Hardcoded max entity len. The +1 is for the trailing null. */
       char *rv = (char *) nsMemory::Alloc(strlen(string) * 6 + 1);
       char *ptr = rv;

       if(rv)
         {
              for(; *string != '\0'; string++)
                {
                     if(*string == '<')
                       {
                            *ptr++ = '&';
                            *ptr++ = 'l';
                            *ptr++ = 't';
                            *ptr++ = ';';
                       }
                     else if(*string == '>')
                       {
                            *ptr++ = '&';
                            *ptr++ = 'g';
                            *ptr++ = 't';
                            *ptr++ = ';';
                       }
                     else if(*string == '&')
                       {
                            *ptr++ = '&';
                            *ptr++ = 'a';
                            *ptr++ = 'm';
                            *ptr++ = 'p';
                            *ptr++ = ';';
                       }
                     else if (*string == '"')
                       {
                            *ptr++ = '&';
                            *ptr++ = 'q';
                            *ptr++ = 'u';
                            *ptr++ = 'o';
                            *ptr++ = 't';
                            *ptr++ = ';';
                       }                  
                     else if (*string == '\'')
                       {
                            *ptr++ = '&';
                            *ptr++ = '#';
                            *ptr++ = '3';
                            *ptr++ = '9';
                            *ptr++ = ';';
                       }
                     else
                       {
                            *ptr++ = *string;
                       }
                }
              *ptr = '\0';
         }

       return(rv);
}

Here is the call graph for this function:

Here is the caller graph for this function:

NS_COM PRUnichar* nsEscapeHTML2 ( const PRUnichar aSourceBuffer,
PRInt32  aSourceBufferLen 
)

Definition at line 284 of file nsEscape.cpp.

{
  // if the caller didn't calculate the length
  if (aSourceBufferLen == -1) {
    aSourceBufferLen = nsCRT::strlen(aSourceBuffer); // ...then I will
  }

  /* XXX Hardcoded max entity len. */
  PRUnichar *resultBuffer = (PRUnichar *)nsMemory::Alloc(aSourceBufferLen *
                            6 * sizeof(PRUnichar) + sizeof(PRUnichar('\0')));
  PRUnichar *ptr = resultBuffer;

  if (resultBuffer) {
    PRInt32 i;

    for(i = 0; i < aSourceBufferLen; i++) {
      if(aSourceBuffer[i] == '<') {
        *ptr++ = '&';
        *ptr++ = 'l';
        *ptr++ = 't';
        *ptr++ = ';';
      } else if(aSourceBuffer[i] == '>') {
        *ptr++ = '&';
        *ptr++ = 'g';
        *ptr++ = 't';
        *ptr++ = ';';
      } else if(aSourceBuffer[i] == '&') {
        *ptr++ = '&';
        *ptr++ = 'a';
        *ptr++ = 'm';
        *ptr++ = 'p';
        *ptr++ = ';';
      } else if (aSourceBuffer[i] == '"') {
        *ptr++ = '&';
        *ptr++ = 'q';
        *ptr++ = 'u';
        *ptr++ = 'o';
        *ptr++ = 't';
        *ptr++ = ';';
      } else if (aSourceBuffer[i] == '\'') {
        *ptr++ = '&';
        *ptr++ = '#';
        *ptr++ = '3';
        *ptr++ = '9';
        *ptr++ = ';';
      } else {
        *ptr++ = aSourceBuffer[i];
      }
    }
    *ptr = 0;
  }

  return resultBuffer;
}

Here is the call graph for this function:

Here is the caller graph for this function:

NS_COM char* nsUnescape ( char *  str)

Definition at line 168 of file nsEscape.cpp.

{
       nsUnescapeCount(str);
       return str;
}

Here is the call graph for this function:

NS_COM PRInt32 nsUnescapeCount ( char *  str)

Definition at line 176 of file nsEscape.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 call graph for this function:


Variable Documentation

Initial value:

{
        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,       
        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,          
        0,1023,   0, 512,1023,   0,1023,1023,1023,1023,1023,1023,1023,1023, 953, 784,       
     1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1008, 912,   0,1008,   0, 768,       
     1008,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,       
     1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023, 896, 896, 896, 896,1023,       
        0,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,       
     1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023, 896,1012, 896,1023,   0,       
        0    
}

Definition at line 341 of file nsEscape.cpp.

Initial value:

    
    {    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 
               0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  
               0,0,0,0,0,0,0,0,0,0,7,4,0,7,7,4,  
         7,7,7,7,7,7,7,7,7,7,0,0,0,0,0,0, 
            0,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,     
            
            
            7,7,7,7,7,7,7,7,7,7,7,0,0,0,0,7,     
            0,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,     
            7,7,7,7,7,7,7,7,7,7,7,0,0,0,0,0,     
               0, }

Definition at line 45 of file nsEscape.cpp.