diff options
-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 |