Tests for evil side-effects during 'internal methods'.
R=kmillikin@chromium.org BUG= TEST= Review URL: http://codereview.chromium.org/8200002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@9558 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
313f9505b4
commit
357b45dea5
@ -33,9 +33,9 @@
|
||||
|
||||
// Helper.
|
||||
|
||||
function TestWithProxies(test, handler) {
|
||||
test(handler, Proxy.create)
|
||||
test(handler, function(h) {return Proxy.createFunction(h, function() {})})
|
||||
function TestWithProxies(test, x, y, z) {
|
||||
test(Proxy.create, x, y, z)
|
||||
test(function(h) {return Proxy.createFunction(h, function() {})}, x, y, z)
|
||||
}
|
||||
|
||||
|
||||
@ -48,7 +48,7 @@ function TestGetOwnProperty(handler) {
|
||||
TestWithProxies(TestGetOwnProperty2, handler)
|
||||
}
|
||||
|
||||
function TestGetOwnProperty2(handler, create) {
|
||||
function TestGetOwnProperty2(create, handler) {
|
||||
var p = create(handler)
|
||||
assertEquals(42, Object.getOwnPropertyDescriptor(p, "a").value)
|
||||
assertEquals("a", key)
|
||||
@ -91,7 +91,7 @@ function TestGetOwnPropertyThrow(handler) {
|
||||
TestWithProxies(TestGetOwnPropertyThrow2, handler)
|
||||
}
|
||||
|
||||
function TestGetOwnPropertyThrow2(handler, create) {
|
||||
function TestGetOwnPropertyThrow2(create, handler) {
|
||||
var p = create(handler)
|
||||
assertThrows(function(){ Object.getOwnPropertyDescriptor(p, "a") }, "myexn")
|
||||
assertThrows(function(){ Object.getOwnPropertyDescriptor(p, 77) }, "myexn")
|
||||
@ -130,7 +130,7 @@ function TestGet(handler) {
|
||||
TestWithProxies(TestGet2, handler)
|
||||
}
|
||||
|
||||
function TestGet2(handler, create) {
|
||||
function TestGet2(create, handler) {
|
||||
var p = create(handler)
|
||||
assertEquals(42, p.a)
|
||||
assertEquals("a", key)
|
||||
@ -191,7 +191,7 @@ function TestGetCall(handler) {
|
||||
TestWithProxies(TestGetCall2, handler)
|
||||
}
|
||||
|
||||
function TestGetCall2(handler, create) {
|
||||
function TestGetCall2(create, handler) {
|
||||
var p = create(handler)
|
||||
assertEquals(55, p.f())
|
||||
assertEquals(55, p["f"]())
|
||||
@ -277,7 +277,7 @@ function TestGetThrow(handler) {
|
||||
TestWithProxies(TestGetThrow2, handler)
|
||||
}
|
||||
|
||||
function TestGetThrow2(handler, create) {
|
||||
function TestGetThrow2(create, handler) {
|
||||
var p = create(handler)
|
||||
assertThrows(function(){ p.a }, "myexn")
|
||||
assertThrows(function(){ p["b"] }, "myexn")
|
||||
@ -338,11 +338,11 @@ TestGetThrow(Proxy.create({
|
||||
var key
|
||||
var val
|
||||
|
||||
function TestSet(handler, create) {
|
||||
function TestSet(handler) {
|
||||
TestWithProxies(TestSet2, handler)
|
||||
}
|
||||
|
||||
function TestSet2(handler, create) {
|
||||
function TestSet2(create, handler) {
|
||||
var p = create(handler)
|
||||
assertEquals(42, p.a = 42)
|
||||
assertEquals("a", key)
|
||||
@ -425,11 +425,11 @@ TestSet(Proxy.create({
|
||||
}))
|
||||
|
||||
|
||||
function TestSetThrow(handler, create) {
|
||||
function TestSetThrow(handler) {
|
||||
TestWithProxies(TestSetThrow2, handler)
|
||||
}
|
||||
|
||||
function TestSetThrow2(handler, create) {
|
||||
function TestSetThrow2(create, handler) {
|
||||
var p = create(handler)
|
||||
assertThrows(function(){ p.a = 42 }, "myexn")
|
||||
assertThrows(function(){ p["b"] = 42 }, "myexn")
|
||||
@ -548,11 +548,11 @@ TestSetThrow(Proxy.create({
|
||||
var key
|
||||
var val
|
||||
|
||||
function TestSetForDerived(handler, create) {
|
||||
function TestSetForDerived(handler) {
|
||||
TestWithProxies(TestSetForDerived2, handler)
|
||||
}
|
||||
|
||||
function TestSetForDerived2(handler, create) {
|
||||
function TestSetForDerived2(create, handler) {
|
||||
var p = create(handler)
|
||||
var o = Object.create(p, {x: {value: 88, writable: true},
|
||||
'1': {value: 89, writable: true}})
|
||||
@ -625,6 +625,40 @@ TestSetForDerived({
|
||||
})
|
||||
|
||||
|
||||
// Evil proxy-induced side-effects shouldn't crash.
|
||||
// TODO(rossberg): proper behaviour isn't really spec'ed yet, so ignore results.
|
||||
|
||||
TestWithProxies(function(create) {
|
||||
var calls = 0
|
||||
var handler = {
|
||||
getPropertyDescriptor: function() {
|
||||
++calls
|
||||
return (calls % 2 == 1)
|
||||
? {get: function() { return 5 }, configurable: true}
|
||||
: {set: function() { return false }, configurable: true}
|
||||
}
|
||||
}
|
||||
var p = create(handler)
|
||||
var o = Object.create(p)
|
||||
// Make proxy prototype property read-only after CanPut check.
|
||||
try { o.x = 4 } catch (e) { assertInstanceof(e, Error) }
|
||||
})
|
||||
|
||||
TestWithProxies(function(create) {
|
||||
var handler = {
|
||||
getPropertyDescriptor: function() {
|
||||
Object.defineProperty(o, "x", {get: function() { return 5 }});
|
||||
return {set: function() {}}
|
||||
}
|
||||
}
|
||||
var p = create(handler)
|
||||
var o = Object.create(p)
|
||||
// Make object property read-only after CanPut check.
|
||||
try { o.x = 4 } catch (e) { assertInstanceof(e, Error) }
|
||||
})
|
||||
|
||||
|
||||
|
||||
// TODO(rossberg): TestSetReject, returning false
|
||||
// TODO(rossberg): TestGetProperty, TestSetProperty
|
||||
|
||||
@ -639,7 +673,7 @@ function TestDefine(handler) {
|
||||
TestWithProxies(TestDefine2, handler)
|
||||
}
|
||||
|
||||
function TestDefine2(handler, create) {
|
||||
function TestDefine2(create, handler) {
|
||||
var p = create(handler)
|
||||
assertEquals(p, Object.defineProperty(p, "a", {value: 44}))
|
||||
assertEquals("a", key)
|
||||
@ -735,7 +769,7 @@ function TestDefineThrow(handler) {
|
||||
TestWithProxies(TestDefineThrow2, handler)
|
||||
}
|
||||
|
||||
function TestDefineThrow2(handler, create) {
|
||||
function TestDefineThrow2(create, handler) {
|
||||
var p = create(handler)
|
||||
assertThrows(function(){ Object.defineProperty(p, "a", {value: 44})}, "myexn")
|
||||
assertThrows(function(){ Object.defineProperty(p, 0, {value: 44})}, "myexn")
|
||||
@ -785,7 +819,7 @@ function TestDelete(handler) {
|
||||
TestWithProxies(TestDelete2, handler)
|
||||
}
|
||||
|
||||
function TestDelete2(handler, create) {
|
||||
function TestDelete2(create, handler) {
|
||||
var p = create(handler)
|
||||
assertEquals(true, delete p.a)
|
||||
assertEquals("a", key)
|
||||
@ -835,7 +869,7 @@ function TestDeleteThrow(handler) {
|
||||
TestWithProxies(TestDeleteThrow2, handler)
|
||||
}
|
||||
|
||||
function TestDeleteThrow2(handler, create) {
|
||||
function TestDeleteThrow2(create, handler) {
|
||||
var p = create(handler)
|
||||
assertThrows(function(){ delete p.a }, "myexn")
|
||||
assertThrows(function(){ delete p["b"] }, "myexn");
|
||||
@ -876,7 +910,7 @@ function TestDescriptor(handler) {
|
||||
TestWithProxies(TestDescriptor2, handler)
|
||||
}
|
||||
|
||||
function TestDescriptor2(handler, create) {
|
||||
function TestDescriptor2(create, handler) {
|
||||
var p = create(handler)
|
||||
var descs = [
|
||||
{configurable: true},
|
||||
@ -915,7 +949,7 @@ function TestDescriptorThrow(handler) {
|
||||
TestWithProxies(TestDescriptorThrow2, handler)
|
||||
}
|
||||
|
||||
function TestDescriptorThrow2(handler, create) {
|
||||
function TestDescriptorThrow2(create, handler) {
|
||||
var p = create(handler)
|
||||
assertThrows(function(){ Object.getOwnPropertyDescriptor(p, "a") }, "myexn")
|
||||
}
|
||||
@ -939,7 +973,7 @@ function TestComparison(eq) {
|
||||
TestWithProxies(TestComparison2, eq)
|
||||
}
|
||||
|
||||
function TestComparison2(eq, create) {
|
||||
function TestComparison2(create, eq) {
|
||||
var p1 = create({})
|
||||
var p2 = create({})
|
||||
|
||||
@ -982,7 +1016,7 @@ function TestIn(handler) {
|
||||
TestWithProxies(TestIn2, handler)
|
||||
}
|
||||
|
||||
function TestIn2(handler, create) {
|
||||
function TestIn2(create, handler) {
|
||||
var p = create(handler)
|
||||
assertTrue("a" in p)
|
||||
assertEquals("a", key)
|
||||
@ -1066,7 +1100,7 @@ function TestInThrow(handler) {
|
||||
TestWithProxies(TestInThrow2, handler)
|
||||
}
|
||||
|
||||
function TestInThrow2(handler, create) {
|
||||
function TestInThrow2(create, handler) {
|
||||
var p = create(handler)
|
||||
assertThrows(function(){ return "a" in o }, "myexn")
|
||||
assertThrows(function(){ return 99 in o }, "myexn")
|
||||
@ -1115,7 +1149,7 @@ function TestInForDerived(handler) {
|
||||
TestWithProxies(TestInForDerived2, handler)
|
||||
}
|
||||
|
||||
function TestInForDerived2(handler, create) {
|
||||
function TestInForDerived2(create, handler) {
|
||||
var p = create(handler)
|
||||
var o = Object.create(p)
|
||||
|
||||
@ -1272,7 +1306,7 @@ function TestHasOwn(handler) {
|
||||
TestWithProxies(TestHasOwn2, handler)
|
||||
}
|
||||
|
||||
function TestHasOwn2(handler, create) {
|
||||
function TestHasOwn2(create, handler) {
|
||||
var p = create(handler)
|
||||
assertTrue(Object.prototype.hasOwnProperty.call(p, "a"))
|
||||
assertEquals("a", key)
|
||||
@ -1330,7 +1364,7 @@ function TestHasOwnThrow(handler) {
|
||||
TestWithProxies(TestHasOwnThrow2, handler)
|
||||
}
|
||||
|
||||
function TestHasOwnThrow2(handler, create) {
|
||||
function TestHasOwnThrow2(create, handler) {
|
||||
var p = create(handler)
|
||||
assertThrows(function(){ Object.prototype.hasOwnProperty.call(p, "a")},
|
||||
"myexn")
|
||||
@ -1495,12 +1529,12 @@ TestPrototype()
|
||||
// Property names (Object.getOwnPropertyNames, Object.keys).
|
||||
|
||||
function TestPropertyNames(names, handler) {
|
||||
TestWithProxies(TestPropertyNames2, [names, handler])
|
||||
TestWithProxies(TestPropertyNames2, handler, names)
|
||||
}
|
||||
|
||||
function TestPropertyNames2(names_handler, create) {
|
||||
var p = create(names_handler[1])
|
||||
assertArrayEquals(names_handler[0], Object.getOwnPropertyNames(p))
|
||||
function TestPropertyNames2(create, handler, names) {
|
||||
var p = create(handler)
|
||||
assertArrayEquals(names, Object.getOwnPropertyNames(p))
|
||||
}
|
||||
|
||||
TestPropertyNames([], {
|
||||
@ -1527,7 +1561,7 @@ function TestPropertyNamesThrow(handler) {
|
||||
TestWithProxies(TestPropertyNamesThrow2, handler)
|
||||
}
|
||||
|
||||
function TestPropertyNamesThrow2(handler, create) {
|
||||
function TestPropertyNamesThrow2(create, handler) {
|
||||
var p = create(handler)
|
||||
assertThrows(function(){ Object.getOwnPropertyNames(p) }, "myexn")
|
||||
}
|
||||
@ -1543,12 +1577,12 @@ TestPropertyNamesThrow({
|
||||
|
||||
|
||||
function TestKeys(names, handler) {
|
||||
TestWithProxies(TestKeys2, [names, handler])
|
||||
TestWithProxies(TestKeys2, handler, names)
|
||||
}
|
||||
|
||||
function TestKeys2(names_handler, create) {
|
||||
var p = create(names_handler[1])
|
||||
assertArrayEquals(names_handler[0], Object.keys(p))
|
||||
function TestKeys2(create, handler, names) {
|
||||
var p = create(handler)
|
||||
assertArrayEquals(names, Object.keys(p))
|
||||
}
|
||||
|
||||
TestKeys([], {
|
||||
@ -1605,7 +1639,7 @@ function TestKeysThrow(handler) {
|
||||
TestWithProxies(TestKeysThrow2, handler)
|
||||
}
|
||||
|
||||
function TestKeysThrow2(handler, create) {
|
||||
function TestKeysThrow2(create, handler) {
|
||||
var p = create(handler)
|
||||
assertThrows(function(){ Object.keys(p) }, "myexn")
|
||||
}
|
||||
@ -1782,8 +1816,8 @@ function TestFixThrow(handler) {
|
||||
TestWithProxies(TestFixThrow2, handler)
|
||||
}
|
||||
|
||||
function TestFixThrow2(handler) {
|
||||
var p = Proxy.create(handler, {})
|
||||
function TestFixThrow2(create, handler) {
|
||||
var p = create(handler, {})
|
||||
assertThrows(function(){ Object.seal(p) }, "myexn")
|
||||
assertThrows(function(){ Object.freeze(p) }, "myexn")
|
||||
assertThrows(function(){ Object.preventExtensions(p) }, "myexn")
|
||||
@ -1809,6 +1843,135 @@ TestFixThrow({
|
||||
})
|
||||
|
||||
|
||||
// Freeze a proxy in the middle of operations on it.
|
||||
// TODO(rossberg): actual behaviour not specified consistently at the moment,
|
||||
// just make sure that we do not crash.
|
||||
function TestReentrantFix(f) {
|
||||
TestWithProxies(f, Object.freeze)
|
||||
TestWithProxies(f, Object.seal)
|
||||
TestWithProxies(f, Object.preventExtensions)
|
||||
}
|
||||
|
||||
TestReentrantFix(function(create, freeze) {
|
||||
var handler = {
|
||||
get get() { freeze(p); return undefined },
|
||||
fix: function() { return {} }
|
||||
}
|
||||
var p = create(handler)
|
||||
// Freeze while getting get trap.
|
||||
try { p.x } catch (e) { assertInstanceof(e, Error) }
|
||||
})
|
||||
|
||||
TestReentrantFix(function(create, freeze) {
|
||||
var handler = {
|
||||
get: function() { freeze(p); return 3 },
|
||||
fix: function() { return {} }
|
||||
}
|
||||
var p = create(handler)
|
||||
// Freeze while executing get trap.
|
||||
try { p.x } catch (e) { assertInstanceof(e, Error) }
|
||||
})
|
||||
|
||||
TestReentrantFix(function(create, freeze) {
|
||||
var handler = {
|
||||
getPropertyDescriptor: function() { freeze(p); return undefined },
|
||||
fix: function() { return {} }
|
||||
}
|
||||
var p = create(handler)
|
||||
// Freeze while executing default get trap.
|
||||
try { p.x } catch (e) { assertInstanceof(e, Error) }
|
||||
})
|
||||
|
||||
TestReentrantFix(function(create, freeze) {
|
||||
var handler = {
|
||||
getPropertyDescriptor: function() { freeze(p); return {get: function(){}} },
|
||||
fix: function() { return {} }
|
||||
}
|
||||
var p = create(handler)
|
||||
var o = Object.create(p)
|
||||
// Freeze while getting a property from prototype.
|
||||
try { o.x } catch (e) { assertInstanceof(e, Error) }
|
||||
})
|
||||
|
||||
TestReentrantFix(function(create, freeze) {
|
||||
var handler = {
|
||||
get set() { freeze(p); return undefined },
|
||||
fix: function() { return {} }
|
||||
}
|
||||
var p = create(handler)
|
||||
// Freeze while getting set trap.
|
||||
try { p.x = 4 } catch (e) { assertInstanceof(e, Error) }
|
||||
})
|
||||
|
||||
TestReentrantFix(function(create, freeze) {
|
||||
var handler = {
|
||||
set: function() { freeze(p); return true },
|
||||
fix: function() { return {} }
|
||||
}
|
||||
var p = create(handler)
|
||||
// Freeze while executing set trap.
|
||||
try { p.x = 4 } catch (e) { assertInstanceof(e, Error) }
|
||||
})
|
||||
|
||||
TestReentrantFix(function(create, freeze) {
|
||||
var handler = {
|
||||
getOwnPropertyDescriptor: function() { freeze(p); return undefined },
|
||||
fix: function() { return {} }
|
||||
}
|
||||
var p = create(handler)
|
||||
// Freeze while executing default set trap.
|
||||
try { p.x } catch (e) { assertInstanceof(e, Error) }
|
||||
})
|
||||
|
||||
TestReentrantFix(function(create, freeze) {
|
||||
var handler = {
|
||||
getPropertyDescriptor: function() { freeze(p); return {set: function(){}} },
|
||||
fix: function() { return {} }
|
||||
}
|
||||
var p = create(handler)
|
||||
var o = Object.create(p)
|
||||
// Freeze while setting a property in prototype, dropping the property!
|
||||
try { o.x = 4 } catch (e) { assertInstanceof(e, Error) }
|
||||
})
|
||||
|
||||
TestReentrantFix(function(create, freeze) {
|
||||
var handler = {
|
||||
getPropertyDescriptor: function() { freeze(p); return {set: function(){}} },
|
||||
fix: function() { return {x: {get: function(){}}} }
|
||||
}
|
||||
var p = create(handler)
|
||||
var o = Object.create(p)
|
||||
// Freeze while setting a property in prototype, making it read-only!
|
||||
try { o.x = 4 } catch (e) { assertInstanceof(e, Error) }
|
||||
})
|
||||
|
||||
TestReentrantFix(function(create, freeze) {
|
||||
var handler = {
|
||||
get fix() { freeze(p); return function(){} }
|
||||
}
|
||||
var p = create(handler)
|
||||
// Freeze while getting fix trap.
|
||||
try { Object.freeze(p) } catch (e) { assertInstanceof(e, Error) }
|
||||
p = create(handler)
|
||||
try { Object.seal(p) } catch (e) { assertInstanceof(e, Error) }
|
||||
p = create(handler)
|
||||
try { Object.preventExtensions(p) } catch (e) { assertInstanceof(e, Error) }
|
||||
})
|
||||
|
||||
TestReentrantFix(function(create, freeze) {
|
||||
var handler = {
|
||||
fix: function() { freeze(p); return {} }
|
||||
}
|
||||
var p = create(handler)
|
||||
// Freeze while executing fix trap.
|
||||
try { Object.freeze(p) } catch (e) { assertInstanceof(e, Error) }
|
||||
p = create(handler)
|
||||
try { Object.seal(p) } catch (e) { assertInstanceof(e, Error) }
|
||||
p = create(handler)
|
||||
try { Object.preventExtensions(p) } catch (e) { assertInstanceof(e, Error) }
|
||||
})
|
||||
|
||||
|
||||
|
||||
// String conversion (Object.prototype.toString,
|
||||
// Object.prototype.toLocaleString,
|
||||
@ -1901,7 +2064,7 @@ function TestValueOf(handler) {
|
||||
TestWithProxies(TestValueOf2, handler)
|
||||
}
|
||||
|
||||
function TestValueOf2(handler, create) {
|
||||
function TestValueOf2(create, handler) {
|
||||
var p = create(handler)
|
||||
assertSame(p, Object.prototype.valueOf.call(p))
|
||||
}
|
||||
@ -1918,7 +2081,7 @@ function TestIsEnumerable(handler) {
|
||||
TestWithProxies(TestIsEnumerable2, handler)
|
||||
}
|
||||
|
||||
function TestIsEnumerable2(handler, create) {
|
||||
function TestIsEnumerable2(create, handler) {
|
||||
var p = create(handler)
|
||||
assertTrue(Object.prototype.propertyIsEnumerable.call(p, "a"))
|
||||
assertEquals("a", key)
|
||||
@ -1967,7 +2130,7 @@ function TestIsEnumerableThrow(handler) {
|
||||
TestWithProxies(TestIsEnumerableThrow2, handler)
|
||||
}
|
||||
|
||||
function TestIsEnumerableThrow2(handler, create) {
|
||||
function TestIsEnumerableThrow2(create, handler) {
|
||||
var p = create(handler)
|
||||
assertThrows(function(){ Object.prototype.propertyIsEnumerable.call(p, "a") },
|
||||
"myexn")
|
||||
|
Loading…
Reference in New Issue
Block a user