Skip to content

Commit d4ad9b7

Browse files
committed
Throw in FFI::addr() when referencing temporary pointer
Closes phpGH-9601
1 parent c153ec8 commit d4ad9b7

File tree

3 files changed

+52
-0
lines changed

3 files changed

+52
-0
lines changed

ext/ffi/ffi.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4215,6 +4215,11 @@ ZEND_METHOD(FFI, addr) /* {{{ */
42154215
cdata = (zend_ffi_cdata*)Z_OBJ_P(zv);
42164216
type = ZEND_FFI_TYPE(cdata->type);
42174217

4218+
if (GC_REFCOUNT(&cdata->std) == 1 && Z_REFCOUNT_P(arg) == 1 && type->kind == ZEND_FFI_TYPE_POINTER) {
4219+
zend_throw_error(zend_ffi_exception_ce, "FFI::addr() cannot create a reference to a temporary pointer");
4220+
RETURN_THROWS();
4221+
}
4222+
42184223
new_type = emalloc(sizeof(zend_ffi_type));
42194224
new_type->kind = ZEND_FFI_TYPE_POINTER;
42204225
new_type->attr = 0;

ext/ffi/tests/addr_to_owned.phpt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
--TEST--
2+
FFI Referencing temporary owned data transfers ownership
3+
--EXTENSIONS--
4+
ffi
5+
--INI--
6+
ffi.enable=1
7+
--FILE--
8+
<?php
9+
$ffi = \FFI::cdef(<<<'CPP'
10+
typedef struct {
11+
int8_t bar;
12+
} Foo;
13+
CPP);
14+
$structPtr = \FFI::addr($ffi->new('Foo'));
15+
var_dump($structPtr);
16+
?>
17+
--EXPECT--
18+
object(FFI\CData:struct <anonymous>*)#3 (1) {
19+
[0]=>
20+
object(FFI\CData:struct <anonymous>)#2 (1) {
21+
["bar"]=>
22+
int(0)
23+
}
24+
}

ext/ffi/tests/nested_addr.phpt

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
--TEST--
2+
FFI Cannot nest FFI::addr() calls
3+
--EXTENSIONS--
4+
ffi
5+
--INI--
6+
ffi.enable=1
7+
--FILE--
8+
<?php
9+
$ffi = \FFI::cdef(<<<'CPP'
10+
typedef struct {
11+
int8_t bar;
12+
} Foo;
13+
CPP);
14+
15+
$struct = $ffi->new('Foo');
16+
$structPtrPtr = \FFI::addr(\FFI::addr($struct));
17+
?>
18+
--EXPECTF--
19+
Fatal error: Uncaught FFI\Exception: FFI::addr() cannot create a reference to a temporary pointer in %s:%d
20+
Stack trace:
21+
#0 %s(%d): FFI::addr(Object(FFI\CData:struct <anonymous>*))
22+
#1 {main}
23+
thrown in %s on line %d

0 commit comments

Comments
 (0)