mirror of
https://github.com/php/php-src.git
synced 2025-08-15 13:38:49 +02:00
Fix segfault caused by weak references to FFI objects (#12488)
Thank you!
This commit is contained in:
parent
83a505e85f
commit
04b35a44ce
5 changed files with 119 additions and 0 deletions
|
@ -24,6 +24,7 @@
|
||||||
#include "php_scandir.h"
|
#include "php_scandir.h"
|
||||||
#include "zend_exceptions.h"
|
#include "zend_exceptions.h"
|
||||||
#include "zend_closures.h"
|
#include "zend_closures.h"
|
||||||
|
#include "zend_weakrefs.h"
|
||||||
#include "main/SAPI.h"
|
#include "main/SAPI.h"
|
||||||
#include "ffi_arginfo.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_ctype *ctype = (zend_ffi_ctype*)object;
|
||||||
|
|
||||||
zend_ffi_type_dtor(ctype->type);
|
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);
|
zend_hash_destroy(ffi->tags);
|
||||||
efree(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 *cdata = (zend_ffi_cdata*)object;
|
||||||
|
|
||||||
zend_ffi_cdata_dtor(cdata);
|
zend_ffi_cdata_dtor(cdata);
|
||||||
|
|
||||||
|
if (UNEXPECTED(GC_FLAGS(object) & IS_OBJ_WEAKLY_REFERENCED)) {
|
||||||
|
zend_weakrefs_notify(object);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
|
17
ext/ffi/tests/weak_reference_001.phpt
Normal file
17
ext/ffi/tests/weak_reference_001.phpt
Normal 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)
|
36
ext/ffi/tests/weak_reference_002.phpt
Normal file
36
ext/ffi/tests/weak_reference_002.phpt
Normal 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)
|
17
ext/ffi/tests/weak_reference_003.phpt
Normal file
17
ext/ffi/tests/weak_reference_003.phpt
Normal 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)
|
36
ext/ffi/tests/weak_reference_004.phpt
Normal file
36
ext/ffi/tests/weak_reference_004.phpt
Normal 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)
|
Loading…
Add table
Add a link
Reference in a new issue