summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRemi Collet <remi@remirepo.net>2019-10-24 08:19:48 +0200
committerRemi Collet <remi@remirepo.net>2019-10-24 08:19:48 +0200
commitc21dae38420a57adc2c677a76d50a44db3c496bc (patch)
treef44e9944be9e22429d95dbcb2d5d7dc6ec9038bf
parentee9164c1626225f1507cf3a8b215adaa487ea71c (diff)
allow wildcards in ffi.preload
-rw-r--r--05c5e5dfde91955263469daa2dd5afcbb5199d17.patch26
-rw-r--r--1417352dda354c22db43a8d4dbaa967575e2720c.patch332
-rw-r--r--1c9bfcb6a766d4062f2dd1e594b30831d59cc36c.patch81
-rw-r--r--20-ffi.ini2
-rw-r--r--598bf7f5d5f9c76fd003590083c98736eb7702ab.patch22
-rw-r--r--dcd772325d0f7702a525f03c7d5dd04bf96d8e18.patch47
-rw-r--r--php-ffi.patch730
-rw-r--r--php.spec15
8 files changed, 736 insertions, 519 deletions
diff --git a/05c5e5dfde91955263469daa2dd5afcbb5199d17.patch b/05c5e5dfde91955263469daa2dd5afcbb5199d17.patch
deleted file mode 100644
index 81cdc23..0000000
--- a/05c5e5dfde91955263469daa2dd5afcbb5199d17.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From 05c5e5dfde91955263469daa2dd5afcbb5199d17 Mon Sep 17 00:00:00 2001
-From: Dmitry Stogov <dmitry@zend.com>
-Date: Mon, 21 Oct 2019 14:52:26 +0300
-Subject: [PATCH] Fixed bug #78512 (Cannot make preload work)
-
----
- NEWS | 3 +++
- ext/opcache/ZendAccelerator.c | 5 +++++
- 2 files changed, 8 insertions(+)
-
-diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c
-index 056c7739a0b6..636058dd0875 100644
---- a/ext/opcache/ZendAccelerator.c
-+++ b/ext/opcache/ZendAccelerator.c
-@@ -4565,6 +4565,11 @@ static int accel_finish_startup(void)
- zend_accel_error(ACCEL_LOG_FATAL, "Preloading failed to waitpid(%d)", pid);
- return FAILURE;
- }
-+
-+ if (ZCSG(preload_script)) {
-+ preload_load();
-+ }
-+
- zend_shared_alloc_unlock();
- if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
- return SUCCESS;
diff --git a/1417352dda354c22db43a8d4dbaa967575e2720c.patch b/1417352dda354c22db43a8d4dbaa967575e2720c.patch
deleted file mode 100644
index 5e4da11..0000000
--- a/1417352dda354c22db43a8d4dbaa967575e2720c.patch
+++ /dev/null
@@ -1,332 +0,0 @@
-From 1417352dda354c22db43a8d4dbaa967575e2720c Mon Sep 17 00:00:00 2001
-From: Dmitry Stogov <dmitry@zend.com>
-Date: Tue, 22 Oct 2019 17:52:56 +0300
-Subject: [PATCH] Allow loading FFI bindings through ffi.preload directive
-
----
- Zend/zend_compile.h | 3 +
- ext/ffi/ffi.c | 101 ++++++++++++++++++++++++++++------
- ext/ffi/php_ffi.h | 1 +
- ext/ffi/tests/302.phpt | 15 +++++
- ext/opcache/ZendAccelerator.c | 31 +++++++----
- 5 files changed, 124 insertions(+), 27 deletions(-)
- create mode 100644 ext/ffi/tests/302.phpt
-
-diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h
-index 499d0d64b641..c21554e4641e 100644
---- a/Zend/zend_compile.h
-+++ b/Zend/zend_compile.h
-@@ -1094,6 +1094,9 @@ END_EXTERN_C()
- /* disable jumptable optimization for switch statements */
- #define ZEND_COMPILE_NO_JUMPTABLES (1<<16)
-
-+/* this flag is set when compiler invoked during preloading in separate process */
-+#define ZEND_COMPILE_PRELOAD_IN_CHILD (1<<17)
-+
- /* The default value for CG(compiler_options) */
- #define ZEND_COMPILE_DEFAULT ZEND_COMPILE_HANDLE_OP_ARRAY
-
-diff --git a/ext/ffi/ffi.c b/ext/ffi/ffi.c
-index 1edba157a171..4b7144e11ccc 100644
---- a/ext/ffi/ffi.c
-+++ b/ext/ffi/ffi.c
-@@ -3083,15 +3083,13 @@ static zend_ffi_type *zend_ffi_remember_type(zend_ffi_type *type) /* {{{ */
- }
- /* }}} */
-
--ZEND_METHOD(FFI, load) /* {{{ */
-+static zend_ffi *zend_ffi_load(const char *filename, zend_bool preload) /* {{{ */
- {
-- zend_string *fn;
- struct stat buf;
- int fd;
-- char *filename, *code, *code_pos, *scope_name, *lib;
-+ char *code, *code_pos, *scope_name, *lib;
- size_t code_size, scope_name_len;
- zend_ffi *ffi;
-- zend_bool preload = (CG(compiler_options) & ZEND_COMPILE_PRELOAD) != 0;
- DL_HANDLE handle = NULL;
- zend_ffi_scope *scope = NULL;
- zend_string *name;
-@@ -3099,19 +3097,13 @@ ZEND_METHOD(FFI, load) /* {{{ */
- zend_ffi_tag *tag;
- void *addr;
-
-- ZEND_FFI_VALIDATE_API_RESTRICTION();
-- ZEND_PARSE_PARAMETERS_START(1, 1)
-- Z_PARAM_STR(fn)
-- ZEND_PARSE_PARAMETERS_END();
--
-- filename = ZSTR_VAL(fn);
- if (stat(filename, &buf) != 0) {
- if (preload) {
- zend_error(E_WARNING, "FFI: failed pre-loading '%s', file doesn't exist", filename);
- } else {
- zend_throw_error(zend_ffi_exception_ce, "Failed loading '%s', file doesn't exist", filename);
- }
-- return;
-+ return NULL;
- }
-
- if ((buf.st_mode & S_IFMT) != S_IFREG) {
-@@ -3120,7 +3112,7 @@ ZEND_METHOD(FFI, load) /* {{{ */
- } else {
- zend_throw_error(zend_ffi_exception_ce, "Failed loading '%s', not a regular file", filename);
- }
-- return;
-+ return NULL;
- }
-
- code_size = buf.st_size;
-@@ -3134,7 +3126,7 @@ ZEND_METHOD(FFI, load) /* {{{ */
- }
- efree(code);
- close(fd);
-- return;
-+ return NULL;
- }
- close(fd);
- code[code_size] = 0;
-@@ -3153,7 +3145,7 @@ ZEND_METHOD(FFI, load) /* {{{ */
- if (!code_pos) {
- efree(code);
- FFI_G(persistent) = 0;
-- return;
-+ return NULL;
- }
- code_size -= code_pos - code;
-
-@@ -3318,7 +3310,11 @@ ZEND_METHOD(FFI, load) /* {{{ */
- }
- }
-
-- ffi = (zend_ffi*)zend_ffi_new(zend_ffi_ce);
-+ if (EG(objects_store).object_buckets) {
-+ ffi = (zend_ffi*)zend_ffi_new(zend_ffi_ce);
-+ } else {
-+ ffi = ecalloc(1, sizeof(zend_ffi));
-+ }
- ffi->symbols = scope->symbols;
- ffi->tags = scope->tags;
- ffi->persistent = 1;
-@@ -3333,7 +3329,7 @@ ZEND_METHOD(FFI, load) /* {{{ */
- FFI_G(symbols) = NULL;
- FFI_G(tags) = NULL;
-
-- RETURN_OBJ(&ffi->std);
-+ return ffi;
-
- cleanup:
- efree(code);
-@@ -3348,6 +3344,30 @@ ZEND_METHOD(FFI, load) /* {{{ */
- FFI_G(tags) = NULL;
- }
- FFI_G(persistent) = 0;
-+ return NULL;
-+}
-+/* }}} */
-+
-+ZEND_METHOD(FFI, load) /* {{{ */
-+{
-+ zend_string *fn;
-+ zend_ffi *ffi;
-+
-+ ZEND_FFI_VALIDATE_API_RESTRICTION();
-+ ZEND_PARSE_PARAMETERS_START(1, 1)
-+ Z_PARAM_STR(fn)
-+ ZEND_PARSE_PARAMETERS_END();
-+
-+ if (CG(compiler_options) & ZEND_COMPILE_PRELOAD_IN_CHILD) {
-+ zend_throw_error(zend_ffi_exception_ce, "FFI::load() doesn't work in conjunction with \"opcache.pelaod_user\". Use \"ffi.preload\" instead.");
-+ return;
-+ }
-+
-+ ffi = zend_ffi_load(ZSTR_VAL(fn), (CG(compiler_options) & ZEND_COMPILE_PRELOAD) != 0);
-+
-+ if (ffi) {
-+ RETURN_OBJ(&ffi->std);
-+ }
- }
- /* }}} */
-
-@@ -4813,8 +4833,51 @@ static ZEND_INI_DISP(zend_ffi_enable_displayer_cb) /* {{{ */
-
- ZEND_INI_BEGIN()
- ZEND_INI_ENTRY3_EX("ffi.enable", "preload", ZEND_INI_SYSTEM, OnUpdateFFIEnable, NULL, NULL, NULL, zend_ffi_enable_displayer_cb)
-+ STD_ZEND_INI_ENTRY("ffi.preload", NULL, ZEND_INI_SYSTEM, OnUpdateString, preload, zend_ffi_globals, ffi_globals)
- ZEND_INI_END()
-
-+static int zend_ffi_preload(char *preload) /* {{{ */
-+{
-+ zend_ffi *ffi;
-+ char *s = NULL, *e, *filename;
-+
-+ e = preload;
-+ while (*e) {
-+ switch (*e) {
-+ case ZEND_PATHS_SEPARATOR:
-+ if (s) {
-+ filename = estrndup(s, e-s);
-+ ffi = zend_ffi_load(filename, 1);
-+ efree(filename);
-+ if (!ffi) {
-+ return FAILURE;
-+ }
-+ efree(ffi);
-+ s = NULL;
-+ }
-+ break;
-+ default:
-+ if (!s) {
-+ s = e;
-+ }
-+ break;
-+ }
-+ e++;
-+ }
-+ if (s) {
-+ filename = estrndup(s, e-s);
-+ ffi = zend_ffi_load(filename, 1);
-+ efree(filename);
-+ if (!ffi) {
-+ return FAILURE;
-+ }
-+ efree(ffi);
-+ }
-+
-+ return SUCCESS;
-+}
-+/* }}} */
-+
- /* {{{ ZEND_MINIT_FUNCTION
- */
- ZEND_MINIT_FUNCTION(ffi)
-@@ -4976,6 +5039,12 @@ ZEND_MINIT_FUNCTION(ffi)
- zend_ffi_ctype_handlers.get_properties = zend_fake_get_properties;
- zend_ffi_ctype_handlers.get_gc = zend_fake_get_gc;
-
-+ if (FFI_G(preload)) {
-+ if (zend_ffi_preload(FFI_G(preload)) != SUCCESS) {
-+ return FAILURE;
-+ }
-+ }
-+
- return SUCCESS;
- }
- /* }}} */
-diff --git a/ext/ffi/php_ffi.h b/ext/ffi/php_ffi.h
-index 0f511fccf05c..b9f01d6e96f4 100644
---- a/ext/ffi/php_ffi.h
-+++ b/ext/ffi/php_ffi.h
-@@ -38,6 +38,7 @@ ZEND_BEGIN_MODULE_GLOBALS(ffi)
- HashTable types;
-
- /* preloading */
-+ char *preload;
- HashTable *scopes; /* list of preloaded scopes */
-
- /* callbacks */
-diff --git a/ext/ffi/tests/302.phpt b/ext/ffi/tests/302.phpt
-new file mode 100644
-index 000000000000..cb0d73d56880
---- /dev/null
-+++ b/ext/ffi/tests/302.phpt
-@@ -0,0 +1,15 @@
-+--TEST--
-+FFI 302: FFI preloading
-+--SKIPIF--
-+<?php require_once('skipif.inc'); ?>
-+<?php if (substr(PHP_OS, 0, 3) == 'WIN') die('skip not for Windows'); ?>
-+--INI--
-+ffi.enable=1
-+ffi.preload={PWD}/300.h
-+--FILE--
-+<?php
-+$ffi = FFI::scope("TEST_300");
-+$ffi->printf("Hello World from %s!\n", "PHP");
-+?>
-+--EXPECT--
-+Hello World from PHP!
-diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c
-index 636058dd0875..704e1c38d9b7 100644
---- a/ext/opcache/ZendAccelerator.c
-+++ b/ext/opcache/ZendAccelerator.c
-@@ -4140,14 +4140,17 @@ static void preload_load(void)
- if (EG(class_table)) {
- EG(persistent_classes_count) = EG(class_table)->nNumUsed;
- }
-- CG(map_ptr_last) = ZCSG(map_ptr_last);
-+ if (CG(map_ptr_last) != ZCSG(map_ptr_last)) {
-+ CG(map_ptr_last) = ZCSG(map_ptr_last);
-+ CG(map_ptr_size) = ZEND_MM_ALIGNED_SIZE_EX(CG(map_ptr_last) + 1, 4096);
-+ CG(map_ptr_base) = perealloc(CG(map_ptr_base), CG(map_ptr_size) * sizeof(void*), 1);
-+ }
- }
-
- static int accel_preload(const char *config)
- {
- zend_file_handle file_handle;
- int ret;
-- uint32_t orig_compiler_options;
- char *orig_open_basedir;
- size_t orig_map_ptr_last;
- zval *zv;
-@@ -4159,14 +4162,6 @@ static int accel_preload(const char *config)
- preload_orig_compile_file = accelerator_orig_compile_file;
- accelerator_orig_compile_file = preload_compile_file;
-
-- orig_compiler_options = CG(compiler_options);
-- CG(compiler_options) |= ZEND_COMPILE_PRELOAD;
-- CG(compiler_options) |= ZEND_COMPILE_HANDLE_OP_ARRAY;
--// CG(compiler_options) |= ZEND_COMPILE_IGNORE_INTERNAL_CLASSES;
-- CG(compiler_options) |= ZEND_COMPILE_DELAYED_BINDING;
-- CG(compiler_options) |= ZEND_COMPILE_NO_CONSTANT_SUBSTITUTION;
--// CG(compiler_options) |= ZEND_COMPILE_IGNORE_OTHER_FILES;
--
- orig_map_ptr_last = CG(map_ptr_last);
-
- /* Compile and execute proloading script */
-@@ -4207,7 +4202,6 @@ static int accel_preload(const char *config)
- ret = FAILURE;
- } zend_end_try();
-
-- CG(compiler_options) = orig_compiler_options;
- PG(open_basedir) = orig_open_basedir;
- accelerator_orig_compile_file = preload_orig_compile_file;
- ZCG(enabled) = 1;
-@@ -4500,6 +4494,7 @@ static int accel_finish_startup(void)
- char *(*orig_getenv)(char *name, size_t name_len TSRMLS_DC) = sapi_module.getenv;
- size_t (*orig_ub_write)(const char *str, size_t str_length) = sapi_module.ub_write;
- void (*orig_flush)(void *server_context) = sapi_module.flush;
-+ uint32_t orig_compiler_options = CG(compiler_options);
- #ifdef ZEND_SIGNALS
- zend_bool old_reset_signals = SIGG(reset);
- #endif
-@@ -4595,6 +4590,18 @@ static int accel_finish_startup(void)
- sapi_module.ub_write = preload_ub_write;
- sapi_module.flush = preload_flush;
-
-+#ifndef ZEND_WIN32
-+ if (in_child) {
-+ CG(compiler_options) |= ZEND_COMPILE_PRELOAD_IN_CHILD;
-+ }
-+#endif
-+ CG(compiler_options) |= ZEND_COMPILE_PRELOAD;
-+ CG(compiler_options) |= ZEND_COMPILE_HANDLE_OP_ARRAY;
-+ CG(compiler_options) |= ZEND_COMPILE_IGNORE_INTERNAL_CLASSES;
-+ CG(compiler_options) |= ZEND_COMPILE_DELAYED_BINDING;
-+ CG(compiler_options) |= ZEND_COMPILE_NO_CONSTANT_SUBSTITUTION;
-+ CG(compiler_options) |= ZEND_COMPILE_IGNORE_OTHER_FILES;
-+
- zend_interned_strings_switch_storage(1);
-
- #ifdef ZEND_SIGNALS
-@@ -4648,6 +4655,8 @@ static int accel_finish_startup(void)
- SIGG(reset) = old_reset_signals;
- #endif
-
-+ CG(compiler_options) = orig_compiler_options;
-+
- sapi_module.activate = orig_activate;
- sapi_module.deactivate = orig_deactivate;
- sapi_module.register_server_variables = orig_register_server_variables;
diff --git a/1c9bfcb6a766d4062f2dd1e594b30831d59cc36c.patch b/1c9bfcb6a766d4062f2dd1e594b30831d59cc36c.patch
deleted file mode 100644
index cc43800..0000000
--- a/1c9bfcb6a766d4062f2dd1e594b30831d59cc36c.patch
+++ /dev/null
@@ -1,81 +0,0 @@
-From 1c9bfcb6a766d4062f2dd1e594b30831d59cc36c Mon Sep 17 00:00:00 2001
-From: "Christoph M. Becker" <cmbecker69@gmx.de>
-Date: Tue, 22 Oct 2019 11:33:00 +0200
-Subject: [PATCH] Fix #78716: Function name mangling is wrong for some
- parameter types
-
-We have to cater to function parameter alignment when calculating the
-parameter size.
----
- NEWS | 4 ++++
- ext/ffi/ffi.c | 2 +-
- ext/ffi/tests/callconv.phpt | 30 +++++++++++++++---------------
- ext/ffi/tests/callconv_x86.dll | Bin 8704 -> 8704 bytes
- 4 files changed, 20 insertions(+), 16 deletions(-)
-
-diff --git a/ext/ffi/ffi.c b/ext/ffi/ffi.c
-index 1d6f84b6b223..1edba157a171 100644
---- a/ext/ffi/ffi.c
-+++ b/ext/ffi/ffi.c
-@@ -775,7 +775,7 @@ static size_t zend_ffi_arg_size(zend_ffi_type *type) /* {{{ */
- size_t arg_size = 0;
-
- ZEND_HASH_FOREACH_PTR(type->func.args, arg_type) {
-- arg_size += ZEND_FFI_TYPE(arg_type)->size;
-+ arg_size += MAX(ZEND_FFI_TYPE(arg_type)->size, sizeof(size_t));
- } ZEND_HASH_FOREACH_END();
- return arg_size;
- }
-diff --git a/ext/ffi/tests/callconv.phpt b/ext/ffi/tests/callconv.phpt
-index aa481de2249c..233c73f11010 100644
---- a/ext/ffi/tests/callconv.phpt
-+++ b/ext/ffi/tests/callconv.phpt
-@@ -9,32 +9,32 @@ if (PHP_INT_SIZE != 4) die("skip this test is for 32bit platforms only");
- --FILE--
- <?php
- $header = <<<HEADER
--void __cdecl cdecl_func(int arg1, double arg2);
--void __stdcall stdcall_func(int arg1, double arg2);
--void __fastcall fastcall_func(int arg1, double arg2);
-+void __cdecl cdecl_func(int arg1, double arg2, char arg3);
-+void __stdcall stdcall_func(int arg1, double arg2, char arg3);
-+void __fastcall fastcall_func(int arg1, double arg2, char arg3);
- HEADER;
- $headername = __DIR__ . '/callconv.h';
- $dllname = __DIR__ . "/callconv_x86.dll";
-
- $ffi1 = FFI::cdef($header, $dllname);
--$ffi1->cdecl_func(1, 2.3);
--$ffi1->stdcall_func(4, 5.6);
--$ffi1->fastcall_func(7, 8.9);
-+$ffi1->cdecl_func(1, 2.3, 'a');
-+$ffi1->stdcall_func(4, 5.6, 'b');
-+$ffi1->fastcall_func(7, 8.9, 'c');
-
- file_put_contents($headername, "#define FFI_LIB \"$dllname\"\n$header");
-
- $ffi2 = FFI::load($headername);
--$ffi2->cdecl_func(2, 3.4);
--$ffi2->stdcall_func(5, 6.7);
--$ffi2->fastcall_func(8, 9.1);
-+$ffi2->cdecl_func(2, 3.4, 'a');
-+$ffi2->stdcall_func(5, 6.7, 'b');
-+$ffi2->fastcall_func(8, 9.1, 'c');
- ?>
- --EXPECT--
--cdecl: 1, 2.300000
--stdcall: 4, 5.600000
--fastcall: 7, 8.900000
--cdecl: 2, 3.400000
--stdcall: 5, 6.700000
--fastcall: 8, 9.100000
-+cdecl: 1, 2.300000, a
-+stdcall: 4, 5.600000, b
-+fastcall: 7, 8.900000, c
-+cdecl: 2, 3.400000, a
-+stdcall: 5, 6.700000, b
-+fastcall: 8, 9.100000, c
- --CLEAN--
- <?php
- unlink(__DIR__ . '/callconv.h');
-
diff --git a/20-ffi.ini b/20-ffi.ini
index 4d1073c..a4e30cc 100644
--- a/20-ffi.ini
+++ b/20-ffi.ini
@@ -7,5 +7,5 @@ extension=ffi
; "true" - always enabled
;ffi.enable=preload
-; List of headers files to preload
+; List of headers files to preload, wildcard patterns allowed.
;ffi.preload=
diff --git a/598bf7f5d5f9c76fd003590083c98736eb7702ab.patch b/598bf7f5d5f9c76fd003590083c98736eb7702ab.patch
deleted file mode 100644
index d7ac048..0000000
--- a/598bf7f5d5f9c76fd003590083c98736eb7702ab.patch
+++ /dev/null
@@ -1,22 +0,0 @@
-From 598bf7f5d5f9c76fd003590083c98736eb7702ab Mon Sep 17 00:00:00 2001
-From: "Christoph M. Becker" <cmbecker69@gmx.de>
-Date: Tue, 22 Oct 2019 17:53:34 +0200
-Subject: [PATCH] Fix typo
-
----
- ext/ffi/ffi.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/ext/ffi/ffi.c b/ext/ffi/ffi.c
-index 4b7144e11ccc..17e8a8409d1f 100644
---- a/ext/ffi/ffi.c
-+++ b/ext/ffi/ffi.c
-@@ -3359,7 +3359,7 @@ ZEND_METHOD(FFI, load) /* {{{ */
- ZEND_PARSE_PARAMETERS_END();
-
- if (CG(compiler_options) & ZEND_COMPILE_PRELOAD_IN_CHILD) {
-- zend_throw_error(zend_ffi_exception_ce, "FFI::load() doesn't work in conjunction with \"opcache.pelaod_user\". Use \"ffi.preload\" instead.");
-+ zend_throw_error(zend_ffi_exception_ce, "FFI::load() doesn't work in conjunction with \"opcache.preload_user\". Use \"ffi.preload\" instead.");
- return;
- }
-
diff --git a/dcd772325d0f7702a525f03c7d5dd04bf96d8e18.patch b/dcd772325d0f7702a525f03c7d5dd04bf96d8e18.patch
deleted file mode 100644
index 8d06ce8..0000000
--- a/dcd772325d0f7702a525f03c7d5dd04bf96d8e18.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From dcd772325d0f7702a525f03c7d5dd04bf96d8e18 Mon Sep 17 00:00:00 2001
-From: Remi Collet <remi@php.net>
-Date: Wed, 23 Oct 2019 07:49:13 +0200
-Subject: [PATCH] add new ffi.preload option in php.ini and display ini
- entries in MINFO
-
----
- ext/ffi/ffi.c | 2 ++
- php.ini-development | 3 +++
- php.ini-production | 3 +++
- 3 files changed, 8 insertions(+)
-
-diff --git a/ext/ffi/ffi.c b/ext/ffi/ffi.c
-index 17e8a8409d1f..39bf2f82bf09 100644
---- a/ext/ffi/ffi.c
-+++ b/ext/ffi/ffi.c
-@@ -5077,6 +5077,8 @@ ZEND_MINFO_FUNCTION(ffi)
- php_info_print_table_start();
- php_info_print_table_header(2, "FFI support", "enabled");
- php_info_print_table_end();
-+
-+ DISPLAY_INI_ENTRIES();
- }
- /* }}} */
-
-diff --git a/php.ini-development b/php.ini-development
-index 3aefcd071db4..3f0c90cfca89 100644
---- a/php.ini-development
-+++ b/php.ini-development
-@@ -1945,3 +1945,6 @@ ldap.max_links = -1
- ; "false" - always disabled
- ; "true" - always enabled
- ;ffi.enable=preload
-+
-+; List of headers files to preload
-+;ffi.preload=
-diff --git a/php.ini-production b/php.ini-production
-index 8dc9a32e0026..867de11c60d4 100644
---- a/php.ini-production
-+++ b/php.ini-production
-@@ -1947,3 +1947,6 @@ ldap.max_links = -1
- ; "false" - always disabled
- ; "true" - always enabled
- ;ffi.enable=preload
-+
-+; List of headers files to preload
-+;ffi.preload=
diff --git a/php-ffi.patch b/php-ffi.patch
new file mode 100644
index 0000000..6ae2686
--- /dev/null
+++ b/php-ffi.patch
@@ -0,0 +1,730 @@
+From 05c5e5dfde91955263469daa2dd5afcbb5199d17 Mon Sep 17 00:00:00 2001
+From: Dmitry Stogov <dmitry@zend.com>
+Date: Mon, 21 Oct 2019 14:52:26 +0300
+Subject: [PATCH] Fixed bug #78512 (Cannot make preload work)
+
+---
+ NEWS | 3 +++
+ ext/opcache/ZendAccelerator.c | 5 +++++
+ 2 files changed, 8 insertions(+)
+
+diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c
+index 056c7739a0b6..636058dd0875 100644
+--- a/ext/opcache/ZendAccelerator.c
++++ b/ext/opcache/ZendAccelerator.c
+@@ -4565,6 +4565,11 @@ static int accel_finish_startup(void)
+ zend_accel_error(ACCEL_LOG_FATAL, "Preloading failed to waitpid(%d)", pid);
+ return FAILURE;
+ }
++
++ if (ZCSG(preload_script)) {
++ preload_load();
++ }
++
+ zend_shared_alloc_unlock();
+ if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
+ return SUCCESS;
+From 1c9bfcb6a766d4062f2dd1e594b30831d59cc36c Mon Sep 17 00:00:00 2001
+From: "Christoph M. Becker" <cmbecker69@gmx.de>
+Date: Tue, 22 Oct 2019 11:33:00 +0200
+Subject: [PATCH] Fix #78716: Function name mangling is wrong for some
+ parameter types
+
+We have to cater to function parameter alignment when calculating the
+parameter size.
+---
+ NEWS | 4 ++++
+ ext/ffi/ffi.c | 2 +-
+ ext/ffi/tests/callconv.phpt | 30 +++++++++++++++---------------
+ ext/ffi/tests/callconv_x86.dll | Bin 8704 -> 8704 bytes
+ 4 files changed, 20 insertions(+), 16 deletions(-)
+
+diff --git a/ext/ffi/ffi.c b/ext/ffi/ffi.c
+index 1d6f84b6b223..1edba157a171 100644
+--- a/ext/ffi/ffi.c
++++ b/ext/ffi/ffi.c
+@@ -775,7 +775,7 @@ static size_t zend_ffi_arg_size(zend_ffi_type *type) /* {{{ */
+ size_t arg_size = 0;
+
+ ZEND_HASH_FOREACH_PTR(type->func.args, arg_type) {
+- arg_size += ZEND_FFI_TYPE(arg_type)->size;
++ arg_size += MAX(ZEND_FFI_TYPE(arg_type)->size, sizeof(size_t));
+ } ZEND_HASH_FOREACH_END();
+ return arg_size;
+ }
+diff --git a/ext/ffi/tests/callconv.phpt b/ext/ffi/tests/callconv.phpt
+index aa481de2249c..233c73f11010 100644
+--- a/ext/ffi/tests/callconv.phpt
++++ b/ext/ffi/tests/callconv.phpt
+@@ -9,32 +9,32 @@ if (PHP_INT_SIZE != 4) die("skip this test is for 32bit platforms only");
+ --FILE--
+ <?php
+ $header = <<<HEADER
+-void __cdecl cdecl_func(int arg1, double arg2);
+-void __stdcall stdcall_func(int arg1, double arg2);
+-void __fastcall fastcall_func(int arg1, double arg2);
++void __cdecl cdecl_func(int arg1, double arg2, char arg3);
++void __stdcall stdcall_func(int arg1, double arg2, char arg3);
++void __fastcall fastcall_func(int arg1, double arg2, char arg3);
+ HEADER;
+ $headername = __DIR__ . '/callconv.h';
+ $dllname = __DIR__ . "/callconv_x86.dll";
+
+ $ffi1 = FFI::cdef($header, $dllname);
+-$ffi1->cdecl_func(1, 2.3);
+-$ffi1->stdcall_func(4, 5.6);
+-$ffi1->fastcall_func(7, 8.9);
++$ffi1->cdecl_func(1, 2.3, 'a');
++$ffi1->stdcall_func(4, 5.6, 'b');
++$ffi1->fastcall_func(7, 8.9, 'c');
+
+ file_put_contents($headername, "#define FFI_LIB \"$dllname\"\n$header");
+
+ $ffi2 = FFI::load($headername);
+-$ffi2->cdecl_func(2, 3.4);
+-$ffi2->stdcall_func(5, 6.7);
+-$ffi2->fastcall_func(8, 9.1);
++$ffi2->cdecl_func(2, 3.4, 'a');
++$ffi2->stdcall_func(5, 6.7, 'b');
++$ffi2->fastcall_func(8, 9.1, 'c');
+ ?>
+ --EXPECT--
+-cdecl: 1, 2.300000
+-stdcall: 4, 5.600000
+-fastcall: 7, 8.900000
+-cdecl: 2, 3.400000
+-stdcall: 5, 6.700000
+-fastcall: 8, 9.100000
++cdecl: 1, 2.300000, a
++stdcall: 4, 5.600000, b
++fastcall: 7, 8.900000, c
++cdecl: 2, 3.400000, a
++stdcall: 5, 6.700000, b
++fastcall: 8, 9.100000, c
+ --CLEAN--
+ <?php
+ unlink(__DIR__ . '/callconv.h');
+
+From 1417352dda354c22db43a8d4dbaa967575e2720c Mon Sep 17 00:00:00 2001
+From: Dmitry Stogov <dmitry@zend.com>
+Date: Tue, 22 Oct 2019 17:52:56 +0300
+Subject: [PATCH] Allow loading FFI bindings through ffi.preload directive
+
+---
+ Zend/zend_compile.h | 3 +
+ ext/ffi/ffi.c | 101 ++++++++++++++++++++++++++++------
+ ext/ffi/php_ffi.h | 1 +
+ ext/ffi/tests/302.phpt | 15 +++++
+ ext/opcache/ZendAccelerator.c | 31 +++++++----
+ 5 files changed, 124 insertions(+), 27 deletions(-)
+ create mode 100644 ext/ffi/tests/302.phpt
+
+diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h
+index 499d0d64b641..c21554e4641e 100644
+--- a/Zend/zend_compile.h
++++ b/Zend/zend_compile.h
+@@ -1094,6 +1094,9 @@ END_EXTERN_C()
+ /* disable jumptable optimization for switch statements */
+ #define ZEND_COMPILE_NO_JUMPTABLES (1<<16)
+
++/* this flag is set when compiler invoked during preloading in separate process */
++#define ZEND_COMPILE_PRELOAD_IN_CHILD (1<<17)
++
+ /* The default value for CG(compiler_options) */
+ #define ZEND_COMPILE_DEFAULT ZEND_COMPILE_HANDLE_OP_ARRAY
+
+diff --git a/ext/ffi/ffi.c b/ext/ffi/ffi.c
+index 1edba157a171..4b7144e11ccc 100644
+--- a/ext/ffi/ffi.c
++++ b/ext/ffi/ffi.c
+@@ -3083,15 +3083,13 @@ static zend_ffi_type *zend_ffi_remember_type(zend_ffi_type *type) /* {{{ */
+ }
+ /* }}} */
+
+-ZEND_METHOD(FFI, load) /* {{{ */
++static zend_ffi *zend_ffi_load(const char *filename, zend_bool preload) /* {{{ */
+ {
+- zend_string *fn;
+ struct stat buf;
+ int fd;
+- char *filename, *code, *code_pos, *scope_name, *lib;
++ char *code, *code_pos, *scope_name, *lib;
+ size_t code_size, scope_name_len;
+ zend_ffi *ffi;
+- zend_bool preload = (CG(compiler_options) & ZEND_COMPILE_PRELOAD) != 0;
+ DL_HANDLE handle = NULL;
+ zend_ffi_scope *scope = NULL;
+ zend_string *name;
+@@ -3099,19 +3097,13 @@ ZEND_METHOD(FFI, load) /* {{{ */
+ zend_ffi_tag *tag;
+ void *addr;
+
+- ZEND_FFI_VALIDATE_API_RESTRICTION();
+- ZEND_PARSE_PARAMETERS_START(1, 1)
+- Z_PARAM_STR(fn)
+- ZEND_PARSE_PARAMETERS_END();
+-
+- filename = ZSTR_VAL(fn);
+ if (stat(filename, &buf) != 0) {
+ if (preload) {
+ zend_error(E_WARNING, "FFI: failed pre-loading '%s', file doesn't exist", filename);
+ } else {
+ zend_throw_error(zend_ffi_exception_ce, "Failed loading '%s', file doesn't exist", filename);
+ }
+- return;
++ return NULL;
+ }
+
+ if ((buf.st_mode & S_IFMT) != S_IFREG) {
+@@ -3120,7 +3112,7 @@ ZEND_METHOD(FFI, load) /* {{{ */
+ } else {
+ zend_throw_error(zend_ffi_exception_ce, "Failed loading '%s', not a regular file", filename);
+ }
+- return;
++ return NULL;
+ }
+
+ code_size = buf.st_size;
+@@ -3134,7 +3126,7 @@ ZEND_METHOD(FFI, load) /* {{{ */
+ }
+ efree(code);
+ close(fd);
+- return;
++ return NULL;
+ }
+ close(fd);
+ code[code_size] = 0;
+@@ -3153,7 +3145,7 @@ ZEND_METHOD(FFI, load) /* {{{ */
+ if (!code_pos) {
+ efree(code);
+ FFI_G(persistent) = 0;
+- return;
++ return NULL;
+ }
+ code_size -= code_pos - code;
+
+@@ -3318,7 +3310,11 @@ ZEND_METHOD(FFI, load) /* {{{ */
+ }
+ }
+
+- ffi = (zend_ffi*)zend_ffi_new(zend_ffi_ce);
++ if (EG(objects_store).object_buckets) {
++ ffi = (zend_ffi*)zend_ffi_new(zend_ffi_ce);
++ } else {
++ ffi = ecalloc(1, sizeof(zend_ffi));
++ }
+ ffi->symbols = scope->symbols;
+ ffi->tags = scope->tags;
+ ffi->persistent = 1;
+@@ -3333,7 +3329,7 @@ ZEND_METHOD(FFI, load) /* {{{ */
+ FFI_G(symbols) = NULL;
+ FFI_G(tags) = NULL;
+
+- RETURN_OBJ(&ffi->std);
++ return ffi;
+
+ cleanup:
+ efree(code);
+@@ -3348,6 +3344,30 @@ ZEND_METHOD(FFI, load) /* {{{ */
+ FFI_G(tags) = NULL;
+ }
+ FFI_G(persistent) = 0;
++ return NULL;
++}
++/* }}} */
++
++ZEND_METHOD(FFI, load) /* {{{ */
++{
++ zend_string *fn;
++ zend_ffi *ffi;
++
++ ZEND_FFI_VALIDATE_API_RESTRICTION();
++ ZEND_PARSE_PARAMETERS_START(1, 1)
++ Z_PARAM_STR(fn)
++ ZEND_PARSE_PARAMETERS_END();
++
++ if (CG(compiler_options) & ZEND_COMPILE_PRELOAD_IN_CHILD) {
++ zend_throw_error(zend_ffi_exception_ce, "FFI::load() doesn't work in conjunction with \"opcache.pelaod_user\". Use \"ffi.preload\" instead.");
++ return;
++ }
++
++ ffi = zend_ffi_load(ZSTR_VAL(fn), (CG(compiler_options) & ZEND_COMPILE_PRELOAD) != 0);
++
++ if (ffi) {
++ RETURN_OBJ(&ffi->std);
++ }
+ }
+ /* }}} */
+
+@@ -4813,8 +4833,51 @@ static ZEND_INI_DISP(zend_ffi_enable_displayer_cb) /* {{{ */
+
+ ZEND_INI_BEGIN()
+ ZEND_INI_ENTRY3_EX("ffi.enable", "preload", ZEND_INI_SYSTEM, OnUpdateFFIEnable, NULL, NULL, NULL, zend_ffi_enable_displayer_cb)
++ STD_ZEND_INI_ENTRY("ffi.preload", NULL, ZEND_INI_SYSTEM, OnUpdateString, preload, zend_ffi_globals, ffi_globals)
+ ZEND_INI_END()
+
++static int zend_ffi_preload(char *preload) /* {{{ */
++{
++ zend_ffi *ffi;
++ char *s = NULL, *e, *filename;
++
++ e = preload;
++ while (*e) {
++ switch (*e) {
++ case ZEND_PATHS_SEPARATOR:
++ if (s) {
++ filename = estrndup(s, e-s);
++ ffi = zend_ffi_load(filename, 1);
++ efree(filename);
++ if (!ffi) {
++ return FAILURE;
++ }
++ efree(ffi);
++ s = NULL;
++ }
++ break;
++ default:
++ if (!s) {
++ s = e;
++ }
++ break;
++ }
++ e++;
++ }
++ if (s) {
++ filename = estrndup(s, e-s);
++ ffi = zend_ffi_load(filename, 1);
++ efree(filename);
++ if (!ffi) {
++ return FAILURE;
++ }
++ efree(ffi);
++ }
++
++ return SUCCESS;
++}
++/* }}} */
++
+ /* {{{ ZEND_MINIT_FUNCTION
+ */
+ ZEND_MINIT_FUNCTION(ffi)
+@@ -4976,6 +5039,12 @@ ZEND_MINIT_FUNCTION(ffi)
+ zend_ffi_ctype_handlers.get_properties = zend_fake_get_properties;
+ zend_ffi_ctype_handlers.get_gc = zend_fake_get_gc;
+
++ if (FFI_G(preload)) {
++ if (zend_ffi_preload(FFI_G(preload)) != SUCCESS) {
++ return FAILURE;
++ }
++ }
++
+ return SUCCESS;
+ }
+ /* }}} */
+diff --git a/ext/ffi/php_ffi.h b/ext/ffi/php_ffi.h
+index 0f511fccf05c..b9f01d6e96f4 100644
+--- a/ext/ffi/php_ffi.h
++++ b/ext/ffi/php_ffi.h
+@@ -38,6 +38,7 @@ ZEND_BEGIN_MODULE_GLOBALS(ffi)
+ HashTable types;
+
+ /* preloading */
++ char *preload;
+ HashTable *scopes; /* list of preloaded scopes */
+
+ /* callbacks */
+diff --git a/ext/ffi/tests/302.phpt b/ext/ffi/tests/302.phpt
+new file mode 100644
+index 000000000000..cb0d73d56880
+--- /dev/null
++++ b/ext/ffi/tests/302.phpt
+@@ -0,0 +1,15 @@
++--TEST--
++FFI 302: FFI preloading
++--SKIPIF--
++<?php require_once('skipif.inc'); ?>
++<?php if (substr(PHP_OS, 0, 3) == 'WIN') die('skip not for Windows'); ?>
++--INI--
++ffi.enable=1
++ffi.preload={PWD}/300.h
++--FILE--
++<?php
++$ffi = FFI::scope("TEST_300");
++$ffi->printf("Hello World from %s!\n", "PHP");
++?>
++--EXPECT--
++Hello World from PHP!
+diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c
+index 636058dd0875..704e1c38d9b7 100644
+--- a/ext/opcache/ZendAccelerator.c
++++ b/ext/opcache/ZendAccelerator.c
+@@ -4140,14 +4140,17 @@ static void preload_load(void)
+ if (EG(class_table)) {
+ EG(persistent_classes_count) = EG(class_table)->nNumUsed;
+ }
+- CG(map_ptr_last) = ZCSG(map_ptr_last);
++ if (CG(map_ptr_last) != ZCSG(map_ptr_last)) {
++ CG(map_ptr_last) = ZCSG(map_ptr_last);
++ CG(map_ptr_size) = ZEND_MM_ALIGNED_SIZE_EX(CG(map_ptr_last) + 1, 4096);
++ CG(map_ptr_base) = perealloc(CG(map_ptr_base), CG(map_ptr_size) * sizeof(void*), 1);
++ }
+ }
+
+ static int accel_preload(const char *config)
+ {
+ zend_file_handle file_handle;
+ int ret;
+- uint32_t orig_compiler_options;
+ char *orig_open_basedir;
+ size_t orig_map_ptr_last;
+ zval *zv;
+@@ -4159,14 +4162,6 @@ static int accel_preload(const char *config)
+ preload_orig_compile_file = accelerator_orig_compile_file;
+ accelerator_orig_compile_file = preload_compile_file;
+
+- orig_compiler_options = CG(compiler_options);
+- CG(compiler_options) |= ZEND_COMPILE_PRELOAD;
+- CG(compiler_options) |= ZEND_COMPILE_HANDLE_OP_ARRAY;
+-// CG(compiler_options) |= ZEND_COMPILE_IGNORE_INTERNAL_CLASSES;
+- CG(compiler_options) |= ZEND_COMPILE_DELAYED_BINDING;
+- CG(compiler_options) |= ZEND_COMPILE_NO_CONSTANT_SUBSTITUTION;
+-// CG(compiler_options) |= ZEND_COMPILE_IGNORE_OTHER_FILES;
+-
+ orig_map_ptr_last = CG(map_ptr_last);
+
+ /* Compile and execute proloading script */
+@@ -4207,7 +4202,6 @@ static int accel_preload(const char *config)
+ ret = FAILURE;
+ } zend_end_try();
+
+- CG(compiler_options) = orig_compiler_options;
+ PG(open_basedir) = orig_open_basedir;
+ accelerator_orig_compile_file = preload_orig_compile_file;
+ ZCG(enabled) = 1;
+@@ -4500,6 +4494,7 @@ static int accel_finish_startup(void)
+ char *(*orig_getenv)(char *name, size_t name_len TSRMLS_DC) = sapi_module.getenv;
+ size_t (*orig_ub_write)(const char *str, size_t str_length) = sapi_module.ub_write;
+ void (*orig_flush)(void *server_context) = sapi_module.flush;
++ uint32_t orig_compiler_options = CG(compiler_options);
+ #ifdef ZEND_SIGNALS
+ zend_bool old_reset_signals = SIGG(reset);
+ #endif
+@@ -4595,6 +4590,18 @@ static int accel_finish_startup(void)
+ sapi_module.ub_write = preload_ub_write;
+ sapi_module.flush = preload_flush;
+
++#ifndef ZEND_WIN32
++ if (in_child) {
++ CG(compiler_options) |= ZEND_COMPILE_PRELOAD_IN_CHILD;
++ }
++#endif
++ CG(compiler_options) |= ZEND_COMPILE_PRELOAD;
++ CG(compiler_options) |= ZEND_COMPILE_HANDLE_OP_ARRAY;
++ CG(compiler_options) |= ZEND_COMPILE_IGNORE_INTERNAL_CLASSES;
++ CG(compiler_options) |= ZEND_COMPILE_DELAYED_BINDING;
++ CG(compiler_options) |= ZEND_COMPILE_NO_CONSTANT_SUBSTITUTION;
++ CG(compiler_options) |= ZEND_COMPILE_IGNORE_OTHER_FILES;
++
+ zend_interned_strings_switch_storage(1);
+
+ #ifdef ZEND_SIGNALS
+@@ -4648,6 +4655,8 @@ static int accel_finish_startup(void)
+ SIGG(reset) = old_reset_signals;
+ #endif
+
++ CG(compiler_options) = orig_compiler_options;
++
+ sapi_module.activate = orig_activate;
+ sapi_module.deactivate = orig_deactivate;
+ sapi_module.register_server_variables = orig_register_server_variables;
+From 598bf7f5d5f9c76fd003590083c98736eb7702ab Mon Sep 17 00:00:00 2001
+From: "Christoph M. Becker" <cmbecker69@gmx.de>
+Date: Tue, 22 Oct 2019 17:53:34 +0200
+Subject: [PATCH] Fix typo
+
+---
+ ext/ffi/ffi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/ext/ffi/ffi.c b/ext/ffi/ffi.c
+index 4b7144e11ccc..17e8a8409d1f 100644
+--- a/ext/ffi/ffi.c
++++ b/ext/ffi/ffi.c
+@@ -3359,7 +3359,7 @@ ZEND_METHOD(FFI, load) /* {{{ */
+ ZEND_PARSE_PARAMETERS_END();
+
+ if (CG(compiler_options) & ZEND_COMPILE_PRELOAD_IN_CHILD) {
+- zend_throw_error(zend_ffi_exception_ce, "FFI::load() doesn't work in conjunction with \"opcache.pelaod_user\". Use \"ffi.preload\" instead.");
++ zend_throw_error(zend_ffi_exception_ce, "FFI::load() doesn't work in conjunction with \"opcache.preload_user\". Use \"ffi.preload\" instead.");
+ return;
+ }
+
+From dcd772325d0f7702a525f03c7d5dd04bf96d8e18 Mon Sep 17 00:00:00 2001
+From: Remi Collet <remi@php.net>
+Date: Wed, 23 Oct 2019 07:49:13 +0200
+Subject: [PATCH] add new ffi.preload option in php.ini and display ini
+ entries in MINFO
+
+---
+ ext/ffi/ffi.c | 2 ++
+ php.ini-development | 3 +++
+ php.ini-production | 3 +++
+ 3 files changed, 8 insertions(+)
+
+diff --git a/ext/ffi/ffi.c b/ext/ffi/ffi.c
+index 17e8a8409d1f..39bf2f82bf09 100644
+--- a/ext/ffi/ffi.c
++++ b/ext/ffi/ffi.c
+@@ -5077,6 +5077,8 @@ ZEND_MINFO_FUNCTION(ffi)
+ php_info_print_table_start();
+ php_info_print_table_header(2, "FFI support", "enabled");
+ php_info_print_table_end();
++
++ DISPLAY_INI_ENTRIES();
+ }
+ /* }}} */
+
+diff --git a/php.ini-development b/php.ini-development
+index 3aefcd071db4..3f0c90cfca89 100644
+--- a/php.ini-development
++++ b/php.ini-development
+@@ -1945,3 +1945,6 @@ ldap.max_links = -1
+ ; "false" - always disabled
+ ; "true" - always enabled
+ ;ffi.enable=preload
++
++; List of headers files to preload
++;ffi.preload=
+diff --git a/php.ini-production b/php.ini-production
+index 8dc9a32e0026..867de11c60d4 100644
+--- a/php.ini-production
++++ b/php.ini-production
+@@ -1947,3 +1947,6 @@ ldap.max_links = -1
+ ; "false" - always disabled
+ ; "true" - always enabled
+ ;ffi.enable=preload
++
++; List of headers files to preload
++;ffi.preload=
+From fea8c5481bfae651167d90393ddae89e591b0d55 Mon Sep 17 00:00:00 2001
+From: Dmitry Stogov <dmitry@zend.com>
+Date: Wed, 23 Oct 2019 17:18:11 +0300
+Subject: [PATCH] Added suppot for glob() wildcard matching in ffi.preload
+ directive
+
+---
+ ext/ffi/ffi.c | 93 +++++++++++++++++++++++++++++++++++++-----
+ ext/ffi/tests/303.phpt | 15 +++++++
+ php.ini-development | 2 +-
+ php.ini-production | 2 +-
+ 4 files changed, 99 insertions(+), 13 deletions(-)
+ create mode 100644 ext/ffi/tests/303.phpt
+
+diff --git a/ext/ffi/ffi.c b/ext/ffi/ffi.c
+index e2476653f72f..ca6e7c4ef523 100644
+--- a/ext/ffi/ffi.c
++++ b/ext/ffi/ffi.c
+@@ -35,6 +35,14 @@
+ #include <sys/stat.h>
+ #include <fcntl.h>
+
++#ifdef HAVE_GLOB
++#ifdef PHP_WIN32
++#include "win32/glob.h"
++#else
++#include <glob.h>
++#endif
++#endif
++
+ ZEND_DECLARE_MODULE_GLOBALS(ffi)
+
+ typedef enum _zend_ffi_tag_kind {
+@@ -4836,10 +4844,50 @@ ZEND_INI_BEGIN()
+ STD_ZEND_INI_ENTRY("ffi.preload", NULL, ZEND_INI_SYSTEM, OnUpdateString, preload, zend_ffi_globals, ffi_globals)
+ ZEND_INI_END()
+
++static int zend_ffi_preload_glob(const char *filename) /* {{{ */
++{
++#ifdef HAVE_GLOB
++ glob_t globbuf;
++ int ret;
++ unsigned int i;
++
++ memset(&globbuf, 0, sizeof(glob_t));
++
++ ret = glob(filename, 0, NULL, &globbuf);
++#ifdef GLOB_NOMATCH
++ if (ret == GLOB_NOMATCH || !globbuf.gl_pathc) {
++#else
++ if (!globbuf.gl_pathc) {
++#endif
++ /* pass */
++ } else {
++ for(i=0 ; i<globbuf.gl_pathc; i++) {
++ zend_ffi *ffi = zend_ffi_load(globbuf.gl_pathv[i], 1);
++ if (!ffi) {
++ globfree(&globbuf);
++ return FAILURE;
++ }
++ efree(ffi);
++ }
++ globfree(&globbuf);
++ }
++#else
++ zend_ffi *ffi = zend_ffi_load(filename, 1);
++ if (!ffi) {
++ return FAILURE;
++ }
++ efree(ffi);
++#endif
++
++ return SUCCESS;
++}
++/* }}} */
++
+ static int zend_ffi_preload(char *preload) /* {{{ */
+ {
+ zend_ffi *ffi;
+ char *s = NULL, *e, *filename;
++ zend_bool is_glob = 0;
+
+ e = preload;
+ while (*e) {
+@@ -4847,15 +4895,30 @@ static int zend_ffi_preload(char *preload) /* {{{ */
+ case ZEND_PATHS_SEPARATOR:
+ if (s) {
+ filename = estrndup(s, e-s);
+- ffi = zend_ffi_load(filename, 1);
+- efree(filename);
+- if (!ffi) {
+- return FAILURE;
+- }
+- efree(ffi);
+ s = NULL;
++ if (!is_glob) {
++ ffi = zend_ffi_load(filename, 1);
++ efree(filename);
++ if (!ffi) {
++ return FAILURE;
++ }
++ efree(ffi);
++ } else {
++ int ret = zend_ffi_preload_glob(filename);
++
++ efree(filename);
++ if (ret != SUCCESS) {
++ return FAILURE;
++ }
++ is_glob = 0;
++ }
+ }
+ break;
++ case '*':
++ case '?':
++ case '[':
++ is_glob = 1;
++ break;
+ default:
+ if (!s) {
+ s = e;
+@@ -4866,12 +4929,20 @@ static int zend_ffi_preload(char *preload) /* {{{ */
+ }
+ if (s) {
+ filename = estrndup(s, e-s);
+- ffi = zend_ffi_load(filename, 1);
+- efree(filename);
+- if (!ffi) {
+- return FAILURE;
++ if (!is_glob) {
++ ffi = zend_ffi_load(filename, 1);
++ efree(filename);
++ if (!ffi) {
++ return FAILURE;
++ }
++ efree(ffi);
++ } else {
++ int ret = zend_ffi_preload_glob(filename);
++ efree(filename);
++ if (ret != SUCCESS) {
++ return FAILURE;
++ }
+ }
+- efree(ffi);
+ }
+
+ return SUCCESS;
+diff --git a/ext/ffi/tests/303.phpt b/ext/ffi/tests/303.phpt
+new file mode 100644
+index 000000000000..756adbbf401a
+--- /dev/null
++++ b/ext/ffi/tests/303.phpt
+@@ -0,0 +1,15 @@
++--TEST--
++FFI 303: FFI preloading flob
++--SKIPIF--
++<?php require_once('skipif.inc'); ?>
++<?php if (substr(PHP_OS, 0, 3) == 'WIN') die('skip not for Windows'); ?>
++--INI--
++ffi.enable=1
++ffi.preload={PWD}/300*.h
++--FILE--
++<?php
++$ffi = FFI::scope("TEST_300");
++$ffi->printf("Hello World from %s!\n", "PHP");
++?>
++--EXPECT--
++Hello World from PHP!
+diff --git a/php.ini-development b/php.ini-development
+index 3f0c90cfca89..f44c541a7a10 100644
+--- a/php.ini-development
++++ b/php.ini-development
+@@ -1946,5 +1946,5 @@ ldap.max_links = -1
+ ; "true" - always enabled
+ ;ffi.enable=preload
+
+-; List of headers files to preload
++; List of headers files to preload, wilcards allowed.
+ ;ffi.preload=
+diff --git a/php.ini-production b/php.ini-production
+index 867de11c60d4..b7f2536fd992 100644
+--- a/php.ini-production
++++ b/php.ini-production
+@@ -1948,5 +1948,5 @@ ldap.max_links = -1
+ ; "true" - always enabled
+ ;ffi.enable=preload
+
+-; List of headers files to preload
++; List of headers files to preload, wilcards allowed.
+ ;ffi.preload=
+From 69b608cf13f24f7859e564254263fa789e722211 Mon Sep 17 00:00:00 2001
+From: Remi Collet <remi@php.net>
+Date: Thu, 24 Oct 2019 07:43:49 +0200
+Subject: [PATCH] typo and better wording
+
+---
+ php.ini-development | 2 +-
+ php.ini-production | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/php.ini-development b/php.ini-development
+index f44c541a7a10..5bd274016041 100644
+--- a/php.ini-development
++++ b/php.ini-development
+@@ -1946,5 +1946,5 @@ ldap.max_links = -1
+ ; "true" - always enabled
+ ;ffi.enable=preload
+
+-; List of headers files to preload, wilcards allowed.
++; List of headers files to preload, wildcard patterns allowed.
+ ;ffi.preload=
+diff --git a/php.ini-production b/php.ini-production
+index b7f2536fd992..beea6b26500f 100644
+--- a/php.ini-production
++++ b/php.ini-production
+@@ -1948,5 +1948,5 @@ ldap.max_links = -1
+ ; "true" - always enabled
+ ;ffi.enable=preload
+
+-; List of headers files to preload, wilcards allowed.
++; List of headers files to preload, wildcard patterns allowed.
+ ;ffi.preload=
diff --git a/php.spec b/php.spec
index 2964063..35ac5cc 100644
--- a/php.spec
+++ b/php.spec
@@ -108,7 +108,7 @@
Summary: PHP scripting language for creating dynamic web sites
Name: %{?scl_prefix}php
Version: %{upver}%{?lower:~%{lower}}%{?gh_date:.%{gh_date}}
-Release: 30%{?dist}
+Release: 31%{?dist}
# All files licensed under PHP version 3.01, except
# Zend is licensed under Zend
# TSRM is licensed under BSD
@@ -174,11 +174,7 @@ Patch91: php-7.2.0-oci8conf.patch
Patch300: php-7.0.10-datetests.patch
# WIP
-Patch100: https://github.com/php/php-src/commit/05c5e5dfde91955263469daa2dd5afcbb5199d17.patch
-Patch101: https://github.com/php/php-src/commit/1c9bfcb6a766d4062f2dd1e594b30831d59cc36c.patch
-Patch102: https://github.com/php/php-src/commit/1417352dda354c22db43a8d4dbaa967575e2720c.patch
-Patch103: https://github.com/php/php-src/commit/598bf7f5d5f9c76fd003590083c98736eb7702ab.patch
-Patch104: https://github.com/php/php-src/commit/dcd772325d0f7702a525f03c7d5dd04bf96d8e18.patch
+Patch100: php-ffi.patch
BuildRequires: gnupg2
BuildRequires: bzip2-devel
@@ -951,10 +947,6 @@ sed -e 's/php-devel/%{?scl_prefix}php-devel/' -i scripts/phpize.in
# WIP patch
%patch100 -p1
-%patch101 -p1
-%patch102 -p1
-%patch103 -p1
-%patch104 -p1
# Prevent %%doc confusion over LICENSE files
cp Zend/LICENSE Zend/ZEND_LICENSE
@@ -1814,6 +1806,9 @@ fi
%changelog
+* Thu Oct 24 2019 Remi Collet <remi@remirepo.net> - 7.4.0~rc4-31
+- allow wildcards in ffi.preload
+
* Wed Oct 23 2019 Remi Collet <remi@remirepo.net> - 7.4.0~rc4-30
- fix preload, add more upstream patches for #78713 #78716