-
Notifications
You must be signed in to change notification settings - Fork 8k
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.