|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2020-05-07 06:01 UTC] peratx at itxtech dot org
Description:
------------
When accessing Windows LPSTR, the whole program crashes.
===========
php -v
PHP 7.3.8 (cli) (built: Jul 30 2019 12:44:06) ( ZTS MSVC15 (Visual C++ 2017) x64 )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.8, Copyright (c) 1998-2018 Zend Technologies
with Zend OPcache v7.3.8, Copyright (c) 1999-2018, by Zend Technologies
php -m
[PHP Modules]
bcmath
calendar
Core
ctype
curl
date
dom
filter
gd
hash
iconv
json
libxml
mbstring
mysqli
mysqlnd
openssl
pcre
PDO
pdo_mysql
Phar
pthreads
readline
Reflection
runkit7
session
SimpleXML
sockets
sodium
SPL
sqlite3
standard
tokenizer
wddx
xml
xmlreader
xmlwriter
yaml
Zend OPcache
zip
zlib
[Zend Modules]
Zend OPcache
Test script:
---------------
$ffi = \FFI::cdef(<<<EOL
typedef unsigned long DWORD;
typedef int BOOL;
typedef DWORD *LPDWORD;
typedef void *LPVOID;
typedef LPVOID HINTERNET;
typedef char* *LPSTR;
typedef struct {
DWORD dwLowDateTime;
DWORD dwHighDateTime;
} FILETIME, *PFILETIME, *LPFILETIME;
typedef struct {
DWORD dwOption;
union {
DWORD dwValue;
LPSTR pszValue;
FILETIME ftValue;
} Value;
} INTERNET_PER_CONN_OPTIONA, *LPINTERNET_PER_CONN_OPTIONA;
typedef struct {
DWORD dwSize;
LPSTR pszConnection;
DWORD dwOptionCount;
DWORD dwOptionError;
LPINTERNET_PER_CONN_OPTIONA pOptions;
} INTERNET_PER_CONN_OPTION_LISTA, *LPINTERNET_PER_CONN_OPTION_LISTA;
typedef DWORD WINAPI_InternetOption;
BOOL InternetSetOptionA(HINTERNET hInternet, WINAPI_InternetOption dwOption, LPVOID lpBuffer, DWORD dwBufferLength);
BOOL InternetQueryOptionA(HINTERNET hInternet, WINAPI_InternetOption dwOption, LPVOID lpBuffer, LPDWORD
lpdwBufferLength);
EOL
, "Wininet.dll");
$list = $ffi->new("INTERNET_PER_CONN_OPTION_LISTA");
$opt = $ffi->new("INTERNET_PER_CONN_OPTIONA");
$str = \FFI::new("char*", "");
$opt->dwOption = 1;
$opt->Value->pszValue = \FFI::addr($str);
$list->dwSize = \FFI::sizeof($list);
$list->pszConnection = null;
$list->dwOptionCount = 1;
$list->dwOptionError = 0;
$list->pOptions = \FFI::addr($opt);
$listptr = \FFI::addr($list);
$int = $ffi->new("DWORD");
$int->cdata = \FFI::sizeof($list) * 2;
$ptr = \FFI::addr($int);
$ffi->InternetQueryOptionA(null, 75, $listptr, $ptr);
var_dump($list);// crashes when it comes to pszValue which is a LPSTR pointer
Expected result:
----------------
object(FFI\CData:struct <anonymous>)#5 (5) {
["dwSize"]=>
int(32)
["pszConnection"]=>
NULL
["dwOptionCount"]=>
int(1)
["dwOptionError"]=>
int(0)
["pOptions"]=>
object(FFI\CData:struct <anonymous>*)#11 (1) {
[0]=>
object(FFI\CData:struct <anonymous>)#12 (2) {
["dwOption"]=>
int(1)
["Value"]=>
object(FFI\CData:union <anonymous>)#13 (3) {
["dwValue"]=>
int(2)
["pszValue"]=>
string(xxx) "xxxxx"
["value...."]
Actual result:
--------------
object(FFI\CData:struct <anonymous>)#5 (5) {
["dwSize"]=>
int(32)
["pszConnection"]=>
NULL
["dwOptionCount"]=>
int(1)
["dwOptionError"]=>
int(0)
["pOptions"]=>
object(FFI\CData:struct <anonymous>*)#11 (1) {
[0]=>
object(FFI\CData:struct <anonymous>)#12 (2) {
["dwOption"]=>
int(1)
["Value"]=>
object(FFI\CData:union <anonymous>)#13 (3) {
["dwValue"]=>
int(2)
["pszValue"]=> //crashes
PatchesPull Requests
Pull requests:
HistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Sun Oct 26 17:00:01 2025 UTC |
Wrong php info, it should be: PHP 7.4.5 (cli) (built: Apr 14 2020 16:17:34) ( ZTS Visual C++ 2017 x64 ) Copyright (c) The PHP Group Zend Engine v3.4.0, Copyright (c) Zend Technologies with Zend OPcache v7.4.5, Copyright (c), by Zend Technologie [PHP Modules] bcmath calendar Core ctype curl date dom FFI filter gd hash iconv json libxml mbstring mysqli mysqlnd openssl pcre PDO pdo_mysql Phar readline Reflection runkit7 session SimpleXML sockets sodium SPL sqlite3 standard tokenizer xml xmlreader xmlwriter yaml Zend OPcache zip zlib [Zend Modules] Zend OPcacheSimpler reproducer: <?php $ffi = FFI::cdef(' typedef union { int num; char *str; } my_union; '); $union = $ffi->new('my_union'); $union->num = 17; var_dump($union); ?> The problem is that FFI can't know which member of the union is actually valid, but assumes that all are.