3

I am building a little game and I've gotten to the point where I need to calculate data in the tips of abilities which is unique to each individual unit. So to do this I figured I'm gonna basically need a formula. I don't know if this is the way it's supposed to be done but here's what I've come up with

tip = 'Hurls a fire ball at your enemy, dealing [X] damage.';
formula = '5 * unit.magicPower * abilitylevel';

So for each unit's tool tip I use

tip.replace('[X]', eval(formula))

Which appears to work fine, but what I'm concerned about is the safety of this code. It hasn't been once or twice that I've seen people discouraging the use of it. Are there any potential issues that may occur with the way I'm using eval()?

php_nub_qq
  • 15,199
  • 21
  • 74
  • 144
  • You'll want to use a library built specifically for doing math, or if you need more JavaScript functionality use a sandbox. That's assuming that this formula is arbitrary. – Brad Apr 19 '14 at 21:05

3 Answers3

5

As long as you control the input into eval, it's safe to use it. The concern comes in when you're using it to process input that you don't control. At that point, it becomes unsafe because it's a full JavaScript parser but people sometimes try to use it as just an expression evaluator (for instance, when parsing JSON from a source they don't control).

The other objection is that it's firing up a full JavaScript parser (and so in theory costly), but frankly unless you're doing this hundreds of thousands of times in a tight loop, it's not going to matter.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • 4
    But saying that you can control anything in javascript is like saying you own gravity – php_nub_qq Apr 19 '14 at 21:06
  • 1
    @php_nub_qq: If you're doing `eval("5 * unit.magicPower * abilityLevel")`, and you define `unit` and the other variables, you're controlling the input. There's no magic someone can throw in that makes that unsafe. – T.J. Crowder Apr 19 '14 at 21:08
  • 1
    @T.J.Crowder In those cases though, there is no reason to use `eval()` at all. – Brad Apr 19 '14 at 21:28
  • @Brad: Yeah, use cases are very few and far between. – T.J. Crowder Apr 19 '14 at 22:48
2

eval is very dangerous if any of the expression is supplied by the user. If you're constructing it entirely from built-in components, it's not very dangerous. However, there are still usually better ways of accomplishing it, such as calling closures.

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • 3
    Arguably, it's not dangerous if the input comes from the *current* user; they could, after all, open the web console and do anything. But if you're using `eval` to evaluate input in a user's browser that comes from a *different* user, *that* becomes dangerous. – T.J. Crowder Apr 19 '14 at 21:07
  • @T.J.Crowder Ahhhh now I see. That opened my eyes a lot! – php_nub_qq Apr 19 '14 at 21:08
1

The basic rule of thumb is to make sure that by default you pass your data/information through eval() only.

You can't stop someone with tools like Firebug if they want to mess with stuff obviously but that is what server-side validation is about.

Now if you're talking about server-side eval() then you really have to be careful. Unfortunately there are a lot of uncooperative people working on JavaScript and it's implementations in browsers so you'll be forced to use eval() in JavaScript, I've never had to use it in PHP.

John
  • 1
  • 13
  • 98
  • 177