File tree 2 files changed +33
-1
lines changed
2 files changed +33
-1
lines changed Original file line number Diff line number Diff line change @@ -4290,7 +4290,8 @@ ZEND_METHOD(FFI, addr) /* {{{ */
4290
4290
cdata = (zend_ffi_cdata * )Z_OBJ_P (zv );
4291
4291
type = ZEND_FFI_TYPE (cdata -> type );
4292
4292
4293
- if (GC_REFCOUNT (& cdata -> std ) == 1 && Z_REFCOUNT_P (arg ) == 1 && type -> kind == ZEND_FFI_TYPE_POINTER ) {
4293
+ if (GC_REFCOUNT (& cdata -> std ) == 1 && Z_REFCOUNT_P (arg ) == 1 && type -> kind == ZEND_FFI_TYPE_POINTER
4294
+ && cdata -> ptr == & cdata -> ptr_holder ) {
4294
4295
zend_throw_error (zend_ffi_exception_ce , "FFI::addr() cannot create a reference to a temporary pointer" );
4295
4296
RETURN_THROWS ();
4296
4297
}
Original file line number Diff line number Diff line change
1
+ --TEST--
2
+ Assignment to CDATA though FFI::addr() trick
3
+ --EXTENSIONS--
4
+ ffi
5
+ --INI--
6
+ ffi.enable=1
7
+ --FILE--
8
+ <?php
9
+ $ f = FFI ::cdef ("typedef struct { char *bar; } other; " );
10
+ class Container {
11
+ public $ data ;
12
+ function __construct ($ f ) { $ this ->data = $ f ->new ("other " ); }
13
+ function &getBar () { return $ this ->data ->bar ; } // return by ref to get CData instead of null
14
+ }
15
+ $ container = new Container ($ f );
16
+ $ data = $ f ->new ("char[2] " );
17
+ $ data [0 ] = "1 " ;
18
+ FFI ::addr ($ container ->getBar ())[0 ] = $ f ->cast ("char* " , $ data ); // directly write it
19
+ var_dump ($ container );
20
+ ?>
21
+ --EXPECT--
22
+ object(Container)#2 (1) {
23
+ ["data"]=>
24
+ object(FFI\CData:struct <anonymous>)#3 (1) {
25
+ ["bar"]=>
26
+ object(FFI\CData:char*)#6 (1) {
27
+ [0]=>
28
+ string(1) "1"
29
+ }
30
+ }
31
+ }
You can’t perform that action at this time.
0 commit comments