Skip to content

Commit adaf726

Browse files
committed
Fixed regression introduced by php#9601
1 parent 6f355c6 commit adaf726

File tree

2 files changed

+33
-1
lines changed

2 files changed

+33
-1
lines changed

ext/ffi/ffi.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -4290,7 +4290,8 @@ ZEND_METHOD(FFI, addr) /* {{{ */
42904290
cdata = (zend_ffi_cdata*)Z_OBJ_P(zv);
42914291
type = ZEND_FFI_TYPE(cdata->type);
42924292

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) {
42944295
zend_throw_error(zend_ffi_exception_ce, "FFI::addr() cannot create a reference to a temporary pointer");
42954296
RETURN_THROWS();
42964297
}

ext/ffi/tests/addr_in_lval.phpt

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
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+
}

0 commit comments

Comments
 (0)