Revision: 5356
Author: [email protected]
Date: Mon Apr 15 15:20:52 2013
Log: SES: Downgrade FIREFOX_15_FREEZE_PROBLEM and partially repair.
https://codereview.appspot.com/8710044
We want to be able to run despite FIREFOX_15_FREEZE_PROBLEM, so
* Rename to FREEZE_IS_FRAME_DEPENDENT since the semantics changed.
* Revise the test to more precisely test for the diagnosed problem and
consider deviations to be new symptoms.
* Add a partial repair which causes Object.freeze to fail if it looks
like it would succeed misleadingly.
* Remove conditional disabling of isFrozen assertion in tests.
[email protected], [email protected]
http://code.google.com/p/google-caja/source/detail?r=5356
Modified:
/trunk/src/com/google/caja/ses/repairES5.js
/trunk/tests/com/google/caja/plugin/es53-test-domado-dom-guest.html
=======================================
--- /trunk/src/com/google/caja/ses/repairES5.js Tue Apr 9 19:24:18 2013
+++ /trunk/src/com/google/caja/ses/repairES5.js Mon Apr 15 15:20:52 2013
@@ -1836,16 +1836,65 @@
}
/**
- * In Firefox 15+, Object.freeze and Object.isFrozen only work for
- * descendents of that same Object.
+ * In Firefox 15+, the [[Extensible]] flag is not correctly readable or
+ * settable from code originating from a different frame than the object.
+ *
+ * This test is written in terms of Object.freeze because that's what we
care
+ * about the correct operation of.
*/
- function test_FIREFOX_15_FREEZE_PROBLEM() {
- var otherObject = inTestFrame(function(window) { return window.Object;
});
- if (!otherObject) { return false; }
+ function test_FREEZE_IS_FRAME_DEPENDENT() {
+ // This test is extensive because it needs to verify not just the
behavior
+ // of the known problem, but that our repair for it was adequate.
- var obj = {};
- otherObject.freeze(obj);
- return !Object.isFrozen(obj);
+ var other = inTestFrame(function(window) { return {
+ Object: window.Object,
+ mutator: window.Function('o', 'o.x = 1;')
+ }; });
+ if (!other) { return false; }
+
+ var frozenInOtherFrame = other.Object();
+ var freezeSucceeded;
+ try {
+ Object.freeze(frozenInOtherFrame);
+ freezeSucceeded = true;
+ } catch (e) {
+ freezeSucceeded = false;
+ }
+ if (Object.isFrozen(frozenInOtherFrame) &&
+ other.Object.isFrozen(frozenInOtherFrame) &&
+ freezeSucceeded) {
+ // desired behavior
+ } else if (!Object.isFrozen(frozenInOtherFrame) &&
+ !other.Object.isFrozen(frozenInOtherFrame) &&
+ !freezeSucceeded) {
+ // adequate repair
+ } else if (Object.isFrozen(frozenInOtherFrame) &&
+ !other.Object.isFrozen(frozenInOtherFrame) &&
+ freezeSucceeded) {
+ // expected problem
+ return true;
+ } else {
+ return 'Other freeze failure: ' +
Object.isFrozen(frozenInOtherFrame) +
+ other.Object.isFrozen(frozenInOtherFrame) + freezeSucceeded;
+ }
+
+ var frozenInThisFrame = Object.freeze({});
+ // This is another sign of the problem, but we can't repair it and
will live
+ // with it.
+ //if (Object.isFrozen(frozenInThisFrame) &&
+ // other.Object.isFrozen(frozenInThisFrame)) {
+ // // desired behavior
+ //} else if (!Object.isFrozen(frozenInThisFrame)) {
+ // return 'Object.isFrozen is broken in this frame';
+ //} else if (!other.Object.isFrozen(frozenInThisFrame)) {
+ // return true;
+ //}
+ other.mutator(frozenInThisFrame);
+ if (frozenInThisFrame.x !== undefined) {
+ return 'mutable in other frame';
+ }
+
+ return false; // all tests passed
}
/**
@@ -2764,6 +2813,35 @@
}
});
}
+
+ function repair_FREEZE_IS_FRAME_DEPENDENT() {
+ // Every operation which sets an object's [[Extensible]] to false.
+ fix('preventExtensions');
+ fix('freeze');
+ fix('seal');
+
+ function fix(prop) {
+ var base = Object[prop];
+ Object.defineProperty(Object, prop, {
+ configurable: true, // attributes per ES5.1 section 15
+ writable: true,
+ value: function frameCheckWrapper(obj) {
+ var parent = obj;
+ while (Object.getPrototypeOf(parent) !== null) {
+ parent = Object.getPrototypeOf(parent);
+ }
+ if (parent === obj || parent === Object.prototype) {
+ // Unsoundly assuming this object is from this frame; we're
trying
+ // to catch mistakes here, not to do a 100% repair.
+ return base(obj);
+ } else {
+ throw new Error(
+ 'Cannot reliably ' + prop + ' object from other frame.');
+ }
+ }
+ });
+ }
+ }
function repair_POP_IGNORES_FROZEN() {
var pop = Array.prototype.pop;
@@ -3484,12 +3562,13 @@
tests: [] // TODO(erights): Add to test262
},
{
- id: 'FIREFOX_15_FREEZE_PROBLEM',
- description: 'Firefox 15 cross-frame freeze problem',
- test: test_FIREFOX_15_FREEZE_PROBLEM,
- repair: void 0,
- preSeverity: severities.NOT_ISOLATED,
- canRepair: false,
+ id: 'FREEZE_IS_FRAME_DEPENDENT',
+ description: 'Object.freeze falsely succeeds on other-frame objects',
+ test: test_FREEZE_IS_FRAME_DEPENDENT,
+ repair: repair_FREEZE_IS_FRAME_DEPENDENT,
+ // NO_KNOWN_EXPLOITness depends on using exactly one SES frame
+ preSeverity: severities.NO_KNOWN_EXPLOIT_SPEC_VIOLATION,
+ canRepair: false, // repair is useful but inadequate
urls: ['https://bugzilla.mozilla.org/show_bug.cgi?id=784892',
'https://bugzilla.mozilla.org/show_bug.cgi?id=674195'],
sections: [],
=======================================
--- /trunk/tests/com/google/caja/plugin/es53-test-domado-dom-guest.html Wed
Apr 10 16:01:07 2013
+++ /trunk/tests/com/google/caja/plugin/es53-test-domado-dom-guest.html Mon
Apr 15 15:20:52 2013
@@ -2192,9 +2192,6 @@
<script type="text/javascript">
jsunitRegister('testInterfaceGlobals',
function testInterfaceGlobals() {
- var freezeBug = ((cajaVM.es5ProblemReports || {})
- .FIREFOX_15_FREEZE_PROBLEM || {}).afterFailure;
-
function assertInstanceof(className, object) {
assertTrue('Class ' + className + ' exists',
className in window);
@@ -2213,10 +2210,8 @@
record.typenames.forEach(function(typename) {
assertInstanceof(typename, record.sample);
- if (!freezeBug) {
- assertTrue(typename + ' prototype frozen',
- Object.isFrozen(window[typename].prototype));
- }
+ assertTrue(typename + ' prototype frozen',
+ Object.isFrozen(window[typename].prototype));
});
});
--
---
You received this message because you are subscribed to the Google Groups "Google Caja Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.