Bug 1052139 - Adjust tests to tolerate an immutable global object prototype chain. r=bz

This commit is contained in:
Jeff Walden 2015-09-29 08:49:26 -07:00
parent 3155be71a3
commit 148998fa87
41 changed files with 306 additions and 165 deletions

View File

@ -0,0 +1,7 @@
function globalPrototypeChainIsMutable()
{
if (typeof immutablePrototypesEnabled !== "function")
return true;
return !immutablePrototypesEnabled();
}

View File

@ -1,7 +1,10 @@
// |jit-test| error:RangeError;
load(libdir + "immutable-prototype.js");
if (!this.hasOwnProperty("TypedObject"))
throw new RangeError();
this.__proto__ = Proxy.create({});
if (globalPrototypeChainIsMutable())
this.__proto__ = Proxy.create({});
new TypedObject.StructType;

View File

@ -1,10 +1,16 @@
// Binary: cache/js-dbg-32-fadb38356e0f-linux
// Flags: -j
//
this.__proto__ = Proxy.create({
has:function(){return false},
set:function(){}
});
load(libdir + "immutable-prototype.js");
if (globalPrototypeChainIsMutable())
{
this.__proto__ = Proxy.create({
has:function(){return false},
set:function(){}
});
}
(function(){
eval("(function(){ for(var j=0;j<6;++j) if(j%2==1) p=0; })")();
})()

View File

@ -3,4 +3,9 @@
// Binary: cache/js-dbg-64-b22e82ce2364-linux
// Flags:
//
print(__proto__ = Proxy.create(this, ""))
load(libdir + "immutable-prototype.js");
if (globalPrototypeChainIsMutable())
__proto__ = Proxy.create(this, "");
throw new InternalError("fallback");

View File

@ -1,6 +1,8 @@
// Binary: cache/js-dbg-64-21e90d198613-linux
// Flags:
//
load(libdir + "immutable-prototype.js");
var x = {};
function jsTestDriverEnd()
{
@ -9,27 +11,35 @@ function jsTestDriverEnd()
}
x = {};
}
var o2 = this;
var o5 = Function.prototype.__proto__;
var o5 = Object.prototype;
function f28(o) {
var _var_ = o;
_var_['__proto_'+'_'] = null;
}
function _var_(
f7) { function f15(o) {
var _var_ = o;
if (globalPrototypeChainIsMutable())
_var_['__proto_'+'_'] = null;
}
function _var_(f7) {
function f15(o) {}
}
function f39(o) {
for(var j=0; j<5; j++) {
try { o.__proto__ = o2; } catch(e) {}
}
for(var j=0; j<5; j++) {
try { o.__proto__ = o2; } catch(e) {}
}
}
for(var i=0; i<11; i++) {
f39(o5);
f28(o2);
f39(o5);
f28(o2);
}
jsTestDriverEnd();
{
delete Function;
}
jsTestDriverEnd();

View File

@ -1,11 +1,14 @@
// Binary: cache/js-dbg-32-d5fcfa622f16-linux
// Flags:
//
load(libdir + "immutable-prototype.js");
Function.toLocaleString.__proto__ = null
y = {}.__proto__
y.p = function() {}
y.__defineSetter__("", function() {})
y.__proto__ = Function.toLocaleString
if (globalPrototypeChainIsMutable())
y.__proto__ = Function.toLocaleString;
function b(a) {
this.__proto__ = a;
Object.freeze(this)

View File

@ -1,9 +1,13 @@
// Binary: cache/js-dbg-64-a37127f33d22-linux
// Flags: -m -n
//
a = {}
b = __proto__
load(libdir + "immutable-prototype.js");
a = {};
b = __proto__;
for (i = 0; i < 9; i++) {
__proto__ = a
a.__proto__ = b
if (globalPrototypeChainIsMutable()) {
__proto__ = a;
a.__proto__ = b
}
}

View File

@ -1,9 +1,13 @@
// Binary: cache/js-dbg-64-1210706b4576-linux
// Flags:
//
load(libdir + "immutable-prototype.js");
if (globalPrototypeChainIsMutable()) {
this.__proto__ = null;
Object.prototype.__proto__ = this;
}
this.__proto__ = null;
Object.prototype.__proto__ = this;
function exploreProperties(obj) {
var props = [];
for (var o = obj; o; o = Object.getPrototypeOf(o)) {

View File

@ -1,9 +1,12 @@
// Binary: cache/js-dbg-32-c5b90ea7e475-linux
// Flags: -m -n -a
//
load(libdir + "immutable-prototype.js");
var save__proto__ = __proto__;
__proto__ = save__proto__;
if (globalPrototypeChainIsMutable())
__proto__ = save__proto__;
function bar(x, y) {
return x + y;
}

View File

@ -1,7 +1,11 @@
// Binary: cache/js-dbg-64-4de07a341aab-linux
// Flags: -m -n -a
//
this.__proto__ = [];
load(libdir + "immutable-prototype.js");
if (globalPrototypeChainIsMutable())
this.__proto__ = [];
var msPerDay = 86400000;
for ( var time = 0, year = 1969; year >= 0; year-- ) {
time -= TimeInYear(year);

View File

@ -1,9 +1,13 @@
// Binary: cache/js-dbg-32-1fd6c40d3852-linux
// Flags: --ion-eager
//
load(libdir + "immutable-prototype.js");
function TestCase(n, d, e, a) {};
if (globalPrototypeChainIsMutable())
this.__proto__ = [];
var msPerDay = 86400000;
var TIME_1900 = -2208988800000;
function TimeFromYear( y ) {

View File

@ -1,14 +0,0 @@
// |jit-test| error:InternalError
// Binary: cache/js-dbg-64-1761f4a9081c-linux
// Flags: --ion-eager
//
p = Proxy.create({
has: function() function r() s += ''
})
Object.prototype.__proto__ = p
function TestCase(n) {
this.name = n
}
new TestCase()

View File

@ -1,7 +1,9 @@
// Accessing a name that isn't a global property is a ReferenceError,
// even if a proxy is on the global's prototype chain.
load(libdir + "asserts.js");
load(libdir + "immutable-prototype.js");
var g = newGlobal();
g.__proto__ = {};
if (globalPrototypeChainIsMutable())
g.__proto__ = {};
assertThrowsInstanceOf(() => g.eval("s += ''"), g.ReferenceError);

View File

@ -1,10 +1,14 @@
load(libdir + "immutable-prototype.js");
var n = 0;
this.__proto__ = new Proxy({}, {
has: function () {
if (++n === 2)
return false;
a = 0;
}
});
if (globalPrototypeChainIsMutable()) {
this.__proto__ = new Proxy({}, {
has: function () {
if (++n === 2)
return false;
a = 0;
}
});
}
a = 0;
assertEq(a, 0);

View File

@ -1,9 +1,13 @@
// |jit-test| error: m is not defined
this.__proto__ = Proxy.create({
has:function(){
try {
aa0 = Function(undefined);
} catch (aa) {}
}
});
load(libdir + "immutable-prototype.js");
if (globalPrototypeChainIsMutable()) {
this.__proto__ = Proxy.create({
has:function(){
try {
aa0 = Function(undefined);
} catch (aa) {}
}
});
}
m();

View File

@ -1,5 +1,9 @@
this.__proto__ = [];
print(length);
load(libdir + "immutable-prototype.js");
Object.prototype.length = 0;
if (globalPrototypeChainIsMutable())
this.__proto__ = [];
function f() {
eval('Math');
length = 2;

View File

@ -1,4 +1,4 @@
this.__proto__ = null;
Function.prototype.__proto__ = null;
function testLenientAndStrict(code, lenient_pred, strict_pred) {
return (strict_pred("'use strict'; " + code) &&

View File

@ -1,4 +1,8 @@
this.__proto__ = [];
load(libdir + "immutable-prototype.js");
if (globalPrototypeChainIsMutable())
this.__proto__ = null;
gczeal(2);
gc();
var box = evalcx('lazy');

View File

@ -1,3 +1,11 @@
this.__proto__ = null;
Object.prototype.__proto__ = this;
for (var x in Object.prototype);
load(libdir + "immutable-prototype.js");
if (globalPrototypeChainIsMutable()) {
this.__proto__ = null;
Object.prototype.__proto__ = this;
}
for (var y in Object.prototype)
continue;
for (var x in this)
continue;

View File

@ -1,11 +1,15 @@
c = (0).__proto__
load(libdir + "immutable-prototype.js");
c = Number.prototype;
function f(o) {
o.__proto__ = null
for (x in o) {}
}
for (i = 0; i < 9; i++) {
f(c)
Function.prototype.__proto__.__proto__ = c
for (x in Function.prototype.__proto__) {}
f(Math.__proto__)
if (globalPrototypeChainIsMutable())
Object.prototype.__proto__ = c;
for (x in Object.prototype)
continue;
f(Math.__proto__);
}

View File

@ -1,3 +1,5 @@
load(libdir + "immutable-prototype.js");
var summary = '';
var actual = '';
gcPreserveCode()
@ -12,7 +14,8 @@ var p = Proxy.create({
has : function(id) {},
set : function() {}
});
Object.prototype.__proto__ = p;
if (globalPrototypeChainIsMutable())
Object.prototype.__proto__ = p;
new TestCase;
var expect = '';
reportCompare(expect, actual, summary);

View File

@ -1,10 +1,21 @@
// |jit-test| error: InternalError
// |jit-test| error: TypeError
load(libdir + "immutable-prototype.js");
p = Proxy.create({
has: function() function r() s += ''
})
Object.prototype.__proto__ = p
function TestCase(n) {
this.name = n
has: function() { return function r() { return (s += ''); } },
get: function() { throw new TypeError("hit get"); }
});
if (globalPrototypeChainIsMutable()) {
Object.prototype.__proto__ = p;
} else {
Object.defineProperty(Object.prototype, "name",
{ set(v) { throw new TypeError("hit name"); },
enumerable: true,
configurable: true });
}
new TestCase()
function TestCase(n) {
this.name = n;
}
new TestCase();

View File

@ -1,4 +1,6 @@
// |jit-test| error: 42
load(libdir + "immutable-prototype.js");
function f(y) {}
for each(let e in newGlobal()) {
if (e.name === "quit" || e.name == "readline" || e.name == "terminate" ||
@ -10,18 +12,22 @@ for each(let e in newGlobal()) {
} catch (r) {}
}
(function() {
arguments.__proto__.__proto__ = newGlobal()
arguments;
if (globalPrototypeChainIsMutable())
Object.prototype.__proto__ = newGlobal()
function f(y) {
y()
}
for each(b in []) {
if (b.name === "quit" || b.name == "readline" || b.name == "terminate" ||
b.name == "nestedShell")
continue;
try {
f(b)
} catch (e) {}
}
var arr = [];
arr.__proto__ = newGlobal();
for each (b in arr) {
if (b.name === "quit" || b.name == "readline" || b.name == "terminate" ||
b.name == "nestedShell")
continue;
try {
f(b)
} catch (e) {}
}
})();
throw 42;

View File

@ -1,11 +1,21 @@
load(libdir + "immutable-prototype.js");
var count = 0;
Object.defineProperty(__proto__, "__iterator__", {
get: (function() {
count++;
})
})
__proto__ = (function(){})
if (globalPrototypeChainIsMutable()) {
Object.defineProperty(__proto__, "__iterator__", {
get: (function() {
count++;
})
});
} else {
count = 7;
}
if (globalPrototypeChainIsMutable())
__proto__ = (function(){});
for (var m = 0; m < 7; ++m) {
for (var a in 6) {}
}
assertEq(count, 7);

View File

@ -1,5 +1,10 @@
load(libdir + "immutable-prototype.js");
// Random chosen test: js/src/jit-test/tests/auto-regress/bug700295.js
__proto__ = null
Object.prototype.__proto__ = this
if (globalPrototypeChainIsMutable()) {
__proto__ = null;
Object.prototype.__proto__ = this;
}
// Random chosen test: js/src/jit-test/tests/debug/Memory-takeCensus-05.js
Debugger(newGlobal()).memory.takeCensus()
Debugger(newGlobal()).memory.takeCensus();

View File

@ -1,12 +1,18 @@
this.__proto__ = [];
load(libdir + "immutable-prototype.js");
if (globalPrototypeChainIsMutable())
this.__proto__ = [];
var T = TypedObject;
var ObjectStruct = new T.StructType({f: T.Object});
var o = new ObjectStruct();
minorgc();
function writeObject(o, v) {
o.f = v;
assertEq(typeof o.f, "object");
}
for (var i = 0; i < 5; i++)
writeObject(o, { toString: function() { return "helo"} }
);
writeObject(o, { toString: function() { return "helo"; } });

View File

@ -1,5 +1,8 @@
load(libdir + "immutable-prototype.js");
function f2() {
__proto__ = null;
if (globalPrototypeChainIsMutable())
__proto__ = null;
}
for (var j = 0; j < 50; j++)

View File

@ -1,7 +1,7 @@
var p = Proxy.create({
has : function(id) {}
});
Object.prototype.__proto__ = p;
RegExp.prototype.__proto__ = p;
function f() {
if (/a/.exec("a"))
return 1;

View File

@ -1,8 +1,11 @@
__proto__ = Function();
load(libdir + "immutable-prototype.js");
if (globalPrototypeChainIsMutable())
__proto__ = Function();
eval("\
var MS = 16;\
addNewTestCase(new Date(1899,11,31,16,0,0), \"new Date(1899,11,31,16,0,0)\",\
typeof UTC_DAY == 'undefined');\
addNewTestCase(new Date(1899,11,31,16,0,0), \"new Date(1899,11,31,16,0,0)\", typeof UTC_DAY == 'undefined');\
function addNewTestCase( DateCase, DateString, ResultArray ) {\
ResultArray[MS];\
}\

View File

@ -1,9 +1,14 @@
// |jit-test| error: ReferenceError
load(libdir + "immutable-prototype.js");
p = Proxy.create({
has: function() {},
set: function() {}
})
Object.prototype.__proto__ = p
});
if (globalPrototypeChainIsMutable())
Object.prototype.__proto__ = p;
n = [];
(function() {
var a = [];

View File

@ -1,17 +1,23 @@
function TestCase(n, d, e, a)
load(libdir + "immutable-prototype.js");
function TestCase(n, d, e, a) {
this.name=n;
return n;
}
function reportCompare (expected, actual, description) {
new TestCase
}
reportCompare(true, "isGenerator" in Function, "Function.prototype.isGenerator present");
var p = Proxy.create({
has : function(id) {},
set : function(obj, id, v, rec) {}
});
function test() {
Object.prototype.__proto__=null
TestCase.prototype.__proto__=null
if (new TestCase)
Object.prototype.__proto__=p
TestCase.prototype.__proto__=p
}
test();
new TestCase;

View File

@ -1,5 +1,6 @@
// A proxy on the prototype chain of the global can't intercept lazy definition of globals.
// Thanks to André Bargull for this one.
load(libdir + "immutable-prototype.js");
var global = this;
var status = "pass";
@ -7,6 +8,9 @@ var handler = {
get: function get(t, pk, r) { status = "FAIL get"; },
has: function has(t, pk) { status = "FAIL has"; }
};
Object.prototype.__proto__ = new Proxy(Object.create(null), handler);
if (globalPrototypeChainIsMutable())
Object.prototype.__proto__ = new Proxy(Object.create(null), handler);
Map;
assertEq(status, "pass");

View File

@ -1,5 +1,6 @@
// A proxy on the prototype chain of the global should not observe anything at
// all about lazy resolution of globals.
load(libdir + "immutable-prototype.js");
var global = this;
var status = "pass";
@ -16,12 +17,17 @@ var handler = new Proxy({}, metaHandler);
// 2. Then we create a proxy using 'handler' as its handler. This means the test
// will fail if *any* method of the handler is called, not just get/has/invoke.
var angryProxy = new Proxy(Object.create(null), handler);
this.__proto__ = angryProxy;
Object.prototype.__proto__ = angryProxy;
if (globalPrototypeChainIsMutable()) {
this.__proto__ = angryProxy;
Object.prototype.__proto__ = angryProxy;
}
// Trip the alarm once, to make sure the proxies are working.
this.nonExistingProperty;
assertEq(status, "SMASH");
if (globalPrototypeChainIsMutable())
assertEq(status, "SMASH");
else
assertEq(status, "pass");
// OK. Reset the status and run the actual test.
status = "pass";

View File

@ -1,23 +1,29 @@
// The global object can be the receiver passed to the get and set traps of a Proxy.
var global = this;
var proto = Object.getPrototypeOf(global);
var gets = 0, sets = 0;
Object.setPrototypeOf(global, new Proxy(proto, {
has(t, id) {
return id === "bareword" || Reflect.has(t, id);
},
get(t, id, r) {
gets++;
assertEq(r, global);
return Reflect.get(t, id, r);
},
set(t, id, v, r) {
sets++;
assertEq(r, global);
return Reflect.set(t, id, v, r);
}
}));
try {
Object.setPrototypeOf(global, new Proxy(proto, {
has(t, id) {
return id === "bareword" || Reflect.has(t, id);
},
get(t, id, r) {
gets++;
assertEq(r, global);
return Reflect.get(t, id, r);
},
set(t, id, v, r) {
sets++;
assertEq(r, global);
return Reflect.set(t, id, v, r);
}
}));
} catch (e) {
global.bareword = undefined;
gets = 1;
sets = 1;
}
assertEq(bareword, undefined);
assertEq(gets, 1);

View File

@ -36,6 +36,13 @@ if (typeof setImmutablePrototype !== "function")
}
}
if (typeof immutablePrototypesEnabled !== "function" &&
typeof SpecialPowers !== "undefined")
{
immutablePrototypesEnabled =
SpecialPowers.Cu.getJSTestingFunctions().immutablePrototypesEnabled;
}
if (typeof wrap !== "function")
{
// good enough
@ -87,10 +94,10 @@ function checkPrototypeMutationFailure(obj, desc)
function runNormalTests(global)
{
if (typeof setImmutablePrototype !== "function" ||
(typeof immutablePrototypesEnabled === "function" &&
!immutablePrototypesEnabled()))
typeof immutablePrototypesEnabled !== "function" ||
!immutablePrototypesEnabled())
{
print("no usable setImmutablePrototype function available, skipping tests");
print("no testable setImmutablePrototype function available, skipping tests");
return;
}

View File

@ -12,8 +12,8 @@ var expect = 'No Crash';
printBugNumber(BUGNUMBER);
printStatus (summary);
this.__proto__ = [];
this.unwatch("x");
var obj = Object.create([]);
obj.unwatch("x");
if (typeof reportCompare === "function")
reportCompare(true, true);

View File

@ -26,7 +26,7 @@ function test()
}
else
{
window.__proto__.__proto__ = [{}];
try { window.__proto__.__proto__ = [{}]; } catch (e) {}
for (var j in window);
}
reportCompare(expect, actual, summary);

View File

@ -12,19 +12,15 @@ var expect = '';
printBugNumber(BUGNUMBER);
printStatus (summary);
var save__proto__ = __proto__;
try
{
for (x in function(){}) ([]);
this.__defineGetter__("x", Function);
__proto__ = x;
prototype += [];
var obj = Object.create(x);
obj.prototype += [];
}
catch(ex)
{
}
__proto__ = save__proto__;
reportCompare(expect, actual, summary);

View File

@ -12,18 +12,14 @@ var expect = '';
printBugNumber(BUGNUMBER);
printStatus (summary);
var save__proto__ = __proto__;
try
{
Function.prototype.prototype;
__proto__ = Function();
prototype = prototype;
var obj = Object.create(Function());
obj.prototype = obj.prototype;
}
catch(ex)
{
}
__proto__ = save__proto__;
reportCompare(expect, actual, summary);

View File

@ -12,21 +12,18 @@ var expect = '';
printBugNumber(BUGNUMBER);
printStatus (summary);
var save__proto__ = __proto__;
var obj;
try
{
Function.prototype.prototype = function() { return 42; }
__proto__ = Function();
prototype = prototype;
obj = Object.create(Function());
obj.prototype = obj.prototype;
}
catch(ex)
{
}
expect = 'object';
actual = typeof prototype;
__proto__ = save__proto__;
actual = typeof obj.prototype;
reportCompare(expect, actual, summary);

View File

@ -64,24 +64,26 @@ Object.defineProperty(Object.prototype, "__proto__", { set: undefined });
performProtoTests("behavior after making Object.prototype.__proto__'s " +
"[[Set]] === undefined");
try
{
var superProto = Object.create(null);
poisonProto(superProto);
setProto.call(Object.prototype, superProto);
var superProto = Object.create(null);
poisonProto(superProto);
setProto.call(Object.prototype, superProto);
performProtoTests("behavior after mutating Object.prototype.[[Prototype]]");
performProtoTests("behavior after mutating Object.prototype.[[Prototype]]");
// Note: The handler below will have to be updated to exempt a scriptable
// getPrototypeOf trap (to instead consult the target whose [[Prototype]]
// is safely non-recursive), if we ever implement one.
var death = new Proxy(Object.create(null),
new Proxy({}, { get: function() { passed = false; } }));
// Note: The handler below will have to be updated to exempt a scriptable
// getPrototypeOf trap (to instead consult the target whose [[Prototype]]
// is safely non-recursive), if we ever implement one.
var death = new Proxy(Object.create(null),
new Proxy({}, { get: function() { passed = false; } }));
setProto.call(Object.prototype, death);
performProtoTests("behavior after making Object.prototype.[[Prototype]] a " +
"proxy that throws for any access");
setProto.call(Object.prototype, death);
performProtoTests("behavior after making Object.prototype.[[Prototype]] a " +
"proxy that throws for any access");
}
catch (e) {}
if (typeof reportCompare === "function")
reportCompare(true, true);