mirror of
https://github.com/php/php-src.git
synced 2026-03-24 08:12:21 +01:00
Fix order of checks to throw exception with better message
This clarifies the "->cdata" meaning.
This commit is contained in:
@@ -1169,20 +1169,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);
|
||||
@@ -1201,6 +1191,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");
|
||||
@@ -1238,20 +1242,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;
|
||||
@@ -1270,6 +1264,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
38
ext/ffi/tests/047.phpt
Normal 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)
|
||||
}
|
||||
Reference in New Issue
Block a user