Merge branch 'PHP-8.1'

* PHP-8.1:
  Fix order of checks to throw exception with better message
This commit is contained in:
Dmitry Stogov 2022-08-11 09:32:18 +03:00
commit 04d5faed23
2 changed files with 71 additions and 26 deletions

View file

@ -1215,20 +1215,10 @@ static zval *zend_ffi_cdata_read_field(zend_object *obj, zend_string *field_name
if (cache_slot && *cache_slot == type) {
field = *(cache_slot + 1);
} else {
if (type->kind == ZEND_FFI_TYPE_POINTER) {
type = ZEND_FFI_TYPE(type->pointer.type);
}
if (UNEXPECTED(type->kind != ZEND_FFI_TYPE_STRUCT)) {
if (type->kind == ZEND_FFI_TYPE_POINTER) {
/* transparently dereference the pointer */
if (UNEXPECTED(!ptr)) {
zend_throw_error(zend_ffi_exception_ce, "NULL pointer dereference");
return &EG(uninitialized_zval);
}
ptr = (void*)(*(char**)ptr);
if (UNEXPECTED(!ptr)) {
zend_throw_error(zend_ffi_exception_ce, "NULL pointer dereference");
return &EG(uninitialized_zval);
}
type = ZEND_FFI_TYPE(type->pointer.type);
}
if (UNEXPECTED(type->kind != ZEND_FFI_TYPE_STRUCT)) {
zend_throw_error(zend_ffi_exception_ce, "Attempt to read field '%s' of non C struct/union", ZSTR_VAL(field_name));
return &EG(uninitialized_zval);
@ -1247,6 +1237,20 @@ static zval *zend_ffi_cdata_read_field(zend_object *obj, zend_string *field_name
}
}
if (ZEND_FFI_TYPE(cdata->type)->kind == ZEND_FFI_TYPE_POINTER) {
/* transparently dereference the pointer */
if (UNEXPECTED(!ptr)) {
zend_throw_error(zend_ffi_exception_ce, "NULL pointer dereference");
return &EG(uninitialized_zval);
}
ptr = (void*)(*(char**)ptr);
if (UNEXPECTED(!ptr)) {
zend_throw_error(zend_ffi_exception_ce, "NULL pointer dereference");
return &EG(uninitialized_zval);
}
type = ZEND_FFI_TYPE(type->pointer.type);
}
#if 0
if (UNEXPECTED(!ptr)) {
zend_throw_error(zend_ffi_exception_ce, "NULL pointer dereference");
@ -1284,20 +1288,10 @@ static zval *zend_ffi_cdata_write_field(zend_object *obj, zend_string *field_nam
if (cache_slot && *cache_slot == type) {
field = *(cache_slot + 1);
} else {
if (type->kind == ZEND_FFI_TYPE_POINTER) {
type = ZEND_FFI_TYPE(type->pointer.type);
}
if (UNEXPECTED(type->kind != ZEND_FFI_TYPE_STRUCT)) {
if (type->kind == ZEND_FFI_TYPE_POINTER) {
/* transparently dereference the pointer */
if (UNEXPECTED(!ptr)) {
zend_throw_error(zend_ffi_exception_ce, "NULL pointer dereference");
return value;
}
ptr = (void*)(*(char**)ptr);
if (UNEXPECTED(!ptr)) {
zend_throw_error(zend_ffi_exception_ce, "NULL pointer dereference");
return value;
}
type = ZEND_FFI_TYPE(type->pointer.type);
}
if (UNEXPECTED(type->kind != ZEND_FFI_TYPE_STRUCT)) {
zend_throw_error(zend_ffi_exception_ce, "Attempt to assign field '%s' of non C struct/union", ZSTR_VAL(field_name));
return value;
@ -1316,6 +1310,19 @@ static zval *zend_ffi_cdata_write_field(zend_object *obj, zend_string *field_nam
}
}
if (ZEND_FFI_TYPE(cdata->type)->kind == ZEND_FFI_TYPE_POINTER) {
/* transparently dereference the pointer */
if (UNEXPECTED(!ptr)) {
zend_throw_error(zend_ffi_exception_ce, "NULL pointer dereference");
return value;
}
ptr = (void*)(*(char**)ptr);
if (UNEXPECTED(!ptr)) {
zend_throw_error(zend_ffi_exception_ce, "NULL pointer dereference");
return value;
}
}
#if 0
if (UNEXPECTED(!ptr)) {
zend_throw_error(zend_ffi_exception_ce, "NULL pointer dereference");

38
ext/ffi/tests/047.phpt Normal file
View file

@ -0,0 +1,38 @@
--TEST--
FFI 047: FFI::CData->cdata meaning
--EXTENSIONS--
ffi
--INI--
ffi.enable=1
--FILE--
<?php
$x = FFI::new("int");
$x->cdata = 42;
var_dump($x);
$x = FFI::new("int*");
try {
$x->cdata = 42;
var_dump($x);
} catch (Throwable $e) {
echo $e->getMessage() . "\n";
}
$x = FFI::new("struct {int cdata;}");
try {
$x->cdata = 42;
var_dump($x);
} catch (Throwable $e) {
echo $e->getMessage() . "\n";
}
?>
--EXPECTF--
object(FFI\CData:int32_t)#%d (1) {
["cdata"]=>
int(42)
}
Attempt to assign field 'cdata' of non C struct/union
object(FFI\CData:struct <anonymous>)#%d (1) {
["cdata"]=>
int(42)
}