mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Fix leaking definitions on FFI::cdef()->new()
Previously, FFI_G(symbols) and FFI_G(tags) were never cleaned up when calling new on an existing object. However, if cdef() is called without parameters these globals are NULL and might be created when new() creates new definitions. These would then be discarded without freeing them. Closes GH-11751
This commit is contained in:
parent
6e3c520f51
commit
11d6bea98a
3 changed files with 69 additions and 60 deletions
3
NEWS
3
NEWS
|
@ -2,7 +2,8 @@ PHP NEWS
|
|||
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||
?? ??? ????, PHP 8.1.23
|
||||
|
||||
|
||||
- FFI:
|
||||
. Fix leaking definitions when using FFI::cdef()->new(...). (ilutov)
|
||||
|
||||
03 Aug 2023, PHP 8.1.22
|
||||
|
||||
|
|
112
ext/ffi/ffi.c
112
ext/ffi/ffi.c
|
@ -3684,22 +3684,22 @@ ZEND_METHOD(FFI, new) /* {{{ */
|
|||
FFI_G(symbols) = NULL;
|
||||
FFI_G(tags) = NULL;
|
||||
}
|
||||
bool clean_symbols = FFI_G(symbols) == NULL;
|
||||
bool clean_tags = FFI_G(tags) == NULL;
|
||||
|
||||
FFI_G(default_type_attr) = 0;
|
||||
|
||||
if (zend_ffi_parse_type(ZSTR_VAL(type_def), ZSTR_LEN(type_def), &dcl) != SUCCESS) {
|
||||
zend_ffi_type_dtor(dcl.type);
|
||||
if (Z_TYPE(EX(This)) != IS_OBJECT) {
|
||||
if (FFI_G(tags)) {
|
||||
zend_hash_destroy(FFI_G(tags));
|
||||
efree(FFI_G(tags));
|
||||
FFI_G(tags) = NULL;
|
||||
}
|
||||
if (FFI_G(symbols)) {
|
||||
zend_hash_destroy(FFI_G(symbols));
|
||||
efree(FFI_G(symbols));
|
||||
FFI_G(symbols) = NULL;
|
||||
}
|
||||
if (clean_tags && FFI_G(tags)) {
|
||||
zend_hash_destroy(FFI_G(tags));
|
||||
efree(FFI_G(tags));
|
||||
FFI_G(tags) = NULL;
|
||||
}
|
||||
if (clean_symbols && FFI_G(symbols)) {
|
||||
zend_hash_destroy(FFI_G(symbols));
|
||||
efree(FFI_G(symbols));
|
||||
FFI_G(symbols) = NULL;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -3709,15 +3709,13 @@ ZEND_METHOD(FFI, new) /* {{{ */
|
|||
is_const = 1;
|
||||
}
|
||||
|
||||
if (Z_TYPE(EX(This)) != IS_OBJECT) {
|
||||
if (FFI_G(tags)) {
|
||||
zend_ffi_tags_cleanup(&dcl);
|
||||
}
|
||||
if (FFI_G(symbols)) {
|
||||
zend_hash_destroy(FFI_G(symbols));
|
||||
efree(FFI_G(symbols));
|
||||
FFI_G(symbols) = NULL;
|
||||
}
|
||||
if (clean_tags && FFI_G(tags)) {
|
||||
zend_ffi_tags_cleanup(&dcl);
|
||||
}
|
||||
if (clean_symbols && FFI_G(symbols)) {
|
||||
zend_hash_destroy(FFI_G(symbols));
|
||||
efree(FFI_G(symbols));
|
||||
FFI_G(symbols) = NULL;
|
||||
}
|
||||
FFI_G(symbols) = NULL;
|
||||
FFI_G(tags) = NULL;
|
||||
|
@ -3828,22 +3826,22 @@ ZEND_METHOD(FFI, cast) /* {{{ */
|
|||
FFI_G(symbols) = NULL;
|
||||
FFI_G(tags) = NULL;
|
||||
}
|
||||
bool clean_symbols = FFI_G(symbols) == NULL;
|
||||
bool clean_tags = FFI_G(tags) == NULL;
|
||||
|
||||
FFI_G(default_type_attr) = 0;
|
||||
|
||||
if (zend_ffi_parse_type(ZSTR_VAL(type_def), ZSTR_LEN(type_def), &dcl) != SUCCESS) {
|
||||
zend_ffi_type_dtor(dcl.type);
|
||||
if (Z_TYPE(EX(This)) != IS_OBJECT) {
|
||||
if (FFI_G(tags)) {
|
||||
zend_hash_destroy(FFI_G(tags));
|
||||
efree(FFI_G(tags));
|
||||
FFI_G(tags) = NULL;
|
||||
}
|
||||
if (FFI_G(symbols)) {
|
||||
zend_hash_destroy(FFI_G(symbols));
|
||||
efree(FFI_G(symbols));
|
||||
FFI_G(symbols) = NULL;
|
||||
}
|
||||
if (clean_tags && FFI_G(tags)) {
|
||||
zend_hash_destroy(FFI_G(tags));
|
||||
efree(FFI_G(tags));
|
||||
FFI_G(tags) = NULL;
|
||||
}
|
||||
if (clean_symbols && FFI_G(symbols)) {
|
||||
zend_hash_destroy(FFI_G(symbols));
|
||||
efree(FFI_G(symbols));
|
||||
FFI_G(symbols) = NULL;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -3853,15 +3851,13 @@ ZEND_METHOD(FFI, cast) /* {{{ */
|
|||
is_const = 1;
|
||||
}
|
||||
|
||||
if (Z_TYPE(EX(This)) != IS_OBJECT) {
|
||||
if (FFI_G(tags)) {
|
||||
zend_ffi_tags_cleanup(&dcl);
|
||||
}
|
||||
if (FFI_G(symbols)) {
|
||||
zend_hash_destroy(FFI_G(symbols));
|
||||
efree(FFI_G(symbols));
|
||||
FFI_G(symbols) = NULL;
|
||||
}
|
||||
if (clean_tags && FFI_G(tags)) {
|
||||
zend_ffi_tags_cleanup(&dcl);
|
||||
}
|
||||
if (clean_symbols && FFI_G(symbols)) {
|
||||
zend_hash_destroy(FFI_G(symbols));
|
||||
efree(FFI_G(symbols));
|
||||
FFI_G(symbols) = NULL;
|
||||
}
|
||||
FFI_G(symbols) = NULL;
|
||||
FFI_G(tags) = NULL;
|
||||
|
@ -3994,35 +3990,33 @@ ZEND_METHOD(FFI, type) /* {{{ */
|
|||
FFI_G(symbols) = NULL;
|
||||
FFI_G(tags) = NULL;
|
||||
}
|
||||
bool clean_symbols = FFI_G(symbols) == NULL;
|
||||
bool clean_tags = FFI_G(tags) == NULL;
|
||||
|
||||
FFI_G(default_type_attr) = 0;
|
||||
|
||||
if (zend_ffi_parse_type(ZSTR_VAL(type_def), ZSTR_LEN(type_def), &dcl) != SUCCESS) {
|
||||
zend_ffi_type_dtor(dcl.type);
|
||||
if (Z_TYPE(EX(This)) != IS_OBJECT) {
|
||||
if (FFI_G(tags)) {
|
||||
zend_hash_destroy(FFI_G(tags));
|
||||
efree(FFI_G(tags));
|
||||
FFI_G(tags) = NULL;
|
||||
}
|
||||
if (FFI_G(symbols)) {
|
||||
zend_hash_destroy(FFI_G(symbols));
|
||||
efree(FFI_G(symbols));
|
||||
FFI_G(symbols) = NULL;
|
||||
}
|
||||
if (clean_tags && FFI_G(tags)) {
|
||||
zend_hash_destroy(FFI_G(tags));
|
||||
efree(FFI_G(tags));
|
||||
FFI_G(tags) = NULL;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (Z_TYPE(EX(This)) != IS_OBJECT) {
|
||||
if (FFI_G(tags)) {
|
||||
zend_ffi_tags_cleanup(&dcl);
|
||||
}
|
||||
if (FFI_G(symbols)) {
|
||||
if (clean_symbols && FFI_G(symbols)) {
|
||||
zend_hash_destroy(FFI_G(symbols));
|
||||
efree(FFI_G(symbols));
|
||||
FFI_G(symbols) = NULL;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (clean_tags && FFI_G(tags)) {
|
||||
zend_ffi_tags_cleanup(&dcl);
|
||||
}
|
||||
if (clean_symbols && FFI_G(symbols)) {
|
||||
zend_hash_destroy(FFI_G(symbols));
|
||||
efree(FFI_G(symbols));
|
||||
FFI_G(symbols) = NULL;
|
||||
}
|
||||
FFI_G(symbols) = NULL;
|
||||
FFI_G(tags) = NULL;
|
||||
|
|
14
ext/ffi/tests/cdef_new.phpt
Normal file
14
ext/ffi/tests/cdef_new.phpt
Normal file
|
@ -0,0 +1,14 @@
|
|||
--TEST--
|
||||
Definitions should not leak when using FFI::cdef()->new(...)
|
||||
--EXTENSIONS--
|
||||
ffi
|
||||
--FILE--
|
||||
<?php
|
||||
$struct = \FFI::cdef()->new('struct Example { uint32_t x; }');
|
||||
var_dump($struct);
|
||||
?>
|
||||
--EXPECT--
|
||||
object(FFI\CData:struct Example)#2 (1) {
|
||||
["x"]=>
|
||||
int(0)
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue