Closed Bug 744494 Opened 12 years ago Closed 12 years ago

Object.freeze of constructor's prototype denies modification of instances

Categories

(Core :: JavaScript Engine, defect)

11 Branch
x86_64
Windows 7
defect
Not set
normal

Tracking

()

RESOLVED INVALID

People

(Reporter: andremiguelcruz, Unassigned)

Details

User Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.66 Safari/535.11

Steps to reproduce:

(function () {
    'use strict';

    // create a constructor
    var A = function () {};
A.prototype.foo = "bar";
    Object.freeze(A.prototype);   // freeze prototype

   // create an instance
   var a = new A();
   a.foo = "baz";   // throws a['foo'] is read only

   Object.isFrozen(a);   // false
}());


Actual results:

Couldn't modify a property of the instance, even if the object is not frozen but it's proto is.


Expected results:

The property foo should have been written to a, even if a.__proto__ is frozen.

If you try the same code in chrome, safari, IE9.
Opera seems to have the same behavior as firefox.

Tested this in Firefox 11 but probably Firefox 4 has the same issue.
15.2.3.9 Object.freeze ( O )
When the freeze function is called, the following steps are taken:
1. If Type(o) is not Object throw a TypeError exception.
2. For each named own property name P of O,
a. Let desc be the result of calling the [[GetOwnProperty]] internal method of O with P.
b. If IsDataDescriptor(desc) is true, then
i. If desc.[[Writable]] is true, set desc.[[Writable]] to false.
c. If desc.[[Configurable]] is true, set desc.[[Configurable]] to false.
d. Call the [[DefineOwnProperty]] internal method of O with P, desc, and true as arguments.
3. Set the [[Extensible]] internal property of O to false.
4. Return O.
After further investigation IE9 does not throw any error but instead fails silently even with 'use strict', that means that the property is not set with the value 'baz'.
Assignee: nobody → general
Component: Untriaged → JavaScript Engine
Product: Firefox → Core
QA Contact: untriaged → general
This isn't a bug.

  a.foo = "baz";   // throws a['foo'] is read only

...causes the [[Put]] operation to be called with Throw=true.  The first step of that is to call [[CanPut]].  When that finds a data descriptor property on the prototype chain, the return is the value of descriptor.[[Writable]].  As the "foo" property was marked non-writable when the prototype object was frozen, [[CanPut]] returns false.  Thus per [[Put]] step 1a, a TypeError is thrown.

Firefox and Opera get it right, and the other browsers/engines get it wrong.
Status: UNCONFIRMED → RESOLVED
Closed: 12 years ago
Resolution: --- → INVALID
(In reply to Jeff Walden [:Waldo] (busy, try to prefer other reviewers if possible) from comment #3)
> This isn't a bug.
> 
>   a.foo = "baz";   // throws a['foo'] is read only
> 
> ...causes the [[Put]] operation to be called with Throw=true.  The first
> step of that is to call [[CanPut]].  When that finds a data descriptor
> property on the prototype chain, the return is the value of
> descriptor.[[Writable]].  As the "foo" property was marked non-writable when
> the prototype object was frozen, [[CanPut]] returns false.  Thus per [[Put]]
> step 1a, a TypeError is thrown.
> 
> Firefox and Opera get it right, and the other browsers/engines get it wrong.

Jeff, it would be good to get this standardize among engines. What shall I do to make it so? Report a bug in the chromium? Report a bug to the IE team?
You need to log in before you can comment on or make changes to this bug.