Bug 892203 - DOMConstructors for SandboxOptions. r=bholley

This commit is contained in:
Gabor Krizsanits 2013-09-04 12:16:04 +02:00
parent 77cc54733e
commit 1cb4e55c92
7 changed files with 74 additions and 16 deletions

View File

@ -20,7 +20,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=817284
/** Test for Bug 817284 **/
var cu = Components.utils;
var sb = cu.Sandbox("http://example.com", {wantXHRConstructor: true});
var sb = cu.Sandbox("http://example.com", { wantDOMConstructors: ["XMLHttpRequest"] });
// Test event handler calls
var xhr = cu.evalInSandbox(

View File

@ -870,6 +870,41 @@ xpc::SandboxProxyHandler::iterate(JSContext *cx, JS::Handle<JSObject*> proxy,
return BaseProxyHandler::iterate(cx, proxy, flags, vp);
}
bool
xpc::SandboxOptions::DOMConstructors::Parse(JSContext* cx, JS::HandleObject obj)
{
NS_ENSURE_TRUE(JS_IsArrayObject(cx, obj), false);
uint32_t length;
bool ok = JS_GetArrayLength(cx, obj, &length);
NS_ENSURE_TRUE(ok, false);
for (uint32_t i = 0; i < length; i++) {
RootedValue nameValue(cx);
ok = JS_GetElement(cx, obj, i, &nameValue);
NS_ENSURE_TRUE(ok, false);
NS_ENSURE_TRUE(nameValue.isString(), false);
char *name = JS_EncodeString(cx, nameValue.toString());
NS_ENSURE_TRUE(name, false);
if (!strcmp(name, "XMLHttpRequest")) {
XMLHttpRequest = true;
} else {
// Reporting error, if one of the DOM constructor names is unknown.
return false;
}
}
return true;
}
bool
xpc::SandboxOptions::DOMConstructors::Define(JSContext* cx, JS::HandleObject obj)
{
if (XMLHttpRequest &&
!JS_DefineFunction(cx, obj, "XMLHttpRequest", CreateXMLHttpRequest, 0, JSFUN_CONSTRUCTOR))
return false;
return true;
}
nsresult
xpc::CreateSandboxObject(JSContext *cx, jsval *vp, nsISupports *prinOrSop, SandboxOptions& options)
{
@ -972,15 +1007,13 @@ xpc::CreateSandboxObject(JSContext *cx, jsval *vp, nsISupports *prinOrSop, Sandb
if (!JS_DefineFunctions(cx, sandbox, SandboxFunctions))
return NS_ERROR_XPC_UNEXPECTED;
if (options.wantXHRConstructor &&
!JS_DefineFunction(cx, sandbox, "XMLHttpRequest", CreateXMLHttpRequest, 0, JSFUN_CONSTRUCTOR))
return NS_ERROR_XPC_UNEXPECTED;
if (options.wantExportHelpers &&
(!JS_DefineFunction(cx, sandbox, "exportFunction", ExportFunction, 3, 0) ||
!JS_DefineFunction(cx, sandbox, "evalInWindow", EvalInWindow, 2, 0)))
return NS_ERROR_XPC_UNEXPECTED;
if (!options.DOMConstructors.Define(cx, sandbox))
return NS_ERROR_XPC_UNEXPECTED;
}
if (vp) {
@ -1242,6 +1275,26 @@ GetStringPropFromOptions(JSContext *cx, HandleObject from, const char *name, nsC
return NS_OK;
}
/*
* Helper that tries to get a list of DOM constructors from the options object.
*/
static nsresult
GetDOMConstructorsFromOptions(JSContext *cx, HandleObject from, SandboxOptions& options)
{
RootedValue value(cx);
bool found;
nsresult rv = GetPropFromOptions(cx, from, "wantDOMConstructors", &value, &found);
NS_ENSURE_SUCCESS(rv, rv);
if (!found)
return NS_OK;
NS_ENSURE_TRUE(value.isObject(), NS_ERROR_INVALID_ARG);
RootedObject ctors(cx, &value.toObject());
bool ok = options.DOMConstructors.Parse(cx, ctors);
NS_ENSURE_TRUE(ok, NS_ERROR_INVALID_ARG);
return NS_OK;
}
/*
* Helper that parsing the sandbox options object (from) and sets the fields of the incoming options struct (options).
*/
@ -1262,10 +1315,6 @@ ParseOptionsObject(JSContext *cx, jsval from, SandboxOptions &options)
"wantComponents", &options.wantComponents);
NS_ENSURE_SUCCESS(rv, rv);
rv = GetBoolPropFromOptions(cx, optionsObject,
"wantXHRConstructor", &options.wantXHRConstructor);
NS_ENSURE_SUCCESS(rv, rv);
rv = GetBoolPropFromOptions(cx, optionsObject,
"wantExportHelpers", &options.wantExportHelpers);
NS_ENSURE_SUCCESS(rv, rv);
@ -1278,6 +1327,9 @@ ParseOptionsObject(JSContext *cx, jsval from, SandboxOptions &options)
"sameZoneAs", options.sameZoneAs.address());
NS_ENSURE_SUCCESS(rv, rv);
rv = GetDOMConstructorsFromOptions(cx, optionsObject, options);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}

View File

@ -3699,10 +3699,16 @@ bool
IsSandbox(JSObject *obj);
struct SandboxOptions {
struct DOMConstructors {
DOMConstructors() { mozilla::PodZero(this); }
bool Parse(JSContext* cx, JS::HandleObject obj);
bool Define(JSContext* cx, JS::HandleObject obj);
bool XMLHttpRequest;
};
SandboxOptions(JSContext *cx)
: wantXrays(true)
, wantComponents(true)
, wantXHRConstructor(false)
, wantExportHelpers(false)
, proto(xpc_GetSafeJSContext())
, sameZoneAs(xpc_GetSafeJSContext())
@ -3710,11 +3716,11 @@ struct SandboxOptions {
bool wantXrays;
bool wantComponents;
bool wantXHRConstructor;
bool wantExportHelpers;
JS::RootedObject proto;
nsCString sandboxName;
JS::RootedObject sameZoneAs;
DOMConstructors DOMConstructors;
};
JSObject *

View File

@ -10,7 +10,7 @@ var httpbody = "<?xml version='1.0' ?><root>0123456789</root>";
var sb = cu.Sandbox(["http://www.example.com",
"http://localhost:4444/simple"],
{wantXHRConstructor: true});
{ wantDOMConstructors: ["XMLHttpRequest"] });
function createXHR(loc, async)
{

View File

@ -11,7 +11,7 @@ function run_test() {
// Make sure that we can waive on a non-Xrayable object, and that we preserve
// transitive waiving behavior.
var sb = new Cu.Sandbox('http://www.example.com', {wantXHRConstructor: true});
var sb = new Cu.Sandbox('http://www.example.com', { wantDOMConstructors: ["XMLHttpRequest"] });
Cu.evalInSandbox('this.xhr = new XMLHttpRequest();', sb);
Cu.evalInSandbox('this.jsobj = {mynative: xhr};', sb);
do_check_true(!Cu.isXrayWrapper(XPCNativeWrapper.unwrap(sb.xhr)));

View File

@ -5,7 +5,7 @@ function run_test() {
// NB: We use an nsEP here so that we can have access to Components, but still
// have Xray behavior from this scope.
var contentSB = new Cu.Sandbox(['http://www.google.com'],
{wantXHRConstructor: true, wantComponents: true});
{ wantDOMConstructors: ["XMLHttpRequest"], wantComponents: true });
// Make an XHR in the content sandbox.
Cu.evalInSandbox('xhr = new XMLHttpRequest();', contentSB);

View File

@ -1,8 +1,8 @@
function run_test() {
var Cu = Components.utils;
var epsb = new Cu.Sandbox(["http://example.com", "http://example.org"], { wantExportHelpers: true });
subsb = new Cu.Sandbox("http://example.com", { wantXHRConstructor: true });
subsb2 = new Cu.Sandbox("http://example.com", { wantXHRConstructor: true });
subsb = new Cu.Sandbox("http://example.com", { wantDOMConstructors: ["XMLHttpRequest"] });
subsb2 = new Cu.Sandbox("http://example.com", { wantDOMConstructors: ["XMLHttpRequest"] });
xorigsb = new Cu.Sandbox("http://test.com");
epsb.subsb = subsb;