Skip to content

Commit 84cb42e

Browse files
committed
Merge branch 'PHP-8.2'
* PHP-8.2: Fix leaking definitions on FFI::cdef()->new()
2 parents 4c92e7b + 88fab26 commit 84cb42e

File tree

3 files changed

+86
-0
lines changed

3 files changed

+86
-0
lines changed

NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ PHP NEWS
22
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
33
?? ??? ????, PHP 8.3.0beta2
44

5+
- FFI:
6+
. Fix leaking definitions when using FFI::cdef()->new(...). (ilutov)
7+
58
- Streams:
69
. Fixed bug GH-11735 (Use-after-free when unregistering user stream wrapper
710
from itself). (ilutov)

ext/ffi/ffi.c

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3773,11 +3773,14 @@ ZEND_METHOD(FFI, new) /* {{{ */
37733773
FFI_G(symbols) = NULL;
37743774
FFI_G(tags) = NULL;
37753775
}
3776+
bool clean_symbols = FFI_G(symbols) == NULL;
3777+
bool clean_tags = FFI_G(tags) == NULL;
37763778

37773779
FFI_G(default_type_attr) = 0;
37783780

37793781
if (zend_ffi_parse_type(ZSTR_VAL(type_def), ZSTR_LEN(type_def), &dcl) == FAILURE) {
37803782
zend_ffi_type_dtor(dcl.type);
3783+
<<<<<<< HEAD
37813784
if (is_static_call) {
37823785
if (FFI_G(tags)) {
37833786
zend_hash_destroy(FFI_G(tags));
@@ -3789,6 +3792,17 @@ ZEND_METHOD(FFI, new) /* {{{ */
37893792
efree(FFI_G(symbols));
37903793
FFI_G(symbols) = NULL;
37913794
}
3795+
=======
3796+
if (clean_tags && FFI_G(tags)) {
3797+
zend_hash_destroy(FFI_G(tags));
3798+
efree(FFI_G(tags));
3799+
FFI_G(tags) = NULL;
3800+
}
3801+
if (clean_symbols && FFI_G(symbols)) {
3802+
zend_hash_destroy(FFI_G(symbols));
3803+
efree(FFI_G(symbols));
3804+
FFI_G(symbols) = NULL;
3805+
>>>>>>> PHP-8.2
37923806
}
37933807
return;
37943808
}
@@ -3798,6 +3812,7 @@ ZEND_METHOD(FFI, new) /* {{{ */
37983812
is_const = 1;
37993813
}
38003814

3815+
<<<<<<< HEAD
38013816
if (is_static_call) {
38023817
if (FFI_G(tags)) {
38033818
zend_ffi_tags_cleanup(&dcl);
@@ -3807,6 +3822,15 @@ ZEND_METHOD(FFI, new) /* {{{ */
38073822
efree(FFI_G(symbols));
38083823
FFI_G(symbols) = NULL;
38093824
}
3825+
=======
3826+
if (clean_tags && FFI_G(tags)) {
3827+
zend_ffi_tags_cleanup(&dcl);
3828+
}
3829+
if (clean_symbols && FFI_G(symbols)) {
3830+
zend_hash_destroy(FFI_G(symbols));
3831+
efree(FFI_G(symbols));
3832+
FFI_G(symbols) = NULL;
3833+
>>>>>>> PHP-8.2
38103834
}
38113835
FFI_G(symbols) = NULL;
38123836
FFI_G(tags) = NULL;
@@ -3925,11 +3949,14 @@ ZEND_METHOD(FFI, cast) /* {{{ */
39253949
FFI_G(symbols) = NULL;
39263950
FFI_G(tags) = NULL;
39273951
}
3952+
bool clean_symbols = FFI_G(symbols) == NULL;
3953+
bool clean_tags = FFI_G(tags) == NULL;
39283954

39293955
FFI_G(default_type_attr) = 0;
39303956

39313957
if (zend_ffi_parse_type(ZSTR_VAL(type_def), ZSTR_LEN(type_def), &dcl) == FAILURE) {
39323958
zend_ffi_type_dtor(dcl.type);
3959+
<<<<<<< HEAD
39333960
if (is_static_call) {
39343961
if (FFI_G(tags)) {
39353962
zend_hash_destroy(FFI_G(tags));
@@ -3941,6 +3968,17 @@ ZEND_METHOD(FFI, cast) /* {{{ */
39413968
efree(FFI_G(symbols));
39423969
FFI_G(symbols) = NULL;
39433970
}
3971+
=======
3972+
if (clean_tags && FFI_G(tags)) {
3973+
zend_hash_destroy(FFI_G(tags));
3974+
efree(FFI_G(tags));
3975+
FFI_G(tags) = NULL;
3976+
}
3977+
if (clean_symbols && FFI_G(symbols)) {
3978+
zend_hash_destroy(FFI_G(symbols));
3979+
efree(FFI_G(symbols));
3980+
FFI_G(symbols) = NULL;
3981+
>>>>>>> PHP-8.2
39443982
}
39453983
return;
39463984
}
@@ -3950,6 +3988,7 @@ ZEND_METHOD(FFI, cast) /* {{{ */
39503988
is_const = 1;
39513989
}
39523990

3991+
<<<<<<< HEAD
39533992
if (is_static_call) {
39543993
if (FFI_G(tags)) {
39553994
zend_ffi_tags_cleanup(&dcl);
@@ -3959,6 +3998,15 @@ ZEND_METHOD(FFI, cast) /* {{{ */
39593998
efree(FFI_G(symbols));
39603999
FFI_G(symbols) = NULL;
39614000
}
4001+
=======
4002+
if (clean_tags && FFI_G(tags)) {
4003+
zend_ffi_tags_cleanup(&dcl);
4004+
}
4005+
if (clean_symbols && FFI_G(symbols)) {
4006+
zend_hash_destroy(FFI_G(symbols));
4007+
efree(FFI_G(symbols));
4008+
FFI_G(symbols) = NULL;
4009+
>>>>>>> PHP-8.2
39624010
}
39634011
FFI_G(symbols) = NULL;
39644012
FFI_G(tags) = NULL;
@@ -4099,11 +4147,14 @@ ZEND_METHOD(FFI, type) /* {{{ */
40994147
FFI_G(symbols) = NULL;
41004148
FFI_G(tags) = NULL;
41014149
}
4150+
bool clean_symbols = FFI_G(symbols) == NULL;
4151+
bool clean_tags = FFI_G(tags) == NULL;
41024152

41034153
FFI_G(default_type_attr) = 0;
41044154

41054155
if (zend_ffi_parse_type(ZSTR_VAL(type_def), ZSTR_LEN(type_def), &dcl) == FAILURE) {
41064156
zend_ffi_type_dtor(dcl.type);
4157+
<<<<<<< HEAD
41074158
if (is_static_call) {
41084159
if (FFI_G(tags)) {
41094160
zend_hash_destroy(FFI_G(tags));
@@ -4124,10 +4175,28 @@ ZEND_METHOD(FFI, type) /* {{{ */
41244175
zend_ffi_tags_cleanup(&dcl);
41254176
}
41264177
if (FFI_G(symbols)) {
4178+
=======
4179+
if (clean_tags && FFI_G(tags)) {
4180+
zend_hash_destroy(FFI_G(tags));
4181+
efree(FFI_G(tags));
4182+
FFI_G(tags) = NULL;
4183+
}
4184+
if (clean_symbols && FFI_G(symbols)) {
4185+
>>>>>>> PHP-8.2
41274186
zend_hash_destroy(FFI_G(symbols));
41284187
efree(FFI_G(symbols));
41294188
FFI_G(symbols) = NULL;
41304189
}
4190+
return;
4191+
}
4192+
4193+
if (clean_tags && FFI_G(tags)) {
4194+
zend_ffi_tags_cleanup(&dcl);
4195+
}
4196+
if (clean_symbols && FFI_G(symbols)) {
4197+
zend_hash_destroy(FFI_G(symbols));
4198+
efree(FFI_G(symbols));
4199+
FFI_G(symbols) = NULL;
41314200
}
41324201
FFI_G(symbols) = NULL;
41334202
FFI_G(tags) = NULL;

ext/ffi/tests/cdef_new.phpt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
--TEST--
2+
Definitions should not leak when using FFI::cdef()->new(...)
3+
--EXTENSIONS--
4+
ffi
5+
--FILE--
6+
<?php
7+
$struct = \FFI::cdef()->new('struct Example { uint32_t x; }');
8+
var_dump($struct);
9+
?>
10+
--EXPECT--
11+
object(FFI\CData:struct Example)#2 (1) {
12+
["x"]=>
13+
int(0)
14+
}

0 commit comments

Comments
 (0)