]> granicus.if.org Git - php/commitdiff
Added suppot for glob() wildcard matching in ffi.preload directive
authorDmitry Stogov <dmitry@zend.com>
Wed, 23 Oct 2019 14:18:11 +0000 (17:18 +0300)
committerRemi Collet <remi@php.net>
Thu, 24 Oct 2019 05:40:07 +0000 (07:40 +0200)
ext/ffi/ffi.c
ext/ffi/tests/303.phpt [new file with mode: 0644]
php.ini-development
php.ini-production

index e2476653f72f29982fd229cf23e385fe6e11ab72..ca6e7c4ef5233866002d3d2b1cb40db1f060ecb2 100644 (file)
 #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 (file)
index 0000000..756adbb
--- /dev/null
@@ -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!
index 3f0c90cfca8945436285ff94a21b06d774a627fa..f44c541a7a10446fb5d631938c760e600f2f7504 100644 (file)
@@ -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=
index 867de11c60d4e06ad9704633e873e5fdc1934a5b..b7f2536fd9926ab47e46ddfdc4d38d4e1cfcca67 100644 (file)
@@ -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=