From adaf726373ff2c60d347eee36a7155e6ac9a55df Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 22 Nov 2023 21:25:15 +0300 Subject: [PATCH] Fixed regression introduced by https://github.com/php/php-src/pull/9601 --- ext/ffi/ffi.c | 3 ++- ext/ffi/tests/addr_in_lval.phpt | 31 +++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 ext/ffi/tests/addr_in_lval.phpt diff --git a/ext/ffi/ffi.c b/ext/ffi/ffi.c index ccbedf8ef35..b0b650b7be9 100644 --- a/ext/ffi/ffi.c +++ b/ext/ffi/ffi.c @@ -4290,7 +4290,8 @@ ZEND_METHOD(FFI, addr) /* {{{ */ cdata = (zend_ffi_cdata*)Z_OBJ_P(zv); type = ZEND_FFI_TYPE(cdata->type); - if (GC_REFCOUNT(&cdata->std) == 1 && Z_REFCOUNT_P(arg) == 1 && type->kind == ZEND_FFI_TYPE_POINTER) { + if (GC_REFCOUNT(&cdata->std) == 1 && Z_REFCOUNT_P(arg) == 1 && type->kind == ZEND_FFI_TYPE_POINTER + && cdata->ptr == &cdata->ptr_holder) { zend_throw_error(zend_ffi_exception_ce, "FFI::addr() cannot create a reference to a temporary pointer"); RETURN_THROWS(); } diff --git a/ext/ffi/tests/addr_in_lval.phpt b/ext/ffi/tests/addr_in_lval.phpt new file mode 100644 index 00000000000..43c5d31f085 --- /dev/null +++ b/ext/ffi/tests/addr_in_lval.phpt @@ -0,0 +1,31 @@ +--TEST-- +Assignment to CDATA though FFI::addr() trick +--EXTENSIONS-- +ffi +--INI-- +ffi.enable=1 +--FILE-- +data = $f->new("other"); } + function &getBar() { return $this->data->bar; } // return by ref to get CData instead of null +} +$container = new Container($f); +$data = $f->new("char[2]"); +$data[0] = "1"; +FFI::addr($container->getBar())[0] = $f->cast("char*", $data); // directly write it +var_dump($container); +?> +--EXPECT-- +object(Container)#2 (1) { + ["data"]=> + object(FFI\CData:struct )#3 (1) { + ["bar"]=> + object(FFI\CData:char*)#6 (1) { + [0]=> + string(1) "1" + } + } +}