From 7d7333df5e370a07e795432a6d8574554252511b Mon Sep 17 00:00:00 2001 From: Nawarian Date: Mon, 8 Mar 2021 21:43:36 +0100 Subject: [PATCH 1/5] Resolve struct type for internal struct fields --- ext/ffi/ffi.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ext/ffi/ffi.c b/ext/ffi/ffi.c index d119ea050cbf5..8efa2a8ca3927 100644 --- a/ext/ffi/ffi.c +++ b/ext/ffi/ffi.c @@ -58,6 +58,7 @@ typedef enum _zend_ffi_tag_kind { static const char *zend_ffi_tag_kind_name[3] = {"enum", "struct", "union"}; +static ffi_type *zend_ffi_get_type(zend_ffi_type *type); typedef struct _zend_ffi_tag { zend_ffi_tag_kind kind; @@ -339,6 +340,9 @@ static ffi_type *zend_ffi_make_fake_struct_type(zend_ffi_type *type) /* {{{ */ case ZEND_FFI_TYPE_POINTER: t->elements[i] = &ffi_type_pointer; break; + case ZEND_FFI_TYPE_STRUCT: + t->elements[i] = zend_ffi_get_type(ZEND_FFI_TYPE(field->type)); + break; default: efree(t); return NULL; From 8bd913b5cf3420a3dd595afbb5bd98ae5a406e29 Mon Sep 17 00:00:00 2001 From: Nawarian Date: Fri, 12 Mar 2021 18:02:19 +0100 Subject: [PATCH 2/5] Add test case for nested structs --- ext/ffi/tests/bug80847.phpt | 41 +++++++++++++++++++++++++++++++++++++ ext/zend_test/php_test.h | 8 ++++++++ ext/zend_test/test.c | 5 +++++ 3 files changed, 54 insertions(+) create mode 100644 ext/ffi/tests/bug80847.phpt diff --git a/ext/ffi/tests/bug80847.phpt b/ext/ffi/tests/bug80847.phpt new file mode 100644 index 0000000000000..88ca0b85bb033 --- /dev/null +++ b/ext/ffi/tests/bug80847.phpt @@ -0,0 +1,41 @@ +--TEST-- +Bug #80847 (Nested structs) +--SKIPIF-- +if (!extension_loaded('ffi') die('skip ffi extension not available'); +if (!extension_loaded('zend-test') die('skip zend-test extension not available'); +--FILE-- +new('bug80847_02'); +var_dump($ffi->bug80847($test)); +?> +--EXPECT-- +object(FFI\CData:struct bug80847_02)#3 (1) { + ["a"]=> + object(FFI\CData:struct bug80847_01)#4 (1) { + ["a"]=> + int(0) + } +} diff --git a/ext/zend_test/php_test.h b/ext/zend_test/php_test.h index 03e6d836e29f5..80019e3cc4d2d 100644 --- a/ext/zend_test/php_test.h +++ b/ext/zend_test/php_test.h @@ -37,6 +37,14 @@ struct bug79096 { uint64_t b; }; +typedef struct bug80847_01 { + uint64_t a; +} bug80847_01; + +typedef struct bug80847_02 { + bug80847_01 b; +} bug80847_02; + #ifdef PHP_WIN32 # define PHP_ZEND_TEST_API __declspec(dllexport) #elif defined(__GNUC__) && __GNUC__ >= 4 diff --git a/ext/zend_test/test.c b/ext/zend_test/test.c index 4f81adc6ac11a..7712db43322e0 100644 --- a/ext/zend_test/test.c +++ b/ext/zend_test/test.c @@ -342,3 +342,8 @@ void bug79177(void) { bug79177_cb(); } + +PHP_ZEND_TEST_API bug80847_02 bug80847(bug80847_02 b) +{ + return b; +} From 61806701672dab070084f74b27c793ab8aaea955 Mon Sep 17 00:00:00 2001 From: Nawarian Date: Fri, 12 Mar 2021 22:23:56 +0100 Subject: [PATCH 3/5] Fix memory leaks --- ext/ffi/ffi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/ffi/ffi.c b/ext/ffi/ffi.c index 8efa2a8ca3927..85a337c8f3201 100644 --- a/ext/ffi/ffi.c +++ b/ext/ffi/ffi.c @@ -341,7 +341,7 @@ static ffi_type *zend_ffi_make_fake_struct_type(zend_ffi_type *type) /* {{{ */ t->elements[i] = &ffi_type_pointer; break; case ZEND_FFI_TYPE_STRUCT: - t->elements[i] = zend_ffi_get_type(ZEND_FFI_TYPE(field->type)); + t->elements[i] = &ffi_type_pointer; break; default: efree(t); From 3376e2c8da1bc648e8cc011b037bf693c45579cc Mon Sep 17 00:00:00 2001 From: Nawarian Date: Fri, 12 Mar 2021 22:38:43 +0100 Subject: [PATCH 4/5] Fix arg type in test file --- ext/ffi/tests/bug80847.phpt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/ffi/tests/bug80847.phpt b/ext/ffi/tests/bug80847.phpt index 88ca0b85bb033..68fa07d07bde2 100644 --- a/ext/ffi/tests/bug80847.phpt +++ b/ext/ffi/tests/bug80847.phpt @@ -15,7 +15,7 @@ $header = << Date: Mon, 15 Mar 2021 10:37:10 +0100 Subject: [PATCH 5/5] Remove unnecessary function declaration --- ext/ffi/ffi.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/ext/ffi/ffi.c b/ext/ffi/ffi.c index 85a337c8f3201..4f37032c23030 100644 --- a/ext/ffi/ffi.c +++ b/ext/ffi/ffi.c @@ -58,8 +58,6 @@ typedef enum _zend_ffi_tag_kind { static const char *zend_ffi_tag_kind_name[3] = {"enum", "struct", "union"}; -static ffi_type *zend_ffi_get_type(zend_ffi_type *type); - typedef struct _zend_ffi_tag { zend_ffi_tag_kind kind; zend_ffi_type *type;