7

How to convert string to real javascript object if we don't use new Function

var sum = new Function('a', 'b', 'return a + b')
console.log(sum(2, 6))

So 'a', 'b', 'return a + b' is generated by another javascript snippet and everything is string format. eslint suggests do not use Function constrctor The Function constructor is eval. (no-new-func) If not using Function constrctor is there another option can do the same job? Thanks

olo
  • 5,225
  • 15
  • 52
  • 92
  • Fix the code which generates the string you are evaling so it generates something else. – Quentin Jun 28 '19 at 08:40
  • 1
    This **has** to have a dupetarget ... – T.J. Crowder Jun 28 '19 at 08:40
  • @GrafiCodeStudio - Except the answers there are predominantly "Use new Function" (because the question is about avoiding `eval`). – T.J. Crowder Jun 28 '19 at 08:41
  • @T.J.Crowder I thought OP wanted to avoid eval too – GrafiCode Jun 28 '19 at 08:41
  • @GrafiCodeStudio - Right, but pointing them at answers saying "use new Function instead" isn't really helpful. :-) – T.J. Crowder Jun 28 '19 at 08:42
  • `everything is string format` -- what you are trying to do is eval a string. This goes to the very core of the eslint warning - **it does not want you to eval strings as code**. So no matter what mechanism you try you should in theory get that warning – slebetman Jun 28 '19 at 08:42
  • I don't think there's a way around `eval` or `new Function` or a parser that effectively does the same thing - just disable the linter rule, maybe? – CertainPerformance Jun 28 '19 at 08:42
  • How is `'return a + b'` generated? Is it always going to be a mathematical equation? – nick zoum Jun 28 '19 at 08:43
  • eslint says that mostly to help devs avoid XSS attacks as both `Function` and `eval` are prime vectors for attack. If you're sure of the integrity of the string being passed into `Function` (ie it's something you've created and not passed in from a user-facing form) you can probably carry on using it, and turn off the eslint rule. – Andy Jun 28 '19 at 08:43
  • @GrafiCodeStudio - But I agree that there *has* to be a dupetarget for this. :-) Still looking... – T.J. Crowder Jun 28 '19 at 08:46
  • [Related](https://stackoverflow.com/questions/55896785/javascript-write-a-function-that-can-solve-a-math-expression-without-eval) if the function really does math. – T.J. Crowder Jun 28 '19 at 08:47
  • (Have to get to work and this is surprisingly hard to search for... :-) ) – T.J. Crowder Jun 28 '19 at 08:51
  • 1
    @T.J.Crowder this one is highly-commented: https://stackoverflow.com/questions/44567324/create-js-function-from-string-without-eval-and-new-function "Without eval AND Function" – GrafiCode Jun 28 '19 at 10:17
  • @GrafiCodeStudio - Great find! – T.J. Crowder Jun 28 '19 at 10:25

1 Answers1

8

...is there another option can do the same job?

There is (eval), but it's even worse than new Function.

Creating a function from a string is fundamentally insecure. If you can absolutely trust that the string is safe and you have no choice but to convert a string into a function, then new Function is the right tool.

But instead, the better option is to avoid having to create a function from a string.


Re the "absolutely trust" bit, here's an example of what not to do: Don't allow Bob to provide the string, and then use that string as code in Alice's environment (her browser, or worse in an unrestricted environment like Node.js). Doing so exposes Alice to a security risk. (Obviously, on sites like SO, if Alice is a programmer and can read the code before running it, that's different. ;-) )

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • 1
    Thanks! yes, I got `eval can be harmful. (no-eval)` then looks like `new Function` seems a must for this use case – olo Jun 28 '19 at 08:44
  • @olo Not if you are only using this for math expressions. Please check [the following fiddle](https://jsfiddle.net/nick_zoum/rkqzywpe/10/) – nick zoum Jun 28 '19 at 11:14