Commit: 02409669e4201ec2cb90f1e6df316dddbe04561e
Author: Dmitry Stogov <[email protected]> Wed, 31 Jul 2013 03:01:19 +0400
Parents: cb17c9951182690b75f57cdf1707609a8478af6f
Branches: PHP-5.5 master
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=02409669e4201ec2cb90f1e6df316dddbe04561e
Log:
Added support for glob symbols in blacklist entries (?, *, **)
Changed paths:
M NEWS
A ext/opcache/tests/blacklist.inc
M ext/opcache/tests/blacklist.phpt
M ext/opcache/tests/opcache-2.blacklist
M ext/opcache/zend_accelerator_blacklist.c
Diff:
diff --git a/NEWS b/NEWS
index d21126d..60b2760 100644
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,8 @@ PHP NEWS
limited case). (Arpad)
- OPcahce:
+ . Added support for glob symbols in blacklist entries (?, *, **).
+ (Terry Elison, Dmitry)
. Fixed bug #65338 (Enabling both php_opcache and php_wincache AVs on
shutdown).. (Dmitry)
diff --git a/ext/opcache/tests/blacklist.inc b/ext/opcache/tests/blacklist.inc
new file mode 100644
index 0000000..a9db751
--- /dev/null
+++ b/ext/opcache/tests/blacklist.inc
@@ -0,0 +1,3 @@
+<?php
+ echo "ok\n";
+?>
diff --git a/ext/opcache/tests/blacklist.phpt b/ext/opcache/tests/blacklist.phpt
index f4a3472..57e4c30 100644
--- a/ext/opcache/tests/blacklist.phpt
+++ b/ext/opcache/tests/blacklist.phpt
@@ -9,7 +9,13 @@ opcache.blacklist_filename={PWD}/opcache-*.blacklist
--FILE--
<?php
$conf = opcache_get_configuration();
-print_r($conf['blacklist']);
+$conf = $conf['blacklist'];
+$conf[3] = preg_replace("!^\\Q".dirname(__FILE__)."\\E!", "__DIR__",
$conf[3]);
+$conf[4] = preg_replace("!^\\Q".dirname(__FILE__)."\\E!", "__DIR__",
$conf[4]);
+print_r($conf);
+include("blacklist.inc");
+$status = opcache_get_status();
+print_r(count($status['scripts']));
?>
--EXPECT--
Array
@@ -17,4 +23,10 @@ Array
[0] => /path/to/foo
[1] => /path/to/foo2
[2] => /path/to/bar
-)
\ No newline at end of file
+ [3] => __DIR__/blacklist.inc
+ [4] => __DIR__/current.php
+ [5] => /tmp/path/?nocache.inc
+ [6] => /tmp/path/*/somedir
+)
+ok
+1
diff --git a/ext/opcache/tests/opcache-2.blacklist b/ext/opcache/tests/opcache-2.blacklist
index 4f6580a..575d9fa 100644
--- a/ext/opcache/tests/opcache-2.blacklist
+++ b/ext/opcache/tests/opcache-2..blacklist
@@ -1 +1,6 @@
/path/to/bar
+; wildcard and relative entires
+blacklist.inc
+./current.php
+/tmp/path/?nocache.inc
+/tmp/path/*/somedir
diff --git a/ext/opcache/zend_accelerator_blacklist.c b/ext/opcache/zend_accelerator_blacklist.c
index b09d0e5..b11d41e 100644
--- a/ext/opcache/zend_accelerator_blacklist.c
+++ b/ext/opcache/zend_accelerator_blacklist.c
@@ -86,9 +86,9 @@ static void blacklist_report_regexp_error(regex_t *comp_regex, int reg_err)
static void zend_accel_blacklist_update_regexp(zend_blacklist *blacklist)
{
- char *regexp;
- int i, j, clen, reg_err, end = 0, rlen = 6;
+ int i, reg_err;
zend_regexp_list **regexp_list_it, *it;
+ char regexp[12*1024], *p, *end, *c, *backtrack = NULL;
if (blacklist->pos == 0) {
/* we have no blacklist to talk about */
@@ -96,36 +96,91 @@ static void zend_accel_blacklist_update_regexp(zend_blacklist *blacklist)
}
regexp_list_it = &(blacklist->regexp_list);
- for (i = 0; i < blacklist->pos; i++) {
- rlen += blacklist->entries[i].path_length * 2 + 2;
- /* don't create a regexp buffer bigger than 12K)*/
- if ((i + 1 == blacklist->pos) || ((rlen + blacklist->entries[i + 1].path_length * 2 + 2)
> (12 * 1024))) {
- regexp = (char *)malloc(rlen);
- if (!regexp) {
- zend_accel_error(ACCEL_LOG_ERROR, "malloc() failed\n");
- return;
+ regexp[0] = '^';
+ regexp[1] = '(';
+ p = regexp + 2;
+ end = regexp + sizeof(regexp) - sizeof("[^\\\\]*)\0");
+
+ for (i = 0; i < blacklist->pos; ) {
+ c = blacklist->entries[i].path;
+ if (p + blacklist->entries[i].path_length < end) {
+ while (*c && p < end) {
+ switch (*c) {
+ case '?':
+ c++;
+#ifdef ZEND_WIN32
+ p[0] = '['; /* * => [^\\] on Win32 */
+ p[1] = '^';
+ p[2] = '\\';
+ p[3] = '\\';
+ p[4] = ']';
+ p += 5;
+#else
+ p[0] = '['; /* * => [^/] on *nix */
+ p[1] = '^';
+ p[2] = '/';
+ p[3] = ']';
+ p += 4;
+#endif
+ break;
+ case '*':
+ c++;
+ if (*c == '*') {
+ c++;
+ p[0] = '.'; /* ** => .* */
+ p[1] = '*';
+ p += 2;
+ } else {
+#ifdef ZEND_WIN32
+ p[0] = '['; /* * => [^\\]* on Win32 */
+ p[1] = '^';
+ p[2] = '\\';
+ p[3] = '\\';
+ p[4] = ']';
+ p[5] = '*';
+ p += 6;
+#else
+ p[0] = '['; /* * => [^/]* on *nix */
+ p[1] = '^';
+ p[2] = '/';
+ p[3] = ']';
+ p[4] = '*';
+ p += 5;
+#endif
+ }
+ break;
+ case '^':
+ case '.':
+ case '[':
+ case ']':
+ case '$':
+ case '(':
+ case ')':
+ case '|':
+ case '+':
+ case '{':
+ case '}':
+ case '\\':
+ *p++ = '\\';
+ /* break missing intentionally */
+ default:
+ *p++ = *c++;
+ }
}
- regexp[0] = '^';
- regexp[1] = '(';
-
- clen = 2;
- for (j = end; j <= i; j++) {
+ }
- int c;
- if (j != end) {
- regexp[clen++] = '|';
- }
- /* copy mangled filename */
- for (c = 0; c < blacklist->entries[j]..path_length; c++) {
- if (strchr("^.[]$()|*+?{}\\", blacklist->entries[j].path[c])) {
- regexp[clen++] = '\\';
- }
- regexp[clen++] = blacklist->entries[j].path[c];
+ if (*c || i == blacklist->pos - 1) {
+ if (*c) {
+ if (!backtrack) {
+ zend_accel_error(ACCEL_LOG_ERROR, "Too long blacklist entry\n");
}
+ p = backtrack;
+ } else {
+ i++;
}
- regexp[clen++] = ')';
- regexp[clen] = '\0';
+ *p++ = ')';
+ *p++ = '\0';
it = (zend_regexp_list*)malloc(sizeof(zend_regexp_list));
if (!it) {
@@ -138,11 +193,13 @@ static void zend_accel_blacklist_update_regexp(zend_blacklist *blacklist)
blacklist_report_regexp_error(&it->comp_regex, reg_err);
}
/* prepare for the next iteration */
- free(regexp);
- end = i + 1;
- rlen = 6;
+ p = regexp + 2;
*regexp_list_it = it;
regexp_list_it = &it->next;
+ } else {
+ backtrack = p;
+ *p++ = '|';
+ i++;
}
}
}
@@ -182,9 +239,9 @@ static void zend_accel_blacklist_loadone(zend_blacklist *blacklist, char *filena
void zend_accel_blacklist_load(zend_blacklist *blacklist, char *filename)
#endif
{
- char buf[MAXPATHLEN + 1], real_path[MAXPATHLEN + 1];
+ char buf[MAXPATHLEN + 1], real_path[MAXPATHLEN + 1], *blacklist_path = NULL;
FILE *fp;
- int path_length;
+ int path_length, blacklist_path_length;
TSRMLS_FETCH();
if ((fp = fopen(filename, "r")) == NULL) {
@@ -194,6 +251,11 @@ void zend_accel_blacklist_load(zend_blacklist *blacklist, char *filename)
zend_accel_error(ACCEL_LOG_DEBUG,"Loading blacklist file: '%s'", filename);
+ if (VCWD_REALPATH(filename, buf)) {
+ blacklist_path_length = zend_dirname(buf, strlen(buf));
+ blacklist_path = zend_strndup(buf, blacklist_path_length);
+ }
+
memset(buf, 0, sizeof(buf));
memset(real_path, 0, sizeof(real_path));
@@ -230,7 +292,11 @@ void zend_accel_blacklist_load(zend_blacklist *blacklist, char *filename)
}
path_dup = zend_strndup(pbuf, path_length);
- expand_filepath(path_dup, real_path TSRMLS_CC);
+ if (blacklist_path) {
+ expand_filepath_ex(path_dup, real_path, blacklist_path, blacklist_path_length TSRMLS_CC);
+ } else {
+ expand_filepath(path_dup, real_path TSRMLS_CC);
+ }
path_length = strlen(real_path);
free(path_dup);
@@ -247,6 +313,9 @@ void zend_accel_blacklist_load(zend_blacklist *blacklist, char *filename)
blacklist->pos++;
}
fclose(fp);
+ if (blacklist_path) {
+ free(blacklist_path);
+ }
zend_accel_blacklist_update_regexp(blacklist);
}
@@ -254,7 +323,8 @@ void zend_accel_blacklist_load(zend_blacklist *blacklist, char *filename)
void zend_accel_blacklist_load(zend_blacklist *blacklist, char *filename)
{
glob_t globbuf;
- int ret, i;
+ int ret;
+ unsigned int i;
memset(&globbuf, 0, sizeof(glob_t));