]> granicus.if.org Git - php/commitdiff
Fixed bug #80781
authorNikita Popov <nikita.ppv@gmail.com>
Mon, 22 Feb 2021 08:33:23 +0000 (09:33 +0100)
committerNikita Popov <nikita.ppv@gmail.com>
Mon, 22 Feb 2021 08:36:43 +0000 (09:36 +0100)
zend_find_array_dim_slow() may throw, make sure to handle this.
This backports the code we already use for this on PHP-8.0,
and also backports an exception check that makes this easier to
catch.

NEWS
Zend/tests/bug80781.phpt [new file with mode: 0644]
Zend/zend_execute.c
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

diff --git a/NEWS b/NEWS
index a3c388901f8a05b96951d0eb0f11276ccdb18b57..3cb29d3cb49e7f53cca808f5739e07f6047531ed 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,10 @@ PHP                                                                        NEWS
 |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 ?? ??? 2021, php 7.4.17
 
+- Core:
+  . Fixed bug #80781 (Error handler that throws ErrorException infinite loop).
+    (Nikita)
+
 - Intl:
   . Fixed bug #80763 (msgfmt_format() does not accept DateTime references).
     (cmb)
diff --git a/Zend/tests/bug80781.phpt b/Zend/tests/bug80781.phpt
new file mode 100644 (file)
index 0000000..3e8715d
--- /dev/null
@@ -0,0 +1,32 @@
+--TEST--
+Bug #80781: Error handler that throws ErrorException infinite loop
+--FILE--
+<?php
+
+function handle(int $severity, string $message, string $file, int $line): bool {
+       if((error_reporting() & $severity) !== 0) {
+               throw new \ErrorException($message, 0, $severity, $file, $line);
+       }
+
+       return true; // stfu operator
+}
+
+set_error_handler('handle');
+
+function getPlugin(string $plugin) : bool{
+       return false;
+}
+
+$data = [];
+$array = [];
+if (isset($array[$data]) or getPlugin($data)) {
+
+}
+
+?>
+--EXPECTF--
+Fatal error: Uncaught ErrorException: Illegal offset type in isset or empty in %s:%d
+Stack trace:
+#0 %s(%d): handle(2, 'Illegal offset ...', %s, %d, Array)
+#1 {main}
+  thrown in %s on line %d
index f58b1131ba18a63065d3aa467b26071a5de1bd21..90ffa5afb69ef68cf532e3df4bcfff7aeb8b6e03 100644 (file)
@@ -4555,6 +4555,7 @@ static zend_always_inline zend_execute_data *_zend_vm_stack_push_call_frame(uint
        if (check_exception) { \
                OPLINE = EX(opline) + (skip); \
        } else { \
+               ZEND_ASSERT(!EG(exception)); \
                OPLINE = opline + (skip); \
        } \
        ZEND_VM_CONTINUE()
index bc7550f4ed80e9f3c906700949846758ae0cfcde..d693f4f3599bf6dd34f79dc4049a83870948cd63 100644 (file)
@@ -6937,6 +6937,10 @@ ZEND_VM_C_LABEL(num_index_prop):
                        ZEND_VM_C_GOTO(isset_again);
                } else {
                        value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC);
+                       if (UNEXPECTED(EG(exception))) {
+                               result = 0;
+                               ZEND_VM_C_GOTO(isset_dim_obj_exit);
+                       }
                }
 
                if (!(opline->extended_value & ZEND_ISEMPTY)) {
index 0e65367eb5a791310b3ec729ee0e3a3dc62a5f05..dc49bcd4342dbe0d8cc3489733c58e68a37b182e 100644 (file)
@@ -6302,6 +6302,10 @@ num_index_prop:
                        goto isset_again;
                } else {
                        value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC);
+                       if (UNEXPECTED(EG(exception))) {
+                               result = 0;
+                               goto isset_dim_obj_exit;
+                       }
                }
 
                if (!(opline->extended_value & ZEND_ISEMPTY)) {
@@ -8496,6 +8500,10 @@ num_index_prop:
                        goto isset_again;
                } else {
                        value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC);
+                       if (UNEXPECTED(EG(exception))) {
+                               result = 0;
+                               goto isset_dim_obj_exit;
+                       }
                }
 
                if (!(opline->extended_value & ZEND_ISEMPTY)) {
@@ -10949,6 +10957,10 @@ num_index_prop:
                        goto isset_again;
                } else {
                        value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC);
+                       if (UNEXPECTED(EG(exception))) {
+                               result = 0;
+                               goto isset_dim_obj_exit;
+                       }
                }
 
                if (!(opline->extended_value & ZEND_ISEMPTY)) {
@@ -14985,6 +14997,10 @@ num_index_prop:
                        goto isset_again;
                } else {
                        value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC);
+                       if (UNEXPECTED(EG(exception))) {
+                               result = 0;
+                               goto isset_dim_obj_exit;
+                       }
                }
 
                if (!(opline->extended_value & ZEND_ISEMPTY)) {
@@ -16402,6 +16418,10 @@ num_index_prop:
                        goto isset_again;
                } else {
                        value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC);
+                       if (UNEXPECTED(EG(exception))) {
+                               result = 0;
+                               goto isset_dim_obj_exit;
+                       }
                }
 
                if (!(opline->extended_value & ZEND_ISEMPTY)) {
@@ -17689,6 +17709,10 @@ num_index_prop:
                        goto isset_again;
                } else {
                        value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC);
+                       if (UNEXPECTED(EG(exception))) {
+                               result = 0;
+                               goto isset_dim_obj_exit;
+                       }
                }
 
                if (!(opline->extended_value & ZEND_ISEMPTY)) {
@@ -41505,6 +41529,10 @@ num_index_prop:
                        goto isset_again;
                } else {
                        value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC);
+                       if (UNEXPECTED(EG(exception))) {
+                               result = 0;
+                               goto isset_dim_obj_exit;
+                       }
                }
 
                if (!(opline->extended_value & ZEND_ISEMPTY)) {
@@ -44950,6 +44978,10 @@ num_index_prop:
                        goto isset_again;
                } else {
                        value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC);
+                       if (UNEXPECTED(EG(exception))) {
+                               result = 0;
+                               goto isset_dim_obj_exit;
+                       }
                }
 
                if (!(opline->extended_value & ZEND_ISEMPTY)) {
@@ -50123,6 +50155,10 @@ num_index_prop:
                        goto isset_again;
                } else {
                        value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC);
+                       if (UNEXPECTED(EG(exception))) {
+                               result = 0;
+                               goto isset_dim_obj_exit;
+                       }
                }
 
                if (!(opline->extended_value & ZEND_ISEMPTY)) {