- From: Maciej Stachowiak <mjs@apple.com>
- Date: Sat, 15 Feb 2014 01:57:02 -0800
- To: Erik Arvidsson <arv@chromium.org>
- Cc: Alex Russell <slightlyoff@google.com>, Elliott Sprehn <esprehn@chromium.org>, Dimitri Glazkov <dglazkov@chromium.org>, Arthur Barstow <art.barstow@nokia.com>, "public-webapps@w3.org WG" <public-webapps@w3.org>, Boris Zbarsky <bzbarsky@mozilla.com>
- Message-id: <F39439F6-5CE6-414F-BB21-0DD4D81F92C9@apple.com>
On Feb 14, 2014, at 9:00 AM, Erik Arvidsson <arv@chromium.org> wrote: > > > > On Thu, Feb 13, 2014 at 9:00 PM, Maciej Stachowiak <mjs@apple.com> wrote: > > On Feb 13, 2014, at 4:01 PM, Alex Russell <slightlyoff@google.com> wrote: >> A closure is an iron-clad isolation mechanism for object ownership with regards to the closing-over function object. There's absolutely no iteration of the closed-over state of a function object; any such enumeration would be a security hole (as with the old Mozilla object-as-param-to-eval bug). You can't get the value of "foo" in this example except with the consent of the returned function: > >> >> var maybeVendFoo = function() { >> var foo = 1; >> return function(willMaybeCall) { >> if (/* some test */) { willMaybeCall(foo); } >> } >> }; >> >> Leakage via other methods can be locked down by the first code to run in an environment (caja does this, and nothing prevents it from doing this for SD as it can pre-process/filter scripts that might try to access internals). > > Caja is effective for protecting a page from code it embeds, since the page can have a guarantee that its code is the first to run. But it cannot be used to protect embedded code from a page, so for example a JS library cannot guarantee that objects it holds only in closure variables will not leak to the surrounding page... > > That is incorrect. It is definitely possible to write code that does not leak to the environment. It is painful to do because like Ryosuke wrote you cannot use any of the built in functions or objects. You can only use primitives and literals. But with a compile to JS language this can be made less painful and in the days of LLVM to JS compilers this seems like a trivial problem. Let's assume for the sake of argument that there was actually a practical way to do this for nontrivial code[*]. Even if that were the case, it would not be relevant to the way in which today's JS programs use closures. They find closures useful even without a transpiler to a primitives-only subset of the language. So one cannot claim the value of closures for encapsulation follows from this theoretical possibility. Regards, Maciej * - And really, it is not that practical. Many algorithms require a variable-sized data structure, or one that is indexable, or one that is associative - and you can't do any of that with only primitives and a fixed set of variable slots. And you can't do anything to a primitive that would potentially invoke a method call explicitly or implicitly, which includes such things as number-to-string conversion, using functions on the Math object on numbers, and the majority of things you would do to a string (such as converting to/from char codes). What remains is pretty narrow. This is setting aside that you would not be able to do anything useful to the outside world besides return a value. For reference, the LLVM-to-JS compilers that exist make major use of non-primitives, in particular Emscripten uses a giant typed array to represent memory.
Received on Saturday, 15 February 2014 09:57:38 UTC