PHP 7 changes parse error handling of eval() & co.

Discussions and requests related to new CMSimple features, plugins, templates etc. and how to develop.
Please don't ask for support at this forums!
Post Reply
cmb
Posts: 14225
Joined: Tue Jun 21, 2011 11:04 am
Location: Bingen, RLP, DE
Contact:

PHP 7 changes parse error handling of eval() & co.

Post by cmb » Thu Dec 17, 2015 11:31 am

I just noticed that PHP 7 changes the way parse errors are handled in eval'd strings. Formerly the execution has been continued, but now the ParseError is propagated to the calling script, see https://wiki.php.net/rfc/engine_excepti ... patibility. Most likely we'll have to cater for this when evaluating CMSimple scripting and plugin calls in XH 1.7[1].

[1] Even though our schedule for XH 1.7 has been delayed, I still suggest to ignore PHP 7 compatibility issues for XH 1.6.
Christoph M. Becker – Plugins for CMSimple_XH

cmb
Posts: 14225
Joined: Tue Jun 21, 2011 11:04 am
Location: Bingen, RLP, DE
Contact:

Re: PHP 7 changes parse error handling of eval() & co.

Post by cmb » Wed Jun 01, 2016 12:56 pm

The following patch is supposed to solve this issue under PHP 5 and 7 (it would break PHP 4 compatibility, though):

Code: Select all

 cmsimple/functions.php | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/cmsimple/functions.php b/cmsimple/functions.php
index bc3a00c..040de36 100644
--- a/cmsimple/functions.php
+++ b/cmsimple/functions.php
@@ -181,7 +181,11 @@ function evaluate_cmsimple_scripting($__text, $__compat = true)
                     $__script
                 );
                 $__scope_before = array_keys(get_defined_vars());
-                eval($__script);
+                try {
+                    eval($__script);
+                } catch (ParseError $ex) {
+                    trigger_error('Parse error: ' . $ex->getMessage(), E_USER_WARNING);
+                }
                 $__scope_after = array_keys(get_defined_vars());
                 $__diff = array_diff($__scope_after, $__scope_before);
                 foreach ($__diff as $__var) {
@@ -243,9 +247,14 @@ function evaluate_plugincall($text)
         );
         $function = $call[1][0];
         if (function_exists($function)) {
-            $results[] = XH_evaluateSinglePluginCall(
+            try {
+                $results[] = XH_evaluateSinglePluginCall(
                 $function . '(' . $arguments . ')'
             );
+            } catch (ParseError $ex) {
+                $results[] = '';
+                trigger_error('Parse error: ' . $ex->getMessage(), E_USER_WARNING);
+            }
         } else {
             $results[] = sprintf($message, $function);
         }
The behavior on PHP 7 is roughly the same as on PHP 5. However, we could consider showing a message about the parse error (no details, though) on the page (that would be really hacky for PHP 5, but rather clean for PHP 7).

PS: I'm quite surprised that PHP 5 doesn't seem to complain about the use of ParseError, but I assume this is a deliberate decision of the PHP developers. Anyhow, it saves us some ugly workarounds for PHP 5/7 compatibility.
Last edited by cmb on Wed Jun 01, 2016 12:58 pm, edited 1 time in total.
Reason: added PS
Christoph M. Becker – Plugins for CMSimple_XH

cmb
Posts: 14225
Joined: Tue Jun 21, 2011 11:04 am
Location: Bingen, RLP, DE
Contact:

Re: PHP 7 changes parse error handling of eval() & co.

Post by cmb » Mon Jun 06, 2016 1:09 pm

Another somewhat related issue might come up with PHP 7.1. The Replace "Missing argument" warning with "Too few arguments" exception RFC is currently in voting, and if it passes (what's not unlikely) some plugin calls would fail with an exception instead succeeding with a warning. That would result in a White Screen of Death.

Note that some plugins make explicit use of that "feature", for instance, gbook 0.8.4beta3 which explains in its help file:
Plug the guestbook in your CMSimple-page by adding the line
#CMSimple $output.= GBlist();#
or
#CMSimple $output.= GBlist(cFilename);#
However, gblist() is declared as:

Code: Select all

function gblist($gb_filename) {…}
Of course, the fix is simple, but the webmaster would have to notice the issue first.
Christoph M. Becker – Plugins for CMSimple_XH

Post Reply