CSC/ECE 517 Fall 2012/ch1 1w28 mv: Difference between revisions
No edit summary |
No edit summary |
||
(18 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
= eval = | |||
Eval function in most of the languages will either be a valid string representing expression in the language or some languages may allow blocks of valid code. The input is executed by the interpreter or compiler in same manner as other code in the language. | |||
= Advantage of eval = | |||
eval is useful for writing metaprogamming code in most of the languages. This is a great asset for statically typed languages where most of the operatioons are performed at the compile time. Consider the following case: | |||
Problem statement: | |||
Write a script to accept directories and pattern as input and send the files matching the pattern to a different server using sftp. | |||
We can maintain a string to store all the filenames to be moved to a directory on destination server preceded with appropriate sftp commands and use eval method to execute those commands in batch mode. | |||
= Disadvantages of eval = | |||
=== Slow in Execution === | |||
The code executed by eval runs slower, thus , whenever possible alternative techniques should be used. | |||
=== Security Risks === | |||
[[File:Security-risk.png|thumb|Border "border"|Location|Alignment|Size 0.5|link=http://expertiza.csc.ncsu.edu/wiki/index.php/File:Security-risk.png|alt=Alt|eval as a dangerous method in PHP]] | |||
'''JavaScript eval()''' | |||
<br>Because most JSON-formatted text is also syntactically legal JavaScript code, an easy way for a JavaScript program to parse JSON-formatted data is to use the built-in JavaScript eval() function, which was designed to evaluate JavaScript expressions. Rather than using a JSON-specific parser, the JavaScript interpreter itself is used to execute the JSON data to produce native JavaScript objects. However, there are some Unicode characters that are valid in JSON strings but invalid in JavaScript, so additional escaping would be needed before using a JavaScript interpreter. | |||
Unless precautions are taken to validate the data first, the eval technique is subject to security vulnerabilities if the data and the entire JavaScript environment is not within the control of a single trusted source. For example, if the data is itself not trusted, it may be subject to malicious JavaScript code injection attacks. Also, such breaches of trust may create vulnerabilities for data theft, authentication forgery, and other potential misuse of data and resources. Regular expressions can be used to validate the data prior to invoking eval(). Consider the following contrived example: | |||
[[File:Problem-eval.png|thumb|Border "border"|Location|Alignment|Size 0.5|link=http://expertiza.csc.ncsu.edu/wiki/index.php/File:Problem-eval.png|alt=Alt|JavaScript eval risk ]] | |||
''' <html> <br><head><br></head><br><body><br><script type="text/javascript" lang="javascript"> ''' | |||
'''alert("some problem");<br>var evalstring="obj={ name:'username',address: '238 Milton , st. Mary , WT 87382'}; ''' | |||
'''alert('This is malicious code');";<br>eval(evalstring);<br></script><br></body><br></head><br> </html> ''' | |||
Let's assume that the client side script is expecting a JSON object from the server. However, along with the JSON object it can also send other valid javascript statement. If the above code is run in the browser, after the execution of eval there will be an alert message saying 'This is malicious code'. The alert statement represents a placeholder for any malacious javascript code. This can be avoided by using the safe Javascript library at JSON.org which contains the JSON.parse method. | |||
= eval in Different Languages = | |||
== Perl == | |||
The general form of [[Perl (programming language)|Perl]] expects an expression or a block of code as an expression. The expression passed as an argument is parsed and executed as small Perl program. If there are no errors in the expression , which is parsed , then it is executed within the lexical context of the current Perl program. | |||
=== Error Handling with eval === | |||
Eval can be used to trap the errors. During execution of the routines , the program might die due to errors and interrupt the code. However , using eval , the code can still be running if the errors are handled inside the eval without being exited. We can evaluate the functionality of eval from the given code.<br> | |||
''' print "enter number 1 \n"; <br>$number1 = <STDIN>; <br>chomp $number1; <br>print "enter number 2 \n"; <br>$number2 = <STDIN>; ''' '''<br>chomp $number2; <br>print "division output is "; <br>$x =eval {$result = $number1/$number2}; <br>print "$x\n$@"; <br>$sum =''' '''$number1 + $number2; <br>print "sum is $sum \n"; <br>''' | |||
The above given code prompts the user to give 2 inputs and then performs the division and addition of the numbers. If the second number entered by the user is 0 , then in that case code exits showing the error message and it does not calculate the addition. However , we can handle this exception using eval. Eval handles the exception, shows the appropriate error message and then return the control back to the program without exiting it. Hence , even if the second input is 0 , the addition is performed by the eval method. | |||
== Ruby == | |||
Most non-compiled languages have some kind of eval function, which will take a string and execute it as code. The eval method in Ruby accomplishes this, and is rather straightforward. The prototype of eval | |||
eval(string [, binding [, filename [,lineno]]]) → obj. | |||
Consider the following example code:<br> | |||
''' #!/usr/bin/env ruby<br>code = "Time.now"<br>result = eval(code)<br>puts result'''<br> | |||
The method call Time.now is stored in a string. It's not executed, compiled or even looked at (other than determining that it's a string literal) by the Ruby interpreter. It's just a string, anything could be in there. However, once you call the eval method, that all changes. The Ruby interpreter parses this string as if it were Ruby code and runs it. It will return whatever the code evaluates to. | |||
Simple enough, but why would anyone want to use this? There's a lot of debate whether eval should be used, and it's often considered bad form and hackish. There are also some pretty big security implications in using eval at all in your code, so it's not something that should be used lightly. There is one great use for eval though: developer consoles. Adding a way for programmers to issue Ruby commands to your program directly by using eval can be a powerful debugging tool and quite easy to implement. | |||
''' Using bindings in eval: ''' | |||
You can use eval to run code from a string, but things are not as simple as they seem. The eval method executes code, but where in the program is that code executed? The context in which code is executed is called a binding. Code is bound to a context of instance variable, local variables, and global variables. If you were to reference the variable x, it's up to the binding to decide which variable named x you're referring to. Examine the following code.<br> | |||
'''#!/usr/bin/env ruby<br>def func<br>x = 1337<br>return binding<br>end<br>x = 10<br>binding = func()<br>puts''' | |||
'''eval("x", binding)<br>puts eval("x")<br>bind1 = func(1337)<br>''' | |||
'''bind2 = func(404)<br>puts eval("number", bind1)<br>puts eval("number", bind2)''' | |||
This program works just as you would expect. Two invocations of the func method, and two numbers printed out. Bindings are an interesting feature, but just like eval, their use is controversial. While they can be useful at times, there's often a better way to achieve the same result. | |||
== PHP == | |||
In PHP, eval executes code in a string almost exactly as if it had been put in the file instead of the call to eval(). The only exception is that errors are reported as coming from a call to eval(), and return statements become the result of the function. | |||
Unlike some languages, the argument to eval must be a string of one or more complete statements, not just expressions; however, one can get the "expression" form of eval by putting the expression in a return statement, which causes eval to return the result of that expression.<br> | |||
'''eval prototype''' : mixed eval ( string $code ) | |||
The code in eval doesn't have to be wrapped in PHP tags ( <?php ?> ). If there is parse error in the argument to eval then it returns false. eval can return a value if the last statement in the argument passed to eval has a return statement then eval will return a value which can be stored in a string.<br> | |||
'''<?php<br>$string = 'cup';<br>$name = 'coffee';<br>$str = 'This is a $string with my $name in it.';''' | |||
'''<br>echo $str. "\n";<br>eval("\$str = \"$str\";");<br>echo $str. "\n";<br>?>''' | |||
The above code will output<br> | |||
"This is a $string with my $name in it.<br> | |||
This is a cup with my coffee in it."<br> | |||
Unlike perl if there is a fatal error in the code passed to eval the whole script exits. | |||
= References = | |||
http://ruby.about.com/od/advancedruby/a/Eval-Running-Code-On-The-Fly.htm<br> | |||
http://php.net/manual/en/function.eval.php<br> | |||
http://www.ruby-doc.org/core-1.9.3/Kernel.html<br> | |||
http://en.wikipedia.org/wiki/Eval#PHP<br> | |||
http://img.com.com/i/tr/bldr/pub/evalcalc.html?eq=<br> |
Latest revision as of 03:30, 20 September 2012
eval
Eval function in most of the languages will either be a valid string representing expression in the language or some languages may allow blocks of valid code. The input is executed by the interpreter or compiler in same manner as other code in the language.
Advantage of eval
eval is useful for writing metaprogamming code in most of the languages. This is a great asset for statically typed languages where most of the operatioons are performed at the compile time. Consider the following case:
Problem statement: Write a script to accept directories and pattern as input and send the files matching the pattern to a different server using sftp.
We can maintain a string to store all the filenames to be moved to a directory on destination server preceded with appropriate sftp commands and use eval method to execute those commands in batch mode.
Disadvantages of eval
Slow in Execution
The code executed by eval runs slower, thus , whenever possible alternative techniques should be used.
Security Risks
JavaScript eval()
Because most JSON-formatted text is also syntactically legal JavaScript code, an easy way for a JavaScript program to parse JSON-formatted data is to use the built-in JavaScript eval() function, which was designed to evaluate JavaScript expressions. Rather than using a JSON-specific parser, the JavaScript interpreter itself is used to execute the JSON data to produce native JavaScript objects. However, there are some Unicode characters that are valid in JSON strings but invalid in JavaScript, so additional escaping would be needed before using a JavaScript interpreter.
Unless precautions are taken to validate the data first, the eval technique is subject to security vulnerabilities if the data and the entire JavaScript environment is not within the control of a single trusted source. For example, if the data is itself not trusted, it may be subject to malicious JavaScript code injection attacks. Also, such breaches of trust may create vulnerabilities for data theft, authentication forgery, and other potential misuse of data and resources. Regular expressions can be used to validate the data prior to invoking eval(). Consider the following contrived example:
<html>
<head>
</head>
<body>
<script type="text/javascript" lang="javascript">
alert("some problem");
var evalstring="obj={ name:'username',address: '238 Milton , st. Mary , WT 87382'};
alert('This is malicious code');";
eval(evalstring);
</script>
</body>
</head>
</html>
Let's assume that the client side script is expecting a JSON object from the server. However, along with the JSON object it can also send other valid javascript statement. If the above code is run in the browser, after the execution of eval there will be an alert message saying 'This is malicious code'. The alert statement represents a placeholder for any malacious javascript code. This can be avoided by using the safe Javascript library at JSON.org which contains the JSON.parse method.
eval in Different Languages
Perl
The general form of Perl expects an expression or a block of code as an expression. The expression passed as an argument is parsed and executed as small Perl program. If there are no errors in the expression , which is parsed , then it is executed within the lexical context of the current Perl program.
Error Handling with eval
Eval can be used to trap the errors. During execution of the routines , the program might die due to errors and interrupt the code. However , using eval , the code can still be running if the errors are handled inside the eval without being exited. We can evaluate the functionality of eval from the given code.
print "enter number 1 \n";
$number1 = <STDIN>;
chomp $number1;
print "enter number 2 \n";
$number2 = <STDIN>;
chomp $number2;
print "division output is ";
$x =eval {$result = $number1/$number2};
print "$x\n$@";
$sum = $number1 + $number2;
print "sum is $sum \n";
The above given code prompts the user to give 2 inputs and then performs the division and addition of the numbers. If the second number entered by the user is 0 , then in that case code exits showing the error message and it does not calculate the addition. However , we can handle this exception using eval. Eval handles the exception, shows the appropriate error message and then return the control back to the program without exiting it. Hence , even if the second input is 0 , the addition is performed by the eval method.
Ruby
Most non-compiled languages have some kind of eval function, which will take a string and execute it as code. The eval method in Ruby accomplishes this, and is rather straightforward. The prototype of eval
eval(string [, binding [, filename [,lineno]]]) → obj.
Consider the following example code:
#!/usr/bin/env ruby
code = "Time.now"
result = eval(code)
puts result
The method call Time.now is stored in a string. It's not executed, compiled or even looked at (other than determining that it's a string literal) by the Ruby interpreter. It's just a string, anything could be in there. However, once you call the eval method, that all changes. The Ruby interpreter parses this string as if it were Ruby code and runs it. It will return whatever the code evaluates to.
Simple enough, but why would anyone want to use this? There's a lot of debate whether eval should be used, and it's often considered bad form and hackish. There are also some pretty big security implications in using eval at all in your code, so it's not something that should be used lightly. There is one great use for eval though: developer consoles. Adding a way for programmers to issue Ruby commands to your program directly by using eval can be a powerful debugging tool and quite easy to implement.
Using bindings in eval:
You can use eval to run code from a string, but things are not as simple as they seem. The eval method executes code, but where in the program is that code executed? The context in which code is executed is called a binding. Code is bound to a context of instance variable, local variables, and global variables. If you were to reference the variable x, it's up to the binding to decide which variable named x you're referring to. Examine the following code.
#!/usr/bin/env ruby
def func
x = 1337
return binding
end
x = 10
binding = func()
puts
eval("x", binding)
puts eval("x")
bind1 = func(1337)
bind2 = func(404)
puts eval("number", bind1)
puts eval("number", bind2)
This program works just as you would expect. Two invocations of the func method, and two numbers printed out. Bindings are an interesting feature, but just like eval, their use is controversial. While they can be useful at times, there's often a better way to achieve the same result.
PHP
In PHP, eval executes code in a string almost exactly as if it had been put in the file instead of the call to eval(). The only exception is that errors are reported as coming from a call to eval(), and return statements become the result of the function.
Unlike some languages, the argument to eval must be a string of one or more complete statements, not just expressions; however, one can get the "expression" form of eval by putting the expression in a return statement, which causes eval to return the result of that expression.
eval prototype : mixed eval ( string $code )
The code in eval doesn't have to be wrapped in PHP tags ( <?php ?> ). If there is parse error in the argument to eval then it returns false. eval can return a value if the last statement in the argument passed to eval has a return statement then eval will return a value which can be stored in a string.
<?php
$string = 'cup';
$name = 'coffee';
$str = 'This is a $string with my $name in it.';
echo $str. "\n";
eval("\$str = \"$str\";");
echo $str. "\n";
?>
The above code will output
"This is a $string with my $name in it.
This is a cup with my coffee in it."
Unlike perl if there is a fatal error in the code passed to eval the whole script exits.
References
http://ruby.about.com/od/advancedruby/a/Eval-Running-Code-On-The-Fly.htm
http://php.net/manual/en/function.eval.php
http://www.ruby-doc.org/core-1.9.3/Kernel.html
http://en.wikipedia.org/wiki/Eval#PHP
http://img.com.com/i/tr/bldr/pub/evalcalc.html?eq=