Status: New
Owner: ----
New issue 842 by polarjs: Object.freeze() throws exception is Object or
Array has been extended
http://code.google.com/p/v8/issues/detail?id=842
Here's a simple test case:
=== BEGIN ===
//Object.prototype.myfunc = function() {}
//Array.prototype.myfunc = function() {}
var obj = { name: "n1" };
function test() {
print("BEGIN test");
try {
obj = Object.freeze(obj);
} catch (e) {
print("Caught exception: " + e);
}
print("END test");
}
test();
=== END ===
If you run the above with the d8 shell, you will get the following output:
./d8_g test.js
BEGIN test
END test
If you uncomment one of the 2 lines at the top of the test file which
extends the Object or Array class, then you'll get the following output:
./d8_g test.js
BEGIN test
Caught exception: TypeError: Cannot call method 'isConfigurable' of
undefined
END test
The exception is being thrown from inside Object.freeze() because
ObjectGetOwnPropertyNames() will return a list that include "myfunc", but
GetOwnProperty() will return for an undefined for it.
From what I can tell, the insertion of "myfunc" into the list of keys
happened in Runtime_GetLocalElementNames() when if called
Factory::NewJSArrayWithElements(names). The names list there does not
include the extension, but the created array inherited it from the
prototype. And when ObjectFreeze() iterates over the array returned by
ObjectGetOwnPropertyNames() using the for-in loop, the iteration also
produced the keys that were inherited from the prototype.
I'm not sure what the right thing to do here is, but it seems like user
code is able to defeat Object.freeze() simply by extending Object or
Array. This is probably not a desirable side effect.
Testing details: tested and reproduced this on bleeding edge rev 5332.
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev