Why exactly is eval evil?

前端 未结 12 1411
没有蜡笔的小新
没有蜡笔的小新 2020-11-22 09:51

I know that Lisp and Scheme programmers usually say that eval should be avoided unless strictly necessary. I’ve seen the same recommendation for several program

相关标签:
12条回答
  • 2020-11-22 10:13

    Eval is just unsecure. For example you have following code:

    eval('
    hello('.$_GET['user'].');
    ');
    

    Now user comes to your site and enters url http://example.com/file.php?user=);$is_admin=true;echo(

    Then the resulting code would be:

    hello();$is_admin=true;echo();
    
    0 讨论(0)
  • 2020-11-22 10:17

    Another couple of points on Lisp eval :

    • It evaluates under the global environment, losing your local context.
    • Sometimes you may be tempted to use eval, when you really meant to use the read-macro '#.' which evaluates at read-time.
    0 讨论(0)
  • 2020-11-22 10:18

    There have been many great answers but here is another take from Matthew Flatt, one of the implementers of Racket:

    http://blog.racket-lang.org/2011/10/on-eval-in-dynamic-languages-generally.html

    He makes many of the points that have already been covered but some people may find his take interesting nonetheless.

    Summary: The context in which it's used affects the result of eval but is often not considered by programmers, leading to unexpected results.

    0 讨论(0)
  • 2020-11-22 10:19

    eval (in any language) is not evil in the same way that a chainsaw is not evil. It is a tool. It happens to be a powerful tool that, when misused, can sever limbs and eviscerate (metaphorically speaking), but the same can be said for many tools in a programmer's toolbox including:

    • goto and friends
    • lock-based threading
    • continuations
    • macros (hygenic or other)
    • pointers
    • restartable exceptions
    • self-modifying code
    • ...and a cast of thousands.

    If you find yourself having to use any of these powerful, potentially dangerous tools ask yourself three times "why?" in a chain. For example:

    "Why do I have to use eval?" "Because of foo." "Why is foo necessary?" "Because ..."

    If you get to the end of that chain and the tool still looks like it's the right thing to do, then do it. Document the Hell out of it. Test the Hell out of it. Double-check correctness and security over and over and over again. But do it.

    0 讨论(0)
  • 2020-11-22 10:28

    IMO, this question is not specific to LISP. Here is an answer on the same question for PHP, and it applies to LISP, Ruby, and other other language that has an eval:

    The main problems with eval() are:

    • Potential unsafe input. Passing an untrusted parameter is a way to fail. It is often not a trivial task to make sure that a parameter (or part of it) is fully trusted.
    • Trickyness. Using eval() makes code clever, therefore more difficult to follow. To quote Brian Kernighan "Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it"

    The main problem with actual use of eval() is only one:

    • inexperienced developers who use it without enough consideration.

    Taken from here.

    I think the trickyness piece is an amazing point. The obsession with code golf and concise code has always resulted in "clever" code (for which evals are a great tool). But you should write your code for readability, IMO, not to demonstrate that you're a smarty and not to save paper (you won't be printing it anyway).

    Then in LISP there's some problem related to the context in which eval is run, so untrusted code could get access to more things; this problem seems to be common anyway.

    0 讨论(0)
  • 2020-11-22 10:29

    "When should I use eval?" might be a better question.

    The short answer is "when your program is intended to write another program at runtime, and then run it". Genetic programming is an example of a situation where it likely makes sense to use eval.

    0 讨论(0)
提交回复
热议问题