Skip to content

Commit 198f613

Browse files
committed
Merge branch 'PHP-8.2' into PHP-8.3
* PHP-8.2: [ci skip] NEWS [ci skip] NEWS Fix segfault caused by weak references to FFI objects (#12488)
2 parents e7cbcfd + ae9118a commit 198f613

File tree

5 files changed

+119
-0
lines changed

5 files changed

+119
-0
lines changed

ext/ffi/ffi.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "php_scandir.h"
2525
#include "zend_exceptions.h"
2626
#include "zend_closures.h"
27+
#include "zend_weakrefs.h"
2728
#include "main/SAPI.h"
2829

2930
#include <ffi.h>
@@ -2201,6 +2202,10 @@ static void zend_ffi_ctype_free_obj(zend_object *object) /* {{{ */
22012202
zend_ffi_ctype *ctype = (zend_ffi_ctype*)object;
22022203

22032204
zend_ffi_type_dtor(ctype->type);
2205+
2206+
if (UNEXPECTED(GC_FLAGS(object) & IS_OBJ_WEAKLY_REFERENCED)) {
2207+
zend_weakrefs_notify(object);
2208+
}
22042209
}
22052210
/* }}} */
22062211

@@ -2426,6 +2431,10 @@ static void zend_ffi_free_obj(zend_object *object) /* {{{ */
24262431
zend_hash_destroy(ffi->tags);
24272432
efree(ffi->tags);
24282433
}
2434+
2435+
if (UNEXPECTED(GC_FLAGS(object) & IS_OBJ_WEAKLY_REFERENCED)) {
2436+
zend_weakrefs_notify(object);
2437+
}
24292438
}
24302439
/* }}} */
24312440

@@ -2434,6 +2443,10 @@ static void zend_ffi_cdata_free_obj(zend_object *object) /* {{{ */
24342443
zend_ffi_cdata *cdata = (zend_ffi_cdata*)object;
24352444

24362445
zend_ffi_cdata_dtor(cdata);
2446+
2447+
if (UNEXPECTED(GC_FLAGS(object) & IS_OBJ_WEAKLY_REFERENCED)) {
2448+
zend_weakrefs_notify(object);
2449+
}
24372450
}
24382451
/* }}} */
24392452

ext/ffi/tests/weak_reference_001.phpt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
--TEST--
2+
Weak reference to \FFI
3+
--EXTENSIONS--
4+
ffi
5+
--INI--
6+
ffi.enable=1
7+
--FILE--
8+
<?php
9+
$ffi = \FFI::cdef('');
10+
$ref = \WeakReference::create($ffi);
11+
var_dump($ref->get() === $ffi);
12+
unset($ffi);
13+
var_dump($ref->get() === null);
14+
?>
15+
--EXPECTF--
16+
bool(true)
17+
bool(true)

ext/ffi/tests/weak_reference_002.phpt

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
--TEST--
2+
Weak reference to \FFI\CData
3+
--EXTENSIONS--
4+
ffi
5+
--INI--
6+
ffi.enable=1
7+
--FILE--
8+
<?php
9+
$cdata_value = \FFI::new('int');
10+
$cdata_array = \FFI::new('int[1]');
11+
$cdata_free = \FFI::new('int[1]', false);
12+
\FFI::free($cdata_free);
13+
14+
$ref_value = \WeakReference::create($cdata_value);
15+
$ref_array = \WeakReference::create($cdata_array);
16+
$ref_free = \WeakReference::create($cdata_free);
17+
18+
var_dump($ref_value->get() === $cdata_value);
19+
var_dump($ref_array->get() === $cdata_array);
20+
var_dump($ref_free->get() === $cdata_free);
21+
22+
unset($cdata_value);
23+
unset($cdata_array);
24+
unset($cdata_free);
25+
26+
var_dump($ref_value->get() === null);
27+
var_dump($ref_array->get() === null);
28+
var_dump($ref_free->get() === null);
29+
?>
30+
--EXPECTF--
31+
bool(true)
32+
bool(true)
33+
bool(true)
34+
bool(true)
35+
bool(true)
36+
bool(true)

ext/ffi/tests/weak_reference_003.phpt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
--TEST--
2+
Weak reference to \FFI\CType
3+
--EXTENSIONS--
4+
ffi
5+
--INI--
6+
ffi.enable=1
7+
--FILE--
8+
<?php
9+
$ctype = \FFI::type('int');
10+
$ref = \WeakReference::create($ctype);
11+
var_dump($ref->get() === $ctype);
12+
unset($ctype);
13+
var_dump($ref->get() === null);
14+
?>
15+
--EXPECTF--
16+
bool(true)
17+
bool(true)

ext/ffi/tests/weak_reference_004.phpt

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
--TEST--
2+
Using FFI Types for keys of a WeakMap
3+
--EXTENSIONS--
4+
ffi
5+
--INI--
6+
ffi.enable=1
7+
--FILE--
8+
<?php
9+
$map = new WeakMap();
10+
11+
$ffi = \FFI::cdef('');
12+
$cdata_value = \FFI::new('int');
13+
$cdata_array = \FFI::new('int[1]');
14+
$cdata_free = \FFI::new('int[1]', false);
15+
\FFI::free($cdata_free);
16+
$ctype = \FFI::type('int');
17+
18+
$map[$ffi] = 'ffi';
19+
$map[$cdata_value] = 'cdata_value';
20+
$map[$cdata_array] = 'cdata_array';
21+
$map[$cdata_free] = 'cdata_free';
22+
$map[$ctype] = 'ctype';
23+
24+
var_dump(count($map) === 5);
25+
26+
unset($ffi);
27+
unset($cdata_value);
28+
unset($cdata_array);
29+
unset($cdata_free);
30+
unset($ctype);
31+
32+
var_dump(count($map) === 0);
33+
?>
34+
--EXPECTF--
35+
bool(true)
36+
bool(true)

0 commit comments

Comments
 (0)