New Proposal: ES Call Stack

Ranando King kingmph at gmail.com
Mon Jan 14 22:01:56 UTC 2019


Isiah, that works when you're in full control of all the code. However,
when you're writing B, and A is 3rd party (or the reverse in DI cases) then
the API is out of your control. In cases like that, it's better if the data
itself knew the restrictions. That keeps dependencies low.

On Mon, Jan 14, 2019 at 3:57 PM Ranando King <kingmph at gmail.com> wrote:

> We agree trying to learn about the caller should not affect how the caller
> works. That's why I was thinking more on the lines of an "id" carried
> around by every function object. As long as that "id" uniquely identified
> the function without providing any access to the function itself, it would
> satisfy my needs as well as TC39 and engine builder constraints.
>
> On Mon, Jan 14, 2019 at 1:31 AM Isiah Meadows <isiahmeadows at gmail.com>
> wrote:
>
>> You could substitute a function parameter accepting an object here or a
>> class instance for globals to dodge this. Doesn't change my point.
>>
>> Here's how you deal with permissions like that: have A know what data B
>> is allowed to access, then pass B an object with only that data. If
>> necessary, make the exposed methods form a closure over the relevant
>> private data.
>>
>> On Mon, Jan 14, 2019 at 00:50 Ranando King <kingmph at gmail.com> wrote:
>>
>>> That's all fine and dandy until you're dealing with a project that has a
>>> "no globals" mandate. The problem that I'd want to be able to solve is one
>>> of gaining and losing control during a single function's execution.
>>> For example: say function A is privileged, but function B is not. Function
>>> A calls function B with some data that B should only partially be able to
>>> access. Right now, that's hardly possible. There's no way for the data
>>> being passed to know if it is ok for B to use those functions or
>>> properties. If it was possible for the data methods to peek at the stack
>>> and recognize that the current function isn't privileged, then the problem
>>> is solved.
>>>
>>> I know class-fields will make this a little easier, but it doesn't
>>> solve the problem, especially when there's a "no constructors" mandate.
>>>
>>> On Sun, Jan 13, 2019 at 9:08 PM Isiah Meadows <isiahmeadows at gmail.com>
>>> wrote:
>>>
>>>> As for security, scope control is usually the more important thing to
>>>> monitor. That's covered in realms for the most part, but also a few other
>>>> things. Stack traces don't play a major part here, and whenever untrusted
>>>> calls need made and tracked through the stack, it's not that hard to just
>>>> save and restore global data as needed.
>>>> On Sun, Jan 13, 2019 at 22:05 Isiah Meadows <isiahmeadows at gmail.com>
>>>> wrote:
>>>>
>>>>> You may be interested in this:
>>>>> https://github.com/tc39/proposal-error-stacks
>>>>> On Sun, Jan 13, 2019 at 22:02 Ranando King <kingmph at gmail.com> wrote:
>>>>>
>>>>>> ES used to have Function.caller for traversing the call stack, but
>>>>>> apparently this was very problematic for engine development and prevented
>>>>>> various optimizations. So now it doesn't work in strict mode which makes it
>>>>>> useless for code involving `"use strict"` or `class`. One of the main use
>>>>>> cases for such functionality was being able to determine where a given
>>>>>> function was called from.
>>>>>>
>>>>>> I was thinking of a global static class that is able to uniquely
>>>>>> identify each execution context on the call stack without giving any access
>>>>>> to the context objects themselves. I was thinking of maybe something like
>>>>>> this:
>>>>>>
>>>>>> ```js
>>>>>> class CallStackEntry {
>>>>>>   #className;    //Name of the class or null
>>>>>>   #functionName; //Name of the function or null
>>>>>>   #fileName;     //Name of the source file or null
>>>>>>   #line;         //Source line number
>>>>>>   #offset;       //Source character offset on the line
>>>>>>   #id;           //Symbol
>>>>>>   get fileName() { return this.#filename; }
>>>>>>   get line() { return this.#line; }
>>>>>>   get offset() { return this.#offset; }
>>>>>>   get id() { return this.#id; }
>>>>>>   constructor(_fileName, _line_, _offset, _id) {
>>>>>>     this.#fileName = _fileName;
>>>>>>     this.#line = _line;
>>>>>>     this.#offset = _offset;
>>>>>>     this.#id = _id;
>>>>>>   }
>>>>>> }
>>>>>>
>>>>>> class CallStack {
>>>>>>   static #callStack = []; //Internally managed
>>>>>>   static get stackLimit() {...}
>>>>>>   static set stackLimit(v) {...}
>>>>>>   static get stack() {
>>>>>>     //return the call stack as an array of CallStackEntry objects
>>>>>>   }
>>>>>> }
>>>>>> ```
>>>>>>
>>>>>> With something like this, security-type software would be able to
>>>>>> clearly identify functions without granting any access rights to the
>>>>>> corresponding function.
>>>>>>
>>>>>>
>>>>>> _______________________________________________
>>>>>> 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/20190114/ec96b4d4/attachment-0001.html>


More information about the es-discuss mailing list