Merge branch 'PHP-8.3'

* PHP-8.3:
  [ci skip] NEWS
  [ci skip] NEWS
  [ci skip] NEWS
  Fix segfault caused by weak references to FFI objects (#12488)
This commit is contained in:
Arnaud Le Blanc 2023-10-28 15:06:36 +02:00
commit d30c78d7f9
5 changed files with 119 additions and 0 deletions

View File

@ -24,6 +24,7 @@
#include "php_scandir.h"
#include "zend_exceptions.h"
#include "zend_closures.h"
#include "zend_weakrefs.h"
#include "main/SAPI.h"
#include <ffi.h>
@ -2201,6 +2202,10 @@ static void zend_ffi_ctype_free_obj(zend_object *object) /* {{{ */
zend_ffi_ctype *ctype = (zend_ffi_ctype*)object;
zend_ffi_type_dtor(ctype->type);
if (UNEXPECTED(GC_FLAGS(object) & IS_OBJ_WEAKLY_REFERENCED)) {
zend_weakrefs_notify(object);
}
}
/* }}} */
@ -2426,6 +2431,10 @@ static void zend_ffi_free_obj(zend_object *object) /* {{{ */
zend_hash_destroy(ffi->tags);
efree(ffi->tags);
}
if (UNEXPECTED(GC_FLAGS(object) & IS_OBJ_WEAKLY_REFERENCED)) {
zend_weakrefs_notify(object);
}
}
/* }}} */
@ -2434,6 +2443,10 @@ static void zend_ffi_cdata_free_obj(zend_object *object) /* {{{ */
zend_ffi_cdata *cdata = (zend_ffi_cdata*)object;
zend_ffi_cdata_dtor(cdata);
if (UNEXPECTED(GC_FLAGS(object) & IS_OBJ_WEAKLY_REFERENCED)) {
zend_weakrefs_notify(object);
}
}
/* }}} */

View File

@ -0,0 +1,17 @@
--TEST--
Weak reference to \FFI
--EXTENSIONS--
ffi
--INI--
ffi.enable=1
--FILE--
<?php
$ffi = \FFI::cdef('');
$ref = \WeakReference::create($ffi);
var_dump($ref->get() === $ffi);
unset($ffi);
var_dump($ref->get() === null);
?>
--EXPECTF--
bool(true)
bool(true)

View File

@ -0,0 +1,36 @@
--TEST--
Weak reference to \FFI\CData
--EXTENSIONS--
ffi
--INI--
ffi.enable=1
--FILE--
<?php
$cdata_value = \FFI::new('int');
$cdata_array = \FFI::new('int[1]');
$cdata_free = \FFI::new('int[1]', false);
\FFI::free($cdata_free);
$ref_value = \WeakReference::create($cdata_value);
$ref_array = \WeakReference::create($cdata_array);
$ref_free = \WeakReference::create($cdata_free);
var_dump($ref_value->get() === $cdata_value);
var_dump($ref_array->get() === $cdata_array);
var_dump($ref_free->get() === $cdata_free);
unset($cdata_value);
unset($cdata_array);
unset($cdata_free);
var_dump($ref_value->get() === null);
var_dump($ref_array->get() === null);
var_dump($ref_free->get() === null);
?>
--EXPECTF--
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)

View File

@ -0,0 +1,17 @@
--TEST--
Weak reference to \FFI\CType
--EXTENSIONS--
ffi
--INI--
ffi.enable=1
--FILE--
<?php
$ctype = \FFI::type('int');
$ref = \WeakReference::create($ctype);
var_dump($ref->get() === $ctype);
unset($ctype);
var_dump($ref->get() === null);
?>
--EXPECTF--
bool(true)
bool(true)

View File

@ -0,0 +1,36 @@
--TEST--
Using FFI Types for keys of a WeakMap
--EXTENSIONS--
ffi
--INI--
ffi.enable=1
--FILE--
<?php
$map = new WeakMap();
$ffi = \FFI::cdef('');
$cdata_value = \FFI::new('int');
$cdata_array = \FFI::new('int[1]');
$cdata_free = \FFI::new('int[1]', false);
\FFI::free($cdata_free);
$ctype = \FFI::type('int');
$map[$ffi] = 'ffi';
$map[$cdata_value] = 'cdata_value';
$map[$cdata_array] = 'cdata_array';
$map[$cdata_free] = 'cdata_free';
$map[$ctype] = 'ctype';
var_dump(count($map) === 5);
unset($ffi);
unset($cdata_value);
unset($cdata_array);
unset($cdata_free);
unset($ctype);
var_dump(count($map) === 0);
?>
--EXPECTF--
bool(true)
bool(true)