Closed Bug 837627 Opened 11 years ago Closed 11 years ago

Throw when trying to set __proto__ to a non-object

Categories

(Core :: JavaScript Engine, defect)

x86
Linux
defect
Not set
normal

Tracking

()

RESOLVED INVALID

People

(Reporter: bruant.d, Unassigned)

Details

From Twitter https://twitter.com/olov/status/298395329945030657

  var o = {};
  o.__proto__ = 1;

What happens: the script goes on
Expected : throw when trying to set something different than null or an object
I'm not sure that it necessarily should throw. Both V8 and JSC fails silently when assigning a primitive other than null (such as 1) to __proto__ so I don't see an issue with being consistent with that.

What triggered my Twitter-question was when I realized that an object created with Object.create(null) allows for assigning non-null primitives to __proto__, which seemed a bit inconsistent (#837630). V8 is consistent but JSC seems to have the same behavior as SM, for what it's worth.

It would be interesting to understand what's intended behavior, what's not and perhaps get it documented somewhere (if not already).
Nitrofish Extreme's source has a comment saying that __proto__ passed a non-null, non-object silently does nothing for compatibility with SpiderMonkey.

    // Setting __proto__ of a primitive should have no effect.
    if (!exec->thisValue().isObject())
        return JSValue::encode(jsUndefined());

v8 has the same comment:

  // Silently ignore the change if value is not a JSObject or null.
  // SpiderMonkey behaves this way.
  if (!value->IsJSReceiver() && !value->IsNull()) return value;

I don't much care whether an exception is or is not thrown here.  I think, designing on a clean slate, an exception would be better.  At this point, I'd guess it's more trouble than it's worth to retrofit rigor onto this.  I could well be wrong, tho.  I'd expect an uphill slog against the backwards-compatibility warriors in TC39.
Hmm, that Nitro comment doesn't actually mention SpiderMonkey.  I'm certain it did at one point in the past.  Meh.  Rest of the comment still holds.
Oh, I just quoted the wrong code in Nitro, moving too fast:

    // Setting __proto__ to a non-object, non-null value is silently ignored to match Mozilla.
    if (!value.isObject() && !value.isNull())
        return JSValue::encode(jsUndefined());
I wasn't aware of V8/JSC behavior. I assumed they threw, but they silently fail. It's likely to be better for backward-compat.
Closing as invalid. Feel free to reopen.
Status: NEW → RESOLVED
Closed: 11 years ago
Resolution: --- → INVALID
You need to log in before you can comment on or make changes to this bug.