Why we need to clean up __proto__

Axel Rauschmayer axel at rauschma.de
Wed Dec 28 01:09:43 PST 2011


The cleanest solution to the problem you outlined seems to be to never use objects as dictionaries(?) That is, one would separate the concerns program definition and application data. Allen’s object model reformation (allowing one to override the [] operator) would help, too.
http://wiki.ecmascript.org/doku.php?id=strawman:object_model_reformation


On Dec 27, 2011, at 3:53 , Mark S. Miller wrote:

> Or, "Even Crock's Code Doesn't Overcome All The Bad Parts."
> 
> 
> In this message, I explain why I believe we need to clean up __proto__. I'll start a separate thread on how to clean it up -- which is just my documenting a suggestion from Dave Herman.
> 
> 
> From <http://eleventyone.done.hu/OReilly.JavaScript.The.Good.Parts.May.2008.pdf> PDF page 119
> 
>    that.on = function (type, ....) {    
>       ....
>       var registry = {};
>       ....
>       if (registry.hasOwnProperty(type)) {    
>           registry[type].push(handler);
>       } else {
>           registry[type] = [handler];
>       }
>       ....
>   };
> 
> This "registry" is a classic use of an object as a string-to-value map. Note that the "type" parameter comes in from the client of the abstraction. The only validation performed on it is the "hasOwnProperty" check above. Elsewhere Crock points out that this hasOwnProperty check does not work if "hasOwnProperty" itself is ever used as a key, and so we should instead say:
> 
>       if (Object.prototype.hasOwnProperty.call(registry, type)) {
> 
> This still doesn't yet work on most actual browsers for a reason explained below.
> 
> 
> 
> <aside on why ES5 does not really help>
> 
> Going beyond "Good Parts", EcmaScript 5 gives us two new opportunities to clean up this code further. 
> 
> 1) We can protect ourselves from other code monkey patching away Object.prototype.hasOwnProperty and/or Object.prototype.hasOwnProperty.call by using <http://wiki.ecmascript.org/doku.php?id=conventions:safe_meta_programming> at initialization time, assuming that this module gets to initialize itself before such monkey patching may have occurred:
> 
>   var bind = Function.prototype.bind;
>   var uncurryThis = bind.bind(bind.call);
> 
>   var hopFn = uncurryThis({}.hasOwnProperty);
> 
> So that we can say
> 
>       if (hopFn(registry, type)) {
> 
> 2) We can replace the initialization of "registry" with
> 
>       var registry = Object.create(null);
> 
> or, if we wish the same protection from post-initialization monkey patching
> 
>   var create = Object.create;
>   ...
>       var registry = create(null);
> 
> It turns out that neither of these additional ES5-based paranoid steps helps with the worst problem remaining with Crock's corrected code. Likewise, nothing so far proposed for ES-next would help, except for Dave Herman's suggestion which I will write up shortly.
> 
> </aside on why ES5 does not really help>
> 
> 
> 
> As you've probably already guessed from the title of this email, the problem occurs on most platforms when the function is called with an argument of "__proto__". Since we do a "hasOwnProperty" check first, the way in which this goes wrong depends on the platform. Evaluating
> 
>     [{}.hasOwnProperty('__proto__'), {}.__proto__.hasOwnProperty('__proto__')]
> 
> on various browsers gives:
> 
> false,false       // Chrome
> true,true         // WebKit Nightly
> false,true        // FF Nightly
> false,false       // Opera 12 alpha
> throws TypeError  // IE10 Preview 2
> 
> Since IE doesn't treat "__proto__" as special magic, no problem there. WebKit Nightly will take the branch that happens to fail safe here, but only for the reason that there's no "Object.prototype.push". All we can say is that we got lucky this time. When Chrome, FF, and Opera evaluate
> 
>       registry['__proto__'] = [handler];
> 
> they change registry to inherit from [handler] rather than Object.prototype. WebKit would do the same if it had executed this line.
> 
> Think this exercise is academic and doesn't arise in real systems?  As observed at <http://www.google.com/support/forum/p/Google+Docs/thread?tid=0cd4a00bd4aef9e4>, until recently, on all non-IE browsers, if you typed "__proto__" at the beginning of a new Google Doc, your Google Doc would hang. This was tracked down to such a buggy use of an object as a string map. (To avoid such problems, Caja is shifting to using <http://code.google.com/p/es-lab/source/browse/trunk/src/ses/StringMap.js>, which does seem safe on all platforms.)
> 
> 
> --
>     Cheers,
>     --MarkM
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss

-- 
Dr. Axel Rauschmayer
axel at rauschma.de

home: rauschma.de
twitter: twitter.com/rauschma
blog: 2ality.com



-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20111228/55d098b7/attachment.html>


More information about the es-discuss mailing list