Skip to content

Commit ebd1a36

Browse files
committed
Fix GH-14215: Cannot use FFI::load on CRLF header file with apache2handler
Some modules may reset _fmode, which causes mangling of line endings. Always be explicit like we do in other places where the native open call is used. Closes GH-14218.
1 parent 719fa46 commit ebd1a36

File tree

7 files changed

+64
-2
lines changed

7 files changed

+64
-2
lines changed

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ PHP NEWS
2323
. Fix crash in ParentNode::append() when dealing with a fragment
2424
containing text nodes. (nielsdos)
2525

26+
- FFI:
27+
. Fixed bug GH-14215 (Cannot use FFI::load on CRLF header file with
28+
apache2handler). (nielsdos)
29+
2630
- FPM:
2731
. Fix bug GH-14175 (Show decimal number instead of scientific notation in
2832
systemd status). (Benjamin Cremer)

ext/ffi/ffi.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3255,7 +3255,11 @@ static zend_ffi *zend_ffi_load(const char *filename, bool preload) /* {{{ */
32553255

32563256
code_size = buf.st_size;
32573257
code = emalloc(code_size + 1);
3258-
fd = open(filename, O_RDONLY, 0);
3258+
int open_flags = O_RDONLY;
3259+
#ifdef PHP_WIN32
3260+
open_flags |= _O_BINARY;
3261+
#endif
3262+
fd = open(filename, open_flags, 0);
32593263
if (fd < 0 || read(fd, code, code_size) != code_size) {
32603264
if (preload) {
32613265
zend_error(E_WARNING, "FFI: Failed pre-loading '%s', cannot read_file", filename);

ext/ffi/tests/gh14215.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#define FFI_LIB "Kernel32.dll"
2+
typedef unsigned long DWORD;
3+
DWORD GetLastError(void);

ext/ffi/tests/gh14215.phpt

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
--TEST--
2+
GH-14215 (Cannot use FFI::load on CRLF header file with apache2handler)
3+
--EXTENSIONS--
4+
ffi
5+
zend_test
6+
--SKIPIF--
7+
<?php
8+
if(PHP_OS_FAMILY !== "Windows") {
9+
die('skip only for Windows');
10+
}
11+
?>
12+
--INI--
13+
ffi.enable=1
14+
--FILE--
15+
<?php
16+
zend_test_set_fmode(false);
17+
$header_path = __DIR__.'\\gh14215.h';
18+
$ffi = FFI::load($header_path);
19+
var_dump($ffi->GetLastError());
20+
zend_test_set_fmode(true);
21+
?>
22+
--EXPECT--
23+
int(0)

ext/zend_test/test.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -584,6 +584,18 @@ static ZEND_FUNCTION(zend_test_is_pcre_bundled)
584584
#endif
585585
}
586586

587+
#ifdef PHP_WIN32
588+
static ZEND_FUNCTION(zend_test_set_fmode)
589+
{
590+
bool binary;
591+
ZEND_PARSE_PARAMETERS_START(1, 1)
592+
Z_PARAM_BOOL(binary)
593+
ZEND_PARSE_PARAMETERS_END();
594+
595+
_fmode = binary ? _O_BINARY : _O_TEXT;
596+
}
597+
#endif
598+
587599
static zend_object *zend_test_class_new(zend_class_entry *class_type)
588600
{
589601
zend_object *obj = zend_objects_new(class_type);

ext/zend_test/test.stub.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,10 @@ function zend_test_override_libxml_global_state(): void {}
182182
#endif
183183

184184
function zend_test_is_pcre_bundled(): bool {}
185+
186+
#if defined(PHP_WIN32)
187+
function zend_test_set_fmode(bool $binary): void {}
188+
#endif
185189
}
186190

187191
namespace ZendTestNS {

ext/zend_test/test_arginfo.h

Lines changed: 13 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)