/[jscoverage]/trunk/js/jsscan.cpp
ViewVC logotype

Diff of /trunk/js/jsscan.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 459 by siliconforks, Tue Dec 9 03:37:47 2008 UTC revision 460 by siliconforks, Sat Sep 26 23:15:22 2009 UTC
# Line 54  Line 54 
54  #include <string.h>  #include <string.h>
55  #include "jstypes.h"  #include "jstypes.h"
56  #include "jsarena.h" /* Added by JSIFY */  #include "jsarena.h" /* Added by JSIFY */
57    #include "jsbit.h"
58  #include "jsutil.h" /* Added by JSIFY */  #include "jsutil.h" /* Added by JSIFY */
59  #include "jsdtoa.h"  #include "jsdtoa.h"
60  #include "jsprf.h"  #include "jsprf.h"
# Line 675  Line 676 
676  }  }
677    
678  static JSBool  static JSBool
679  GrowStringBuffer(JSStringBuffer *sb, size_t newlength)  GrowStringBuffer(JSStringBuffer *sb, size_t amount)
680  {  {
681      ptrdiff_t offset;      ptrdiff_t offset = sb->ptr - sb->base;
     jschar *bp;  
   
     offset = PTRDIFF(sb->ptr, sb->base, jschar);  
682      JS_ASSERT(offset >= 0);      JS_ASSERT(offset >= 0);
683      newlength += offset + 1;  
684      if ((size_t)offset < newlength && newlength < ~(size_t)0 / sizeof(jschar))      /*
685          bp = (jschar *) realloc(sb->base, newlength * sizeof(jschar));       * This addition needs an overflow check, but we can defer bounding against
686      else       * ~size_t(0) / sizeof(jschar) till later to consolidate that test.
687          bp = NULL;       */
688      if (!bp) {      size_t newlength = offset + amount + 1;
689          free(sb->base);      if (size_t(offset) < newlength) {
690          sb->base = STRING_BUFFER_ERROR_BASE;          /* Grow by powers of two until 16MB, then grow by that chunk size. */
691          return JS_FALSE;          const size_t CHUNK_SIZE_MASK = JS_BITMASK(24);
692    
693            if (newlength <= CHUNK_SIZE_MASK)
694                newlength = JS_BIT(JS_CeilingLog2(newlength));
695            else if (newlength & CHUNK_SIZE_MASK)
696                newlength = (newlength | CHUNK_SIZE_MASK) + 1;
697    
698            /* Now do the full overflow check. */
699            if (size_t(offset) < newlength && newlength < ~size_t(0) / sizeof(jschar)) {
700                jschar *bp = (jschar *) realloc(sb->base, newlength * sizeof(jschar));
701                if (bp) {
702                    sb->base = bp;
703                    sb->ptr = bp + offset;
704                    sb->limit = bp + newlength - 1;
705                    return true;
706                }
707            }
708      }      }
709      sb->base = bp;  
710      sb->ptr = bp + offset;      /* Either newlength overflow or realloc failure: poison the well. */
711      sb->limit = bp + newlength - 1;      free(sb->base);
712      return JS_TRUE;      sb->base = STRING_BUFFER_ERROR_BASE;
713        return false;
714  }  }
715    
716  static void  static void
# Line 721  Line 736 
736      sb->free(sb);      sb->free(sb);
737  }  }
738    
 #define ENSURE_STRING_BUFFER(sb,n) \  
     ((sb)->ptr + (n) <= (sb)->limit || sb->grow(sb, n))  
   
 static void  
 FastAppendChar(JSStringBuffer *sb, jschar c)  
 {  
     if (!STRING_BUFFER_OK(sb))  
         return;  
     if (!ENSURE_STRING_BUFFER(sb, 1))  
         return;  
     *sb->ptr++ = c;  
 }  
   
739  void  void
740  js_AppendChar(JSStringBuffer *sb, jschar c)  js_AppendChar(JSStringBuffer *sb, jschar c)
741  {  {
# Line 817  Line 819 
819    
820      /* Put the entity, including the '&' already scanned, in ts->tokenbuf. */      /* Put the entity, including the '&' already scanned, in ts->tokenbuf. */
821      offset = PTRDIFF(ts->tokenbuf.ptr, ts->tokenbuf.base, jschar);      offset = PTRDIFF(ts->tokenbuf.ptr, ts->tokenbuf.base, jschar);
822      FastAppendChar(&ts->tokenbuf, '&');      js_FastAppendChar(&ts->tokenbuf, '&');
823      if (!STRING_BUFFER_OK(&ts->tokenbuf))      if (!STRING_BUFFER_OK(&ts->tokenbuf))
824          return JS_FALSE;          return JS_FALSE;
825      while ((c = GetChar(ts)) != ';') {      while ((c = GetChar(ts)) != ';') {
# Line 826  Line 828 
828                                          JSMSG_END_OF_XML_ENTITY);                                          JSMSG_END_OF_XML_ENTITY);
829              return JS_FALSE;              return JS_FALSE;
830          }          }
831          FastAppendChar(&ts->tokenbuf, (jschar) c);          js_FastAppendChar(&ts->tokenbuf, (jschar) c);
832          if (!STRING_BUFFER_OK(&ts->tokenbuf))          if (!STRING_BUFFER_OK(&ts->tokenbuf))
833              return JS_FALSE;              return JS_FALSE;
834      }      }
# Line 1028  Line 1030 
1030                                                 TOKENBUF_LENGTH(),             \                                                 TOKENBUF_LENGTH(),             \
1031                                                 0)                             \                                                 0)                             \
1032                               : NULL)                               : NULL)
1033  #define ADD_TO_TOKENBUF(c)  FastAppendChar(&ts->tokenbuf, (jschar) (c))  #define ADD_TO_TOKENBUF(c)  JS_BEGIN_MACRO                                    \
1034                                    js_FastAppendChar(&ts->tokenbuf, jschar(c));  \
1035                                    if (!TOKENBUF_OK())                           \
1036                                        goto error;                               \
1037                                JS_END_MACRO
1038    
1039  /* The following 4 macros should only be used when TOKENBUF_OK() is true. */  /* The following 4 macros should only be used when TOKENBUF_OK() is true. */
1040  #define TOKENBUF_BASE()     (ts->tokenbuf.base)  #define TOKENBUF_BASE()     (ts->tokenbuf.base)
# Line 1560  Line 1566 
1566           * https://bugzilla.mozilla.org/show_bug.cgi?id=309712           * https://bugzilla.mozilla.org/show_bug.cgi?id=309712
1567           * https://bugzilla.mozilla.org/show_bug.cgi?id=310993           * https://bugzilla.mozilla.org/show_bug.cgi?id=310993
1568           *           *
1569           * So without JSOPTION_XML, we never scan an XML comment or CDATA           * So without JSOPTION_XML, we changed around Firefox 1.5 never to scan
1570           * literal.  We always scan <! as the start of an HTML comment hack           * an XML comment or CDATA literal.  Instead, we always scan <! as the
1571           * to end of line, used since Netscape 2 to hide script tag content           * start of an HTML comment hack to end of line, used since Netscape 2
1572           * from script-unaware browsers.           * to hide script tag content from script-unaware browsers.
1573             *
1574             * But this still leaves XML resources with certain internal structure
1575             * vulnerable to being loaded as script cross-origin, and some internal
1576             * data stolen, so for Firefox 3.5 and beyond, we reject programs whose
1577             * source consists only of XML literals. See:
1578             *
1579             * https://bugzilla.mozilla.org/show_bug.cgi?id=336551
1580             *
1581             * The check for this is in jsparse.cpp, JSCompiler::compileScript.
1582           */           */
1583          if ((ts->flags & TSF_OPERAND) &&          if ((ts->flags & TSF_OPERAND) &&
1584              (JS_HAS_XML_OPTION(cx) || PeekChar(ts) != '!')) {              (JS_HAS_XML_OPTION(cx) || PeekChar(ts) != '!')) {
# Line 1802  Line 1817 
1817          }          }
1818    
1819          if (MatchChar(ts, '*')) {          if (MatchChar(ts, '*')) {
1820                uintN lineno = ts->lineno;
1821              while ((c = GetChar(ts)) != EOF &&              while ((c = GetChar(ts)) != EOF &&
1822                     !(c == '*' && MatchChar(ts, '/'))) {                     !(c == '*' && MatchChar(ts, '/'))) {
1823                  /* Ignore all characters until comment close. */                  /* Ignore all characters until comment close. */
# Line 1811  Line 1827 
1827                                              JSMSG_UNTERMINATED_COMMENT);                                              JSMSG_UNTERMINATED_COMMENT);
1828                  goto error;                  goto error;
1829              }              }
1830                if ((ts->flags & TSF_NEWLINES) && lineno != ts->lineno) {
1831                    ts->flags &= ~TSF_DIRTYLINE;
1832                    tt = TOK_EOL;
1833                    goto eol_out;
1834                }
1835              ts->cursor = (ts->cursor - 1) & NTOKENS_MASK;              ts->cursor = (ts->cursor - 1) & NTOKENS_MASK;
1836              goto retry;              goto retry;
1837          }          }
1838    
1839          if (ts->flags & TSF_OPERAND) {          if (ts->flags & TSF_OPERAND) {
1840              uintN flags;              uintN flags, length;
1841              JSBool inCharClass = JS_FALSE;              JSBool inCharClass = JS_FALSE;
1842    
1843              INIT_TOKENBUF();              INIT_TOKENBUF();
# Line 1841  Line 1862 
1862                  }                  }
1863                  ADD_TO_TOKENBUF(c);                  ADD_TO_TOKENBUF(c);
1864              }              }
1865              for (flags = 0; ; ) {              for (flags = 0, length = TOKENBUF_LENGTH() + 1; ; length++) {
1866                  c = PeekChar(ts);                  c = PeekChar(ts);
1867                  if (c == 'g')                  if (c == 'g' && !(flags & JSREG_GLOB))
1868                      flags |= JSREG_GLOB;                      flags |= JSREG_GLOB;
1869                  else if (c == 'i')                  else if (c == 'i' && !(flags & JSREG_FOLD))
1870                      flags |= JSREG_FOLD;                      flags |= JSREG_FOLD;
1871                  else if (c == 'm')                  else if (c == 'm' && !(flags & JSREG_MULTILINE))
1872                      flags |= JSREG_MULTILINE;                      flags |= JSREG_MULTILINE;
1873                  else if (c == 'y')                  else if (c == 'y' && !(flags & JSREG_STICKY))
1874                      flags |= JSREG_STICKY;                      flags |= JSREG_STICKY;
1875                  else                  else
1876                      break;                      break;
# Line 1857  Line 1878 
1878              }              }
1879              c = PeekChar(ts);              c = PeekChar(ts);
1880              if (JS7_ISLET(c)) {              if (JS7_ISLET(c)) {
1881                  tp->ptr = ts->linebuf.ptr - 1;                  char buf[2] = { '\0' };
1882                    tp->pos.begin.index += length + 1;
1883                    buf[0] = (char)c;
1884                  js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,                  js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
1885                                              JSMSG_BAD_REGEXP_FLAG);                                              JSMSG_BAD_REGEXP_FLAG, buf);
1886                  (void) GetChar(ts);                  (void) GetChar(ts);
1887                  goto error;                  goto error;
1888              }              }

Legend:
Removed from v.459  
changed lines
  Added in v.460

  ViewVC Help
Powered by ViewVC 1.1.24