From bc91b91ab124068f5071be1ade6f7edbd3da3a5c Mon Sep 17 00:00:00 2001 From: Tony Levi Date: Mon, 3 Aug 2015 16:16:03 +0930 Subject: [PATCH] MDL-52333 qtype: PHP7-compatibility in calculate_raw() Code also modified by Tim Hunt --- question/type/calculated/db/upgradelib.php | 15 +++++++++++---- question/type/calculated/question.php | 15 +++++++++++---- question/type/calculatedmulti/db/upgradelib.php | 15 +++++++++++---- 3 files changed, 33 insertions(+), 12 deletions(-) diff --git a/question/type/calculated/db/upgradelib.php b/question/type/calculated/db/upgradelib.php index 22d87107f47..09803be12d7 100644 --- a/question/type/calculated/db/upgradelib.php +++ b/question/type/calculated/db/upgradelib.php @@ -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 . ']'; } /** diff --git a/question/type/calculated/question.php b/question/type/calculated/question.php index af9c819e6c6..99cd17120f7 100644 --- a/question/type/calculated/question.php +++ b/question/type/calculated/question.php @@ -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); } /** diff --git a/question/type/calculatedmulti/db/upgradelib.php b/question/type/calculatedmulti/db/upgradelib.php index 53bf09dd44a..ed4cb25bee1 100644 --- a/question/type/calculatedmulti/db/upgradelib.php +++ b/question/type/calculatedmulti/db/upgradelib.php @@ -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 . ']'; } /**