diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2020-06-19 10:48:34 +0200 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2020-06-19 10:48:34 +0200 |
commit | b461e6b074f42aa786feca9a7b238b32dd75a7cc (patch) | |
tree | 480b321ea207d6ee2bfa3baff699fa9758c594d9 | |
parent | 5d7ff25311f1c640a78ca9ac1b83a0366d4882d2 (diff) | |
parent | 2f56b0018e2963a456e1a313ed8ea1de5cf74349 (diff) | |
download | php-git-b461e6b074f42aa786feca9a7b238b32dd75a7cc.tar.gz |
Merge branch 'PHP-7.4'
* PHP-7.4:
Fixed bug #79710
-rw-r--r-- | ext/spl/spl_directory.c | 9 | ||||
-rw-r--r-- | ext/spl/tests/bug79710.phpt | 40 |
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 |