Skip to content

Commit fea8c54

Browse files
dstogovremicollet
authored andcommitted
Added suppot for glob() wildcard matching in ffi.preload directive
1 parent af57b63 commit fea8c54

File tree

4 files changed

+99
-13
lines changed

4 files changed

+99
-13
lines changed

ext/ffi/ffi.c

Lines changed: 82 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,14 @@
3535
#include <sys/stat.h>
3636
#include <fcntl.h>
3737

38+
#ifdef HAVE_GLOB
39+
#ifdef PHP_WIN32
40+
#include "win32/glob.h"
41+
#else
42+
#include <glob.h>
43+
#endif
44+
#endif
45+
3846
ZEND_DECLARE_MODULE_GLOBALS(ffi)
3947

4048
typedef enum _zend_ffi_tag_kind {
@@ -4836,26 +4844,81 @@ ZEND_INI_BEGIN()
48364844
STD_ZEND_INI_ENTRY("ffi.preload", NULL, ZEND_INI_SYSTEM, OnUpdateString, preload, zend_ffi_globals, ffi_globals)
48374845
ZEND_INI_END()
48384846

4847+
static int zend_ffi_preload_glob(const char *filename) /* {{{ */
4848+
{
4849+
#ifdef HAVE_GLOB
4850+
glob_t globbuf;
4851+
int ret;
4852+
unsigned int i;
4853+
4854+
memset(&globbuf, 0, sizeof(glob_t));
4855+
4856+
ret = glob(filename, 0, NULL, &globbuf);
4857+
#ifdef GLOB_NOMATCH
4858+
if (ret == GLOB_NOMATCH || !globbuf.gl_pathc) {
4859+
#else
4860+
if (!globbuf.gl_pathc) {
4861+
#endif
4862+
/* pass */
4863+
} else {
4864+
for(i=0 ; i<globbuf.gl_pathc; i++) {
4865+
zend_ffi *ffi = zend_ffi_load(globbuf.gl_pathv[i], 1);
4866+
if (!ffi) {
4867+
globfree(&globbuf);
4868+
return FAILURE;
4869+
}
4870+
efree(ffi);
4871+
}
4872+
globfree(&globbuf);
4873+
}
4874+
#else
4875+
zend_ffi *ffi = zend_ffi_load(filename, 1);
4876+
if (!ffi) {
4877+
return FAILURE;
4878+
}
4879+
efree(ffi);
4880+
#endif
4881+
4882+
return SUCCESS;
4883+
}
4884+
/* }}} */
4885+
48394886
static int zend_ffi_preload(char *preload) /* {{{ */
48404887
{
48414888
zend_ffi *ffi;
48424889
char *s = NULL, *e, *filename;
4890+
zend_bool is_glob = 0;
48434891

48444892
e = preload;
48454893
while (*e) {
48464894
switch (*e) {
48474895
case ZEND_PATHS_SEPARATOR:
48484896
if (s) {
48494897
filename = estrndup(s, e-s);
4850-
ffi = zend_ffi_load(filename, 1);
4851-
efree(filename);
4852-
if (!ffi) {
4853-
return FAILURE;
4854-
}
4855-
efree(ffi);
48564898
s = NULL;
4899+
if (!is_glob) {
4900+
ffi = zend_ffi_load(filename, 1);
4901+
efree(filename);
4902+
if (!ffi) {
4903+
return FAILURE;
4904+
}
4905+
efree(ffi);
4906+
} else {
4907+
int ret = zend_ffi_preload_glob(filename);
4908+
4909+
efree(filename);
4910+
if (ret != SUCCESS) {
4911+
return FAILURE;
4912+
}
4913+
is_glob = 0;
4914+
}
48574915
}
48584916
break;
4917+
case '*':
4918+
case '?':
4919+
case '[':
4920+
is_glob = 1;
4921+
break;
48594922
default:
48604923
if (!s) {
48614924
s = e;
@@ -4866,12 +4929,20 @@ static int zend_ffi_preload(char *preload) /* {{{ */
48664929
}
48674930
if (s) {
48684931
filename = estrndup(s, e-s);
4869-
ffi = zend_ffi_load(filename, 1);
4870-
efree(filename);
4871-
if (!ffi) {
4872-
return FAILURE;
4932+
if (!is_glob) {
4933+
ffi = zend_ffi_load(filename, 1);
4934+
efree(filename);
4935+
if (!ffi) {
4936+
return FAILURE;
4937+
}
4938+
efree(ffi);
4939+
} else {
4940+
int ret = zend_ffi_preload_glob(filename);
4941+
efree(filename);
4942+
if (ret != SUCCESS) {
4943+
return FAILURE;
4944+
}
48734945
}
4874-
efree(ffi);
48754946
}
48764947

48774948
return SUCCESS;

ext/ffi/tests/303.phpt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
--TEST--
2+
FFI 303: FFI preloading flob
3+
--SKIPIF--
4+
<?php require_once('skipif.inc'); ?>
5+
<?php if (substr(PHP_OS, 0, 3) == 'WIN') die('skip not for Windows'); ?>
6+
--INI--
7+
ffi.enable=1
8+
ffi.preload={PWD}/300*.h
9+
--FILE--
10+
<?php
11+
$ffi = FFI::scope("TEST_300");
12+
$ffi->printf("Hello World from %s!\n", "PHP");
13+
?>
14+
--EXPECT--
15+
Hello World from PHP!

php.ini-development

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1946,5 +1946,5 @@ ldap.max_links = -1
19461946
; "true" - always enabled
19471947
;ffi.enable=preload
19481948

1949-
; List of headers files to preload
1949+
; List of headers files to preload, wilcards allowed.
19501950
;ffi.preload=

php.ini-production

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1948,5 +1948,5 @@ ldap.max_links = -1
19481948
; "true" - always enabled
19491949
;ffi.enable=preload
19501950

1951-
; List of headers files to preload
1951+
; List of headers files to preload, wilcards allowed.
19521952
;ffi.preload=

0 commit comments

Comments
 (0)