Access imported functions from evaled code

456 Views Asked by At

I have a TypeScript file with the following code:

import { functionTest } from './function_test'

function runnerFunctionTest() {
    console.log("Test");
}

export class Runner {
    run(source : string) {
        eval(source);
    }
}

If I instantiate a Runner and call run("runnerFunctionTest();") the function runs correctly, but if I call run("functionTest();") (which should run the imported function) I get an error saying functionTest is undefined.

How can I fix this?

One thing I tried was replacing the code in run with new Function('functionTest', source).(functionTest); which worked but it will be really annoying to have to add all the imported functions like that - there are around 20 of them and that number will only increase as time goes on.

Also, I am aware of the security implications of calling eval - it is the only way (at least that I know of) to do what I want, which is running arbitrary JavaScript code generated by the user in the user's browser.

1

There are 1 best solutions below

0
On BEST ANSWER

Because import is not a native operator, webpack (or something else) transform it for you. After compiled by webpack, you code becomes:

/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Runner", function() { return Runner; });
/* harmony import */ var _function_test__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2);

function runnerFunctionTest() {
    console.log("Test");
}

class Runner {
    run(source) {
        eval(source);
    }
}

The name functionTest is not existed anymore, that why you can't eval it.

One possible solution is to give it a local name:

import { functionTest } from './function_test'
const function_test = functionTest;
function runnerFunctionTest() {
    console.log("Test");
}

export class Runner {
    run(source : string) {
        eval(source);
    }
}

Then you can run runner.run('function_test()')