Running JS code in a limited context

I am trying to run trusted JS code in an isolated context. This method was mainly developed:

function limitedEval(src, context) {
    return (function() {
        with(this) {
            return eval(src) 
        }
    }).call(context)
}
Run codeHide result

This works fine, however, when the script uses the keyword var, it is stored in the execution context, and not in the provided context in the with statement (which I understand by design). So, for example, the following code does not work:

var ctx = {};
limitedEval('var foo = "hello"', ctx);
limitedEval('alert(foo)', ctx); // error: foo is undefined
Run codeHide result

I would like to be able to call limitedEval () several times and reuse the context. Is it possible?

+4
source share
1 answer

. , limitedEval. , , var, . 1 . - generators. - , , .

// IIFE to store gen_name
var limitedEval = function() {
    // Symbol for generator property so we don't pollute `ctx` namespace
    var gen_name = Symbol();

    return function limitedEval(src, context) {
        if(!(gen_name in context)) {
            // Generator that will run eval and pause til getting the next source code
            var generator = function * () {
                with(this) {
                    while(true) {
                        yield eval( yield );
                    }
                }
            };

            context[gen_name] = generator.call(context);

            // Initially, we need to execute code until reaching the first `yield`
            context[gen_name].next();
        }

        // First, send the source to the `eval`
        context[gen_name].next( src );

        // Second, get the `eval` result
        return context[gen_name].next().value;
    };
}();

var ctx = {};
limitedEval('var foo = "hello"', ctx);
limitedEval('alert(foo);', ctx);

limitedEval , ctx. , ctx. ctx, var. . ctx, .

, .

: , Symbol with(this) with(context)

+4

Source: https://habr.com/ru/post/1677209/


All Articles