php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #80847 CData structs with fields of type struct can't be passed as C function argument
Submitted: 2021-03-08 20:29 UTC Modified: -
From: nawarian at gmail dot com Assigned:
Status: Closed Package: ffi (PECL)
PHP Version: 7.4Git-2021-03-08 (Git) OS: MacOS 10.15.7 (Catalina)
Private report: No CVE-ID: None
 [2021-03-08 20:29 UTC] nawarian at gmail dot com
Description:
------------
Configure line: --without-iconv --with-ffi
PHP Version used: 7.4 (GIT as of 2021-03-08)
Raylib 3.5.0 library installed via HomeBrew: https://github.com/raysan5/raylib/releases/tag/3.5.0

Any struct containing fields of type struct can be normally built, but PHP throws a Fatal Error whenever they are passed.

I found the issue by attempting to run the BeginMode2D() function from raylib. (links below)

This function requires a "struct Camera2D" argument, which itself has two "struct Vector2" fields.

I've attached a patch that mitigates this issue but generates many memory leaks that I don't really know how to mitigate.

---
Hints:

I found that "zend_ffi_make_fake_struct_type" doesn't have a "case ZEND_FFI_TYPE_STRUCT" when iterating over a record's fields, forcing the function to return NULL.

---
Links:

function BeginMode2D(): https://github.com/raysan5/raylib/blob/3.5.0/src/raylib.h#L943

struct Camera2D: https://github.com/raysan5/raylib/blob/3.5.0/src/raylib.h#L299-L304

struct Vector2D: https://github.com/raysan5/raylib/blob/3.5.0/src/raylib.h#L173-L176

Test script:
---------------
A minimal script can be found in this URL: https://gist.github.com/nawarian/319d363dacea2feebc409e5413d03887

Notice that PHP is able to construct CData objects with structs inside. But using them as function argument creates a Fatal Error.

Expected result:
----------------
A native window with dimensions 800x600 and title "Nawarian" and blinking content (black / white) should appear.

Actual result:
--------------
Fatal error: Uncaught FFI\Exception: Passing incompatible argument 1 of C function 'BeginMode2D', expecting 'struct Camera2D', found 'struct Camera2D' in /Users/nsilva/RG/personal/test-ffi/raylib.php:11

Stack trace:
#0 /Users/nsilva/RG/personal/test-ffi/raylib.php(11): FFI->BeginMode2D(Object(FFI\CData:struct Camera2D))
#1 {main}
  thrown in /Users/nsilva/RG/personal/test-ffi/raylib.php on line 11

Patches

incomplete-solution (last revision 2021-03-08 20:29 UTC by nawarian at gmail dot com)

Add a Patch

Pull Requests

Pull requests:

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2021-03-08 20:36 UTC] nawarian at gmail dot com
The following pull request has been associated:

Patch Name: [FFI] Resolve struct type for internal struct fields
On GitHub:  https://github.com/php/php-src/pull/6762
Patch:      https://github.com/php/php-src/pull/6762.patch
 [2021-03-17 06:56 UTC] dmitry@php.net
Automatic comment on behalf of dmitry@zend.com
Revision: http://git.php.net/?p=php-src.git;a=commit;h=38ebb55c7c16486c2603f4df906444ee9d651ad4
Log: Fixed bug #80847 (CData structs with fields of type struct can't be passed as C function argument)
 [2021-03-17 06:56 UTC] dmitry@php.net
-Status: Open +Status: Closed
 
PHP Copyright © 2001-2021 The PHP Group
All rights reserved.
Last updated: Mon May 17 11:01:24 2021 UTC