summaryrefslogtreecommitdiff
path: root/ext/opcache
diff options
context:
space:
mode:
authorOndřej Surý <ondrej@sury.org>2013-08-20 09:06:13 +0200
committerOndřej Surý <ondrej@sury.org>2013-08-20 09:06:13 +0200
commitbf4af35254bfff38b18848b86bb2bf7cf11085de (patch)
tree4357e214a9bbaea82dc6bd318cf2ddaa4c7ba01c /ext/opcache
parentd837b4550418036e76d6adb3c7dad94b1e3a5a6a (diff)
downloadphp-bf4af35254bfff38b18848b86bb2bf7cf11085de.tar.gz
New upstream version 5.5.2+dfsgupstream/5.5.2+dfsg
Diffstat (limited to 'ext/opcache')
-rw-r--r--ext/opcache/Optimizer/block_pass.c86
-rw-r--r--ext/opcache/Optimizer/pass1_5.c52
-rw-r--r--ext/opcache/Optimizer/zend_optimizer.c29
-rw-r--r--ext/opcache/README4
-rw-r--r--ext/opcache/ZendAccelerator.c16
-rw-r--r--ext/opcache/ZendAccelerator.h4
-rw-r--r--ext/opcache/config.m46
-rw-r--r--ext/opcache/tests/blacklist.inc3
-rw-r--r--ext/opcache/tests/blacklist.phpt16
-rw-r--r--ext/opcache/tests/opcache-2.blacklist5
-rw-r--r--ext/opcache/zend_accelerator_blacklist.c146
-rw-r--r--ext/opcache/zend_accelerator_module.c33
12 files changed, 317 insertions, 83 deletions
diff --git a/ext/opcache/Optimizer/block_pass.c b/ext/opcache/Optimizer/block_pass.c
index b8c381406..7f874e7a4 100644
--- a/ext/opcache/Optimizer/block_pass.c
+++ b/ext/opcache/Optimizer/block_pass.c
@@ -558,6 +558,52 @@ static void zend_rebuild_access_path(zend_cfg *cfg, zend_op_array *op_array, int
convert_to_string((v)); \
}
+static void strip_nop(zend_code_block *block)
+{
+ zend_op *opline = block->start_opline;
+ zend_op *end, *new_end;
+ int new_len = 0;
+
+ /* remove leading NOPs */
+ while (block->len > 0 && block->start_opline->opcode == ZEND_NOP) {
+ if (block->len == 1) {
+ /* this block is all NOPs, join with following block */
+ if (block->follow_to) {
+ delete_code_block(block);
+ }
+ return;
+ }
+ block->start_opline++;
+ block->start_opline_no++;
+ block->len--;
+ }
+
+ /* strip the inside NOPs */
+ opline = new_end = block->start_opline;
+ end = opline + block->len;
+
+ while (opline < end) {
+ zend_op *src;
+ int len = 0;
+
+ while (opline < end && opline->opcode == ZEND_NOP) {
+ opline++;
+ }
+ src = opline;
+
+ while (opline < end && opline->opcode != ZEND_NOP) {
+ opline++;
+ }
+ len = opline - src;
+
+ /* move up non-NOP opcodes */
+ memmove(new_end, src, len*sizeof(zend_op));
+
+ new_end += len;
+ }
+ block->len = new_end - block->start_opline;
+}
+
static void zend_optimize_block(zend_code_block *block, zend_op_array *op_array, char *used_ext TSRMLS_DC)
{
zend_op *opline = block->start_opline;
@@ -1168,45 +1214,7 @@ static void zend_optimize_block(zend_code_block *block, zend_op_array *op_array,
opline++;
}
- /* remove leading NOPs */
- while (block->len > 0 && block->start_opline->opcode == ZEND_NOP) {
- if (block->len == 1) {
- /* this block is all NOPs, join with following block */
- if (block->follow_to) {
- delete_code_block(block);
- }
- if (op_array->T) {
- efree(Tsource);
- }
- return;
- }
- block->start_opline++;
- block->start_opline_no++;
- block->len--;
- }
-
- /* strip the inside NOPs */
- opline = block->start_opline;
- end = opline + block->len;
- while (opline < end) {
- if (opline->opcode == ZEND_NOP) {
- zend_op *nop = opline + 1;
- int noplen;
- while (nop < end && nop->opcode == ZEND_NOP) {
- nop++;
- }
- noplen = nop-opline;
- if (nop < end) {
- /* move up non-NOP opcodes */
- memmove(opline, nop, (end-nop)*sizeof(zend_op));
- } else {
- /* all NOPs up to the end, do nothing */
- }
- block->len -= noplen;
- end = block->start_opline + block->len;
- }
- opline++;
- }
+ strip_nop(block);
if (op_array->T) {
efree(Tsource);
diff --git a/ext/opcache/Optimizer/pass1_5.c b/ext/opcache/Optimizer/pass1_5.c
index dc9e7319a..46406c383 100644
--- a/ext/opcache/Optimizer/pass1_5.c
+++ b/ext/opcache/Optimizer/pass1_5.c
@@ -388,6 +388,58 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) {
}
}
break;
+
+#if ZEND_EXTENSION_API_NO >= PHP_5_5_X_API_NO
+ case ZEND_FETCH_R:
+ case ZEND_FETCH_W:
+ case ZEND_FETCH_RW:
+ case ZEND_FETCH_FUNC_ARG:
+ case ZEND_FETCH_IS:
+ case ZEND_FETCH_UNSET:
+ if (opline != op_array->opcodes &&
+ (opline-1)->opcode == ZEND_BEGIN_SILENCE &&
+ (opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_LOCAL &&
+ opline->op1_type == IS_CONST &&
+ opline->op2_type == IS_UNUSED &&
+ Z_TYPE(ZEND_OP1_LITERAL(opline)) == IS_STRING &&
+ (Z_STRLEN(ZEND_OP1_LITERAL(opline)) != sizeof("this")-1 ||
+ memcmp(Z_STRVAL(ZEND_OP1_LITERAL(opline)), "this", sizeof("this")) != 0)) {
+
+ int var = opline->result.var;
+ int level = 0;
+ zend_op *op = opline + 1;
+
+ while (op < end) {
+ if (op->opcode == ZEND_BEGIN_SILENCE) {
+ level++;
+ } else if (op->opcode == ZEND_END_SILENCE) {
+ if (level == 0) {
+ break;
+ } else {
+ level--;
+ }
+ }
+ if (op->op1_type == IS_VAR && op->op1.var == var) {
+ op->op1_type = IS_CV;
+ op->op1.var = zend_optimizer_lookup_cv(op_array,
+ Z_STRVAL(ZEND_OP1_LITERAL(opline)),
+ Z_STRLEN(ZEND_OP1_LITERAL(opline)));
+ MAKE_NOP(opline);
+ break;
+ } else if (op->op2_type == IS_VAR && op->op2.var == var) {
+ op->op2_type = IS_CV;
+ op->op2.var = zend_optimizer_lookup_cv(op_array,
+ Z_STRVAL(ZEND_OP1_LITERAL(opline)),
+ Z_STRLEN(ZEND_OP1_LITERAL(opline)));
+ MAKE_NOP(opline);
+ break;
+ }
+ op++;
+ }
+ }
+ break;
+#endif
+
}
opline++;
i++;
diff --git a/ext/opcache/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c
index a6450ab5c..1f411d5da 100644
--- a/ext/opcache/Optimizer/zend_optimizer.c
+++ b/ext/opcache/Optimizer/zend_optimizer.c
@@ -28,6 +28,35 @@
#define OPTIMIZATION_LEVEL \
ZCG(accel_directives).optimization_level
+#if ZEND_EXTENSION_API_NO >= PHP_5_5_X_API_NO
+static int zend_optimizer_lookup_cv(zend_op_array *op_array, char* name, int name_len)
+{
+ int i = 0;
+ ulong hash_value = zend_inline_hash_func(name, name_len+1);
+
+ while (i < op_array->last_var) {
+ if (op_array->vars[i].name == name ||
+ (op_array->vars[i].hash_value == hash_value &&
+ op_array->vars[i].name_len == name_len &&
+ memcmp(op_array->vars[i].name, name, name_len) == 0)) {
+ return i;
+ }
+ i++;
+ }
+ i = op_array->last_var;
+ op_array->last_var++;
+ op_array->vars = erealloc(op_array->vars, op_array->last_var * sizeof(zend_compiled_variable));
+ if (IS_INTERNED(name)) {
+ op_array->vars[i].name = name;
+ } else {
+ op_array->vars[i].name = estrndup(name, name_len);
+ }
+ op_array->vars[i].name_len = name_len;
+ op_array->vars[i].hash_value = hash_value;
+ return i;
+}
+#endif
+
#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
int zend_optimizer_add_literal(zend_op_array *op_array, const zval *zv TSRMLS_DC)
{
diff --git a/ext/opcache/README b/ext/opcache/README
index 311001224..6c3cc746e 100644
--- a/ext/opcache/README
+++ b/ext/opcache/README
@@ -199,6 +199,10 @@ opcache.protect_memory (default "0")
Protect the shared memory from unexpected writing during script execution.
Useful for internal debugging only.
+opcache.restrict_api (default "")
+ Allows calling OPcache API functions only from PHP scripts which path is
+ started from specified string. The default "" means no restriction.
+
opcache.mmap_base
Mapping base of shared memory segments (for Windows only). All the PHP
processes have to map shared memory into the same address space. This
diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c
index f05798e04..b5474c050 100644
--- a/ext/opcache/ZendAccelerator.c
+++ b/ext/opcache/ZendAccelerator.c
@@ -2163,7 +2163,9 @@ static void accel_fast_zval_ptr_dtor(zval **zval_ptr)
case IS_CONSTANT_ARRAY: {
TSRMLS_FETCH();
+#if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO
GC_REMOVE_ZVAL_FROM_BUFFER(zvalue);
+#endif
if (zvalue->value.ht && (zvalue->value.ht != &EG(symbol_table))) {
/* break possible cycles */
Z_TYPE_P(zvalue) = IS_NULL;
@@ -2176,7 +2178,9 @@ static void accel_fast_zval_ptr_dtor(zval **zval_ptr)
{
TSRMLS_FETCH();
+#if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO
GC_REMOVE_ZVAL_FROM_BUFFER(zvalue);
+#endif
Z_OBJ_HT_P(zvalue)->del_ref(zvalue TSRMLS_CC);
}
break;
@@ -2652,12 +2656,9 @@ static void accel_free_ts_resources()
#endif
}
-static void accel_shutdown(zend_extension *extension)
+void accel_shutdown(TSRMLS_D)
{
zend_ini_entry *ini_entry;
- TSRMLS_FETCH();
-
- (void)extension; /* keep the compiler happy */
zend_accel_blacklist_shutdown(&accel_blacklist);
@@ -2675,6 +2676,11 @@ static void accel_shutdown(zend_extension *extension)
}
#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+# ifndef ZTS
+ zend_hash_clean(CG(function_table));
+ zend_hash_clean(CG(class_table));
+ zend_hash_clean(EG(zend_constants));
+# endif
CG(interned_strings_start) = orig_interned_strings_start;
CG(interned_strings_end) = orig_interned_strings_end;
zend_new_interned_string = orig_new_interned_string;
@@ -2764,7 +2770,7 @@ ZEND_EXT_API zend_extension zend_extension_entry = {
"http://www.zend.com/", /* URL */
"Copyright (c) 1999-2013", /* copyright */
accel_startup, /* startup */
- accel_shutdown, /* shutdown */
+ NULL, /* shutdown */
accel_activate, /* per-script activation */
accel_deactivate, /* per-script deactivation */
NULL, /* message handler */
diff --git a/ext/opcache/ZendAccelerator.h b/ext/opcache/ZendAccelerator.h
index 733e544e1..361b60b08 100644
--- a/ext/opcache/ZendAccelerator.h
+++ b/ext/opcache/ZendAccelerator.h
@@ -27,7 +27,7 @@
#endif
#define ACCELERATOR_PRODUCT_NAME "Zend OPcache"
-#define ACCELERATOR_VERSION "7.0.2-dev"
+#define ACCELERATOR_VERSION "7.0.3-dev"
/* 2 - added Profiler support, on 20010712 */
/* 3 - added support for Optimizer's encoded-only-files mode */
/* 4 - works with the new Optimizer, that supports the file format with licenses */
@@ -232,6 +232,7 @@ typedef struct _zend_accel_directives {
#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
long interned_strings_buffer;
#endif
+ char *restrict_api;
} zend_accel_directives;
typedef struct _zend_accel_globals {
@@ -316,6 +317,7 @@ extern zend_accel_globals accel_globals;
extern char *zps_api_failure_reason;
+void accel_shutdown(TSRMLS_D);
void zend_accel_schedule_restart(zend_accel_restart_reason reason TSRMLS_DC);
void zend_accel_schedule_restart_if_necessary(zend_accel_restart_reason reason TSRMLS_DC);
int zend_accel_invalidate(const char *filename, int filename_len, zend_bool force TSRMLS_DC);
diff --git a/ext/opcache/config.m4 b/ext/opcache/config.m4
index f9c38b1f7..1798fe13f 100644
--- a/ext/opcache/config.m4
+++ b/ext/opcache/config.m4
@@ -3,7 +3,7 @@ dnl $Id$
dnl
PHP_ARG_ENABLE(opcache, whether to enable Zend OPcache support,
-[ --enable-opcache Enable Zend OPcache support], yes)
+[ --enable-opcache Enable Zend OPcache support], yes)
if test "$PHP_OPCACHE" != "no"; then
@@ -357,7 +357,9 @@ extern int lock_file;
# endif
#endif
int main() { return 0; }
-], [], [AC_MSG_ERROR([Don't know how to define struct flock on this system[,] set --enable-opcache=no])], [])
+],
+[AC_MSG_RESULT([done])],
+[AC_MSG_ERROR([Don't know how to define struct flock on this system[,] set --enable-opcache=no])], [])
PHP_NEW_EXTENSION(opcache,
ZendAccelerator.c \
diff --git a/ext/opcache/tests/blacklist.inc b/ext/opcache/tests/blacklist.inc
new file mode 100644
index 000000000..a9db75141
--- /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 f4a34723a..57e4c306d 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 4f6580a77..575d9fab3 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 b09d0e54c..da83cfd31 100644
--- a/ext/opcache/zend_accelerator_blacklist.c
+++ b/ext/opcache/zend_accelerator_blacklist.c
@@ -30,6 +30,10 @@
# include "main/php_regex.h"
#endif
+#if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO
+# include "ext/standard/php_string.h"
+#endif
+
#ifdef ZEND_WIN32
# define REGEX_MODE (REG_EXTENDED|REG_NOSUB|REG_ICASE)
#else
@@ -86,9 +90,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 +100,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 +197,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 +243,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 +255,15 @@ 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)) {
+#if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO
+ blacklist_path_length = php_dirname(buf, strlen(buf));
+#else
+ blacklist_path_length = zend_dirname(buf, strlen(buf));
+#endif
+ blacklist_path = zend_strndup(buf, blacklist_path_length);
+ }
+
memset(buf, 0, sizeof(buf));
memset(real_path, 0, sizeof(real_path));
@@ -230,7 +300,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 +321,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 +331,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));
diff --git a/ext/opcache/zend_accelerator_module.c b/ext/opcache/zend_accelerator_module.c
index fa4e3d85b..f9ddaa98b 100644
--- a/ext/opcache/zend_accelerator_module.c
+++ b/ext/opcache/zend_accelerator_module.c
@@ -71,6 +71,21 @@ static zend_function_entry accel_functions[] = {
{ NULL, NULL, NULL, 0, 0 }
};
+static int validate_api_restriction(TSRMLS_D)
+{
+ if (ZCG(accel_directives).restrict_api && *ZCG(accel_directives).restrict_api) {
+ int len = strlen(ZCG(accel_directives).restrict_api);
+
+ if (!SG(request_info).path_translated ||
+ strlen(SG(request_info).path_translated) < len ||
+ memcmp(SG(request_info).path_translated, ZCG(accel_directives).restrict_api, len) != 0) {
+ zend_error(E_WARNING, ACCELERATOR_PRODUCT_NAME " API is restricted by \"restrict_api\" configuration directive");
+ return 0;
+ }
+ }
+ return 1;
+}
+
static ZEND_INI_MH(OnUpdateMemoryConsumption)
{
long *p;
@@ -251,6 +266,7 @@ ZEND_INI_BEGIN()
STD_PHP_INI_BOOLEAN("opcache.enable_file_override" , "0" , PHP_INI_SYSTEM, OnUpdateBool, accel_directives.file_override_enabled, zend_accel_globals, accel_globals)
STD_PHP_INI_BOOLEAN("opcache.enable_cli" , "0" , PHP_INI_SYSTEM, OnUpdateBool, accel_directives.enable_cli, zend_accel_globals, accel_globals)
STD_PHP_INI_ENTRY("opcache.error_log" , "" , PHP_INI_SYSTEM, OnUpdateString, accel_directives.error_log, zend_accel_globals, accel_globals)
+ STD_PHP_INI_ENTRY("opcache.restrict_api" , "" , PHP_INI_SYSTEM, OnUpdateString, accel_directives.restrict_api, zend_accel_globals, accel_globals)
#ifdef ZEND_WIN32
STD_PHP_INI_ENTRY("opcache.mmap_base", NULL, PHP_INI_SYSTEM, OnUpdateString, accel_directives.mmap_base, zend_accel_globals, accel_globals)
@@ -378,6 +394,7 @@ static ZEND_MSHUTDOWN_FUNCTION(zend_accelerator)
(void)type; /* keep the compiler happy */
UNREGISTER_INI_ENTRIES();
+ accel_shutdown(TSRMLS_C);
return SUCCESS;
}
@@ -516,6 +533,10 @@ static ZEND_FUNCTION(opcache_get_status)
return;
}
+ if (!validate_api_restriction(TSRMLS_C)) {
+ RETURN_FALSE;
+ }
+
if (!accel_startup_ok) {
RETURN_FALSE;
}
@@ -586,6 +607,10 @@ static ZEND_FUNCTION(opcache_get_configuration)
}
#endif
+ if (!validate_api_restriction(TSRMLS_C)) {
+ RETURN_FALSE;
+ }
+
array_init(return_value);
/* directives */
@@ -650,6 +675,10 @@ static ZEND_FUNCTION(opcache_reset)
}
#endif
+ if (!validate_api_restriction(TSRMLS_C)) {
+ RETURN_FALSE;
+ }
+
if (!ZCG(enabled) || !accel_startup_ok || !ZCSG(accelerator_enabled)) {
RETURN_FALSE;
}
@@ -670,6 +699,10 @@ static ZEND_FUNCTION(opcache_invalidate)
return;
}
+ if (!validate_api_restriction(TSRMLS_C)) {
+ RETURN_FALSE;
+ }
+
if (zend_accel_invalidate(script_name, script_name_len, force TSRMLS_CC) == SUCCESS) {
RETURN_TRUE;
} else {