473,320 Members | 1,979 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

eval() is insecure, but what are the alternatives?

Hi!

I don't want to use eval() in order to parse a user-supplied formula.
What alternatives do I have? PHP has no standard functionality for
tokenizing or parsing expressions in this regard.

Here is a simple example: The user supplies the following formula in
string format,
"a = (6+10)/4",
and the script needs to find out what the value of 'a' is.

How can I go about it without using eval(), since using eval in this
case could be very risky! (The user can supply *any* expression, as
there is no function that can determine the meaning of the string as an
expression).

Thank you for taking the time t read my question.

Jan 20 '06 #1
8 12861
There are several options:
1. Check the user input to only contain number, operators and
parenthesis and then supply it to eval. This would be safer than using
eval without checking, but it may still be insecure and it is not the
right option. If you need to accept variables and functions in the
expression, making this secure becomes close to impossible.
2. You may parse the expression and compute the result using PHP code.
This is a better option, but may not be worth the time it takes to
write a parser.

I tried searching the web for a math expression parser, but I did not
found one. I have written something to get you started:
http://svn.linuxonly.nl/filedetails....calculator.php
It is not complete. It does not check parenthesis and does not give
precendence to * over + (for example). It converts the expression to
Reverse Polish notation and than computes it.

If you want to extend my file, you may find
http://en.wikipedia.org/wiki/Reverse_Polish_Notation interesting.
Please send any new version to me.

Good luck.

Jan 20 '06 #2
werner wrote:
I don't want to use eval() in order to parse a user-supplied formula.
What alternatives do I have? PHP has no standard functionality for
tokenizing or parsing expressions in this regard.
Other than writing your own parser (or using one already done), I don't
think you have any alternatives.
Here is a simple example: The user supplies the following formula in
string format,
"a = (6+10)/4",
and the script needs to find out what the value of 'a' is.

How can I go about it without using eval(), since using eval in this
case could be very risky! (The user can supply *any* expression, as
there is no function that can determine the meaning of the string as an
expression).


Example using an already done parser (bc):

<?php
/* needs error checking */
$formula = 'a = (6+10)/4';

/* remove the left part of assignment */
$value = trim(substr($formula, strpos($formula, '=')+1));
$value = escapeshellarg($value);

$calculated = `echo $value | bc`; /* backticks! */
echo $calculated, "\n";
?>

tmp$ php foo.php
4

"bc" is "an arbitrary precision numeric processing language"
http://www.gnu.org/software/bc/bc.html

But, even so, I wouldn't pass input from the user directly to bc without
checking/validating it first (at least not until I've read thoroughly
bc's documentation).

--
If you're posting through Google read <http://cfaj.freeshell.org/google>
Jan 20 '06 #3
There is bc under Unix. Although inserting user-supplied data into a
shell command might be even more dangerous.

Jan 20 '06 #4
Chung Leong wrote:
There is bc under Unix. Although inserting user-supplied data into a
shell command might be even more dangerous.


There's also bc for Windows:
http://gnuwin32.sourceforge.net/packages/bc.htm

And I agree that passing user data to a shell command is dangerous.
but maybe this is enough protection:

$formula = 'user data';
if preg_match('/^[-+*/^()\s0-9]+$/', $formula) {
/* do shell command with properly escaped data */
} else {
/* bad entry */
}

--
If you're posting through Google read <http://cfaj.freeshell.org/google>
Jan 20 '06 #5
Thanks for the input, this topic has had me wrestling with PHP for
quite some time.

Pedro Graca wrote:
$formula = 'user data';
if preg_match('/^[-+*/^()\s0-9]+$/', $formula) {
/* do shell command with properly escaped data */
} else {
/* bad entry */
}
Well, since the user should be able to supply arbitrary variables in
the expression (which will then make the whitelist filtering approach a
bit hard to accomplish, e.g. we'll need to add a "[a-z]+" in there as
well), some innocent-looking "expressions" like 'rm -rf *' might still
slip through.
I have written something to get you started:
http://svn.linuxonly.nl/filedetails....uxonly.nl&path...
It is not complete. It does not check parenthesis and does not give
precendence to * over + (for example). It converts the expression to
Reverse Polish notation and than computes it.
Thanks for the help! I agree with the parser suggestion and have also
previously searched for an expression parser, as this would be the best
approach. I just can't *believe* that there isn't one yet, considering
the complexity of classes found in Pear, Pecl and those made for
academic and educational purposes.

I am also looking at maybe porting an existing Java solution, what do
you think? It's just going to take some time, and I sadly don't have
much of that left.
There is bc under Unix. Although inserting user-supplied data into a
shell command might be even more dangerous.


That is also an interesting approach, but I do feel that I would like
to keep it a native php solution.

Funny thing, though, that there is no native parser function available,
since PHP is after all an interpreted language. Something like eval()
that could return tokens, instead of the evaluated value would be
*extremely* helpful in this regard. What do you think?

Thanks again, everyone.

Jan 20 '06 #6
werner wrote:
I agree with the parser suggestion and have also
previously searched for an expression parser, as this would be the best
approach.

I am also looking at maybe porting an existing Java solution, what do
you think? It's just going to take some time, and I sadly don't have
much of that left.
Use bc! :-)
There is bc under Unix. Although inserting user-supplied data into a
shell command might be even more dangerous.


My example (below) looks safe. It could be made tighter by checking for
long lines, disabling single quotes and "strange" characters (ESC, NUL,
....), and whatever else you might think of.

.... but bc is, perhaps, best discussed on gnu.utils.help.
That is also an interesting approach, but I do feel that I would like
to keep it a native php solution.

<?php
$formula = <<<FORMULA
/*
* find the hypotenuse of a right triangle
* with height = 5 and area = 25
*/

/* !!!! ATTENTION !!! */
rm -rf * ## I tried it!!
## it seems perfectly safe (???)
/* !!! ATTENTION !!! */

scale = 8 ## work with 8 decimals

/* area = h * w / 2 */
h = 5 ## height
area = 25 ## area
w = 2*area / h ## compute width

/* hypotenuse = sqrt(h*h + w*w) */
hyp = sqrt(h*h + w*w) ## compute hypotenuse
hyp ## print (and return) it
FORMULA;

$value = escapeshellarg($formula);
$calculated = `echo $value | bc`; /* backticks! */

// with "rm" in the formula, $calculated will have the error message
// from bc; it might be possible to remove all messages with a
// simple regular expression, I didn't look into that.
echo $calculated;
?>

--
If you're posting through Google read <http://cfaj.freeshell.org/google>
Jan 21 '06 #7
werner wrote:
Hi!

I don't want to use eval() in order to parse a user-supplied formula.
What alternatives do I have? PHP has no standard functionality for
tokenizing or parsing expressions in this regard.

<snip>

You may do sand boxing with <http://in2.php.net/runkit>

--
<?php echo 'Just another PHP saint'; ?>
Email: rrjanbiah-at-Y!com Blog: http://rajeshanbiah.blogspot.com/

Jan 21 '06 #8
http://muparser.sourceforge.net/
if you want to convert the code. fairly complex. better make this one a DLL
extension of PHP.

"Pedro Graca" <he****@dodgeit.com> wrote in message
news:sl*******************@ID-203069.user.individual.net...
werner wrote:
I agree with the parser suggestion and have also
previously searched for an expression parser, as this would be the best
approach.

I am also looking at maybe porting an existing Java solution, what do
you think? It's just going to take some time, and I sadly don't have
much of that left.


Use bc! :-)


http://us2.php.net/manual/en/ref.bc.php (does not have eval-like function)
instead of using backticks, use the library?

http://www.bestcode.com/html/bcparserx.html COM control that evals math,
co$t$ money.
http://www.freevbcode.com/ShowCode.asp?ID=2090 vree vb parser, not too
complicated. I am converting it now. here.

<?php
//Attribute VB_Name = "Module1"
/*
' Acclaimer and Disclaimer!
'************************************************* ********************************************
'* This code is written by Jonathan Adamit (c) 20th in December
2000. *
'* I Am in no way responsible for anything that occures as a result of
implementing *
'* this code or by using it in any way.
*
'* This code is given to you for free to do whatever you want to do with
it. *
'* My only request is that if you use it - you give me the credit for it.
*
'* I will also be very greatful if you E-mail me any improvements or
changes you made to it.*
'* Any comments or changes are to be sent to:
ad****@bgumail.bgu.ac.il *
'************************************************* ********************************************
version 1.0

'
' Example of use and remarks!
'************************************************* ************************************************** **************
'* On Error Resume Next
*
'* Dim X As Double
*
'* X = Parse("2+3*4^2*2*cos[3]+2")
*
'* if Err.Number = 11 Then MsgBox "Division by Zero", , "Uncalculatable"
*
'* if Err.Number = vbObjectError + 555 Then MsgBox "Specified Text Sequence
Not Allowed!", , "Invalid Equation" *
'*---------------------------------------------------------------------------------------------------------------*
'* cos/sin/tan/atn must be enclosed with [] as the example shows.
*
'* Use of absolute signs (|) is allowed.
*
'************************************************* ************************************************** **************
*/

function RemSpaces($Exp) {
return str_replace(" ","",$Exp);
}

function RemPlusMinus($Exp) {
$NewExp="";
$RPM = $Exp;
$Place = strpos($Exp, "+-");
if ($Place === false) { } else {
$NewExp = substr($Exp, 0, ($Place - 1)+1) . "-" . substr($Exp, -1,
(strlen($Exp) - $Place - 1)+1);
if (strpos($NewExp, "+-") === false) { } else {
$NewExp = RemPlusMinus($NewExp);
}
$RPM = $NewExp;
}
$Place = strpos($NewExp, "--");
if ($Place === false) { } else {
$NewExp = substr($NewExp, 0, ($Place - 1)+1) . "+" . substr($NewExp, -1,
(strlen($NewExp) - $Place - 1)+1);
if (strpos($NewExp, "--") === false) { } else {
$NewExp = RemPlusMinus($NewExp);
}
return $NewExp;
}
return $RPM;
}

function isnumeric($x) {
return 1==preg_match("/[\deE\.]/", $x);
}

function IsValid($Exp) {
for ($X = 0; $X < strlen($Exp); $X++) {
switch ($Exp{$X}) {
case "[": case "]": case "(": case ")": case "*": case "/": case "+": case
"-": case "^":
break;
case "|":
if (substr($Exp, $X, 2) == "||") {
echo "mdlParse: Specified Text Sequence Not Allowed";
return false;
}
break;
default:
switch(isnumeric($Exp{$X})) {
case false:
switch($X) {
case 0://1:
$Temp = substr($Exp, $X, 3);
if (($Temp != "tan") && ($Temp != "cos") && ($Temp != "sin") && ($Temp
!= "atn")) {
echo "mdlParse: Specified Text Sequence Not Allowed";
return false;
}
break;
case 1://2:
$Temp = substr($Exp, $X - 1, 3);
if (($Temp != "tan") && ($Temp != "cos") && ($Temp != "sin") && ($Temp
!= "atn")) {
echo "mdlParse: Specified Text Sequence Not Allowed";
return false;
}
break;
default://case Is > 2
$Temp = substr($Exp, $X - 2, 6);
if ((strpos($Temp, "cos[") === false) && (strpos($Temp, "sin[") ===
false) && (strpos($Temp, "tan[") === false) && (strpos($Temp, "atn[") ===
false)) {
echo "mdlParse: Specified Text Sequence Not Allowed";
return false;
}
break;
}
break;
case true:
$Temp = substr($Exp, $X, 2);
//if ((strpos($Temp, "[") >= 0) || (strpos($Temp, "(") >= 0) ||
(strpos($Temp, "s") >= 0) || (strpos($Temp, "c") >= 0) || (strpos($Temp,
"t") >= 0) || (strpos($Temp, "a") >= 0)) {
if ((strpos($Temp, "[") === false) && (strpos($Temp, "(") === false) &&
(strpos($Temp, "s") === false) && (strpos($Temp, "c") === false) &&
(strpos($Temp, "t") === false) && (strpos($Temp, "a") === false)) { } else {
echo "mdlParse: Specified Text Sequence Not Allowed";
return false;
}
break;
} //end switch $X
//Ok:
} //end switch $Exp{$X}
} //end for
return true;
}

function Mul($Exp) {
//Dim Place As Integer //'Where the sign is found
//Dim X As Integer //'Travel backward and forward on the string
//Dim Y As Integer //'Counter
//Dim Before As String //'What number goes before the sign
//Dim After As String //'What number goes after the sign
//Dim NewExp As String
//Dim BeforeStr As String //'Used to save the text that goes before our
calculation
$Exp = RemPlusMinus($Exp); //'Make sure previous calculation didn't leave
+- or --
$M = $Exp; //'Incase there's nothing to do, make sure the
function returns correct information
$Place = strpos($Exp, "*");
if ($Place === false) { } else {
$Y = 0;
$X = $Place;
do {//'loop backwards on the string to find out the number before the sign
$Y++;
$X--;
if ($X < 0) break; //'incase we got to the start of the string
if (($Exp{$X} != "+") && ($Exp{$X} != "-" || $Y == 1) && ($Exp{$X} !=
"/")) {
$Before = substr($Exp, $X, $Y);
}
} while (!(($Exp{$X} == "+") || ($Exp{$X} == "-" && $Y != 1) || ($Exp{$X}
== "/"))); //'As Long as we didn't get to the start or to another sign -
continue traveling backwards.
$BeforeStr = substr($Exp, 0, $X+1);
$Y = 0;
$X = $Place;
do {
$Y++;
$X++;
if (($Exp{$X} != "+") && ($Exp{$X} != "-" || $Y == 1) && ($Exp{$X} !=
"*") && ($Exp{$X} != "/")) {
$After = substr($Exp, $Place + 1, $Y+1); //+1 or -1? I think it's +1.
}
} while (!(($Exp{$X} == "+") || ($Exp{$X} == "-" && $Y != 1) || ($Exp{$X}
== "*") || ($Exp{$X} == "/") || ($X >= strlen($Exp)-1))); //'As long as we
didn't get to the end or to another sign - continue traveling forward.
$NewExp = $BeforeStr . ((double)$Before * (double)$After) . substr($Exp,
$X+1);
if (strpos($NewExp, "*") === false) { } else {
$NewExp = Mul($NewExp); //'Recurse incase there are *'s left
}
return $NewExp;
} //end if
return $M;
}

function Add($Exp) {
$Exp = RemPlusMinus($Exp);
$A = $Exp;
$Place = strpos($Exp, "+");
if ($Place === false) { } else {
$Y = 0;
$X = $Place;
do { //'loop backwards on the string to find out the number before the
sign
$Y++;
$X--;
if ($X < 0) break; //'incase we got to the start of the string
if (($Exp{$X} != "-" || $X == 0) && ($Exp{$X} != "*") && ($Exp{$X} !=
"/")) {
$Before = substr($Exp, $X, $Y);
}
} while (!(($Exp{$X} == "*") Or ($Exp{$X} == "-" && $X != 0) || ($Exp{$X}
== "/")));
$BeforeStr = substr($Exp, 0, $X+1);
$Y = 0;
$X = $Place;
do {
$Y++;
$X++;
if (($Exp{$X} != "+") && ($Exp{$X} != "-") && ($Exp{$X} != "*") &&
($Exp{$X} != "/")) {
$After = substr($Exp, $Place + 1, $Y);
}
} while (($Exp{$X} != "+") && ($Exp{$X} != "-") && ($Exp{$X} != "*") &&
($Exp{$X} != "/") && ($X < strlen($Exp)-1));
$NewExp = $BeforeStr . ((double)$Before + (double)$After) . substr($Exp,
$X+1);
if (strpos($NewExp, "+") === false) { } else {
$NewExp = Add($NewExp); //'Recurse incase there are +'s left
}
return $NewExp;
} //end if
return $A;
}

function Subt($Exp) {
$Exp = RemPlusMinus($Exp);
$S = $Exp;
$Place = strpos($Exp, "-");
if ($Place === 0) $Place = strpos($Exp, "-", 1);
if ($Place > 0) {
$Y = 0;
$X = $Place;
do { //'loop backwards on the string to find out the number before the
sign
$Y++;
$X--;
if ($X < 0) break; //'incase we got to the start of the string
if (($Exp{$X} != "+") && ($Exp{$X} != "*") && ($Exp{$X} != "/")) {
$Before = substr($Exp, $X, $Y);
}
} while (!(($Exp{$X} == "*") || ($Exp{$X} == "+") || ($Exp{$X} == "/")));
$BeforeStr = substr($Exp, 0, $X+1); //+1 added afterwards by Jim
$Y = 0;
$X = $Place;
do {
$Y++;
$X++;
if (($Exp{$X} != "+") && ($Exp{$X} != "-") && ($Exp{$X} != "*") &&
($Exp{$X} != "/")) {
$After = substr($Exp, $Place + 1, $Y+1);
}
} while (!(($Exp{$X} == "+") || ($Exp{$X} == "-") || ($Exp{$X} == "*") ||
($Exp{$X} = "/") || ($X >= strlen(Exp)-1)));
$NewExp = $BeforeStr . ((double)$Before - (double)$After) . substr($Exp,
$X+1);
if (strpos($NewExp, "-") === false) { } else {
$NewExp = Subt($NewExp); //'Recurse incase there are -'s left
}
return $NewExp;
}
return $S;
}

function Parentheses($Exp) {
$Exp = RemPlusMinus($Exp);
$P = $Exp;
$MiddleStr="";
$Place = strpos($Exp, ")");
if ($Place === false) { } else {
$Y = 0;
$X = $Place;
do { //'loop to find the inside of the parentheses
$Y++;
$X--;
if ($X < 0) break; //'incase we got to the start of the string
if ($Exp{$X} != "(") {
$MiddleStr = substr($Exp, $X, $Y);
}
} while ($Exp{$X} != "(");
$BeforeStr = ""; //'if it's the beginning of the string - there is nothing
before.
if ($X >= 0) $BeforeStr = substr($Exp, 0, ($X - 1)+1);
$NewExp = $BeforeStr . Parse($MiddleStr) . substr($Exp, $Place + 1);
if (strpos($Exp, ")") === false) { } else {
$NewExp = Parentheses($NewExp); //'Recurse incase there are more
parentheses
}
return $NewExp;
}
return $P;
}

function Div($Exp) {
//On Error Resume Next
$Exp = RemPlusMinus($Exp);
$D = $Exp;
$Place = strpos($Exp, "/");
if ($Place === false) { } else {
$Y = 0;
$X = $Place;
do {//'loop backwards on the string to find out the number before the sign
$Y++;
$X--;
if ($X < 0) break; //'incase we got to the start of the string
if (($Exp{$X} != "+") && ($Exp{$X} && "-" || $Y == 1) && ($Exp{$X} !=
"*")) {
$Before = substr($Exp, $X, $Y);
}
} while (!(($Exp{$X} == "+") || ($Exp{$X} == "-" && $Y != 1) || ($Exp{$X}
== "*")));
$BeforeStr = substr($Exp, 0, $X+1);
$Y = 0;
$X = $Place;
do {
$Y++;
$X++;
if (($Exp{$X} != "+") && ($Exp{$X} != "-" Or Y == 1) && ($Exp{$X} != "*")
&& ($Exp{$X} != "/")) {
$After = substr($Exp, $Place + 1, $Y+1);
}
} while (!(($Exp{$X} == "+") || ($Exp{$X} == "-" && $Y != 1) || ($Exp{$X}
== "*") || ($Exp{$X} == "/") || ($X >= strlen($Exp)-1)));
if ((double)$After==0.0) {
return "Impossible";
}
$NewExp = $BeforeStr . ((double)$Before / (double)$After) . substr($Exp,
$X+1);
if (strpos($NewExp, "/") === false) { } else {
$NewExp = Div($NewExp); //'Recurse incase there are /'s left
}
return $NewExp;
}
return $D;
}

function Power($Exp) {
$Exp = RemPlusMinus($Exp);
$P = $Exp;
$Place = strpos($Exp, "^");
if ($Place === false) { } else {
$Y = 0;
$X = $Place;
do { //'loop backwards on the string to find out the number before the
sign
$Y++;
$X--;
if ($X < 0) break; //'incase we got to the start of the string
if (($Exp{$X} != "+") && ($Exp{$X} != "-" || X == 0) && ($Exp{$X} != "*")
&& ($Exp{$X} != "/")) {
$Before = substr($Exp, $X, $Y);
}
} while (!(($Exp{$X} == "+") || ($Exp{$X} == "-" && X != 0) || ($Exp{$X}
== "*") || ($Exp{$X} == "/")));
$BeforeStr = substr($Exp, 0, $X+1);
$Y = 0;
$X = $Place;
do {
$Y++;
$X++;
if (($Exp{$X} != "+") && ($Exp{$X} != "-") && ($Exp{$X} != "*") &&
($Exp{$X} != "/")) {
$After = substr($Exp, $Place + 1, $Y+1);
}
} while (!(($Exp{$X} == "+") || ($Exp{$X} == "-") || ($Exp{$X} == "*") ||
($Exp{$X} == "/") || ($X >= strlen($Exp)-1)));
$NewExp = $BeforeStr . bcpow($Before, $After) . substr($Exp, $X+1);
if (strpos($NewExp, "^") === false) { } else {
$NewExp = Power($NewExp); //`'Recurse incase there are ^'s left
}
return $NewExp;
}
return $P;
}

function Abso($Exp) {
$A = $Exp;
$First = strpos($Exp, "|");
if ($First === false) return NULL;
$Second = strpos($Exp, "|", $First + 1);
if ($Second === false) return NULL;
$NewExp = substr($Exp, $First + 1, $Second - $First - 1);
$NewExp = Parse($NewExp);
return substr($Exp, 0, ($First - 1)+1) . abs((double)$NewExp) .
substr($Exp, $Second + 1);
}

function CSTA($Exp) {
//Dim X As Integer 'CSTA = Cos Sin Tan Atn
$MiddleStr="";
$Exp = RemPlusMinus($Exp);
$C = $Exp;
$Place = strpos($Exp, "]");
if ($Place === false) { } else {
$Y = 0;
$X = $Place;
do { //'loop to find the inside of the brackets
$Y++;
$X--;
if ($X < 0) break; //'incase we got to the start of the string
if ($Exp{$X} != "[") {
$MiddleStr = substr($Exp, $X, $Y);
}
} while ($Exp{$X} != "[");
$BeforeStr = ""; //'if it's the beginning of the string - there is nothing
before.
if ($X > 0) $BeforeStr = substr($Exp, 0, ($X - 4)+1);
if ($X > 0) $XType = substr($Exp, $X - 3, 3);
switch($XType) {
case "cos":
$NewExp = $BeforeStr . cos((double)Parse($MiddleStr)) . substr($Exp,
$Place + 1);
break;
case "sin":
$NewExp = $BeforeStr . sin((double)Parse($MiddleStr)) . substr($Exp,
$Place + 1);
break;
case "tan":
$NewExp = $BeforeStr . tan((double)Parse($MiddleStr)) . substr($Exp,
$Place + 1);
break;
case "atn":
$NewExp = $BeforeStr . atan((double)Parse($MiddleStr)) . substr($Exp,
$Place + 1);
break;
}
if (strpos($Exp, "]") === false) { } else {
$NewExp = CSTA($NewExp); // 'Recurse incase there are more brackets
}
return $NewExp;
}
return $C;
}
function Parse($Exp) {
/*'************************************************ **************************************** '*This is the main function. In Mul function you will find detailedexplanation. No need* '*to explain others because they are pretty much the same but with littlechanges. * '************************************************* ***************************************/ $Exp = RemSpaces($Exp); //'Remove Spaces $Exp = RemPlusMinus($Exp); //'Change +- to - and -- to + if (IsValid($Exp)) { //'Invalid equations trapping //'The if's are to make sure the code is run only if neccessary if (strpos($Exp, "[") === false) {} else { $Exp = CSTA($Exp);}//'Eliminate Cos/Sin/Tan/Atn from equation. if (strpos($Exp, "|") === false) { } else { $Exp = Abso($Exp);}//'Eliminate Absolute signs from equation. if (strpos($Exp, "(") === false) {} else { $Exp = Parentheses($Exp);}//'Eliminate Parentheses from equation. if (strpos($Exp, "^") === false) {} else { $Exp = Power($Exp);}//'Eliminate Exponentials from equation. if (strpos($Exp, "*") === false) {} else { $Exp = Mul($Exp);}//'Eliminate Multiplications from equation. if (strpos($Exp, "/")=== false) {} else { $Exp = Div($Exp);}//'Eliminate Divisions from equation. if ($Exp == "Impossible") { //'if Division byZero echo "Division by 0 error\n";//'let the calling procedure know what happened return NULL; } if (strpos($Exp, "+") === false) { } else { $Exp = Add($Exp);}//'Eliminate Addition from equation. if (strpos($Exp, "-", 1) === false) { } else { $Exp = Subt($Exp);}//'Eliminate Subtraction from equation. (why 1?) return (double)$Exp; } else { return NULL; }}//print Parse("|-2|-(4-2)*sin[-3.14]"); //chokes on this in the subtractionarea.//print Parse("2-2-2");//print Parse("|-2|-(4-2)");//print Parse("(4-2)*sin[-3.14]");?>>>>> There is bc under Unix. Although inserting user-supplied data into a>>> shell command might be even more dangerous.>> My example (below) looks safe. It could be made tighter by checking for> long lines, disabling single quotes and "strange" characters (ESC, NUL,> ...), and whatever else you might think of.>> ... but bc is, perhaps, best discussed on gnu.utils.help.>>> That is also an interesting approach, but I do feel that I would like>> to keep it a native php solution.>>> <?php> $formula = <<<FORMULA> /*> * find the hypotenuse of a right triangle> * with height = 5 and area = 25> */>> /* !!!! ATTENTION !!! */> rm -rf * ## I tried it!!> ## it seems perfectly safe (???)> /* !!! ATTENTION !!! */>> scale = 8 ## work with 8 decimals>> /* area = h * w / 2 */> h = 5 ## height> area = 25 ## area> w = 2*area / h ## compute width>> /* hypotenuse = sqrt(h*h + w*w) */> hyp = sqrt(h*h + w*w) ## compute hypotenuse> hyp ## print (and return) it> FORMULA;>> $value = escapeshellarg($formula);> $calculated = `echo $value | bc`; /* backticks! */>> // with "rm" in the formula, $calculated will have the error message> // from bc; it might be possible to remove all messages with a> // simple regular expression, I didn't look into that.> echo $calculated;> ?>>> --> If you're posting through Google read <http://cfaj.freeshell.org/google>

Feb 15 '06 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

8
by: Jason Shohet | last post by:
I want to build a rules engine in a rules.xml page. I was thinking it would look like this: - Rules - rule1 if (0 < iTime <= .5) { iFee = 15; } - rule2 if (.5 < iTime <= 1) { iFee =...
0
by: Don Pedro | last post by:
According to the documentation for the DataBinder class's Eval method should it only be used with discretion due to the fact it is latebound and uses reflection. "CAUTION Since this method...
2
by: JohnZing | last post by:
Hi, Should I use <%# Container.DataItem("Author")%> or <%# DataBinder.Eval(Container.DataItem,"Author") %> What's the difference between both? Thank You
15
by: manstey | last post by:
Hi, I have a text file called a.txt: # comments I read it using this:
10
by: Gordon | last post by:
I have a script that creates new objects based on the value of a form field. Basically, the code looks like this. eval ('new ' + objType.value + '(val1, val2, val3'); objType is a select with...
4
by: Adam C. | last post by:
Mozilla.org suggests using the with statement to control bindings: var f = 2; with({f: 3}){ eval("f"); // evaluates to 3 } But that doesn't work for binding "this".
3
by: Warren DeLano | last post by:
I would like to parse arbitrary insecure text string containing nested Python data structures in eval-compatible form: # For example, given a "config.txt" such as: { 'my_atom' : 1.20,...
0
by: Chris Rebert | last post by:
On Wed, Oct 8, 2008 at 5:34 PM, Warren DeLano <warren@delsci.comwrote: Assuming the data structures are sufficiently basic, i.e. no class instanciations, you can just use the json (AKA...
15
by: r0g | last post by:
Hi There, I know you can use eval to dynamically generate the name of a function you may want to call. Can it (or some equivalent method) also be used to do the same thing for the variables of a...
0
by: DolphinDB | last post by:
The formulas of 101 quantitative trading alphas used by WorldQuant were presented in the paper 101 Formulaic Alphas. However, some formulas are complex, leading to challenges in calculation. Take...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
0
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.