Req #77707 [Asn->Csd]: FFI loses type information for opaque types
| From: | dmitry@php.net | Date: | Mon, 11 Mar 2019 11:27:00 +0000 |
| Subject: | Req #77707 [Asn->Csd]: FFI loses type information for opaque types | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-219906@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=77707&edit=1
ID: 77707
Updated by: dmitry@php.net
Reported by: ircmaxell@php.net
Summary: FFI loses type information for opaque types
-Status: Assigned
+Status: Closed
Type: Feature/Change Request
Package: Unknown/Other Function
Operating System: any
PHP Version: Next Minor Version
Assigned To: dmitry
Block user comment: N
Private report: N
New Comment:
Automatic comment on behalf of dmitry@zend.com
Revision: http://git.php.net/?p=php-src.git;a=commit;h=e623df650fd099325154ffd43cc19002e1cb619e
Log: Fixed bug #77707 (FFI loses type information for opaque types)
Previous Comments:
------------------------------------------------------------------------
[2019-03-07 14:00:52] ircmaxell@php.net
Description:
------------
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:
---------------
<?php
$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, 'libsqlite3.so.0.8.6');
$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);
$ffi->sqlite3_close($mutex);
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
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=77707&edit=1