Skip to content

Commit 04d5fae

Browse files
committed
Merge branch 'PHP-8.1'
* PHP-8.1: Fix order of checks to throw exception with better message
2 parents b0c658f + 18183ff commit 04d5fae

File tree

2 files changed

+71
-26
lines changed

2 files changed

+71
-26
lines changed

ext/ffi/ffi.c

Lines changed: 33 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1215,20 +1215,10 @@ static zval *zend_ffi_cdata_read_field(zend_object *obj, zend_string *field_name
12151215
if (cache_slot && *cache_slot == type) {
12161216
field = *(cache_slot + 1);
12171217
} else {
1218+
if (type->kind == ZEND_FFI_TYPE_POINTER) {
1219+
type = ZEND_FFI_TYPE(type->pointer.type);
1220+
}
12181221
if (UNEXPECTED(type->kind != ZEND_FFI_TYPE_STRUCT)) {
1219-
if (type->kind == ZEND_FFI_TYPE_POINTER) {
1220-
/* transparently dereference the pointer */
1221-
if (UNEXPECTED(!ptr)) {
1222-
zend_throw_error(zend_ffi_exception_ce, "NULL pointer dereference");
1223-
return &EG(uninitialized_zval);
1224-
}
1225-
ptr = (void*)(*(char**)ptr);
1226-
if (UNEXPECTED(!ptr)) {
1227-
zend_throw_error(zend_ffi_exception_ce, "NULL pointer dereference");
1228-
return &EG(uninitialized_zval);
1229-
}
1230-
type = ZEND_FFI_TYPE(type->pointer.type);
1231-
}
12321222
if (UNEXPECTED(type->kind != ZEND_FFI_TYPE_STRUCT)) {
12331223
zend_throw_error(zend_ffi_exception_ce, "Attempt to read field '%s' of non C struct/union", ZSTR_VAL(field_name));
12341224
return &EG(uninitialized_zval);
@@ -1247,6 +1237,20 @@ static zval *zend_ffi_cdata_read_field(zend_object *obj, zend_string *field_name
12471237
}
12481238
}
12491239

1240+
if (ZEND_FFI_TYPE(cdata->type)->kind == ZEND_FFI_TYPE_POINTER) {
1241+
/* transparently dereference the pointer */
1242+
if (UNEXPECTED(!ptr)) {
1243+
zend_throw_error(zend_ffi_exception_ce, "NULL pointer dereference");
1244+
return &EG(uninitialized_zval);
1245+
}
1246+
ptr = (void*)(*(char**)ptr);
1247+
if (UNEXPECTED(!ptr)) {
1248+
zend_throw_error(zend_ffi_exception_ce, "NULL pointer dereference");
1249+
return &EG(uninitialized_zval);
1250+
}
1251+
type = ZEND_FFI_TYPE(type->pointer.type);
1252+
}
1253+
12501254
#if 0
12511255
if (UNEXPECTED(!ptr)) {
12521256
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
12841288
if (cache_slot && *cache_slot == type) {
12851289
field = *(cache_slot + 1);
12861290
} else {
1291+
if (type->kind == ZEND_FFI_TYPE_POINTER) {
1292+
type = ZEND_FFI_TYPE(type->pointer.type);
1293+
}
12871294
if (UNEXPECTED(type->kind != ZEND_FFI_TYPE_STRUCT)) {
1288-
if (type->kind == ZEND_FFI_TYPE_POINTER) {
1289-
/* transparently dereference the pointer */
1290-
if (UNEXPECTED(!ptr)) {
1291-
zend_throw_error(zend_ffi_exception_ce, "NULL pointer dereference");
1292-
return value;
1293-
}
1294-
ptr = (void*)(*(char**)ptr);
1295-
if (UNEXPECTED(!ptr)) {
1296-
zend_throw_error(zend_ffi_exception_ce, "NULL pointer dereference");
1297-
return value;
1298-
}
1299-
type = ZEND_FFI_TYPE(type->pointer.type);
1300-
}
13011295
if (UNEXPECTED(type->kind != ZEND_FFI_TYPE_STRUCT)) {
13021296
zend_throw_error(zend_ffi_exception_ce, "Attempt to assign field '%s' of non C struct/union", ZSTR_VAL(field_name));
13031297
return value;
@@ -1316,6 +1310,19 @@ static zval *zend_ffi_cdata_write_field(zend_object *obj, zend_string *field_nam
13161310
}
13171311
}
13181312

1313+
if (ZEND_FFI_TYPE(cdata->type)->kind == ZEND_FFI_TYPE_POINTER) {
1314+
/* transparently dereference the pointer */
1315+
if (UNEXPECTED(!ptr)) {
1316+
zend_throw_error(zend_ffi_exception_ce, "NULL pointer dereference");
1317+
return value;
1318+
}
1319+
ptr = (void*)(*(char**)ptr);
1320+
if (UNEXPECTED(!ptr)) {
1321+
zend_throw_error(zend_ffi_exception_ce, "NULL pointer dereference");
1322+
return value;
1323+
}
1324+
}
1325+
13191326
#if 0
13201327
if (UNEXPECTED(!ptr)) {
13211328
zend_throw_error(zend_ffi_exception_ce, "NULL pointer dereference");

ext/ffi/tests/047.phpt

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
--TEST--
2+
FFI 047: FFI::CData->cdata meaning
3+
--EXTENSIONS--
4+
ffi
5+
--INI--
6+
ffi.enable=1
7+
--FILE--
8+
<?php
9+
$x = FFI::new("int");
10+
$x->cdata = 42;
11+
var_dump($x);
12+
13+
$x = FFI::new("int*");
14+
try {
15+
$x->cdata = 42;
16+
var_dump($x);
17+
} catch (Throwable $e) {
18+
echo $e->getMessage() . "\n";
19+
}
20+
21+
$x = FFI::new("struct {int cdata;}");
22+
try {
23+
$x->cdata = 42;
24+
var_dump($x);
25+
} catch (Throwable $e) {
26+
echo $e->getMessage() . "\n";
27+
}
28+
?>
29+
--EXPECTF--
30+
object(FFI\CData:int32_t)#%d (1) {
31+
["cdata"]=>
32+
int(42)
33+
}
34+
Attempt to assign field 'cdata' of non C struct/union
35+
object(FFI\CData:struct <anonymous>)#%d (1) {
36+
["cdata"]=>
37+
int(42)
38+
}

0 commit comments

Comments
 (0)