diff --git a/dom/bindings/BindingUtils.cpp b/dom/bindings/BindingUtils.cpp index 5c732251f7a..4708bbb07b8 100644 --- a/dom/bindings/BindingUtils.cpp +++ b/dom/bindings/BindingUtils.cpp @@ -687,7 +687,7 @@ XrayResolveProperty(JSContext* cx, JSObject* wrapper, jsid id, static bool ResolvePrototypeOrConstructor(JSContext* cx, JSObject* wrapper, JSObject* obj, - size_t protoAndIfaceArrayIndex, + size_t protoAndIfaceArrayIndex, unsigned attrs, JSPropertyDescriptor* desc) { JSObject* global = js::GetGlobalForObjectCrossCompartment(obj); @@ -700,7 +700,7 @@ ResolvePrototypeOrConstructor(JSContext* cx, JSObject* wrapper, JSObject* obj, } desc->obj = wrapper; desc->shortid = 0; - desc->attrs = JSPROP_PERMANENT | JSPROP_READONLY; + desc->attrs = attrs; desc->getter = JS_PropertyStub; desc->setter = JS_StrictPropertyStub; desc->value = JS::ObjectValue(*protoOrIface); @@ -718,6 +718,7 @@ XrayResolveNativeProperty(JSContext* cx, JSObject* wrapper, return nativePropertyHooks->mPrototypeID == prototypes::id::_ID_Count || ResolvePrototypeOrConstructor(cx, wrapper, obj, nativePropertyHooks->mPrototypeID, + JSPROP_PERMANENT | JSPROP_READONLY, desc); } @@ -725,7 +726,7 @@ XrayResolveNativeProperty(JSContext* cx, JSObject* wrapper, return nativePropertyHooks->mConstructorID == constructors::id::_ID_Count || ResolvePrototypeOrConstructor(cx, wrapper, obj, nativePropertyHooks->mConstructorID, - desc); + 0, desc); } const NativePropertiesHolder& nativeProperties = diff --git a/dom/tests/mochitest/chrome/test_sandbox_bindings.xul b/dom/tests/mochitest/chrome/test_sandbox_bindings.xul index 10737065dbc..b554268a326 100644 --- a/dom/tests/mochitest/chrome/test_sandbox_bindings.xul +++ b/dom/tests/mochitest/chrome/test_sandbox_bindings.xul @@ -49,6 +49,30 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=741267 } catch (e) { ok(false, "'XMLHttpRequest.prototype' shouldn't throw in a sandbox"); } + try { + var xhr = Components.utils.evalInSandbox("XMLHttpRequest", sandbox); + xhr.prototype = false; + } catch (e) { + ok(true, "'XMLHttpRequest.prototype' should be readonly"); + } + try { + var xhr = Components.utils.evalInSandbox("XMLHttpRequest", sandbox); + delete xhr.prototype; + } catch (e) { + ok(true, "'XMLHttpRequest.prototype' should be permanent"); + } + try { + var xhr = Components.utils.evalInSandbox("XMLHttpRequest.prototype", sandbox); + xhr.constructor = "ok"; + } catch (e) { + is(xhr.constructor, "ok", "'XMLHttpRequest.prototype.constructor' should be writeable"); + } + try { + var xhr = Components.utils.evalInSandbox("XMLHttpRequest.prototype", sandbox); + delete xhr.constructor; + } catch (e) { + is(xhr.constructor, undefined, "'XMLHttpRequest.prototype.constructor' should be permanent"); + } try { var xhr = Components.utils.evalInSandbox("XMLHttpRequest", sandbox); is(xhr, "[object XrayWrapper " + XMLHttpRequest + "]", "'XMLHttpRequest' in a sandbox should return the XMLHttpRequest interface object");