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

Reply via email to