com php-src: Added support for glob symbols in blacklist entries (?, *, **): NEWS ext/opcache/tests/blacklis t.inc ext/opcache/tests/blacklist.phpt
ext/opcache/test s/opcache-2.blacklist ext/opcache/zend_accelerator_bl acklist.c

From: Date: Tue, 30 Jul 2013 23:01:19 +0000
Subject: com php-src: Added support for glob symbols in blacklist entries (?, *, **): NEWS ext/opcache/tests/blacklis t.inc ext/opcache/tests/blacklist.phpt
ext/opcache/test s/opcache-2.blacklist ext/opcache/zend_accelerator_bl acklist.c
Groups: php.cvs 
Request: Send a blank email to [email protected] to get a copy of this message
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));



Thread (1 message)

  • Dmitry Stogov
« previous php.cvs (#72775) next »