mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 22:32:46 +00:00
Bug 1097987 part 6. Require callers of JS_ExecuteScript to either use the global as the scope or pass in an explicit scopechain. r=waldo
This commit is contained in:
parent
5ac546abf3
commit
d1e4959752
@ -177,7 +177,7 @@ Load(JSContext *cx,
|
||||
if (!ok)
|
||||
return false;
|
||||
|
||||
if (!JS_ExecuteScript(cx, obj, script)) {
|
||||
if (!JS_ExecuteScript(cx, script)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -342,7 +342,7 @@ XPCShellEnvironment::ProcessFile(JSContext *cx,
|
||||
.setFileAndLine(filename, 1);
|
||||
JS::Rooted<JSScript*> script(cx);
|
||||
if (JS::Compile(cx, global, options, file, &script))
|
||||
(void)JS_ExecuteScript(cx, global, script, &result);
|
||||
(void)JS_ExecuteScript(cx, script, &result);
|
||||
|
||||
return;
|
||||
}
|
||||
@ -379,7 +379,7 @@ XPCShellEnvironment::ProcessFile(JSContext *cx,
|
||||
&script)) {
|
||||
JSErrorReporter older;
|
||||
|
||||
ok = JS_ExecuteScript(cx, global, script, &result);
|
||||
ok = JS_ExecuteScript(cx, script, &result);
|
||||
if (ok && result != JSVAL_VOID) {
|
||||
/* Suppress error reports from JS::ToString(). */
|
||||
older = JS_SetErrorReporter(JS_GetRuntime(cx), nullptr);
|
||||
@ -603,7 +603,7 @@ XPCShellEnvironment::EvaluateString(const nsString& aString,
|
||||
}
|
||||
|
||||
JS::Rooted<JS::Value> result(cx);
|
||||
bool ok = JS_ExecuteScript(cx, global, script, &result);
|
||||
bool ok = JS_ExecuteScript(cx, script, &result);
|
||||
if (ok && result != JSVAL_VOID) {
|
||||
JSErrorReporter old = JS_SetErrorReporter(JS_GetRuntime(cx), nullptr);
|
||||
JSString* str = JS::ToString(cx, result);
|
||||
|
@ -18,7 +18,7 @@ struct ScriptObjectFixture : public JSAPITest {
|
||||
uc_code[i] = code[i];
|
||||
}
|
||||
|
||||
bool tryScript(JS::HandleObject global, JS::HandleScript script)
|
||||
bool tryScript(JS::HandleScript script)
|
||||
{
|
||||
CHECK(script);
|
||||
|
||||
@ -26,7 +26,7 @@ struct ScriptObjectFixture : public JSAPITest {
|
||||
|
||||
/* After a garbage collection, the script should still work. */
|
||||
JS::RootedValue result(cx);
|
||||
CHECK(JS_ExecuteScript(cx, global, script, &result));
|
||||
CHECK(JS_ExecuteScript(cx, script, &result));
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -43,7 +43,7 @@ BEGIN_FIXTURE_TEST(ScriptObjectFixture, bug438633_CompileScript)
|
||||
options.setFileAndLine(__FILE__, __LINE__);
|
||||
JS::RootedScript script(cx);
|
||||
CHECK(JS_CompileScript(cx, global, code, code_size, options, &script));
|
||||
return tryScript(global, script);
|
||||
return tryScript(script);
|
||||
}
|
||||
END_FIXTURE_TEST(ScriptObjectFixture, bug438633_CompileScript)
|
||||
|
||||
@ -53,7 +53,7 @@ BEGIN_FIXTURE_TEST(ScriptObjectFixture, bug438633_CompileScript_empty)
|
||||
options.setFileAndLine(__FILE__, __LINE__);
|
||||
JS::RootedScript script(cx);
|
||||
CHECK(JS_CompileScript(cx, global, "", 0, options, &script));
|
||||
return tryScript(global, script);
|
||||
return tryScript(script);
|
||||
}
|
||||
END_FIXTURE_TEST(ScriptObjectFixture, bug438633_CompileScript_empty)
|
||||
|
||||
@ -63,7 +63,7 @@ BEGIN_FIXTURE_TEST(ScriptObjectFixture, bug438633_CompileScriptForPrincipals)
|
||||
options.setFileAndLine(__FILE__, __LINE__);
|
||||
JS::RootedScript script(cx);
|
||||
CHECK(JS_CompileScript(cx, global, code, code_size, options, &script));
|
||||
return tryScript(global, script);
|
||||
return tryScript(script);
|
||||
}
|
||||
END_FIXTURE_TEST(ScriptObjectFixture, bug438633_CompileScriptForPrincipals)
|
||||
|
||||
@ -73,7 +73,7 @@ BEGIN_FIXTURE_TEST(ScriptObjectFixture, bug438633_JS_CompileUCScript)
|
||||
options.setFileAndLine(__FILE__, __LINE__);
|
||||
JS::RootedScript script(cx);
|
||||
CHECK(JS_CompileUCScript(cx, global, uc_code, code_size, options, &script));
|
||||
return tryScript(global, script);
|
||||
return tryScript(script);
|
||||
}
|
||||
END_FIXTURE_TEST(ScriptObjectFixture, bug438633_JS_CompileUCScript)
|
||||
|
||||
@ -83,7 +83,7 @@ BEGIN_FIXTURE_TEST(ScriptObjectFixture, bug438633_JS_CompileUCScript_empty)
|
||||
options.setFileAndLine(__FILE__, __LINE__);
|
||||
JS::RootedScript script(cx);
|
||||
CHECK(JS_CompileUCScript(cx, global, uc_code, 0, options, &script));
|
||||
return tryScript(global, script);
|
||||
return tryScript(script);
|
||||
}
|
||||
END_FIXTURE_TEST(ScriptObjectFixture, bug438633_JS_CompileUCScript_empty)
|
||||
|
||||
@ -93,7 +93,7 @@ BEGIN_FIXTURE_TEST(ScriptObjectFixture, bug438633_JS_CompileUCScriptForPrincipal
|
||||
options.setFileAndLine(__FILE__, __LINE__);
|
||||
JS::RootedScript script(cx);
|
||||
CHECK(JS_CompileUCScript(cx, global, uc_code, code_size, options, &script));
|
||||
return tryScript(global, script);
|
||||
return tryScript(script);
|
||||
}
|
||||
END_FIXTURE_TEST(ScriptObjectFixture, bug438633_JS_CompileUCScriptForPrincipals)
|
||||
|
||||
@ -109,7 +109,7 @@ BEGIN_FIXTURE_TEST(ScriptObjectFixture, bug438633_JS_CompileFile)
|
||||
JS::RootedScript script(cx);
|
||||
CHECK(JS::Compile(cx, global, options, script_filename, &script));
|
||||
tempScript.remove();
|
||||
return tryScript(global, script);
|
||||
return tryScript(script);
|
||||
}
|
||||
END_FIXTURE_TEST(ScriptObjectFixture, bug438633_JS_CompileFile)
|
||||
|
||||
@ -124,7 +124,7 @@ BEGIN_FIXTURE_TEST(ScriptObjectFixture, bug438633_JS_CompileFile_empty)
|
||||
JS::RootedScript script(cx);
|
||||
CHECK(JS::Compile(cx, global, options, script_filename, &script));
|
||||
tempScript.remove();
|
||||
return tryScript(global, script);
|
||||
return tryScript(script);
|
||||
}
|
||||
END_FIXTURE_TEST(ScriptObjectFixture, bug438633_JS_CompileFile_empty)
|
||||
|
||||
@ -139,7 +139,7 @@ BEGIN_FIXTURE_TEST(ScriptObjectFixture, bug438633_JS_CompileFileHandle)
|
||||
options.setFileAndLine(script_filename, 1);
|
||||
JS::RootedScript script(cx);
|
||||
CHECK(JS::Compile(cx, global, options, script_stream, &script));
|
||||
return tryScript(global, script);
|
||||
return tryScript(script);
|
||||
}
|
||||
END_FIXTURE_TEST(ScriptObjectFixture, bug438633_JS_CompileFileHandle)
|
||||
|
||||
@ -152,7 +152,7 @@ BEGIN_FIXTURE_TEST(ScriptObjectFixture, bug438633_JS_CompileFileHandle_empty)
|
||||
options.setFileAndLine(script_filename, 1);
|
||||
JS::RootedScript script(cx);
|
||||
CHECK(JS::Compile(cx, global, options, script_stream, &script));
|
||||
return tryScript(global, script);
|
||||
return tryScript(script);
|
||||
}
|
||||
END_FIXTURE_TEST(ScriptObjectFixture, bug438633_JS_CompileFileHandle_empty)
|
||||
|
||||
@ -166,6 +166,6 @@ BEGIN_FIXTURE_TEST(ScriptObjectFixture, bug438633_JS_CompileFileHandleForPrincip
|
||||
options.setFileAndLine("temporary file", 1);
|
||||
JS::RootedScript script(cx);
|
||||
CHECK(JS::Compile(cx, global, options, script_stream, &script));
|
||||
return tryScript(global, script);
|
||||
return tryScript(script);
|
||||
}
|
||||
END_FIXTURE_TEST(ScriptObjectFixture, bug438633_JS_CompileFileHandleForPrincipals)
|
||||
|
@ -57,7 +57,7 @@ BEGIN_TEST(testXDR_bug506491)
|
||||
|
||||
// execute
|
||||
JS::RootedValue v2(cx);
|
||||
CHECK(JS_ExecuteScript(cx, global, script, &v2));
|
||||
CHECK(JS_ExecuteScript(cx, script, &v2));
|
||||
|
||||
// try to break the Block object that is the parent of f
|
||||
JS_GC(rt);
|
||||
@ -83,7 +83,7 @@ BEGIN_TEST(testXDR_bug516827)
|
||||
CHECK(script);
|
||||
|
||||
// execute with null result meaning no result wanted
|
||||
CHECK(JS_ExecuteScript(cx, global, script));
|
||||
CHECK(JS_ExecuteScript(cx, script));
|
||||
return true;
|
||||
}
|
||||
END_TEST(testXDR_bug516827)
|
||||
|
@ -4115,15 +4115,15 @@ ExecuteScript(JSContext *cx, AutoObjectVector &scopeChain, HandleScript scriptAr
|
||||
}
|
||||
|
||||
MOZ_NEVER_INLINE JS_PUBLIC_API(bool)
|
||||
JS_ExecuteScript(JSContext *cx, HandleObject obj, HandleScript scriptArg, MutableHandleValue rval)
|
||||
JS_ExecuteScript(JSContext *cx, HandleScript scriptArg, MutableHandleValue rval)
|
||||
{
|
||||
return ExecuteScript(cx, obj, scriptArg, rval.address());
|
||||
return ExecuteScript(cx, cx->global(), scriptArg, rval.address());
|
||||
}
|
||||
|
||||
MOZ_NEVER_INLINE JS_PUBLIC_API(bool)
|
||||
JS_ExecuteScript(JSContext *cx, HandleObject obj, HandleScript scriptArg)
|
||||
JS_ExecuteScript(JSContext *cx, HandleScript scriptArg)
|
||||
{
|
||||
return ExecuteScript(cx, obj, scriptArg, nullptr);
|
||||
return ExecuteScript(cx, cx->global(), scriptArg, nullptr);
|
||||
}
|
||||
|
||||
MOZ_NEVER_INLINE JS_PUBLIC_API(bool)
|
||||
|
@ -3699,29 +3699,29 @@ extern JS_PUBLIC_API(JSString *)
|
||||
JS_DecompileFunctionBody(JSContext *cx, JS::Handle<JSFunction*> fun, unsigned indent);
|
||||
|
||||
/*
|
||||
* NB: JS_ExecuteScript and the JS::Evaluate APIs use the obj
|
||||
* parameter as the initial scope chain header, the 'this' keyword value, and
|
||||
* the variables object (ECMA parlance for where 'var' and 'function' bind
|
||||
* names) of the execution context for script.
|
||||
* NB: JS_ExecuteScript and the JS::Evaluate APIs come in two flavors: either
|
||||
* they use the global as the scope, or they take an AutoObjectVector of objects
|
||||
* to use as the scope chain. In the former case, the global is also used as
|
||||
* the "this" keyword value and the variables object (ECMA parlance for where
|
||||
* 'var' and 'function' bind names) of the execution context for script. In the
|
||||
* latter case, the first object in the provided list is used, unless the list
|
||||
* is empty, in which case the global is used.
|
||||
*
|
||||
* Using obj as the variables object is problematic if obj's parent (which is
|
||||
* the scope chain link) is not null, which in practice is always true: in
|
||||
* this case, variables created by 'var x = 0', e.g., go in obj, but variables
|
||||
* created by assignment to an unbound id, 'x = 0', go in the last object on
|
||||
* the scope chain linked by parent.
|
||||
* Using a non-global object as the variables object is problematic: in this
|
||||
* case, variables created by 'var x = 0', e.g., go in that object, but
|
||||
* variables created by assignment to an unbound id, 'x = 0', go in the global.
|
||||
*
|
||||
* ECMA calls that last scoping object the "global object", but note that many
|
||||
* embeddings have several such objects. ECMA requires that "global code" be
|
||||
* executed with the variables object equal to this global object. But these
|
||||
* JS API entry points provide freedom to execute code against a "sub-global",
|
||||
* i.e., a parented or scoped object, in which case the variables object will
|
||||
* differ from the last object on the scope chain, resulting in confusing and
|
||||
* non-ECMA explicit vs. implicit variable creation.
|
||||
* ECMA requires that "global code" be executed with the variables object equal
|
||||
* to the global object. But these JS API entry points provide freedom to
|
||||
* execute code against a "sub-global", i.e., a parented or scoped object, in
|
||||
* which case the variables object will differ from the global, resulting in
|
||||
* confusing and non-ECMA explicit vs. implicit variable creation.
|
||||
*
|
||||
* Caveat embedders: unless you already depend on this buggy variables object
|
||||
* binding behavior, you should call RuntimeOptionsRef(rt).setVarObjFix(true)
|
||||
* for each context in the application, if you pass parented objects as the obj
|
||||
* parameter, or may ever pass such objects in the future.
|
||||
* for each context in the application, if you use the versions of
|
||||
* JS_ExecuteScript and JS::Evaluate that take a scope chain argument, or may
|
||||
* ever use them in the future.
|
||||
*
|
||||
* Why a runtime option? The alternative is to add APIs duplicating those below
|
||||
* for the other value of varobjfix, and that doesn't seem worth the code bloat
|
||||
@ -3730,16 +3730,20 @@ JS_DecompileFunctionBody(JSContext *cx, JS::Handle<JSFunction*> fun, unsigned in
|
||||
* more easily hacked into existing code that does not depend on the bug; such
|
||||
* code can continue to use the familiar JS::Evaluate, etc., entry points.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Evaluate a script in the scope of the current global of cx.
|
||||
*/
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_ExecuteScript(JSContext *cx, JS::HandleObject obj, JS::HandleScript script, JS::MutableHandleValue rval);
|
||||
JS_ExecuteScript(JSContext *cx, JS::HandleScript script, JS::MutableHandleValue rval);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_ExecuteScript(JSContext *cx, JS::HandleObject obj, JS::HandleScript script);
|
||||
JS_ExecuteScript(JSContext *cx, JS::HandleScript script);
|
||||
|
||||
/*
|
||||
* As above, but providing an explicit scope chain. scopeChain must not include
|
||||
* the global object on it; that's implicit. It needs to contain the other
|
||||
* objects that should end up on the scripts's scope chain.
|
||||
* objects that should end up on the script's scope chain.
|
||||
*/
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_ExecuteScript(JSContext *cx, JS::AutoObjectVector &scopeChain,
|
||||
|
@ -463,7 +463,7 @@ RunFile(JSContext *cx, const char *filename, FILE *file, bool compileOnly)
|
||||
AnalyzeEntrainedVariables(cx, script);
|
||||
#endif
|
||||
if (script && !compileOnly) {
|
||||
if (!JS_ExecuteScript(cx, cx->global(), script)) {
|
||||
if (!JS_ExecuteScript(cx, script)) {
|
||||
if (!gQuitting && gExitCode != EXITCODE_TIMEOUT)
|
||||
gExitCode = EXITCODE_RUNTIME_ERROR;
|
||||
}
|
||||
@ -489,7 +489,7 @@ EvalAndPrint(JSContext *cx, const char *bytes, size_t length,
|
||||
if (compileOnly)
|
||||
return true;
|
||||
RootedValue result(cx);
|
||||
if (!JS_ExecuteScript(cx, cx->global(), script, &result))
|
||||
if (!JS_ExecuteScript(cx, script, &result))
|
||||
return false;
|
||||
|
||||
if (!result.isUndefined()) {
|
||||
@ -1327,7 +1327,7 @@ Evaluate(JSContext *cx, unsigned argc, jsval *vp)
|
||||
if (!script->scriptSource()->setSourceMapURL(cx, smurl))
|
||||
return false;
|
||||
}
|
||||
if (!JS_ExecuteScript(cx, global, script, args.rval())) {
|
||||
if (!JS_ExecuteScript(cx, script, args.rval())) {
|
||||
if (catchTermination && !JS_IsExceptionPending(cx)) {
|
||||
JSAutoCompartment ac1(cx, callerGlobal);
|
||||
JSString *str = JS_NewStringCopyZ(cx, "terminated");
|
||||
@ -1493,7 +1493,7 @@ Run(JSContext *cx, unsigned argc, jsval *vp)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!JS_ExecuteScript(cx, cx->global(), script))
|
||||
if (!JS_ExecuteScript(cx, script))
|
||||
return false;
|
||||
|
||||
int64_t endClock = PRMJ_Now();
|
||||
@ -2819,7 +2819,7 @@ WorkerMain(void *arg)
|
||||
if (!JS::Compile(cx, global, options, input->chars, input->length, &script))
|
||||
break;
|
||||
RootedValue result(cx);
|
||||
JS_ExecuteScript(cx, global, script, &result);
|
||||
JS_ExecuteScript(cx, script, &result);
|
||||
} while (0);
|
||||
|
||||
JS::SetLargeAllocationFailureCallback(rt, nullptr, nullptr);
|
||||
@ -3561,7 +3561,7 @@ runOffThreadScript(JSContext *cx, unsigned argc, jsval *vp)
|
||||
if (!script)
|
||||
return false;
|
||||
|
||||
return JS_ExecuteScript(cx, cx->global(), script, args.rval());
|
||||
return JS_ExecuteScript(cx, script, args.rval());
|
||||
}
|
||||
|
||||
struct FreeOnReturn
|
||||
|
@ -671,6 +671,7 @@ mozJSComponentLoader::ObjectForLocation(ComponentLoaderInfo &aInfo,
|
||||
RootedObject obj(cx, PrepareObjectForLocation(cx, aComponentFile, aInfo.URI(),
|
||||
mReuseLoaderGlobal, &realFile));
|
||||
NS_ENSURE_TRUE(obj, NS_ERROR_FAILURE);
|
||||
MOZ_ASSERT(JS_IsGlobalObject(obj) == !mReuseLoaderGlobal);
|
||||
|
||||
JSAutoCompartment ac(cx, obj);
|
||||
|
||||
@ -898,6 +899,12 @@ mozJSComponentLoader::ObjectForLocation(ComponentLoaderInfo &aInfo,
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// We must have a script or a function (but not both!) here. We have a
|
||||
// script when we're not reusing the loader global, and a function
|
||||
// otherwise.
|
||||
MOZ_ASSERT(!!script != !!function);
|
||||
MOZ_ASSERT(!!script == JS_IsGlobalObject(obj));
|
||||
|
||||
if (writeToCache) {
|
||||
// We successfully compiled the script, so cache it.
|
||||
if (script) {
|
||||
@ -940,7 +947,7 @@ mozJSComponentLoader::ObjectForLocation(ComponentLoaderInfo &aInfo,
|
||||
if (aPropagateExceptions)
|
||||
ContextOptionsRef(cx).setDontReportUncaught(true);
|
||||
if (script) {
|
||||
ok = JS_ExecuteScript(cx, obj, script);
|
||||
ok = JS_ExecuteScript(cx, script);
|
||||
} else {
|
||||
RootedValue rval(cx);
|
||||
ok = JS_CallFunction(cx, obj, function, JS::HandleValueArray::empty(), &rval);
|
||||
|
@ -379,7 +379,7 @@ mozJSSubScriptLoader::DoLoadSubScriptWithOptions(const nsAString &url,
|
||||
retval);
|
||||
} else {
|
||||
if (JS_IsGlobalObject(targetObj)) {
|
||||
ok = JS_ExecuteScript(cx, targetObj, script, retval);
|
||||
ok = JS_ExecuteScript(cx, script, retval);
|
||||
} else {
|
||||
JS::AutoObjectVector scopeChain(cx);
|
||||
ok = scopeChain.append(targetObj) &&
|
||||
|
@ -345,7 +345,7 @@ Load(JSContext *cx, unsigned argc, jsval *vp)
|
||||
if (!compileOnly) {
|
||||
// XXXbz are we intentionally allowing load.call(someNonGlobalObject)?
|
||||
if (JS_IsGlobalObject(obj)) {
|
||||
if (!JS_ExecuteScript(cx, obj, script)) {
|
||||
if (!JS_ExecuteScript(cx, script)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
@ -838,7 +838,7 @@ ProcessFile(JSContext *cx, const char *filename, FILE *file, bool forceTTY)
|
||||
.setFileAndLine(filename, 1)
|
||||
.setCompileAndGo(true);
|
||||
if (JS::Compile(cx, global, options, file, &script) && !compileOnly)
|
||||
(void)JS_ExecuteScript(cx, global, script, &result);
|
||||
(void)JS_ExecuteScript(cx, script, &result);
|
||||
JS_EndRequest(cx);
|
||||
|
||||
return;
|
||||
@ -878,7 +878,7 @@ ProcessFile(JSContext *cx, const char *filename, FILE *file, bool forceTTY)
|
||||
JSErrorReporter older;
|
||||
|
||||
if (!compileOnly) {
|
||||
ok = JS_ExecuteScript(cx, global, script, &result);
|
||||
ok = JS_ExecuteScript(cx, script, &result);
|
||||
if (ok && result != JSVAL_VOID) {
|
||||
/* Suppress error reports from JS::ToString(). */
|
||||
older = JS_SetErrorReporter(JS_GetRuntime(cx), nullptr);
|
||||
|
@ -668,7 +668,7 @@ ProxyAutoConfig::SetupJS()
|
||||
JS::Rooted<JSScript*> script(cx);
|
||||
if (!JS_CompileScript(cx, global, mPACScript.get(),
|
||||
mPACScript.Length(), options, &script) ||
|
||||
!JS_ExecuteScript(cx, global, script))
|
||||
!JS_ExecuteScript(cx, script))
|
||||
{
|
||||
nsString alertMessage(NS_LITERAL_STRING("PAC file failed to install from "));
|
||||
if (isDataURI) {
|
||||
|
Loading…
Reference in New Issue
Block a user