Description
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.