|  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #77707 FFI loses type information for opaque types
Submitted: 2019-03-07 14:00 UTC Modified: 2019-03-07 14:00 UTC
From: Assigned: dmitry (profile)
Status: Closed Package: Unknown/Other Function
PHP Version: Next Minor Version OS: any
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
Block user comment
Status: Assign to:
Bug Type:
New email:
PHP Version: OS:


 [2019-03-07 14:00 UTC]
Currently, opaque types lose their name information in FFI. So when we use an opaque pointer, such as provided by sqlite3 in the example below, there's no way to know what pointer mismatch occurred, only that one occurred.

If you look carefully at the actual result, see that the type name "sqlite3_mutex" was stripped from the FFI\CData type information. So it only shows an abstract <struct>* description.

Additionally, there's currently no way to go from a FFI\CType instance back to the literal type definition used (in this case either "sqlite3*" or "sqlite3_mutex*"). A method such as FFI\CType->typedef() which returned the string type definition used (in this case, "sqlite3_mutex*" or "sqlite3*"). 

Instead, name information should be retained to greatly aid in debugging when using complex FFI code without needing to generate a typesafe wrapper for FFI.

Test script:

$header = '
typedef struct sqlite3 sqlite3;

int sqlite3_open(const char*, sqlite3 **);
int sqlite3_close(sqlite3*);

const char* sqlite3_errmsg(sqlite3*);

typedef struct sqlite3_mutex sqlite3_mutex;

sqlite3_mutex *sqlite3_mutex_alloc(int);
void sqlite3_mutex_free(sqlite3_mutex*);
void sqlite3_mutex_enter(sqlite3_mutex*);
int sqlite3_mutex_try(sqlite3_mutex*);
void sqlite3_mutex_leave(sqlite3_mutex*);


$ffi = FFI::cdef($header, '');

$db = $ffi->new('sqlite3*');

$result = $ffi->sqlite3_open("test.db", FFI::addr($db));

if ($result > 0) {
    die("Can't open database: " . $ffi->sqlite3_errmsg($db));

$mutex = $ffi->sqlite3_mutex_alloc(2);


echo "Done\n";

Expected result:
Fatal error: Uncaught FFI\Exception: Passing incompatible pointer in /.../test.php:33
Stack trace:
#0 /.../test.php(33): FFI->sqlite3_close(Object(FFI\CData:sqlite3_mutex*))
#1 {main}
  thrown in /.../test.php on line 33

Actual result:
Fatal error: Uncaught FFI\Exception: Passing incompatible pointer in /.../test.php:33
Stack trace:
#0 /.../test.php(33): FFI->sqlite3_close(Object(FFI\CData:<struct>*))
#1 {main}
  thrown in /.../test.php on line 33


Add a Patch

Pull Requests

Add a Pull Request


AllCommentsChangesGit/SVN commitsRelated reports
 [2019-03-07 14:00 UTC]
-Assigned To: +Assigned To: dmitry
 [2019-03-11 11:27 UTC]
Automatic comment on behalf of
Log: Fixed bug #77707 (FFI loses type information for opaque types)
 [2019-03-11 11:27 UTC]
-Status: Assigned +Status: Closed
PHP Copyright © 2001-2020 The PHP Group
All rights reserved.
Last updated: Sun Sep 27 17:01:24 2020 UTC