summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2018-09-19 09:39:21 +0200
committerNikita Popov <nikita.ppv@gmail.com>2018-09-19 09:39:31 +0200
commit040ca85eac21a8de1a6f3c6c96460f0fba4c6827 (patch)
tree319de96553b1185a1f352e31125506bcc8fcd1fe
parentc2da50bc41daa96a36d8a25d4dbbde907b7edfdb (diff)
parentcc1fb02760e95965a6ea1f298d61f510a818caeb (diff)
downloadphp-git-040ca85eac21a8de1a6f3c6c96460f0fba4c6827.tar.gz
Merge branch 'PHP-7.2' into PHP-7.3
-rw-r--r--NEWS2
-rw-r--r--Zend/tests/bug76901.phpt18
-rw-r--r--Zend/zend_builtin_functions.c11
3 files changed, 24 insertions, 7 deletions
diff --git a/NEWS b/NEWS
index c6c3af84b7..a815840809 100644
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,8 @@ PHP NEWS
(Dmitry)
. Fixed bug #76800 (foreach inconsistent if array modified during loop).
(Dmitry)
+ . Fixed bug #76901 (method_exists on SPL iterator passthrough method corrupts
+ memory). (Nikita)
- Standard:
. Fixed bug #75533 (array_reduce is slow when $carry is large array).
diff --git a/Zend/tests/bug76901.phpt b/Zend/tests/bug76901.phpt
new file mode 100644
index 0000000000..8d567d9e0c
--- /dev/null
+++ b/Zend/tests/bug76901.phpt
@@ -0,0 +1,18 @@
+--TEST--
+Bug #76901: method_exists on SPL iterator passthrough method corrupts memory
+--FILE--
+<?php
+
+$it = new ArrayIterator([1, 2, 3]);
+$it = new IteratorIterator($it);
+foreach ($it as $v) {
+ if (method_exists($it, 'offsetGet')) {
+ var_dump($it->offsetGet(0));
+ }
+}
+
+?>
+--EXPECT--
+int(1)
+int(1)
+int(1)
diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c
index 4989b4b5b5..96d5127711 100644
--- a/Zend/zend_builtin_functions.c
+++ b/Zend/zend_builtin_functions.c
@@ -1347,13 +1347,10 @@ ZEND_FUNCTION(method_exists)
if (zend_hash_exists(&ce->function_table, lcname)) {
zend_string_release_ex(lcname, 0);
RETURN_TRUE;
- } else {
- union _zend_function *func = NULL;
-
- if (Z_TYPE_P(klass) == IS_OBJECT
- && Z_OBJ_HT_P(klass)->get_method != NULL
- && (func = Z_OBJ_HT_P(klass)->get_method(&Z_OBJ_P(klass), method_name, NULL)) != NULL
- ) {
+ } else if (Z_TYPE_P(klass) == IS_OBJECT && Z_OBJ_HT_P(klass)->get_method != NULL) {
+ zend_object *obj = Z_OBJ_P(klass);
+ zend_function *func = Z_OBJ_HT_P(klass)->get_method(&obj, method_name, NULL);
+ if (func != NULL) {
if (func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) {
/* Returns true to the fake Closure's __invoke */
RETVAL_BOOL(func->common.scope == zend_ce_closure