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 339955 a2992d672f629f1e56eb35c220779b77eaf53ba8
parent 339954 b3bbb89e91c1939c8c993275cf91d6a4d194edd9
child 339956 2299c291b4398bbb8caa79bfc6064102e053e3ff
push id6249
push userjlund@mozilla.com
push dateMon, 01 Aug 2016 13:59:36 +0000
treeherdermozilla-beta@bad9d4f5bf7e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersshu, abillings, lizzard
bugs1282502
milestone49.0a2
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
@@ -553,16 +553,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
@@ -251,16 +251,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),