Make sure we don't use zresource after the stream has been destroyed.
. Fixed bug #79664 (PDOStatement::getColumnMeta fails on empty result set).
(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)
php_stream_pclose(intern->u.file.stream);
}
intern->u.file.stream = NULL;
+ ZVAL_UNDEF(&intern->u.file.zresource);
}
break;
default:
{
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) {
--- /dev/null
+--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