summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2020-06-19 10:48:34 +0200
committerNikita Popov <nikita.ppv@gmail.com>2020-06-19 10:48:34 +0200
commitb461e6b074f42aa786feca9a7b238b32dd75a7cc (patch)
tree480b321ea207d6ee2bfa3baff699fa9758c594d9
parent5d7ff25311f1c640a78ca9ac1b83a0366d4882d2 (diff)
parent2f56b0018e2963a456e1a313ed8ea1de5cf74349 (diff)
downloadphp-git-b461e6b074f42aa786feca9a7b238b32dd75a7cc.tar.gz
Merge branch 'PHP-7.4'
* PHP-7.4: Fixed bug #79710
-rw-r--r--ext/spl/spl_directory.c9
-rw-r--r--ext/spl/tests/bug79710.phpt40
2 files changed, 47 insertions, 2 deletions
diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c
index f30d7fcf7f..fa33c022b0 100644
--- a/ext/spl/spl_directory.c
+++ b/ext/spl/spl_directory.c
@@ -95,6 +95,7 @@ static void spl_filesystem_object_destroy_object(zend_object *object) /* {{{ */
php_stream_pclose(intern->u.file.stream);
}
intern->u.file.stream = NULL;
+ ZVAL_UNDEF(&intern->u.file.zresource);
}
break;
default:
@@ -1927,12 +1928,16 @@ static int spl_filesystem_file_call(spl_filesystem_object *intern, zend_function
{
zend_fcall_info fci;
zend_fcall_info_cache fcic;
- zval *zresource_ptr = &intern->u.file.zresource;
+ zval *zresource_ptr = &intern->u.file.zresource, *params;
int result;
int num_args = pass_num_args + (arg2 ? 2 : 1);
- zval *params = (zval*)safe_emalloc(num_args, sizeof(zval), 0);
+ if (Z_ISUNDEF_P(zresource_ptr)) {
+ zend_throw_exception_ex(spl_ce_RuntimeException, 0, "Object not initialized");
+ return FAILURE;
+ }
+ params = (zval*)safe_emalloc(num_args, sizeof(zval), 0);
params[0] = *zresource_ptr;
if (arg2) {
diff --git a/ext/spl/tests/bug79710.phpt b/ext/spl/tests/bug79710.phpt
new file mode 100644
index 0000000000..a5c065fd67
--- /dev/null
+++ b/ext/spl/tests/bug79710.phpt
@@ -0,0 +1,40 @@
+--TEST--
+Bug #79710: Reproducible segfault in error_handler during GC involved an SplFileObject
+--FILE--
+<?php
+
+class Target
+{
+ public $sfo;
+ public function __construct($sfo) {
+ $this->sfo = $sfo;
+ }
+ public function __destruct() {
+ // If the SplFileObject is destructed first,
+ // underlying FD is no longer valid and will cause error upon calling flock
+ $this->sfo->flock(2);
+ }
+}
+
+class Run
+{
+ static $sfo;
+ static $foo;
+ public static function main() {
+ // Creation ordering is important for repro
+ // $sfo needed to be destructed before $foo.
+ Run::$sfo = new SplTempFileObject();
+ Run::$foo = new Target(Run::$sfo);
+ }
+}
+
+Run::main();
+
+?>
+--EXPECTF--
+Fatal error: Uncaught RuntimeException: Object not initialized in %s:%d
+Stack trace:
+#0 %s(%d): SplFileObject->flock(2)
+#1 [internal function]: Target->__destruct()
+#2 {main}
+ thrown in %s on line %d