From 029d18f13bcf01aa2f1f08dbdfc6400c081bf7cb Mon Sep 17 00:00:00 2001 From: Andy Wermke Date: Thu, 4 Apr 2013 16:08:53 +0200 Subject: Replaced nasty eval() expressions. --- program/include/rcmail_output_html.php | 35 ++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/program/include/rcmail_output_html.php b/program/include/rcmail_output_html.php index 1290e173e..795c0b381 100644 --- a/program/include/rcmail_output_html.php +++ b/program/include/rcmail_output_html.php @@ -722,7 +722,7 @@ class rcmail_output_html extends rcmail_output */ protected function check_condition($condition) { - return eval("return (".$this->parse_expression($condition).");"); + return $this->eval_expression($condition); } @@ -773,6 +773,37 @@ class rcmail_output_html extends rcmail_output $expression); } + protected function eval_expression ($expression) { + return preg_replace_callback( + array( + '/session:([a-z0-9_]+)/i', + '/config:([a-z0-9_]+)(:([a-z0-9_]+))?/i', + '/env:([a-z0-9_]+)/i', + '/request:([a-z0-9_]+)/i', + '/cookie:([a-z0-9_]+)/i', + '/browser:([a-z0-9_]+)/i', + '/template:name/i', + ), + function($match) { + if(preg_match('/session:([a-z0-9_]+)/i', $match, $matches)) { + return $_SESSION[$matches[1]]; + } else if(preg_match('/config:([a-z0-9_]+)(:([a-z0-9_]+))?/i', $match, $matches)) { + return $this->app->config->get($matches[1],rcube_utils::get_boolean($matches[3])); + } else if(preg_match('/env:([a-z0-9_]+)/i', $match, $matches)) { + return $this->env[$matches[1]]; + } else if(preg_match('/request:([a-z0-9_]+)/i', $match, $matches)) { + return rcube_utils::get_input_value($matches[1], rcube_utils::INPUT_GPC); + } else if(preg_match('/cookie:([a-z0-9_]+)/i', $match, $matches)) { + return $_COOKIE[$matches[1]]; + } else if(preg_match('/browser:([a-z0-9_]+)/i', $match, $matches)) { + return $this->browser->{$matches[1]}; + } else if(preg_match('/template:name/i', $match, $matches)) { + return $this->template_name; + } + }, + $expression); + } + /** * Search for special tags in input and replace them @@ -955,7 +986,7 @@ class rcmail_output_html extends rcmail_output // return code for a specified eval expression case 'exp': $value = $this->parse_expression($attrib['expression']); - return eval("return html::quote($value);"); + return html::quote( $this->eval_expression($attrib['expression']) ); // return variable case 'var': -- cgit v1.2.3 From d67485bebe161c8c46ffe4852e4b4446910ed342 Mon Sep 17 00:00:00 2001 From: Andy Wermke Date: Fri, 5 Apr 2013 12:02:04 +0200 Subject: Replaced stupid fix by create_function() based approach. --- program/include/rcmail_output_html.php | 51 ++++++++++++---------------------- 1 file changed, 17 insertions(+), 34 deletions(-) diff --git a/program/include/rcmail_output_html.php b/program/include/rcmail_output_html.php index f2bdd95a7..3e0a4e674 100644 --- a/program/include/rcmail_output_html.php +++ b/program/include/rcmail_output_html.php @@ -731,7 +731,6 @@ class rcmail_output_html extends rcmail_output /** * Determines if a given condition is met * - * @todo Get rid off eval() once I understand what this does. * @todo Extend this to allow real conditions, not just "set" * @param string Condition statement * @return boolean True if condition is met, False if not @@ -779,45 +778,30 @@ class rcmail_output_html extends rcmail_output ), array( "\$_SESSION['\\1']", - "\$this->app->config->get('\\1',rcube_utils::get_boolean('\\3'))", - "\$this->env['\\1']", + "\$app->config->get('\\1',rcube_utils::get_boolean('\\3'))", + "\$env['\\1']", "rcube_utils::get_input_value('\\1', rcube_utils::INPUT_GPC)", "\$_COOKIE['\\1']", - "\$this->browser->{'\\1'}", + "\$browser->{'\\1'}", $this->template_name, ), $expression); } - + + /** + * Evaluate a given expression and return its result. + * @param string Expression statement + */ protected function eval_expression ($expression) { - return preg_replace_callback( - array( - '/session:([a-z0-9_]+)/i', - '/config:([a-z0-9_]+)(:([a-z0-9_]+))?/i', - '/env:([a-z0-9_]+)/i', - '/request:([a-z0-9_]+)/i', - '/cookie:([a-z0-9_]+)/i', - '/browser:([a-z0-9_]+)/i', - '/template:name/i', - ), - function($match) { - if(preg_match('/session:([a-z0-9_]+)/i', $match, $matches)) { - return $_SESSION[$matches[1]]; - } else if(preg_match('/config:([a-z0-9_]+)(:([a-z0-9_]+))?/i', $match, $matches)) { - return $this->app->config->get($matches[1],rcube_utils::get_boolean($matches[3])); - } else if(preg_match('/env:([a-z0-9_]+)/i', $match, $matches)) { - return $this->env[$matches[1]]; - } else if(preg_match('/request:([a-z0-9_]+)/i', $match, $matches)) { - return rcube_utils::get_input_value($matches[1], rcube_utils::INPUT_GPC); - } else if(preg_match('/cookie:([a-z0-9_]+)/i', $match, $matches)) { - return $_COOKIE[$matches[1]]; - } else if(preg_match('/browser:([a-z0-9_]+)/i', $match, $matches)) { - return $this->browser->{$matches[1]}; - } else if(preg_match('/template:name/i', $match, $matches)) { - return $this->template_name; - } - }, - $expression); + // Prevent function calls in `expression`: + $expression = str_replace("\n", "", $expression); + if(preg_match('#\w+ \s* (/\* .* \*/)* \s* \(#ix', $expression)) + return false; + + // Evaluate expression: + $expression = $this->parse_expression($expression); + $fn = create_function('$app,$browser,$env', "return ($expression);"); + return $fn($this->app, $this->browser, $this->env); } @@ -1002,7 +986,6 @@ class rcmail_output_html extends rcmail_output // return code for a specified eval expression case 'exp': - $value = $this->parse_expression($attrib['expression']); return html::quote( $this->eval_expression($attrib['expression']) ); // return variable -- cgit v1.2.3 From fe245e5f5dbea1c18517471103185e04a52c89b3 Mon Sep 17 00:00:00 2001 From: Andy Wermke Date: Fri, 5 Apr 2013 13:49:32 +0200 Subject: Replaced last eval(). Allowing function calls in expressions. --- program/include/rcmail_output_html.php | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/program/include/rcmail_output_html.php b/program/include/rcmail_output_html.php index 3e0a4e674..772bdccf7 100644 --- a/program/include/rcmail_output_html.php +++ b/program/include/rcmail_output_html.php @@ -793,12 +793,6 @@ class rcmail_output_html extends rcmail_output * @param string Expression statement */ protected function eval_expression ($expression) { - // Prevent function calls in `expression`: - $expression = str_replace("\n", "", $expression); - if(preg_match('#\w+ \s* (/\* .* \*/)* \s* \(#ix', $expression)) - return false; - - // Evaluate expression: $expression = $this->parse_expression($expression); $fn = create_function('$app,$browser,$env', "return ($expression);"); return $fn($this->app, $this->browser, $this->env); @@ -854,7 +848,7 @@ class rcmail_output_html extends rcmail_output // show a label case 'label': if ($attrib['expression']) - $attrib['name'] = eval("return " . $this->parse_expression($attrib['expression']) .";"); + $attrib['name'] = $this->eval_expression($attrib['expression']); if ($attrib['name'] || $attrib['command']) { // @FIXME: 'noshow' is useless, remove? -- cgit v1.2.3 From 58e3a504b98f68595151fa908536b1e35b043b76 Mon Sep 17 00:00:00 2001 From: Andy Wermke Date: Mon, 8 Apr 2013 14:31:28 +0200 Subject: Removed parse_expression() & added error logging to eval_expression(). --- program/include/rcmail_output_html.php | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/program/include/rcmail_output_html.php b/program/include/rcmail_output_html.php index 772bdccf7..0fba66080 100644 --- a/program/include/rcmail_output_html.php +++ b/program/include/rcmail_output_html.php @@ -759,14 +759,11 @@ class rcmail_output_html extends rcmail_output /** - * Parses expression and replaces variables - * + * Parse & evaluate a given expression and return its result. * @param string Expression statement - * @return string Expression value */ - protected function parse_expression($expression) - { - return preg_replace( + protected function eval_expression ($expression) { + $expression = preg_replace( array( '/session:([a-z0-9_]+)/i', '/config:([a-z0-9_]+)(:([a-z0-9_]+))?/i', @@ -785,16 +782,19 @@ class rcmail_output_html extends rcmail_output "\$browser->{'\\1'}", $this->template_name, ), - $expression); - } - - /** - * Evaluate a given expression and return its result. - * @param string Expression statement - */ - protected function eval_expression ($expression) { - $expression = $this->parse_expression($expression); + $expression + ); + $fn = create_function('$app,$browser,$env', "return ($expression);"); + if(!$fn) { + rcube::raise_error(array( + 'code' => 505, + 'type' => 'php', + 'file' => __FILE__, + 'line' => __LINE__, + 'message' => "Expression parse error on: ($expression)"), true, false); + } + return $fn($this->app, $this->browser, $this->env); } -- cgit v1.2.3