Description
With this PHP file:
<?php
header('Content-Type: text/plain');
printf("php version : %s\n", phpversion());
printf("PHP_SAPI : %s\n", PHP_SAPI);
$header_path = __DIR__.'\\header.h';
$ffi = FFI::load($header_path);
$error_code = $ffi->GetLastError();
printf("error code is %d\n", $error_code);
And this header file (saved with CRLF line endings) :
#define FFI_LIB "Kernel32.dll"
typedef unsigned long DWORD;
DWORD GetLastError(void);
I get this output:
php version : 8.1.27
PHP_SAPI : apache2handler
Fatal error: Uncaught FFI\Exception: Failed loading 'header.h', cannot read_file in bug_ffi.php:10
Stack trace:
#0bug_ffi.php(10): FFI::load('hea...')
#1 {main}
thrown in bug_ffi.php on line 10
But if I launch the script directly, I get this :
php .\bug_ffi.php
php version : 8.1.27
PHP_SAPI : cli
error code is 0
What seems to be happening here is that the zend_ffi_load function, which is used by FFI::load(), use stat to get the header size, then use open and read to read the file.
Then it checks if the byte amount returned from read is equal to the file size from stat.
If it's not, then it throws an error Failed loading '%s', cannot read_file.
The problem is that the file was opened in O_TEXT mode, so line endings were converted from CRLF to LF, and the byte amount returned is lower than expected.
I've checked PHP's source code, and it seems that the CGI and CLI main functions have some code to set _fmode to _O_BINARY, which is probably why I don't get the error when I run the script directly.
The sapi/apache2handler/ folder doesn't seems to have any mention of _fmode.
PHP Version
PHP 8.1.27
Edit : It also happens on PHP 8.3.7.
Operating System
Windows 10
Note that I'm using the WAMP version of PHP.
Description
With this PHP file:
And this header file (saved with CRLF line endings) :
I get this output:
But if I launch the script directly, I get this :
What seems to be happening here is that the
zend_ffi_loadfunction, which is used byFFI::load(), usestatto get the header size, then useopenandreadto read the file.Then it checks if the byte amount returned from
readis equal to the file size fromstat.If it's not, then it throws an error
Failed loading '%s', cannot read_file.The problem is that the file was opened in
O_TEXTmode, so line endings were converted from CRLF to LF, and the byte amount returned is lower than expected.I've checked PHP's source code, and it seems that the CGI and CLI
mainfunctions have some code to set_fmodeto_O_BINARY, which is probably why I don't get the error when I run the script directly.The
sapi/apache2handler/folder doesn't seems to have any mention of_fmode.PHP Version
PHP 8.1.27
Edit : It also happens on PHP 8.3.7.
Operating System
Windows 10
Note that I'm using the WAMP version of PHP.