From 0ac3502f9ac78e2c343f15898410561f8ce87853 Mon Sep 17 00:00:00 2001 From: Bobby Holley Date: Mon, 28 Jul 2014 14:55:51 -0700 Subject: [PATCH] Bug 1042996 - Always set an explicit version in evalInSandbox. r=gabor If setVersion() is not invoked on compileOptions, it ends up with JSVERSION_UNKNOWN, which invokes findVersion() on the JSContext, which does a bunch of crazy hunting of previous scripted stack frames that we most certainly don't want for sandboxes, which are supposed to be controlled environments. Using a separate JSContext in evalInSandbox isolates us from these effects, so once we stop doing that we need to be more explicit here. --- js/xpconnect/src/Sandbox.cpp | 5 ++-- .../tests/chrome/test_evalInSandbox.xul | 27 +++++++++++++++++++ 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/js/xpconnect/src/Sandbox.cpp b/js/xpconnect/src/Sandbox.cpp index cfbd97f69b8..87411414dfe 100644 --- a/js/xpconnect/src/Sandbox.cpp +++ b/js/xpconnect/src/Sandbox.cpp @@ -1507,9 +1507,8 @@ xpc::EvalInSandbox(JSContext *cx, HandleObject sandboxArg, const nsAString& sour JSAutoCompartment ac(sandcx, sandbox); JS::CompileOptions options(sandcx); - options.setFileAndLine(filenameBuf.get(), lineNo); - if (jsVersion != JSVERSION_DEFAULT) - options.setVersion(jsVersion); + options.setFileAndLine(filenameBuf.get(), lineNo) + .setVersion(jsVersion); JS::RootedObject rootedSandbox(sandcx, sandbox); ok = JS::Evaluate(sandcx, rootedSandbox, options, PromiseFlatString(source).get(), source.Length(), &v); diff --git a/js/xpconnect/tests/chrome/test_evalInSandbox.xul b/js/xpconnect/tests/chrome/test_evalInSandbox.xul index 75607cabce1..dc5e969987f 100644 --- a/js/xpconnect/tests/chrome/test_evalInSandbox.xul +++ b/js/xpconnect/tests/chrome/test_evalInSandbox.xul @@ -151,6 +151,33 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=533596 ok(false, "sameZoneAs works"); } + // The 'let' keyword only appears with JS 1.7 and above. We use this fact + // to make sure that sandboxes get explict JS versions and don't inherit + // them from the most recent scripted frame. + function checkExplicitVersions() { + const Cu = Components.utils; + var sb = new Cu.Sandbox(sop); + Cu.evalInSandbox('let someVariable = 42', sb, '1.7'); + ok(true, "Didn't throw with let"); + try { + Cu.evalInSandbox('let someVariable = 42', sb); + ok(false, "Should have thrown with let"); + } catch (e) { + ok(true, "Threw with let: " + e); + } + try { + Cu.evalInSandbox('let someVariable = 42', sb, '1.5'); + ok(false, "Should have thrown with let"); + } catch (e) { + ok(true, "Threw with let: " + e); + } + } + var outerSB = new Cu.Sandbox(this); + Cu.evalInSandbox(checkExplicitVersions.toSource(), outerSB, '1.7'); + outerSB.ok = ok; + outerSB.sop = this; + Cu.evalInSandbox('checkExplicitVersions();', outerSB); + Cu.import("resource://gre/modules/jsdebugger.jsm"); addDebuggerToGlobal(this);