Skip to content

Commit

Permalink
Merge branch 'PHP-7.3' into PHP-7.4
Browse files Browse the repository at this point in the history
  • Loading branch information
nikic committed Jun 19, 2020
2 parents 21a2da2 + 32f377b commit 2f56b00
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 2 deletions.
4 changes: 4 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ PHP NEWS
(cmb)
. Fixed several mostly Windows related phpdbg bugs. (cmb)

- SPL:
. Fixed bug #79710 (Reproducible segfault in error_handler during GC
involved an SplFileObject). (Nikita)

- Standard:
. Fixed bug #74267 (segfault with streams and invalid data). (cmb)

Expand Down
9 changes: 7 additions & 2 deletions ext/spl/spl_directory.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,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:
Expand Down Expand Up @@ -2077,12 +2078,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, retval;
zval *zresource_ptr = &intern->u.file.zresource, *params, retval;
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) {
Expand Down
40 changes: 40 additions & 0 deletions ext/spl/tests/bug79710.phpt
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 2f56b00

Please sign in to comment.