Bug 952885: When doing cross-global compilations in the shell, properly wrap CompileOptions members for the new global. r=njn

This commit is contained in:
Jim Blandy 2014-01-22 16:41:15 -08:00
parent bd53b5edbf
commit 942bee8c31
4 changed files with 40 additions and 0 deletions

View File

@ -0,0 +1,6 @@
// Specifying an owning element in a cross-global evaluation shouldn't crash.
// That is, when 'evaluate' switches compartments, it should properly wrap
// the CompileOptions members that will become cross-compartment
// references.
evaluate('42 + 1729', { global: newGlobal(), element: {} });

View File

@ -4373,6 +4373,18 @@ JS::OwningCompileOptions::setSourceMapURL(JSContext *cx, const jschar *s)
return true;
}
bool
JS::OwningCompileOptions::wrap(JSContext *cx, JSCompartment *compartment)
{
if (!compartment->wrap(cx, &elementRoot))
return false;
if (elementPropertyRoot) {
if (!compartment->wrap(cx, elementPropertyRoot.address()))
return false;
}
return true;
}
JS::CompileOptions::CompileOptions(JSContext *cx, JSVersion version)
: ReadOnlyCompileOptions(), elementRoot(cx), elementPropertyRoot(cx)
{
@ -4386,6 +4398,18 @@ JS::CompileOptions::CompileOptions(JSContext *cx, JSVersion version)
asmJSOption = cx->options().asmJS();
}
bool
JS::CompileOptions::wrap(JSContext *cx, JSCompartment *compartment)
{
if (!compartment->wrap(cx, &elementRoot))
return false;
if (elementPropertyRoot) {
if (!compartment->wrap(cx, elementPropertyRoot.address()))
return false;
}
return true;
}
JSScript *
JS::Compile(JSContext *cx, HandleObject obj, const ReadOnlyCompileOptions &options,
const jschar *chars, size_t length)

View File

@ -3506,6 +3506,10 @@ class JS_FRIEND_API(ReadOnlyCompileOptions)
SAVE_SOURCE
} sourcePolicy;
// Wrap any compilation option values that need it as appropriate for
// use from |compartment|.
virtual bool wrap(JSContext *cx, JSCompartment *compartment) = 0;
private:
static JSObject * const nullObjectPtr;
void operator=(const ReadOnlyCompileOptions &) MOZ_DELETE;
@ -3576,6 +3580,8 @@ class JS_FRIEND_API(OwningCompileOptions) : public ReadOnlyCompileOptions
OwningCompileOptions &setSelfHostingMode(bool shm) { selfHostingMode = shm; return *this; }
OwningCompileOptions &setCanLazilyParse(bool clp) { canLazilyParse = clp; return *this; }
OwningCompileOptions &setSourcePolicy(SourcePolicy sp) { sourcePolicy = sp; return *this; }
virtual bool wrap(JSContext *cx, JSCompartment *compartment) MOZ_OVERRIDE;
};
/*
@ -3632,6 +3638,8 @@ class MOZ_STACK_CLASS JS_FRIEND_API(CompileOptions) : public ReadOnlyCompileOpti
CompileOptions &setSelfHostingMode(bool shm) { selfHostingMode = shm; return *this; }
CompileOptions &setCanLazilyParse(bool clp) { canLazilyParse = clp; return *this; }
CompileOptions &setSourcePolicy(SourcePolicy sp) { sourcePolicy = sp; return *this; }
virtual bool wrap(JSContext *cx, JSCompartment *compartment) MOZ_OVERRIDE;
};
extern JS_PUBLIC_API(JSScript *)

View File

@ -1019,6 +1019,8 @@ Evaluate(JSContext *cx, unsigned argc, jsval *vp)
.setElementProperty(elementProperty)
.setSourcePolicy(sourcePolicy)
.setCompileAndGo(compileAndGo);
if (!options.wrap(cx, cx->compartment()))
return false;
script = JS::Compile(cx, global, options, codeChars, codeLength);
if (!script)