descriptors and not only own properties gotcha

Andrea Giammarchi andrea.giammarchi at gmail.com
Thu Dec 18 08:04:50 PST 2014


Yeah, that fails anyway and if you loop through a for/in and attach as own
property you are moving the problem instead of actually solving it in the
current state of the specs.

This is probably closer to what I meant by `Descriptor` solution to improve
reliability of descriptors in possibly hostile envs.
Although it might be even easier to patch upfront defineProperty/ies if
this is a real concern for unknown libraries.

```js
function Descriptor(obj) {
  'use strict';
  for(var
    self = this instanceof Descriptor ?
      this : Object.create(Descriptor.prototype),
    hOP = Object.prototype.hasOwnProperty,
    arr = [
      // common
      'configurable', 'enumerable',
      // data
      'value', 'writable',
      // accessor
      'get', 'set'
    ],
    i = 0, k; i < 6; i++
  ) {
    k = arr[i];
    if (hOP.call(obj, k)) {
      // no extra checks, if it's wrong
      // it should fail later on
      // 'cause explicitly ambiguous
      self[k] = obj[k];
    }
  }
  return self;
}

// avoid inherited properties
Object.setPrototypeOf(
  Descriptor.prototype,
  Object.create(null)
);

// set the constructor
Object.defineProperty(
  Descriptor.prototype,
  'constructor',
  new Descriptor({
    value: Descriptor
  })
);

// and freeze its prototype
Object.freeze(Descriptor.prototype);

```

Regards

On Thu, Dec 18, 2014 at 1:38 PM, Andy Earnshaw <andyearnshaw at gmail.com>
wrote:
>
> *sigh* ignore me I completely misread the initial email.  Serves me right
> for skim reading and speed replying during lunch.
>
> On Thu, Dec 18, 2014 at 1:31 PM, Andy Earnshaw <andyearnshaw at gmail.com>
> wrote:
>>
>> Oops, misfire.  The rest of that:
>>
>>     function shadow(obj, props) {
>>         var ret = Object.create(obj);
>>
>>         for (var k in props)
>>             ret[k] = props[k]
>>
>>         return ret;
>>     }
>>
>>     // Elsewhere...
>>     function defineSomeProps (obj) {
>>         var defaults = { enumerable: true, writable: true, configurable:
>> true };
>>
>>         Object.defineProperties(obj, {
>>             foo1: shadow(defaults, { value: 'bar1' })),
>>             foo2: shadow(defaults, { value: 'bar2' })),
>>             foo3: shadow(defaults, { value: 'bar3' })),
>>             // etc...
>>         });
>>     }
>>
>> If people have a generic shadow() function that creates an object and
>> copies properties to it (less verbosely than just using Object.create),
>> they could be tempted to use it to create ES3-style EWC properties.
>>
>> On Thu, Dec 18, 2014 at 1:24 PM, Andy Earnshaw <andyearnshaw at gmail.com>
>> wrote:
>>>
>>> Can we be sure nobody's ever written something like this:
>>>
>>>     function shadow(obj, props) {
>>>         var ret = Object.create(obj);
>>>     }
>>>
>>> On Thu, Dec 18, 2014 at 10:08 AM, Andrea Giammarchi <
>>> andrea.giammarchi at gmail.com> wrote:
>>>
>>>> My main point is that everything you get from
>>>> `Object.getOwnPropertyDescriptor`, beside undefined or possible abrupt
>>>> errors, will have own properties.
>>>>
>>>> Even es5-shim/sham has been checking own properties for years [1] so I
>>>> am pretty confident nothing will break 'cause own properties is what
>>>> developers always expected and what they've always used despite specs.
>>>>
>>>> Again it's clear the world can live with these possibly inherited
>>>> descriptors properties but it feels very wrong on the practical level. Too
>>>> bad if there won't be ever a fix [2]
>>>>
>>>> [1] https://github.com/es-shims/es5-shim/issues/211#event-208821479
>>>> now fixed
>>>>
>>>> [2] would a new Descriptor({ownproperties:"only"}) instance be ever
>>>> considered ?
>>>>
>>>>
>>>>
>>>> On Wed, Dec 17, 2014 at 8:37 PM, Allen Wirfs-Brock <
>>>> allen at wirfs-brock.com> wrote:
>>>>>
>>>>>
>>>>> On Dec 17, 2014, at 10:30 AM, Andrea Giammarchi wrote:
>>>>>
>>>>> Actually simplifying as proposal: does everyone agree that if a
>>>>> descriptor.[[Value]] is own property no further checks on inherited [[Get]]
>>>>> and [[Set]], or generally speaking Accessor Property related checks, should
>>>>> be made ?
>>>>>
>>>>> This would already fix the `Object.prototype.get` or `.set` case since
>>>>> I believe nobody ever used an inherited `value` property on purpose for
>>>>> descriptors ... or is it?
>>>>>
>>>>> It will keep `enumerable` and `writable` still potentially problematic
>>>>> but at least the following code would never fail:
>>>>>
>>>>> ```js
>>>>> Object.prototype.get = function () {}; Object.defineProperty(
>>>>> Object.prototype, 'toString', Object.getOwnPropertyDescriptor(
>>>>> Object.prototype, 'toString' ) );
>>>>>
>>>>> ```
>>>>>
>>>>> Thanks again for any sort of outcome (or clarification on when and if
>>>>> this will ever be fixed)
>>>>>
>>>>>
>>>>> I'm not sure what you are actually asking.  All specified internal
>>>>> uses of property descriptor objets should pas through ToPropertyDescriptor (
>>>>> http://people.mozilla.org/~jorendorff/es6-draft.html#sec-topropertydescriptor
>>>>> ) which will throw if there is any conflict between get/set and own
>>>>> value/writable properties, regardless of whether they are own or inherited.
>>>>>  (If you know of any uses of such descriptor object in the ES6 spec that
>>>>> don't do this validation, please file a bug).
>>>>>
>>>>> If you want to enforce the same semantics on you ES-level uses of
>>>>> descriptor objects you need to write a ES level implementation of the
>>>>> checks performed by ToPropertyDescriptor.
>>>>>
>>>>> I can see various ways we might improve the specified processing of
>>>>> property descriptor objects but those would generally be breaking changes
>>>>> and we would have to consider the possible impact of such changes before
>>>>> proceeding with them.
>>>>>
>>>>> Allen
>>>>>
>>>>
>>>> _______________________________________________
>>>> es-discuss mailing list
>>>> es-discuss at mozilla.org
>>>> https://mail.mozilla.org/listinfo/es-discuss
>>>>
>>>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20141218/00f34620/attachment.html>


More information about the es-discuss mailing list