Le 24/01/2013 09:52, Tom Van Cutsem a écrit :
2013/1/23 David Bruant <bruan...@gmail.com <mailto:bruan...@gmail.com>>

    Le 23/01/2013 09:38, Tom Van Cutsem a écrit :

        3) because of JS's "invoke = get + apply" semantics, by
        default a proxy always leaves the |this| value pointing at the
        proxy.

        Looking only at 3), sometimes this is what you want, and
        sometimes it isn't.

    In which case would it be what you want?


See the example by Brendan just upstream in this thread.
True, I had read this post too quickly.

    The example Brandon (and Kevin before him) provided showed
    something very intrusive about proxies related to your 3). That
    proxies mediate the access to the public method is one thing, that
    they pretend to be the object acted on inside the method opens a
    entire world.

    Even with fixes suggested by Allen, the hazard can still exist if
    someone does:
        Counter.prototype.increment.call(new Proxy(counter,
    maliciousHandler))


I don't understand why this is a hazard. Even without proxies, |this| is never reliable, unless you use .bind().
I'm not worried about the |this|-reliability for the method, but rather that the target instance can be left in an inconsistent state because of a malicious handler. The important part in the above expression isn't the .call, but that an actual Counter instance is the proxy target.

    I have no idea how this can be mitigated in general without
    creating a mechanism that can be abused to unwrap proxies. For
    classes specifically, maybe an option can make that classes keep
    track of generated objects and throw if non-instance is passed in
    a method as |this| (...which is exactly the kind of things DOM
    Node tree manipulation methods will need)


Recall that it was a goal for classes to be a form of sugar over the existing object model. That means the use of |this| within a method specified using class syntax should really be no different from using |this| outside of classes. Let's try to avoid making up special rules for class instances.
I agree with you, I suggested to add an option, not to change the default semantics. Because of the too-dynamic |this| and everyone being used to it, protecting yourself from malicious proxies from attacks like the one above ("method.call(new Proxy(legitObject, maliciousProxy))") has to be an opt-in. Basically, methods make sure their |this| is an object that came out of the class constructor. It would be nice if this opt-in could be made as simple as an optional keyword in the class syntax. This option would just desugar differently (put all objects created by the constructor in a WeakSet, add a prolog to each method verifying |this| is part of the weakset, continue if yes, throw if not).

Going back to the big discussion thread about proxying DOM objects, I maintain that it's a bad idea to try to make existing APIs (that expect objects of a very specific type) work with any random proxy, either by interacting with it or by unwrapping it. The cleaner thing to do would be to replace/wrap the API with one that also recognizes and accepts certain proxies (still not just anyone's proxies).
I agree. The selector matching use case convinced me there is no chance to put proxies or weird objects in a DOM tree.

David
_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to