Bug 1097987 part 7. Require callers of JS::Evaluate to either use the global as the scope or pass in an explicit scopechain. r=waldo

This commit is contained in:
Boris Zbarsky 2015-03-14 01:36:16 -04:00
Родитель d1e4959752
Коммит fe0f33e72f
15 изменённых файлов: 81 добавлений и 48 удалений

Просмотреть файл

@ -769,7 +769,7 @@ ScriptExecutorRunnable::WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
loadInfo.mScriptTextLength = 0;
JS::Rooted<JS::Value> unused(aCx);
if (!JS::Evaluate(aCx, global, options, srcBuf, &unused)) {
if (!JS::Evaluate(aCx, options, srcBuf, &unused)) {
return true;
}

Просмотреть файл

@ -6188,7 +6188,7 @@ WorkerPrivate::RunExpiredTimeouts(JSContext* aCx)
JS::Rooted<JS::Value> unused(aCx);
if ((expression.IsEmpty() ||
!JS::Evaluate(aCx, global, options,
!JS::Evaluate(aCx, options,
expression.get(), expression.Length(), &unused)) &&
!JS_ReportPendingException(aCx)) {
retval = false;

Просмотреть файл

@ -94,7 +94,7 @@ CreateDataView(JSContext *cx)
JS::Rooted<JS::Value> val(cx);
JS::CompileOptions opts(cx);
if (!JS::Evaluate(cx, global, opts.setFileAndLine(__FILE__, __LINE__),
if (!JS::Evaluate(cx, opts.setFileAndLine(__FILE__, __LINE__),
code, strlen(code), &val))
return nullptr;

Просмотреть файл

@ -42,7 +42,7 @@ BEGIN_TEST(testRedefineGlobalEval)
static const char data[] = "Object.defineProperty(this, 'eval', { configurable: false });";
JS::CompileOptions opts(cx);
CHECK(JS::Evaluate(cx, g, opts.setFileAndLine(__FILE__, __LINE__),
CHECK(JS::Evaluate(cx, opts.setFileAndLine(__FILE__, __LINE__),
data, mozilla::ArrayLength(data) - 1, &v));
return true;

Просмотреть файл

@ -31,7 +31,7 @@ BEGIN_TEST(testGCOutOfMemory)
" array = []; array.push(0);"
"})();";
JS::CompileOptions opts(cx);
bool ok = JS::Evaluate(cx, global, opts, source, strlen(source), &root);
bool ok = JS::Evaluate(cx, opts, source, strlen(source), &root);
/* Check that we get OOM. */
CHECK(!ok);

Просмотреть файл

@ -11,12 +11,14 @@ BEGIN_TEST(testJSEvaluateScript)
CHECK(JS::RuntimeOptionsRef(cx).varObjFix());
static const char src[] = "var x = 5;";
static const char16_t src[] = MOZ_UTF16("var x = 5;");
JS::RootedValue retval(cx);
JS::CompileOptions opts(cx);
CHECK(JS::Evaluate(cx, obj, opts.setFileAndLine(__FILE__, __LINE__),
src, sizeof(src) - 1, &retval));
JS::AutoObjectVector scopeChain(cx);
CHECK(scopeChain.append(obj));
CHECK(JS::Evaluate(cx, scopeChain, opts.setFileAndLine(__FILE__, __LINE__),
src, ArrayLength(src) - 1, &retval));
bool hasProp = true;
CHECK(JS_AlreadyHasOwnProperty(cx, obj, "x", &hasProp));
@ -29,10 +31,10 @@ BEGIN_TEST(testJSEvaluateScript)
// Now do the same thing, but without JSOPTION_VAROBJFIX
JS::RuntimeOptionsRef(cx).setVarObjFix(false);
static const char src2[] = "var y = 5;";
static const char16_t src2[] = MOZ_UTF16("var y = 5;");
CHECK(JS::Evaluate(cx, obj, opts.setFileAndLine(__FILE__, __LINE__),
src2, sizeof(src2) - 1, &retval));
CHECK(JS::Evaluate(cx, scopeChain, opts.setFileAndLine(__FILE__, __LINE__),
src2, ArrayLength(src2) - 1, &retval));
hasProp = false;
CHECK(JS_AlreadyHasOwnProperty(cx, obj, "y", &hasProp));

Просмотреть файл

@ -60,7 +60,7 @@ eval(const char *asciiChars, bool mutedErrors, JS::MutableHandleValue rval)
options.setMutedErrors(mutedErrors)
.setFileAndLine("", 0);
bool ok = JS::Evaluate(cx, global, options, chars, len, rval);
bool ok = JS::Evaluate(cx, options, chars, len, rval);
delete[] chars;
return ok;

Просмотреть файл

@ -19,7 +19,7 @@ BEGIN_TEST(testBug795104)
// We don't want an rval for our Evaluate call
opts.setNoScriptRval(true);
JS::RootedValue unused(cx);
CHECK(JS::Evaluate(cx, global, opts, s, strLen, &unused));
CHECK(JS::Evaluate(cx, opts, s, strLen, &unused));
JS::RootedFunction fun(cx);
JS::AutoObjectVector emptyScopeChain(cx);
// But when compiling a function we don't want to use no-rval

Просмотреть файл

@ -55,7 +55,7 @@ bool JSAPITest::exec(const char *bytes, const char *filename, int lineno)
JS::RootedValue v(cx);
JS::CompileOptions opts(cx);
opts.setFileAndLine(filename, lineno);
return JS::Evaluate(cx, global, opts, bytes, strlen(bytes), &v) ||
return JS::Evaluate(cx, opts, bytes, strlen(bytes), &v) ||
fail(JSAPITestString(bytes), filename, lineno);
}
@ -64,7 +64,7 @@ bool JSAPITest::evaluate(const char *bytes, const char *filename, int lineno,
{
JS::CompileOptions opts(cx);
opts.setFileAndLine(filename, lineno);
return JS::Evaluate(cx, global, opts, bytes, strlen(bytes), vp) ||
return JS::Evaluate(cx, opts, bytes, strlen(bytes), vp) ||
fail(JSAPITestString(bytes), filename, lineno);
}

Просмотреть файл

@ -4158,28 +4158,28 @@ JS::CloneAndExecuteScript(JSContext *cx, HandleObject obj, HandleScript scriptAr
static const unsigned LARGE_SCRIPT_LENGTH = 500*1024;
static bool
Evaluate(JSContext *cx, HandleObject obj, const ReadOnlyCompileOptions &optionsArg,
Evaluate(JSContext *cx, HandleObject scope, const ReadOnlyCompileOptions &optionsArg,
SourceBufferHolder &srcBuf, MutableHandleValue rval)
{
CompileOptions options(cx, optionsArg);
MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
assertSameCompartment(cx, obj);
assertSameCompartment(cx, scope);
AutoLastFrameCheck lfc(cx);
options.setCompileAndGo(obj->is<GlobalObject>());
options.setCompileAndGo(scope->is<GlobalObject>());
SourceCompressionTask sct(cx);
RootedScript script(cx, frontend::CompileScript(cx, &cx->tempLifoAlloc(),
obj, NullPtr(), NullPtr(), options,
scope, NullPtr(), NullPtr(), options,
srcBuf, nullptr, 0, &sct));
if (!script)
return false;
MOZ_ASSERT(script->getVersion() == options.version);
bool result = Execute(cx, script, *obj,
bool result = Execute(cx, script, *scope,
options.noScriptRval ? nullptr : rval.address());
if (!sct.complete())
result = false;
@ -4210,16 +4210,16 @@ Evaluate(JSContext *cx, AutoObjectVector &scopeChain, const ReadOnlyCompileOptio
}
static bool
Evaluate(JSContext *cx, HandleObject obj, const ReadOnlyCompileOptions &optionsArg,
Evaluate(JSContext *cx, const ReadOnlyCompileOptions &optionsArg,
const char16_t *chars, size_t length, MutableHandleValue rval)
{
SourceBufferHolder srcBuf(chars, length, SourceBufferHolder::NoOwnership);
return ::Evaluate(cx, obj, optionsArg, srcBuf, rval);
return ::Evaluate(cx, cx->global(), optionsArg, srcBuf, rval);
}
extern JS_PUBLIC_API(bool)
JS::Evaluate(JSContext *cx, HandleObject obj, const ReadOnlyCompileOptions &options,
const char *bytes, size_t length, MutableHandleValue rval)
JS::Evaluate(JSContext *cx, const ReadOnlyCompileOptions &options,
const char *bytes, size_t length, MutableHandleValue rval)
{
char16_t *chars;
if (options.utf8)
@ -4230,12 +4230,12 @@ JS::Evaluate(JSContext *cx, HandleObject obj, const ReadOnlyCompileOptions &opti
return false;
SourceBufferHolder srcBuf(chars, length, SourceBufferHolder::GiveOwnership);
bool ok = ::Evaluate(cx, obj, options, srcBuf, rval);
bool ok = ::Evaluate(cx, cx->global(), options, srcBuf, rval);
return ok;
}
static bool
Evaluate(JSContext *cx, HandleObject obj, const ReadOnlyCompileOptions &optionsArg,
Evaluate(JSContext *cx, const ReadOnlyCompileOptions &optionsArg,
const char *filename, MutableHandleValue rval)
{
FileContents buffer(cx);
@ -4247,14 +4247,14 @@ Evaluate(JSContext *cx, HandleObject obj, const ReadOnlyCompileOptions &optionsA
CompileOptions options(cx, optionsArg);
options.setFileAndLine(filename, 1);
return Evaluate(cx, obj, options, buffer.begin(), buffer.length(), rval);
return Evaluate(cx, options, buffer.begin(), buffer.length(), rval);
}
JS_PUBLIC_API(bool)
JS::Evaluate(JSContext *cx, HandleObject obj, const ReadOnlyCompileOptions &optionsArg,
JS::Evaluate(JSContext *cx, const ReadOnlyCompileOptions &optionsArg,
SourceBufferHolder &srcBuf, MutableHandleValue rval)
{
return ::Evaluate(cx, obj, optionsArg, srcBuf, rval);
return ::Evaluate(cx, cx->global(), optionsArg, srcBuf, rval);
}
JS_PUBLIC_API(bool)
@ -4265,17 +4265,25 @@ JS::Evaluate(JSContext *cx, AutoObjectVector &scopeChain, const ReadOnlyCompileO
}
JS_PUBLIC_API(bool)
JS::Evaluate(JSContext *cx, HandleObject obj, const ReadOnlyCompileOptions &optionsArg,
JS::Evaluate(JSContext *cx, const ReadOnlyCompileOptions &optionsArg,
const char16_t *chars, size_t length, MutableHandleValue rval)
{
return ::Evaluate(cx, obj, optionsArg, chars, length, rval);
return ::Evaluate(cx, optionsArg, chars, length, rval);
}
JS_PUBLIC_API(bool)
JS::Evaluate(JSContext *cx, HandleObject obj, const ReadOnlyCompileOptions &optionsArg,
JS::Evaluate(JSContext *cx, AutoObjectVector &scopeChain, const ReadOnlyCompileOptions &optionsArg,
const char16_t *chars, size_t length, MutableHandleValue rval)
{
SourceBufferHolder srcBuf(chars, length, SourceBufferHolder::NoOwnership);
return ::Evaluate(cx, scopeChain, optionsArg, srcBuf, rval);
}
JS_PUBLIC_API(bool)
JS::Evaluate(JSContext *cx, const ReadOnlyCompileOptions &optionsArg,
const char *filename, MutableHandleValue rval)
{
return ::Evaluate(cx, obj, optionsArg, filename, rval);
return ::Evaluate(cx, optionsArg, filename, rval);
}
JS_PUBLIC_API(bool)

Просмотреть файл

@ -3765,24 +3765,50 @@ CloneAndExecuteScript(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<JSScr
namespace JS {
/*
* Evaluate the given source buffer in the scope of the current global of cx.
*/
extern JS_PUBLIC_API(bool)
Evaluate(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
Evaluate(JSContext *cx, const ReadOnlyCompileOptions &options,
SourceBufferHolder &srcBuf, JS::MutableHandleValue rval);
/*
* 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 script's scope chain.
*/
extern JS_PUBLIC_API(bool)
Evaluate(JSContext *cx, AutoObjectVector &scopeChain, const ReadOnlyCompileOptions &options,
SourceBufferHolder &srcBuf, JS::MutableHandleValue rval);
/*
* Evaluate the given character buffer in the scope of the current global of cx.
*/
extern JS_PUBLIC_API(bool)
Evaluate(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
Evaluate(JSContext *cx, const ReadOnlyCompileOptions &options,
const char16_t *chars, size_t length, JS::MutableHandleValue rval);
/*
* 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 script's scope chain.
*/
extern JS_PUBLIC_API(bool)
Evaluate(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
Evaluate(JSContext *cx, AutoObjectVector &scopeChain, const ReadOnlyCompileOptions &options,
const char16_t *chars, size_t length, JS::MutableHandleValue rval);
/*
* Evaluate the given byte buffer in the scope of the current global of cx.
*/
extern JS_PUBLIC_API(bool)
Evaluate(JSContext *cx, const ReadOnlyCompileOptions &options,
const char *bytes, size_t length, JS::MutableHandleValue rval);
/*
* Evaluate the given file in the scope of the current global of cx.
*/
extern JS_PUBLIC_API(bool)
Evaluate(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
Evaluate(JSContext *cx, const ReadOnlyCompileOptions &options,
const char *filename, JS::MutableHandleValue rval);
} /* namespace JS */

Просмотреть файл

@ -845,9 +845,6 @@ static bool
LoadScript(JSContext *cx, unsigned argc, jsval *vp, bool scriptRelative)
{
CallArgs args = CallArgsFromVp(argc, vp);
RootedObject thisobj(cx, JS_THIS_OBJECT(cx, vp));
if (!thisobj)
return false;
RootedString str(cx);
for (unsigned i = 0; i < args.length(); i++) {
@ -872,8 +869,8 @@ LoadScript(JSContext *cx, unsigned argc, jsval *vp, bool scriptRelative)
.setNoScriptRval(true);
RootedScript script(cx);
RootedValue unused(cx);
if ((compileOnly && !Compile(cx, thisobj, opts, filename.ptr(), &script)) ||
!Evaluate(cx, thisobj, opts, filename.ptr(), &unused))
if ((compileOnly && !Compile(cx, cx->global(), opts, filename.ptr(), &script)) ||
!Evaluate(cx, opts, filename.ptr(), &unused))
{
return false;
}
@ -2750,7 +2747,7 @@ EvalInContext(JSContext *cx, unsigned argc, jsval *vp)
}
JS::CompileOptions opts(cx);
opts.setFileAndLine(filename.get(), lineno);
if (!JS::Evaluate(cx, sobj, opts, src, srclen, args.rval())) {
if (!JS::Evaluate(cx, opts, src, srclen, args.rval())) {
return false;
}
}
@ -5735,7 +5732,7 @@ ProcessArgs(JSContext *cx, OptionParser *op)
RootedValue rval(cx);
JS::CompileOptions opts(cx);
opts.setFileAndLine("-e", 1);
if (!JS::Evaluate(cx, cx->global(), opts, code, strlen(code), &rval))
if (!JS::Evaluate(cx, opts, code, strlen(code), &rval))
return gExitCode ? gExitCode : EXITCODE_RUNTIME_ERROR;
codeChunks.popFront();
}

Просмотреть файл

@ -1193,7 +1193,7 @@ JSRuntime::initSelfHosting(JSContext *cx)
ok = false;
}
ok = ok && Evaluate(cx, shg, options, src, srcLen, &rv);
ok = ok && Evaluate(cx, options, src, srcLen, &rv);
}
JS_SetErrorReporter(cx->runtime(), oldReporter);
return ok;

Просмотреть файл

@ -1532,8 +1532,8 @@ xpc::EvalInSandbox(JSContext *cx, HandleObject sandboxArg, const nsAString& sour
JS::CompileOptions options(sandcx);
options.setFileAndLine(filenameBuf.get(), lineNo)
.setVersion(jsVersion);
JS::RootedObject rootedSandbox(sandcx, sandbox);
ok = JS::Evaluate(sandcx, rootedSandbox, options,
MOZ_ASSERT(JS_IsGlobalObject(sandbox));
ok = JS::Evaluate(sandcx, options,
PromiseFlatString(source).get(), source.Length(), &v);
// If the sandbox threw an exception, grab it off the context.

Просмотреть файл

@ -1070,7 +1070,7 @@ ProcessArgs(JSContext *cx, char **argv, int argc, XPCShellDirProvider* aDirProvi
JS::CompileOptions opts(cx);
opts.setFileAndLine("-e", 1);
JS::Evaluate(cx, global, opts, argv[i], strlen(argv[i]), &rval);
JS::Evaluate(cx, opts, argv[i], strlen(argv[i]), &rval);
isInteractive = false;
break;