Object.assign interaction with __proto__ field.

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Object.assign interaction with __proto__ field.

Mike Samuel
Might it be a spec bug that in the below, o's prototype changes, and o.x !== b.x?

const a = makeIntercepter();
const b = { x: 1 };
const o = Object.assign(
  {},
  a,
  b);

console.log(`o is plain Object: ${ Object.getPrototypeOf(o) === Object.prototype }`);

console.log(`b.x=${ b.x }, o.x=${ o.x }`);

function makeIntercepter() {
  return JSON.parse(
    // Get an object that has an actual "__proto__" property.
    '{ "__proto__": {} }',
    // Replace the __proto__ property's value with one that
    // traps assignment to x.
    (key, value) => (
      (key === '__proto__')
        ? {
            set x(v) {
              console.log(`intercepted ${ v }`);
            },
            get x() {
              return 2;
            },
          }
        : value));
}

In modern Chrome, Firefox, Safari I get
intercepted 1
getPrototypeOf(o)===Object.prototype: false
b.x=1, o.x=2


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Object.assign interaction with __proto__ field.

Andrea Giammarchi-2
same way `Object.assign` makes getters own properties, anything else special gets assigned right away, including Symbols.

This is a usually ignored gotta of the issue `Object.assign` could actually cause in the wild, specially with polyfills where WeakMap symbols assigned directly might be passed around.

I'm not sure `__proto__` as key deserves any special treatment, compared to all other little gotchas, but FWIW I'm still for banning `__proto__` from the language through 1 year of browsers warnings and a wide community involvement in getting rid of that little "bomb" ECMA kept in core.

NodeJS got bitten with query strings, developers loading user land JSON can get bitten with `"__proto__": null` and so on and so fort.

Regards.



On Wed, Sep 26, 2018 at 3:28 PM Mike Samuel <[hidden email]> wrote:
Might it be a spec bug that in the below, o's prototype changes, and o.x !== b.x?

const a = makeIntercepter();
const b = { x: 1 };
const o = Object.assign(
  {},
  a,
  b);

console.log(`o is plain Object: ${ Object.getPrototypeOf(o) === Object.prototype }`);

console.log(`b.x=${ b.x }, o.x=${ o.x }`);

function makeIntercepter() {
  return JSON.parse(
    // Get an object that has an actual "__proto__" property.
    '{ "__proto__": {} }',
    // Replace the __proto__ property's value with one that
    // traps assignment to x.
    (key, value) => (
      (key === '__proto__')
        ? {
            set x(v) {
              console.log(`intercepted ${ v }`);
            },
            get x() {
              return 2;
            },
          }
        : value));
}

In modern Chrome, Firefox, Safari I get
intercepted 1
getPrototypeOf(o)===Object.prototype: false
b.x=1, o.x=2

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Object.assign interaction with __proto__ field.

Jordan Harband
In reply to this post by Mike Samuel
You don't need JSON.parse there - see `Object.getPrototypeOf({ ['__proto__']: null }) !== null`.

On Wed, Sep 26, 2018 at 10:27 AM, Mike Samuel <[hidden email]> wrote:
Might it be a spec bug that in the below, o's prototype changes, and o.x !== b.x?

const a = makeIntercepter();
const b = { x: 1 };
const o = Object.assign(
  {},
  a,
  b);

console.log(`o is plain Object: ${ Object.getPrototypeOf(o) === Object.prototype }`);

console.log(`b.x=${ b.x }, o.x=${ o.x }`);

function makeIntercepter() {
  return JSON.parse(
    // Get an object that has an actual "__proto__" property.
    '{ "__proto__": {} }',
    // Replace the __proto__ property's value with one that
    // traps assignment to x.
    (key, value) => (
      (key === '__proto__')
        ? {
            set x(v) {
              console.log(`intercepted ${ v }`);
            },
            get x() {
              return 2;
            },
          }
        : value));
}

In modern Chrome, Firefox, Safari I get
intercepted 1
getPrototypeOf(o)===Object.prototype: false
b.x=1, o.x=2


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Object.assign interaction with __proto__ field.

Claude Pache
In reply to this post by Mike Samuel


Le 26 sept. 2018 à 16:27, Mike Samuel <[hidden email]> a écrit :

Might it be a spec bug that in the below, o's prototype changes, and o.x !== b.x?

const a = makeIntercepter();
const b = { x: 1 };
const o = Object.assign(
  {},
  a,
  b);

console.log(`o is plain Object: ${ Object.getPrototypeOf(o) === Object.prototype }`);

console.log(`b.x=${ b.x }, o.x=${ o.x }`);

function makeIntercepter() {
  return JSON.parse(
    // Get an object that has an actual "__proto__" property.
    '{ "__proto__": {} }',
    // Replace the __proto__ property's value with one that
    // traps assignment to x.
    (key, value) => (
      (key === '__proto__')
        ? {
            set x(v) {
              console.log(`intercepted ${ v }`);
            },
            get x() {
              return 2;
            },
          }
        : value));
}

In modern Chrome, Firefox, Safari I get
intercepted 1
getPrototypeOf(o)===Object.prototype: false
b.x=1, o.x=2

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss

🤦 It’s not a bug. But you definitely convinced me to add `delete Object.prototype.__proto__` at the top of my JS.

—Claude


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss