MDL-52333 qtype: PHP7-compatibility in calculate_raw()
authorTony Levi <tony.levi@netspot.com.au>
Mon, 3 Aug 2015 06:46:03 +0000 (16:16 +0930)
committerDavid Monllao <davidm@moodle.com>
Thu, 10 Dec 2015 08:38:57 +0000 (16:38 +0800)
Code also modified by Tim Hunt

question/type/calculated/db/upgradelib.php
question/type/calculated/question.php
question/type/calculatedmulti/db/upgradelib.php

index 22d8710..09803be 100644 (file)
@@ -248,11 +248,18 @@ class qtype_calculated_qe2_attempt_updater extends question_qtype_attempt_update
      * @return float the computed result.
      */
     protected function calculate_raw($expression) {
-        // This validation trick from http://php.net/manual/en/function.eval.php.
-        if (!@eval('return true; $result = ' . $expression . ';')) {
-            return '[Invalid expression ' . $expression . ']';
+        try {
+            // In older PHP versions this this is a way to validate code passed to eval.
+            // The trick came from http://php.net/manual/en/function.eval.php.
+            if (@eval('return true; $result = ' . $expression . ';')) {
+                return eval('return ' . $expression . ';');
+            }
+        } catch (Throwable $e) {
+            // PHP7 and later now throws ParseException and friends from eval(),
+            // which is much better.
         }
-        return eval('return ' . $expression . ';');
+        // In either case of an invalid $expression, we end here.
+        return '[Invalid expression ' . $expression . ']';
     }
 
     /**
index af9c819..99cd171 100644 (file)
@@ -433,11 +433,18 @@ class qtype_calculated_variable_substituter {
      * @return float the computed result.
      */
     protected function calculate_raw($expression) {
-        // This validation trick from http://php.net/manual/en/function.eval.php .
-        if (!@eval('return true; $result = ' . $expression . ';')) {
-            throw new moodle_exception('illegalformulasyntax', 'qtype_calculated', '', $expression);
+        try {
+            // In older PHP versions this this is a way to validate code passed to eval.
+            // The trick came from http://php.net/manual/en/function.eval.php.
+            if (@eval('return true; $result = ' . $expression . ';')) {
+                return eval('return ' . $expression . ';');
+            }
+        } catch (Throwable $e) {
+            // PHP7 and later now throws ParseException and friends from eval(),
+            // which is much better.
         }
-        return eval('return ' . $expression . ';');
+        // In either case of an invalid $expression, we end here.
+        throw new moodle_exception('illegalformulasyntax', 'qtype_calculated', '', $expression);
     }
 
     /**
index 53bf09d..ed4cb25 100644 (file)
@@ -272,11 +272,18 @@ class qtype_calculatedmulti_qe2_attempt_updater extends question_qtype_attempt_u
      * @return float the computed result.
      */
     protected function calculate_raw($expression) {
-        // This validation trick from http://php.net/manual/en/function.eval.php.
-        if (!@eval('return true; $result = ' . $expression . ';')) {
-            return '[Invalid expression ' . $expression . ']';
+        try {
+            // In older PHP versions this this is a way to validate code passed to eval.
+            // The trick came from http://php.net/manual/en/function.eval.php.
+            if (@eval('return true; $result = ' . $expression . ';')) {
+                return eval('return ' . $expression . ';');
+            }
+        } catch (Throwable $e) {
+            // PHP7 and later now throws ParseException and friends from eval(),
+            // which is much better.
         }
-        return eval('return ' . $expression . ';');
+        // In either case of an invalid $expression, we end here.
+        return '[Invalid expression ' . $expression . ']';
     }
 
     /**