Bug 1246215 - Guard against passing non-atoms and non-property names to LookupProperty; r=evilpie
authorMorgan Phillips <winter2718@gmail.com>
Tue, 01 Mar 2016 10:48:52 -0800
changeset 322681 c6437b3b18d7fba700fa6295613c909ad985d1e2
parent 322680 923325f2c56648a587e01c2adf4fd355b152a755
child 322682 3c029ca3348afac9f1d9413a2127e5e62535f80e
push id5913
push userjlund@mozilla.com
push dateMon, 25 Apr 2016 16:57:49 +0000
treeherdermozilla-beta@dcaf0a6fa115 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersevilpie
bugs1246215
milestone47.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1246215 - Guard against passing non-atoms and non-property names to LookupProperty; r=evilpie
js/src/jit-test/tests/debug/Object-forceLexicalInitializationByName.js
js/src/vm/Debugger.cpp
--- a/js/src/jit-test/tests/debug/Object-forceLexicalInitializationByName.js
+++ b/js/src/jit-test/tests/debug/Object-forceLexicalInitializationByName.js
@@ -12,38 +12,46 @@ function evalErrorStr(global, evalString
         return undefined;
     } catch (e) {
         return e.toString();
     }
 }
 
 
 assertEq(evalErrorStr(g, "let y = IDONTEXIST;"), "ReferenceError: IDONTEXIST is not defined");
-
 assertEq(evalErrorStr(g, "y = 1;"),
          "ReferenceError: can't access lexical declaration `y' before initialization");
 
 // Here we flip the uninitialized binding to undfined.
 assertEq(gw.forceLexicalInitializationByName("y"), true);
 assertEq(g.evaluate("y"), undefined);
 g.evaluate("y = 1;");
 assertEq(g.evaluate("y"), 1);
 
 // Ensure that bogus bindings return false, but otherwise trigger no error or
 // side effect.
 assertEq(gw.forceLexicalInitializationByName("idontexist"), false);
 assertEq(evalErrorStr(g, "idontexist"), "ReferenceError: idontexist is not defined");
 
+// Ensure that ropes (non-atoms) behave properly
+assertEq(gw.forceLexicalInitializationByName(("foo" + "bar" + "bop" + "zopple" + 2 + 3).slice(1)),
+                                             false);
+assertEq(evalErrorStr(g, "let oobarbopzopple23 = IDONTEXIST;"), "ReferenceError: IDONTEXIST is not defined");
+assertEq(gw.forceLexicalInitializationByName(("foo" + "bar" + "bop" + "zopple" + 2 + 3).slice(1)),
+                                             true);
+assertEq(g.evaluate("oobarbopzopple23"), undefined);
+
 // Ensure that only strings are accepted by forceLexicalInitializationByName
 const bad_types = [
     2112,
     {geddy: "lee"},
     () => 1,
     [],
-    Array
+    Array,
+    "'1'", // non-identifier
 ]
 
 for (var badType of bad_types) {
     assertThrowsInstanceOf(() => {
         gw.forceLexicalInitializationByName(badType);
     }, TypeError);
 }
 
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -8050,32 +8050,33 @@ DebuggerObject_forceLexicalInitializatio
 
     if (!args[0].isString()) {
         JS_ReportErrorNumber(cx, GetErrorMessage, nullptr,
                              JSMSG_NOT_EXPECTED_TYPE, "Debugger.Object.prototype.forceLexicalInitializationByName",
                              "string", InformalValueTypeName(args[0]));
         return false;
     }
 
-    PropertyName* name = args[0].toString()->asAtom().asPropertyName();
+    RootedId id(cx);
+    if (!ValueToIdentifier(cx, args[0], &id))
+        return false;
+
+    RootedObject pobj(cx);
+    RootedShape shape(cx);
+    if (!LookupProperty(cx, globalLexical, id, &pobj, &shape))
+        return false;
 
     bool initialized = false;
-
-    Shape* s = nullptr;
-    JSObject* scope = nullptr;
-    JSObject* pobj = nullptr;
-
-    if (LookupNameNoGC(cx, name, globalLexical, &scope, &pobj, &s)) {
-        Value v = globalLexical->as<NativeObject>().getSlot(s->slot());
-        if (s->hasSlot() && v.isMagic() && v.whyMagic() == JS_UNINITIALIZED_LEXICAL) {
-            globalLexical->as<NativeObject>().setSlot(s->slot(), UndefinedValue());
+    if (shape) {
+        Value v = globalLexical->as<NativeObject>().getSlot(shape->slot());
+        if (shape->hasSlot() && v.isMagic() && v.whyMagic() == JS_UNINITIALIZED_LEXICAL) {
+            globalLexical->as<NativeObject>().setSlot(shape->slot(), UndefinedValue());
             initialized = true;
-         }
-    }
-
+        }
+    }
     args.rval().setBoolean(initialized);
     return true;
 }
 
 static bool
 DebuggerObject_executeInGlobal(JSContext* cx, unsigned argc, Value* vp)
 {
     THIS_DEBUGOBJECT_OWNER_REFERENT(cx, argc, vp, "executeInGlobal", args, dbg, referent);