]> granicus.if.org Git - php/commitdiff
Handle exceptions during SCCP function evaluation
authorNikita Popov <nikita.ppv@gmail.com>
Fri, 27 Nov 2020 16:00:12 +0000 (17:00 +0100)
committerNikita Popov <nikita.ppv@gmail.com>
Fri, 27 Nov 2020 16:00:12 +0000 (17:00 +0100)
Easier to handle them than to ensure they can't happen in the
first place.

ext/opcache/Optimizer/sccp.c
ext/opcache/tests/opt/sccp_exception.phpt [new file with mode: 0644]

index d0dffc275da3e8a64b7285ce339395006429cf6d..1c4330717ba0cf0843fab8f51f644f213722c367 100644 (file)
@@ -26,6 +26,7 @@
 #include "Optimizer/scdf.h"
 #include "Optimizer/zend_dump.h"
 #include "ext/standard/php_string.h"
+#include "zend_exceptions.h"
 
 /* This implements sparse conditional constant propagation (SCCP) based on the SCDF framework. The
  * used value lattice is defined as follows:
@@ -1040,12 +1041,20 @@ static inline int ct_eval_func_call(
        for (i = 0; i < num_args; i++) {
                ZVAL_COPY(EX_VAR_NUM(i), args[i]);
        }
+       ZVAL_NULL(result);
        func->internal_function.handler(execute_data, result);
        for (i = 0; i < num_args; i++) {
                zval_ptr_dtor_nogc(EX_VAR_NUM(i));
        }
        efree(execute_data);
        EG(current_execute_data) = prev_execute_data;
+
+       if (EG(exception)) {
+               zval_ptr_dtor(result);
+               zend_clear_exception();
+               return FAILURE;
+       }
+
        return SUCCESS;
 }
 
diff --git a/ext/opcache/tests/opt/sccp_exception.phpt b/ext/opcache/tests/opt/sccp_exception.phpt
new file mode 100644 (file)
index 0000000..685dfe1
--- /dev/null
@@ -0,0 +1,12 @@
+--TEST--
+Exception thrown during SCCP evaluation
+--FILE--
+<?php
+var_dump(version_compare('1.2', '2.1', '??'));
+?>
+--EXPECTF--
+Fatal error: Uncaught ValueError: version_compare(): Argument #3 ($operator) must be a valid comparison operator in %s:%d
+Stack trace:
+#0 %s(%d): version_compare('1.2', '2.1', '??')
+#1 {main}
+  thrown in %s on line %d