From 4c97e943d6965829672c0ed5762366234e9b2296 Mon Sep 17 00:00:00 2001 From: sji Date: Sat, 21 Oct 2023 08:13:04 +0900 Subject: [PATCH] Fix segfault caused by weak references to FFI objects --- ext/ffi/ffi.c | 13 ++++++++++ ext/ffi/tests/weak_reference_001.phpt | 17 +++++++++++++ ext/ffi/tests/weak_reference_002.phpt | 36 +++++++++++++++++++++++++++ ext/ffi/tests/weak_reference_003.phpt | 17 +++++++++++++ ext/ffi/tests/weak_reference_004.phpt | 36 +++++++++++++++++++++++++++ 5 files changed, 119 insertions(+) create mode 100644 ext/ffi/tests/weak_reference_001.phpt create mode 100644 ext/ffi/tests/weak_reference_002.phpt create mode 100644 ext/ffi/tests/weak_reference_003.phpt create mode 100644 ext/ffi/tests/weak_reference_004.phpt diff --git a/ext/ffi/ffi.c b/ext/ffi/ffi.c index efb4524c76b1a..a2779b65b120c 100644 --- a/ext/ffi/ffi.c +++ b/ext/ffi/ffi.c @@ -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_arginfo.h" @@ -2143,6 +2144,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); + } } /* }}} */ @@ -2369,6 +2374,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); + } } /* }}} */ @@ -2377,6 +2386,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); + } } /* }}} */ diff --git a/ext/ffi/tests/weak_reference_001.phpt b/ext/ffi/tests/weak_reference_001.phpt new file mode 100644 index 0000000000000..56f0be981f629 --- /dev/null +++ b/ext/ffi/tests/weak_reference_001.phpt @@ -0,0 +1,17 @@ +--TEST-- +Weak reference to \FFI +--EXTENSIONS-- +ffi +--INI-- +ffi.enable=1 +--FILE-- +get() === $ffi); +unset($ffi); +var_dump($ref->get() === null); +?> +--EXPECTF-- +bool(true) +bool(true) diff --git a/ext/ffi/tests/weak_reference_002.phpt b/ext/ffi/tests/weak_reference_002.phpt new file mode 100644 index 0000000000000..5c36cfa703455 --- /dev/null +++ b/ext/ffi/tests/weak_reference_002.phpt @@ -0,0 +1,36 @@ +--TEST-- +Weak reference to \FFI\CData +--EXTENSIONS-- +ffi +--INI-- +ffi.enable=1 +--FILE-- +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) diff --git a/ext/ffi/tests/weak_reference_003.phpt b/ext/ffi/tests/weak_reference_003.phpt new file mode 100644 index 0000000000000..15b9397a6856b --- /dev/null +++ b/ext/ffi/tests/weak_reference_003.phpt @@ -0,0 +1,17 @@ +--TEST-- +Weak reference to \FFI\CType +--EXTENSIONS-- +ffi +--INI-- +ffi.enable=1 +--FILE-- +get() === $ctype); +unset($ctype); +var_dump($ref->get() === null); +?> +--EXPECTF-- +bool(true) +bool(true) diff --git a/ext/ffi/tests/weak_reference_004.phpt b/ext/ffi/tests/weak_reference_004.phpt new file mode 100644 index 0000000000000..500776fa21865 --- /dev/null +++ b/ext/ffi/tests/weak_reference_004.phpt @@ -0,0 +1,36 @@ +--TEST-- +Using FFI Types for keys of a WeakMap +--EXTENSIONS-- +ffi +--INI-- +ffi.enable=1 +--FILE-- + +--EXPECTF-- +bool(true) +bool(true)