diff options
author | Dmitry Stogov <dmitry@zend.com> | 2019-01-14 13:18:28 +0300 |
---|---|---|
committer | Dmitry Stogov <dmitry@zend.com> | 2019-01-14 13:18:28 +0300 |
commit | 920450534ea7bc8852509d159d488a62f8032c80 (patch) | |
tree | 0ca803223228cc8b8b1290fa714de7471ac5cbde | |
parent | d6212835f2c21d6a0dc75bc25b636ce631bff38c (diff) | |
download | php-git-920450534ea7bc8852509d159d488a62f8032c80.tar.gz |
Fixed bug #77263 (Segfault when using 2 RecursiveFilterIterator)
-rw-r--r-- | NEWS | 1 | ||||
-rw-r--r-- | Zend/zend_vm_def.h | 4 | ||||
-rw-r--r-- | Zend/zend_vm_execute.h | 48 | ||||
-rw-r--r-- | ext/spl/tests/bug77263.phpt | 40 |
4 files changed, 93 insertions, 0 deletions
@@ -13,6 +13,7 @@ PHP NEWS . Fixed bug #77339 (__callStatic may get incorrect arguments). (Dmitry) . Fixed bug #77317 (__DIR__, __FILE__, realpath() reveal physical path for subst virtual drive). (Anatol) + . Fixed bug #77263 (Segfault when using 2 RecursiveFilterIterator). (Dmitry) - Fileinfo: . Fixed bug #77346 (webm files incorrectly detected as diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index a49baa5a9b..5071be0fb1 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -3099,6 +3099,10 @@ ZEND_VM_HOT_OBJ_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMPVAR|UNUSED|THIS|CV, EXPECTED(obj == orig_obj)) { CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } + if ((OP1_TYPE & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { + /* Reset "object" to trigger reference counting */ + object = NULL; + } if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { init_func_run_time_cache(&fbc->op_array); } diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 49bc2c0de7..2ed807f1ac 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -5148,6 +5148,10 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_ EXPECTED(obj == orig_obj)) { CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } + if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { + /* Reset "object" to trigger reference counting */ + object = NULL; + } if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { init_func_run_time_cache(&fbc->op_array); } @@ -7325,6 +7329,10 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_ EXPECTED(obj == orig_obj)) { CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } + if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { + /* Reset "object" to trigger reference counting */ + object = NULL; + } if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { init_func_run_time_cache(&fbc->op_array); } @@ -10421,6 +10429,10 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_ EXPECTED(obj == orig_obj)) { CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } + if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { + /* Reset "object" to trigger reference counting */ + object = NULL; + } if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { init_func_run_time_cache(&fbc->op_array); } @@ -14149,6 +14161,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C EXPECTED(obj == orig_obj)) { CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } + if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { + /* Reset "object" to trigger reference counting */ + object = NULL; + } if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { init_func_run_time_cache(&fbc->op_array); } @@ -15759,6 +15775,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_T EXPECTED(obj == orig_obj)) { CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } + if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { + /* Reset "object" to trigger reference counting */ + object = NULL; + } if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { init_func_run_time_cache(&fbc->op_array); } @@ -17636,6 +17656,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C EXPECTED(obj == orig_obj)) { CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } + if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { + /* Reset "object" to trigger reference counting */ + object = NULL; + } if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { init_func_run_time_cache(&fbc->op_array); } @@ -32081,6 +32105,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_S EXPECTED(obj == orig_obj)) { CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } + if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { + /* Reset "object" to trigger reference counting */ + object = NULL; + } if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { init_func_run_time_cache(&fbc->op_array); } @@ -33812,6 +33840,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_T EXPECTED(obj == orig_obj)) { CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } + if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { + /* Reset "object" to trigger reference counting */ + object = NULL; + } if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { init_func_run_time_cache(&fbc->op_array); } @@ -36187,6 +36219,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_C EXPECTED(obj == orig_obj)) { CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } + if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { + /* Reset "object" to trigger reference counting */ + object = NULL; + } if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { init_func_run_time_cache(&fbc->op_array); } @@ -41208,6 +41244,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_S EXPECTED(obj == orig_obj)) { CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } + if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { + /* Reset "object" to trigger reference counting */ + object = NULL; + } if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { init_func_run_time_cache(&fbc->op_array); } @@ -44971,6 +45011,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVA EXPECTED(obj == orig_obj)) { CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } + if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { + /* Reset "object" to trigger reference counting */ + object = NULL; + } if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { init_func_run_time_cache(&fbc->op_array); } @@ -50769,6 +50813,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HA EXPECTED(obj == orig_obj)) { CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } + if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { + /* Reset "object" to trigger reference counting */ + object = NULL; + } if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { init_func_run_time_cache(&fbc->op_array); } diff --git a/ext/spl/tests/bug77263.phpt b/ext/spl/tests/bug77263.phpt new file mode 100644 index 0000000000..ddd5fba3cd --- /dev/null +++ b/ext/spl/tests/bug77263.phpt @@ -0,0 +1,40 @@ +--TEST-- +Bug #77263 (Segfault when using 2 RecursiveFilterIterator) +--FILE-- +<?php +$dir = __DIR__ . '/bug77263'; +mkdir($dir); +mkdir("$dir/subdir"); +touch("$dir/file1"); +touch("$dir/subdir/file2"); + +class Filter1 extends RecursiveFilterIterator { + public function accept() { return $this->getInnerIterator()->getSubPathname() != ''; } +} + +class Filter2 extends RecursiveFilterIterator { + public function accept() { return $this->getInnerIterator()->getSubPathname() != ' '; } +} + +$iterator = new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS ); + +$iterator = new Filter1( $iterator ); + +$iterator = new Filter2( $iterator ); + +$iterator = new RecursiveIteratorIterator( $iterator, RecursiveIteratorIterator::LEAVES_ONLY, RecursiveIteratorIterator::CATCH_GET_CHILD ); + +foreach ( $iterator as $item ) { +} +?> +OK +--CLEAN-- +<?php +$dir = __DIR__ . '/bug77263'; +unlink("$dir/file1"); +unlink("$dir/subdir/file2"); +rmdir("$dir/subdir"); +rmdir($dir); +?> +--EXPECT-- +OK |