Bug 1282502 - Report an error if there are too many block scoped bindings r=shu a=abillings a=lizzard
authorJon Coppeard <jcoppeard@mozilla.com>
Wed, 06 Jul 2016 10:17:19 +0100
changeset 333663 36faf180f49d6e6af84f55231052b1bac85b3bcd
parent 333662 0968b5fb96974b862d6901f9250644d8e478a30f
child 333664 0b4087792d5fa736a0dc18df7aeefecf0a34d99f
push id6214
push userjcoppeard@mozilla.com
push dateThu, 14 Jul 2016 17:06:44 +0000
treeherdermozilla-beta@36faf180f49d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersshu, abillings, lizzard
bugs1282502
milestone48.0
Bug 1282502 - Report an error if there are too many block scoped bindings r=shu a=abillings a=lizzard
js/src/frontend/Parser.cpp
js/src/jsscript.h
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -550,16 +550,19 @@ ParseContext<ParseHandler>::generateBind
 
     /*
      * Avoid pathological edge cases by explicitly limiting the total number of
      * bindings to what will fit in a uint32_t.
      */
     if (UINT32_MAX - args_.length() <= vars_.length() + bodyLevelLexicals_.length())
         return ts.reportError(JSMSG_TOO_MANY_LOCALS);
 
+    if (blockScopeDepth >= Bindings::BLOCK_SCOPED_LIMIT)
+        return ts.reportError(JSMSG_TOO_MANY_LOCALS);
+
     // Fix up slots in non-global contexts. In global contexts all body-level
     // names are dynamically defined and do not live in either frame or
     // CallObject slots.
     if (!sc->isGlobalContext()) {
         // Fix up the blockids of vars, whose static scope is always at the body
         // level. This could not be done up front in ParseContext::define, as
         // the original blockids are used for redeclaration checks.
         for (size_t i = 0; i < vars_.length(); i++)
--- a/js/src/jsscript.h
+++ b/js/src/jsscript.h
@@ -250,16 +250,17 @@ class Bindings
      */
     static const uintptr_t TEMPORARY_STORAGE_BIT = 0x1;
     bool bindingArrayUsingTemporaryStorage() const {
         return bindingArrayAndFlag_ & TEMPORARY_STORAGE_BIT;
     }
 
   public:
     static const uint32_t BODY_LEVEL_LEXICAL_LIMIT = UINT16_LIMIT;
+    static const uint32_t BLOCK_SCOPED_LIMIT = UINT16_LIMIT;
 
     Binding* bindingArray() const {
         return reinterpret_cast<Binding*>(bindingArrayAndFlag_ & ~TEMPORARY_STORAGE_BIT);
     }
 
     Bindings()
       : callObjShape_(nullptr), bindingArrayAndFlag_(TEMPORARY_STORAGE_BIT),
         numArgs_(0), numBlockScoped_(0),