Bug 839792 - Revert Tamper-proofing. r=bz

This reverts bug 821850 part 16, and updates the tests accordingly.
This commit is contained in:
Bobby Holley 2013-02-13 19:16:19 +01:00
parent 4d172878d3
commit 576ed40412
6 changed files with 26 additions and 42 deletions

View File

@ -72,12 +72,6 @@ function waitForClearHistory(aCallback) {
function waitForSearchComplete(aCallback) {
info("Waiting for onSearchComplete");
// onSearchComplete is implemented as an XBL method, which is readonly on
// the prototype. This means that setting it on the derived/bound object
// is an error in strict mode if there's no |own| property. Use defineProperty
// to explicitly make it so.
Object.defineProperty(gURLBar, 'onSearchComplete', { value: gURLBar.onSearchComplete,
writable: true, configurable: true });
let onSearchComplete = gURLBar.onSearchComplete;
registerCleanupFunction(function () {
gURLBar.onSearchComplete = onSearchComplete;

View File

@ -1204,14 +1204,6 @@ nsXBLBinding::DoInitJSClass(JSContext *cx, JSObject *global, JSObject *obj,
return NS_ERROR_OUT_OF_MEMORY;
}
// Make the class object a permanent and read-only property on the global.
// Xrays rely on this to find the correct binding functions.
JSBool found = false;
if (!JS_SetPropertyAttributes(cx, global, c->name,
JSPROP_READONLY | JSPROP_PERMANENT, &found))
return NS_ERROR_FAILURE;
MOZ_ASSERT(found);
// Keep this proto binding alive while we're alive. Do this first so that
// we can guarantee that in XBLFinalize this will be non-null.
// Note that we can't just store aProtoBinding in the private and

View File

@ -44,8 +44,7 @@ public:
unsigned AccessorAttributes() const {
return JSPROP_SHARED | JSPROP_GETTER | JSPROP_SETTER |
JSPROP_READONLY | JSPROP_PERMANENT |
(mJSAttributes & JSPROP_ENUMERATE);
(mJSAttributes & (JSPROP_ENUMERATE | JSPROP_PERMANENT));
}
bool IsEmpty() const { return mFieldTextLength == 0; }

View File

@ -121,8 +121,7 @@ nsXBLProtoImplMethod::InstallMember(JSContext* aCx,
!::JS_DefineUCProperty(aCx, aTargetClassObject,
static_cast<const jschar*>(mName),
name.Length(), OBJECT_TO_JSVAL(method),
NULL, NULL,
JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT)) {
NULL, NULL, JSPROP_ENUMERATE)) {
return NS_ERROR_OUT_OF_MEMORY;
}
}

View File

@ -171,7 +171,7 @@ nsXBLProtoImplProperty::InstallMember(JSContext *aCx,
name.Length(), JSVAL_VOID,
JS_DATA_TO_FUNC_PTR(JSPropertyOp, getter),
JS_DATA_TO_FUNC_PTR(JSStrictPropertyOp, setter),
mJSAttributes | JSPROP_PERMANENT | JSPROP_READONLY))
mJSAttributes))
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;

View File

@ -129,37 +129,36 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=821850
proto.someExpando = 201;
is(bound.someExpando, 201, "Can stick non-XBL properties on the proto");
function checkTamperProof(obj, propName, desc) {
// Previously, this code checked that content couldn't tamper with its XBL
// prototype. But we decided to allow this to reduce regression risk, so for
// now just check that this works.
function checkMayTamper(obj, propName, desc) {
var accessor = !('value' in Object.getOwnPropertyDescriptor(obj, propName));
if (!accessor)
checkRejected(function() { obj[propName] = function() {} }, desc + ": assign");
checkRejected(function() { Object.defineProperty(obj, propName, {value: 3}) }, desc + ": define with value");
checkRejected(function() { Object.defineProperty(obj, propName, {writable: true}) }, desc + ": make writable");
checkRejected(function() { Object.defineProperty(obj, propName, {configurable: true}) }, desc + ": make configurable");
checkRejected(function() { Object.defineProperty(obj, propName, {get: function() {}}) }, desc + ": define with getter");
checkRejected(function() { Object.defineProperty(obj, propName, {set: function() {}}) }, desc + ": define with setter");
checkAllowed(function() { obj[propName] = function() {} }, desc + ": assign");
checkAllowed(function() { Object.defineProperty(obj, propName, {configurable: true, value: 3}) }, desc + ": define with value");
checkAllowed(function() { Object.defineProperty(obj, propName, {configurable: true, writable: true}) }, desc + ": make writable");
checkAllowed(function() { Object.defineProperty(obj, propName, {configurable: true}) }, desc + ": make configurable");
checkAllowed(function() { Object.defineProperty(obj, propName, {configurable: true, get: function() {}}) }, desc + ": define with getter");
checkAllowed(function() { Object.defineProperty(obj, propName, {configurable: true, set: function() {}}) }, desc + ": define with setter");
// Windows are implemented as proxies, and Proxy::delete_ doesn't currently
// pass strict around. Work around it in the window.binding case by just
// checking if delete returns false.
// manually.
if (/testBinding/.exec(propName))
is(delete obj[propName], false, "deleting prototype from window fails");
else
checkRejected(function() { delete obj[propName]; }, desc + ": delete");
checkAllowed(function() { delete obj[propName]; }, desc + ": delete");
if (!accessor)
checkRejected(function() { obj[propName] = function() {} }, desc + ": assign (again)");
checkAllowed(function() { obj[propName] = function() {} }, desc + ": assign (again)");
}
// Make sure we can't modify XBL props on the prototype object, since Xrays
// use it to perform lookups.
checkTamperProof(proto, 'method', "XBL Proto Method");
checkTamperProof(proto, 'prop', "XBL Proto Prop");
checkTamperProof(proto, 'primitiveField', "XBL Field Accessor");
// Make sure content can do whatever it wants with the prototype.
checkMayTamper(proto, 'method', "XBL Proto Method");
checkMayTamper(proto, 'prop', "XBL Proto Prop");
checkMayTamper(proto, 'primitiveField', "XBL Field Accessor");
// Make sure that callers can't tamper with the prototype's definition on
// the window.
// As above, check that content can do what it wants with the prototype's
// property on the global.
var protoName, count = 0;
for (var k of Object.getOwnPropertyNames(window)) {
if (!/testBinding/.exec(k))
@ -168,10 +167,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=821850
protoName = k;
}
is(count, 1, "Should be exactly one prototype object");
checkTamperProof(window, protoName, "XBL prototype prop on window");
checkMayTamper(window, protoName, "XBL prototype prop on window");
// Tamper with the derived object. This doesn't affect the XBL scope thanks
// to Xrays.
bound.method = function() { return "heh"; };
Object.defineProperty(bound, 'method', {value: function() { return "hah" }});
Object.defineProperty(bound, 'prop', {value: "redefined"});
bound.primitiveField = 321;
@ -185,9 +185,9 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=821850
catch (e) { ok(!!/denied|insecure/.exec(e), "Should have thrown security exception: " + e); }
}
function checkRejected(fn, desc) {
try { fn(); ok(false, desc + ": Should have thrown"); }
catch (e) { ok(!!/configurable|read-only/.exec(e), desc + ": Threw correctly: " + e); }
function checkAllowed(fn, desc) {
try { fn(); ok(true, desc + ": Didn't throw"); }
catch (e) { ok(false, desc + ": Threw: " + e); }
}
function setup() {