From b1f755665993b7b98806b9e36de935b212e9765e Mon Sep 17 00:00:00 2001
From: jvoisin
Date: Sun, 17 Apr 2022 17:18:09 +0200
Subject: Fix dom-related test on Debian 11 on PHP7.4
---
src/tests/xxe/disable_xxe_dom_disabled.phpt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/tests/xxe/disable_xxe_dom_disabled.phpt b/src/tests/xxe/disable_xxe_dom_disabled.phpt
index 107171c..4a888ed 100644
--- a/src/tests/xxe/disable_xxe_dom_disabled.phpt
+++ b/src/tests/xxe/disable_xxe_dom_disabled.phpt
@@ -1,7 +1,7 @@
--TEST--
Disable XXE (feature enabled)
--SKIPIF--
-
+
= 80000) print "skip"; ?>
--INI--
sp.configuration_file={PWD}/config/disable_xxe.ini
--
cgit v1.3
From baff5856be20579908497dba99e1e3eb20080684 Mon Sep 17 00:00:00 2001
From: jvoisin
Date: Sun, 17 Apr 2022 17:33:51 +0200
Subject: Improve the portability of the php7 rules
---
config/default.rules | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/config/default.rules b/config/default.rules
index f6d8893..a19d678 100644
--- a/config/default.rules
+++ b/config/default.rules
@@ -49,8 +49,8 @@ sp.disable_function.function("putenv").param("setting").value_r("LD_").drop()
sp.disable_function.function("putenv").param("setting").value_r("GCONV_").drop()
# Since people are stupid enough to use `extract` on things like $_GET or $_POST, we might as well mitigate this vector
-sp.disable_function.function("extract").param("var_array").value_r("^_").drop()
-sp.disable_function.function("extract").param("extract_type").value("0").drop()
+sp.disable_function.function("extract").pos("0").value_r("^_").drop()
+sp.disable_function.function("extract").pos("1").value("0").drop()
# This is also burned:
# ini_set('open_basedir','..');chdir('..');…;chdir('..');ini_set('open_basedir','/');echo(file_get_contents('/etc/passwd'));
@@ -71,7 +71,7 @@ sp.disable_function.function("include").drop()
# Prevent `system`-related injections
sp.disable_function.function("system").param("command").value_r("[$|;&`\\n\\(\\)\\\\]").drop();
-sp.disable_function.function("shell_exec").param("command").value_r("[$|;&`\\n\\(\\)\\\\]").drop();
+sp.disable_function.function("shell_exec").pos("0").value_r("[$|;&`\\n\\(\\)\\\\]").drop();
sp.disable_function.function("exec").param("command").value_r("[$|;&`\\n\\(\\)\\\\]").drop();
sp.disable_function.function("proc_open").param("command").value_r("[$|;&`\\n\\(\\)\\\\]").drop();
--
cgit v1.3
From 5b25788a81bf7ad233d99cf3f5e9ce3dcc5e8602 Mon Sep 17 00:00:00 2001
From: jvoisin
Date: Mon, 2 May 2022 22:36:53 +0200
Subject: Add more tests for php8
---
.../deny_writable_execution_simulation.phpt | 1 -
.../config_disabled_functions_name_type_php8.ini | 1 +
...led_functions_param_str_representation_php8.ini | 1 +
.../disabled_functions_name_type_php8.phpt | 16 ++++++++++++++
...ed_functions_param_str_representation_php8.phpt | 25 ++++++++++++++++++++++
5 files changed, 43 insertions(+), 1 deletion(-)
create mode 100644 src/tests/disable_function/config/config_disabled_functions_name_type_php8.ini
create mode 100644 src/tests/disable_function/config/config_disabled_functions_param_str_representation_php8.ini
create mode 100644 src/tests/disable_function/disabled_functions_name_type_php8.phpt
create mode 100644 src/tests/disable_function/disabled_functions_param_str_representation_php8.phpt
diff --git a/src/tests/deny_writable/deny_writable_execution_simulation.phpt b/src/tests/deny_writable/deny_writable_execution_simulation.phpt
index 1118dc0..e3460e4 100644
--- a/src/tests/deny_writable/deny_writable_execution_simulation.phpt
+++ b/src/tests/deny_writable/deny_writable_execution_simulation.phpt
@@ -1,7 +1,6 @@
--TEST--
Readonly execution attempt (simulation mode)
--SKIPIF--
-= 80000) print "skip"; ?>
+
+--INI--
+sp.configuration_file={PWD}/config/config_disabled_functions_name_type_php8.ini
+--FILE--
+
+--EXPECTF--
+0
+
+Fatal error: [snuffleupagus][0.0.0.0][disabled_function][drop] Aborted execution on call of the function 'strcmp', because its argument '$string1' content (?) matched a rule in %s/disabled_functions_name_type_php8.php on line 3
diff --git a/src/tests/disable_function/disabled_functions_param_str_representation_php8.phpt b/src/tests/disable_function/disabled_functions_param_str_representation_php8.phpt
new file mode 100644
index 0000000..c06e612
--- /dev/null
+++ b/src/tests/disable_function/disabled_functions_param_str_representation_php8.phpt
@@ -0,0 +1,25 @@
+--TEST--
+Disable functions - casting various types to string internally in php8
+--SKIPIF--
+
+--INI--
+sp.configuration_file={PWD}/config/config_disabled_functions_param_str_representation_php8.ini
+--FILE--
+
+--EXPECTF--
+true
+false
+NULL
+1
+1.0
+123
--
cgit v1.3
From efcc16ad74a32d4b735bad73690c49c5cdb63cb7 Mon Sep 17 00:00:00 2001
From: jvoisin
Date: Tue, 3 May 2022 00:04:50 +0200
Subject: Add a `const`
---
src/sp_config.c | 4 ++--
src/sp_config.h | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/sp_config.c b/src/sp_config.c
index 7294b0e..5431eca 100644
--- a/src/sp_config.c
+++ b/src/sp_config.c
@@ -65,10 +65,10 @@ zend_result sp_parse_config(const char *filename) {
}
-zend_result sp_process_rule(sp_parsed_keyword *parsed_rule, sp_config_keyword *config_keywords) {
+zend_result sp_process_rule(sp_parsed_keyword *parsed_rule, const sp_config_keyword *config_keywords) {
for (sp_parsed_keyword *kw = parsed_rule; kw->kw; kw++) {
bool found_kw = false;
- for (sp_config_keyword *ckw = config_keywords; ckw->func; ckw++) {
+ for (const sp_config_keyword *ckw = config_keywords; ckw->func; ckw++) {
if (kw->kwlen == strlen(ckw->token) && !strncmp(kw->kw, ckw->token, kw->kwlen)) {
if (ckw->func) {
int ret = ckw->func(ckw->token, kw, ckw->retval);
diff --git a/src/sp_config.h b/src/sp_config.h
index 6d48240..87710a0 100644
--- a/src/sp_config.h
+++ b/src/sp_config.h
@@ -269,7 +269,7 @@ typedef struct {
#define SP_TOKEN_LIST "list"
-zend_result sp_process_rule(sp_parsed_keyword *parsed_rule, sp_config_keyword *config_keywords);
+zend_result sp_process_rule(sp_parsed_keyword *parsed_rule, const sp_config_keyword *config_keywords);
zend_result sp_parse_config(const char *filename);
--
cgit v1.3
From 3132434447990f24516fb196b3fcf7771895a17b Mon Sep 17 00:00:00 2001
From: jvoisin
Date: Tue, 3 May 2022 00:07:15 +0200
Subject: Help the compiler to optimize sp_do_hash_hmac_sha256 a more
---
src/sp_unserialize.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/sp_unserialize.c b/src/sp_unserialize.c
index 2e7c173..64cf1b5 100644
--- a/src/sp_unserialize.c
+++ b/src/sp_unserialize.c
@@ -8,7 +8,7 @@ static inline void *php_hash_alloc_context(const php_hash_ops *ops) {
}
#endif
-static zend_string *sp_do_hash_hmac_sha256(char *data, size_t data_len, char *key, size_t key_len)
+static zend_string *sp_do_hash_hmac_sha256(char* restrict data, size_t data_len, char* restrict key, size_t key_len)
{
#if PHP_VERSION_ID < 80000
const php_hash_ops *ops = php_hash_fetch_ops(ZEND_STRL("sha256"));
--
cgit v1.3
From 9b11f4105eacc2af8828b65fd946e2b584cdee7e Mon Sep 17 00:00:00 2001
From: jvoisin
Date: Tue, 3 May 2022 00:12:47 +0200
Subject: Speed up a tiny bit `sp_parse_var`
---
src/sp_var_parser.c | 6 +++---
src/sp_var_parser.h | 2 +-
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/sp_var_parser.c b/src/sp_var_parser.c
index 2639991..e7ff766 100644
--- a/src/sp_var_parser.c
+++ b/src/sp_var_parser.c
@@ -245,15 +245,15 @@ static sp_tree *parse_tokens(const char *restrict str,
}
sp_tree *sp_parse_var(const char *line) {
- sp_list_node *tokens_list = NULL;
- sp_tree *tree = NULL;
- const sp_conf_token delimiter_list[] = {
+ static const sp_conf_token delimiter_list[] = {
{.type = OBJECT, .text_repr = OBJECT_TOKEN},
{.type = ARRAY, .text_repr = ARRAY_TOKEN},
{.type = ARRAY_END, .text_repr = ARRAY_END_TOKEN},
{.type = INTERPRETED_STRING, .text_repr = STRING_TOKEN},
{.type = LITERAL_STRING, .text_repr = ESC_STRING_TOKEN},
{.type = CLASS, .text_repr = CLASS_TOKEN}};
+ sp_list_node *tokens_list = NULL;
+ sp_tree *tree = NULL;
if (!line) {
return NULL;
diff --git a/src/sp_var_parser.h b/src/sp_var_parser.h
index 6d53691..c2981a3 100644
--- a/src/sp_var_parser.h
+++ b/src/sp_var_parser.h
@@ -4,7 +4,7 @@
typedef struct sp_token_s {
elem_type type;
- char *text_repr;
+ const char *text_repr;
size_t pos;
} sp_conf_token;
--
cgit v1.3
From 04633d1384edf4fc80be626c29e5f848b17a78bf Mon Sep 17 00:00:00 2001
From: jvoisin
Date: Tue, 3 May 2022 00:23:49 +0200
Subject: Constify a bit sp_var_value.c
---
src/sp_var_value.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/src/sp_var_value.c b/src/sp_var_value.c
index fe37f99..c9e5ade 100644
--- a/src/sp_var_value.c
+++ b/src/sp_var_value.c
@@ -111,7 +111,7 @@ static void *get_entry_hashtable(const HashTable *const ht,
static zval *get_array_value(zend_execute_data *ed, const zval *const zvalue,
const sp_tree *const tree) {
- zval *idx_value = sp_get_var_value(ed, tree->idx, false);
+ const zval *const idx_value = sp_get_var_value(ed, tree->idx, false);
if (!zvalue || !idx_value) {
return NULL;
@@ -129,9 +129,8 @@ static zval *get_array_value(zend_execute_data *ed, const zval *const zvalue,
static zval *get_object_property(zend_execute_data *ed, zval *object,
const char *property, bool is_param) {
const char *const class_name = object->value.obj->ce->name->val;
- HashTable *array = Z_OBJPROP_P(object);
- zval *zvalue = NULL;
- const zval *property_val = get_var_value(ed, property, is_param);
+ const HashTable *const array = Z_OBJPROP_P(object);
+ const zval *const property_val = get_var_value(ed, property, is_param);
size_t len;
if (property_val) {
@@ -141,7 +140,7 @@ static zval *get_object_property(zend_execute_data *ed, zval *object,
property = Z_STRVAL_P(property_val);
}
}
- zvalue = get_entry_hashtable(array, property, strlen(property));
+ zval *zvalue = get_entry_hashtable(array, property, strlen(property));
// TODO do we want to log overflow?
if (!zvalue) {
len = strlen(property) + 4;
--
cgit v1.3
From f120adf586bfede2b5f1ab2d57ce3a8aa5341e77 Mon Sep 17 00:00:00 2001
From: jvoisin
Date: Tue, 3 May 2022 00:34:26 +0200
Subject: Even more const
---
src/sp_config_utils.c | 6 +++---
src/sp_config_utils.h | 2 +-
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/sp_config_utils.c b/src/sp_config_utils.c
index e93ef31..84b1f30 100644
--- a/src/sp_config_utils.c
+++ b/src/sp_config_utils.c
@@ -1,8 +1,8 @@
#include "php_snuffleupagus.h"
-sp_list_node *parse_functions_list(char *value) {
- static const char *sep = ">";
+sp_list_node *parse_functions_list(const char *const value) {
+ static const char *const sep = ">";
if (NULL == strchr(value, sep[0])) {
return NULL;
@@ -10,7 +10,7 @@ sp_list_node *parse_functions_list(char *value) {
sp_list_node *list = NULL;
char *tmp = strdup(value);
- char *function_name;
+ const char *function_name;
char *next_token = tmp;
while ((function_name = strtok_r(NULL, sep, &next_token))) {
list = sp_list_prepend(list, strdup(function_name));
diff --git a/src/sp_config_utils.h b/src/sp_config_utils.h
index 64817a0..a3a2c81 100644
--- a/src/sp_config_utils.h
+++ b/src/sp_config_utils.h
@@ -1,6 +1,6 @@
#ifndef SP_CONFIG_UTILS
#define SP_CONFIG_UTILS
-sp_list_node *parse_functions_list(char *value);
+sp_list_node *parse_functions_list(const char *const value);
#endif /* SP_CONFIG_UTILS */
--
cgit v1.3
From 71ac90cf806b9b69236d759f6fbda7076886a6f1 Mon Sep 17 00:00:00 2001
From: jvoisin
Date: Tue, 3 May 2022 00:36:36 +0200
Subject: Two more const
---
src/sp_disabled_functions.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/sp_disabled_functions.c b/src/sp_disabled_functions.c
index 95e19ad..2e659da 100644
--- a/src/sp_disabled_functions.c
+++ b/src/sp_disabled_functions.c
@@ -16,7 +16,7 @@ char* get_complete_function_path(zend_execute_data const* const execute_data) {
if (!execute_data) {
return NULL; // LCOV_EXCL_LINE
}
- zend_function *func = execute_data->func;
+ const zend_function *const func = execute_data->func;
if (!(func->common.function_name)) {
return NULL;
}
@@ -25,7 +25,7 @@ char* get_complete_function_path(zend_execute_data const* const execute_data) {
char* complete_path_function = NULL;
if ((func->type == ZEND_USER_FUNCTION || func->type == ZEND_INTERNAL_FUNCTION) && func->common.scope) {
- char const* class_name = ZSTR_VAL(func->common.scope->name);
+ const char *const class_name = ZSTR_VAL(func->common.scope->name);
const size_t len = strlen(class_name) + 2 + strlen(function_name) + 1;
complete_path_function = emalloc(len);
snprintf(complete_path_function, len, "%s::%s", class_name, function_name);
--
cgit v1.3
From af93172be680bb75ebdf23ff6533c53f587da18c Mon Sep 17 00:00:00 2001
From: jvoisin
Date: Tue, 3 May 2022 21:22:22 +0200
Subject: Small code formatting fix
---
src/snuffleupagus.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/snuffleupagus.c b/src/snuffleupagus.c
index ebb7f9c..06b93e1 100644
--- a/src/snuffleupagus.c
+++ b/src/snuffleupagus.c
@@ -426,7 +426,7 @@ static void dump_config() {
array_init(&arr_cookies);
sp_cookie *cookie;
- sp_list_node *p = SPCFG(cookie).cookies;
+ const sp_list_node *p = SPCFG(cookie).cookies;
for (; p; p = p->next) {
zval arr_cookie;
array_init(&arr_cookie);
@@ -610,7 +610,9 @@ static PHP_INI_MH(OnUpdateConfiguration) {
(PHP_VERSION_ID < 70400 && ts >= (time_t)1638745200L) ||
(PHP_VERSION_ID < 80000 && ts >= (time_t)1669590000L) ||
(PHP_VERSION_ID < 80100 && ts >= (time_t)1700953200L)) {
- sp_log_warn("End-of-Life Check", "Your PHP version '" PHP_VERSION "' is not officially mainained anymore. Please upgrade as soon as possible. - Note: This message can be switched off by setting 'sp.global.show_old_php_warning.disable();' in your rules file or by setting the environment variable SP_SKIP_OLD_PHP_CHECK=1.");
+ sp_log_warn("End-of-Life Check", "Your PHP version '" PHP_VERSION "' is not officially maintained anymore. " \
+ "Please upgrade as soon as possible. - Note: This message can be switched off by setting " \
+ "'sp.global.show_old_php_warning.disable();' in your rules file or by setting the environment variable SP_SKIP_OLD_PHP_CHECK=1.");
}
}
return SUCCESS;
--
cgit v1.3
From 7c2d1d7d2713c0fa6bda63c376baf25d9f3d712c Mon Sep 17 00:00:00 2001
From: jvoisin
Date: Tue, 3 May 2022 21:48:35 +0200
Subject: More const frenzy
---
src/sp_config.c | 11 +++++------
src/sp_config.h | 6 +++---
2 files changed, 8 insertions(+), 9 deletions(-)
diff --git a/src/sp_config.c b/src/sp_config.c
index 5431eca..d29247b 100644
--- a/src/sp_config.c
+++ b/src/sp_config.c
@@ -6,7 +6,7 @@
static zend_result sp_process_config_root(sp_parsed_keyword *parsed_rule) {
- sp_config_keyword sp_func[] = {
+ static const sp_config_keyword sp_func[] = {
{parse_unserialize, SP_TOKEN_UNSERIALIZE_HMAC, &(SPCFG(unserialize))},
{parse_enable, SP_TOKEN_HARDEN_RANDOM, &(SPCFG(random).enable)},
{parse_log_media, SP_TOKEN_LOG_MEDIA, &(SPCFG(log_media))},
@@ -29,7 +29,7 @@ static zend_result sp_process_config_root(sp_parsed_keyword *parsed_rule) {
return sp_process_rule(parsed_rule, sp_func);
}
-zend_result sp_parse_config(const char *filename) {
+zend_result sp_parse_config(const char *const filename) {
FILE *fd = fopen(filename, "rb");
if (fd == NULL) {
sp_log_err("config", "Could not open configuration file %s : %s", filename, strerror(errno));
@@ -65,7 +65,7 @@ zend_result sp_parse_config(const char *filename) {
}
-zend_result sp_process_rule(sp_parsed_keyword *parsed_rule, const sp_config_keyword *config_keywords) {
+zend_result sp_process_rule(sp_parsed_keyword *parsed_rule, const sp_config_keyword *const config_keywords) {
for (sp_parsed_keyword *kw = parsed_rule; kw->kw; kw++) {
bool found_kw = false;
for (const sp_config_keyword *ckw = config_keywords; ckw->func; ckw++) {
@@ -119,13 +119,12 @@ SP_PARSEKW_FN(parse_list) {
CHECK_DUPLICATE_KEYWORD(retval);
sp_list_node **list = retval;
- char *tok, *tmp;
SP_PARSE_ARG(value);
- tmp = ZSTR_VAL(value);
+ char* tmp = ZSTR_VAL(value);
while (1) {
- tok = strsep(&tmp, ",");
+ const char* const tok = strsep(&tmp, ",");
if (tok == NULL) {
break;
}
diff --git a/src/sp_config.h b/src/sp_config.h
index 87710a0..3d92f2f 100644
--- a/src/sp_config.h
+++ b/src/sp_config.h
@@ -176,7 +176,7 @@ typedef struct {
HashTable *entries; // ht of sp_ini_entry
} sp_config_ini;
-#define SP_PARSE_FN_(fname, kwvar) int fname(char *token, sp_parsed_keyword *kwvar, void *retval)
+#define SP_PARSE_FN_(fname, kwvar) int fname(char const *const token, sp_parsed_keyword *kwvar, void *retval)
#define SP_PARSE_FN(fname) SP_PARSE_FN_(fname, parsed_rule)
#define SP_PARSEKW_FN(fname) SP_PARSE_FN_(fname, kw)
@@ -269,9 +269,9 @@ typedef struct {
#define SP_TOKEN_LIST "list"
-zend_result sp_process_rule(sp_parsed_keyword *parsed_rule, const sp_config_keyword *config_keywords);
+zend_result sp_process_rule(sp_parsed_keyword *parsed_rule, const sp_config_keyword *const config_keywords);
-zend_result sp_parse_config(const char *filename);
+zend_result sp_parse_config(const char *const filename);
#define SP_PARSE_CHECK_ARG_EXISTS(value) \
if (!value) { \
--
cgit v1.3
From 5efe5f9274615cacd05206184fc9a1ab50c1d558 Mon Sep 17 00:00:00 2001
From: jvoisin
Date: Tue, 3 May 2022 22:09:57 +0200
Subject: Add another user to the list!
---
doc/source/papers.rst | 1 +
1 file changed, 1 insertion(+)
diff --git a/doc/source/papers.rst b/doc/source/papers.rst
index 3d043f0..eb63021 100644
--- a/doc/source/papers.rst
+++ b/doc/source/papers.rst
@@ -124,6 +124,7 @@ Notable users
- `AdwCleaner `__'s backend- a notorious anti-pup
- `Alertot `__ - a Chilean continuous web security monitoring company
- `NBS System `__ - a French hosting/security company and author of snuffleupagus
+- `Mangadex `__ - a major manga website
- `Net4All `__ - a Swiss hosting company
- `Oceanet Technology `__ - a French hosting company
- `SwissCenter `__ - a Swiss datacenter & web hosting company
--
cgit v1.3
From d6c78df6c1b54ffbb081d6679bb2eda0005c1dc7 Mon Sep 17 00:00:00 2001
From: jvoisin
Date: Fri, 6 May 2022 20:14:13 +0200
Subject: Snuffleupagus' parser is compatible with re2c 3
---
src/Makefile.frag | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Makefile.frag b/src/Makefile.frag
index e110544..454ba60 100644
--- a/src/Makefile.frag
+++ b/src/Makefile.frag
@@ -1,5 +1,5 @@
$(srcdir)/sp_config_scanner.c: $(srcdir)/sp_config_scanner.re
- if re2c -v |grep ' 2\.' 2>/dev/null; then \
+ if re2c -v |grep ' [23]\.' 2>/dev/null; then \
re2c -bc -o $@ $<; \
re2c --no-generation-date --no-version -bci -o $(srcdir)/sp_config_scanner.cached.c $<; \
else \
--
cgit v1.3
From 924144799f380863aa3b13f444f478eb81dcef6c Mon Sep 17 00:00:00 2001
From: jvoisin
Date: Fri, 6 May 2022 21:11:28 +0200
Subject: Another constify pass
---
src/sp_config_scanner.h | 6 +++---
src/sp_config_scanner.re | 13 +++++++------
2 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/src/sp_config_scanner.h b/src/sp_config_scanner.h
index 3284713..8ce1fb7 100644
--- a/src/sp_config_scanner.h
+++ b/src/sp_config_scanner.h
@@ -19,7 +19,7 @@ typedef struct {
} sp_parsed_keyword;
zend_result sp_config_scan(char *data, zend_result (*process_rule)(sp_parsed_keyword*));
-zend_string *sp_get_arg_string(sp_parsed_keyword *kw);
-zend_string *sp_get_textual_representation(sp_parsed_keyword *parsed_rule);
+zend_string *sp_get_arg_string(sp_parsed_keyword const *const kw);
+zend_string *sp_get_textual_representation(sp_parsed_keyword const *const parsed_rule);
-#endif
\ No newline at end of file
+#endif
diff --git a/src/sp_config_scanner.re b/src/sp_config_scanner.re
index d7c9884..9f1ac2b 100644
--- a/src/sp_config_scanner.re
+++ b/src/sp_config_scanner.re
@@ -7,7 +7,7 @@
#define cs_log_warning(fmt, ...) sp_log_warn("config", fmt, ##__VA_ARGS__)
-zend_string *sp_get_arg_string(sp_parsed_keyword *kw) {
+zend_string *sp_get_arg_string(sp_parsed_keyword const *const kw) {
if (!kw || !kw->arg) {
return NULL;
}
@@ -33,11 +33,10 @@ zend_string *sp_get_arg_string(sp_parsed_keyword *kw) {
return ret;
}
-zend_string *sp_get_textual_representation(sp_parsed_keyword *parsed_rule) {
+zend_string *sp_get_textual_representation(sp_parsed_keyword const *const parsed_rule) {
// a rule is "sp.keyword...keyword(arg);\0"
size_t len = 3; // sp + ;
- sp_parsed_keyword *kw;
- for (kw = parsed_rule; kw->kw; kw++) {
+ for (const sp_parsed_keyword *kw = parsed_rule; kw->kw; kw++) {
len++; // .
len += kw->kwlen;
if (kw->argtype == SP_ARGTYPE_EMPTY) {
@@ -47,10 +46,12 @@ zend_string *sp_get_textual_representation(sp_parsed_keyword *parsed_rule) {
len += kw->arglen;
}
}
+
zend_string *ret = zend_string_alloc(len, 1);
char *ptr = ZSTR_VAL(ret);
+
memcpy(ptr, "sp", 2); ptr += 2;
- for (kw = parsed_rule; kw->kw; kw++) {
+ for (const sp_parsed_keyword *kw = parsed_rule; kw->kw; kw++) {
*ptr++ = '.';
memcpy(ptr, kw->kw, kw->kwlen); ptr += kw->kwlen;
if (kw->argtype == SP_ARGTYPE_EMPTY || kw->argtype == SP_ARGTYPE_STR || kw->argtype == SP_ARGTYPE_UNKNOWN) {
@@ -322,4 +323,4 @@ zend_result sp_config_scan(char *data, zend_result (*process_rule)(sp_parsed_key
out:
zend_hash_destroy(&vars);
return ret;
-}
\ No newline at end of file
+}
--
cgit v1.3
From f2655b0339326fc9abfce20687a20a5cd7a9dd25 Mon Sep 17 00:00:00 2001
From: jvoisin
Date: Fri, 6 May 2022 21:15:56 +0200
Subject: Bump sp_config_scanner.cached.c
---
src/sp_config_scanner.cached.c | 1167 ++++++++++++++++++++--------------------
1 file changed, 584 insertions(+), 583 deletions(-)
diff --git a/src/sp_config_scanner.cached.c b/src/sp_config_scanner.cached.c
index 7617ebf..dfcf25f 100644
--- a/src/sp_config_scanner.cached.c
+++ b/src/sp_config_scanner.cached.c
@@ -14,7 +14,7 @@ enum YYCONDTYPE {
#define cs_log_warning(fmt, ...) sp_log_warn("config", fmt, ##__VA_ARGS__)
-zend_string *sp_get_arg_string(sp_parsed_keyword *kw) {
+zend_string *sp_get_arg_string(sp_parsed_keyword const *const kw) {
if (!kw || !kw->arg) {
return NULL;
}
@@ -40,11 +40,10 @@ zend_string *sp_get_arg_string(sp_parsed_keyword *kw) {
return ret;
}
-zend_string *sp_get_textual_representation(sp_parsed_keyword *parsed_rule) {
+zend_string *sp_get_textual_representation(sp_parsed_keyword const *const parsed_rule) {
// a rule is "sp.keyword...keyword(arg);\0"
size_t len = 3; // sp + ;
- sp_parsed_keyword *kw;
- for (kw = parsed_rule; kw->kw; kw++) {
+ for (const sp_parsed_keyword *kw = parsed_rule; kw->kw; kw++) {
len++; // .
len += kw->kwlen;
if (kw->argtype == SP_ARGTYPE_EMPTY) {
@@ -54,10 +53,12 @@ zend_string *sp_get_textual_representation(sp_parsed_keyword *parsed_rule) {
len += kw->arglen;
}
}
+
zend_string *ret = zend_string_alloc(len, 1);
char *ptr = ZSTR_VAL(ret);
+
memcpy(ptr, "sp", 2); ptr += 2;
- for (kw = parsed_rule; kw->kw; kw++) {
+ for (const sp_parsed_keyword *kw = parsed_rule; kw->kw; kw++) {
*ptr++ = '.';
memcpy(ptr, kw->kw, kw->kwlen); ptr += kw->kwlen;
if (kw->argtype == SP_ARGTYPE_EMPTY || kw->argtype == SP_ARGTYPE_STR || kw->argtype == SP_ARGTYPE_UNKNOWN) {
@@ -227,361 +228,361 @@ yyc_init:
};
yych = *YYCURSOR;
if (yybm[0+yych] & 8) {
- goto yy6;
+ goto yy4;
}
if (yych <= '#') {
if (yych <= '\n') {
- if (yych <= 0x00) goto yy2;
- if (yych <= 0x08) goto yy4;
- goto yy9;
+ if (yych <= 0x00) goto yy1;
+ if (yych <= 0x08) goto yy2;
+ goto yy5;
} else {
- if (yych == '\r') goto yy11;
- if (yych <= '"') goto yy4;
- goto yy12;
+ if (yych == '\r') goto yy6;
+ if (yych <= '"') goto yy2;
+ goto yy7;
}
} else {
if (yych <= '?') {
- if (yych == ';') goto yy12;
- goto yy4;
+ if (yych == ';') goto yy7;
+ goto yy2;
} else {
- if (yych <= '@') goto yy15;
- if (yych == 's') goto yy16;
- goto yy4;
+ if (yych <= '@') goto yy8;
+ if (yych == 's') goto yy9;
+ goto yy2;
}
}
-yy2:
+yy1:
++YYCURSOR;
{ ret = SUCCESS; goto out; }
-yy4:
+yy2:
++YYCURSOR;
-yy5:
+yy3:
{ cs_log_error("Parser error on line %d", lineno); goto out; }
-yy6:
+yy4:
yych = *++YYCURSOR;
if (yybm[0+yych] & 8) {
- goto yy6;
+ goto yy4;
}
{ goto yyc_init; }
-yy9:
+yy5:
++YYCURSOR;
{ lineno++; goto yyc_init; }
-yy11:
+yy6:
yych = *++YYCURSOR;
- if (yych == '\n') goto yy9;
- goto yy5;
-yy12:
+ if (yych == '\n') goto yy5;
+ goto yy3;
+yy7:
yych = *++YYCURSOR;
if (yybm[0+yych] & 16) {
- goto yy12;
+ goto yy7;
}
{ goto yyc_init; }
-yy15:
+yy8:
yyaccept = 0;
yych = *(YYMARKER = ++YYCURSOR);
switch (yych) {
- case 'c': goto yy17;
- case 'e': goto yy19;
- case 'i': goto yy20;
- case 'l': goto yy21;
- case 's': goto yy22;
- case 'w': goto yy23;
- default: goto yy5;
+ case 'c': goto yy10;
+ case 'e': goto yy12;
+ case 'i': goto yy13;
+ case 'l': goto yy14;
+ case 's': goto yy15;
+ case 'w': goto yy16;
+ default: goto yy3;
}
-yy16:
+yy9:
yyaccept = 0;
yych = *(YYMARKER = ++YYCURSOR);
- if (yych == 'e') goto yy24;
- if (yych == 'p') goto yy25;
- goto yy5;
-yy17:
+ if (yych == 'e') goto yy17;
+ if (yych == 'p') goto yy18;
+ goto yy3;
+yy10:
yych = *++YYCURSOR;
- if (yych == 'o') goto yy27;
-yy18:
+ if (yych == 'o') goto yy19;
+yy11:
YYCURSOR = YYMARKER;
if (yyaccept <= 4) {
if (yyaccept <= 2) {
if (yyaccept <= 1) {
if (yyaccept == 0) {
- goto yy5;
+ goto yy3;
} else {
yyt2 = YYCURSOR;
- goto yy67;
+ goto yy54;
}
} else {
yyt2 = YYCURSOR;
- goto yy71;
+ goto yy57;
}
} else {
if (yyaccept == 3) {
- goto yy67;
+ goto yy54;
} else {
- goto yy71;
+ goto yy57;
}
}
} else {
if (yyaccept <= 6) {
if (yyaccept == 5) {
yyt2 = YYCURSOR;
- goto yy86;
+ goto yy69;
} else {
yyt4 = YYCURSOR;
- goto yy91;
+ goto yy73;
}
} else {
if (yyaccept == 7) {
- goto yy86;
+ goto yy69;
} else {
- goto yy91;
+ goto yy73;
}
}
}
+yy12:
+ yych = *++YYCURSOR;
+ if (yych == 'n') goto yy20;
+ if (yych == 'r') goto yy21;
+ goto yy11;
+yy13:
+ yych = *++YYCURSOR;
+ if (yych == 'n') goto yy22;
+ goto yy11;
+yy14:
+ yych = *++YYCURSOR;
+ if (yych == 'o') goto yy23;
+ goto yy11;
+yy15:
+ yych = *++YYCURSOR;
+ if (yych == 'e') goto yy17;
+ goto yy11;
+yy16:
+ yych = *++YYCURSOR;
+ if (yych == 'a') goto yy24;
+ goto yy11;
+yy17:
+ yych = *++YYCURSOR;
+ if (yych == 't') goto yy25;
+ goto yy11;
+yy18:
+ ++YYCURSOR;
+ { kw_i = 0; goto yyc_rule; }
yy19:
yych = *++YYCURSOR;
- if (yych == 'n') goto yy28;
- if (yych == 'r') goto yy29;
- goto yy18;
+ if (yych == 'n') goto yy26;
+ goto yy11;
yy20:
yych = *++YYCURSOR;
- if (yych == 'n') goto yy30;
- goto yy18;
+ if (yych == 'd') goto yy27;
+ goto yy11;
yy21:
yych = *++YYCURSOR;
- if (yych == 'o') goto yy31;
- goto yy18;
+ if (yych == 'r') goto yy28;
+ goto yy11;
yy22:
yych = *++YYCURSOR;
- if (yych == 'e') goto yy24;
- goto yy18;
+ if (yych == 'f') goto yy29;
+ goto yy11;
yy23:
yych = *++YYCURSOR;
- if (yych == 'a') goto yy32;
- goto yy18;
+ if (yych == 'g') goto yy30;
+ goto yy11;
yy24:
yych = *++YYCURSOR;
- if (yych == 't') goto yy33;
- goto yy18;
+ if (yych == 'r') goto yy31;
+ goto yy11;
yy25:
- ++YYCURSOR;
- { kw_i = 0; goto yyc_rule; }
+ yych = *++YYCURSOR;
+ if (yych == '\t') goto yy32;
+ if (yych == ' ') goto yy32;
+ goto yy11;
+yy26:
+ yych = *++YYCURSOR;
+ if (yych == 'd') goto yy33;
+ goto yy11;
yy27:
yych = *++YYCURSOR;
- if (yych == 'n') goto yy34;
- goto yy18;
+ if (yych == '_') goto yy34;
+ goto yy11;
yy28:
yych = *++YYCURSOR;
- if (yych == 'd') goto yy35;
- goto yy18;
+ if (yych == '"') goto yy11;
+ if (yych == 'o') goto yy37;
+ goto yy36;
yy29:
yych = *++YYCURSOR;
- if (yych == 'r') goto yy36;
- goto yy18;
+ if (yych != 'o') goto yy11;
yy30:
yych = *++YYCURSOR;
- if (yych == 'f') goto yy37;
- goto yy18;
+ if (yych == '"') goto yy11;
+ goto yy39;
yy31:
yych = *++YYCURSOR;
- if (yych == 'g') goto yy38;
- goto yy18;
+ if (yych == 'n') goto yy40;
+ goto yy11;
yy32:
- yych = *++YYCURSOR;
- if (yych == 'r') goto yy39;
- goto yy18;
-yy33:
- yych = *++YYCURSOR;
- if (yych == '\t') goto yy40;
- if (yych == ' ') goto yy40;
- goto yy18;
-yy34:
- yych = *++YYCURSOR;
- if (yych == 'd') goto yy42;
- goto yy18;
-yy35:
- yych = *++YYCURSOR;
- if (yych == '_') goto yy43;
- goto yy18;
-yy36:
- yych = *++YYCURSOR;
- if (yych == '"') goto yy18;
- if (yych == 'o') goto yy46;
- goto yy45;
-yy37:
- yych = *++YYCURSOR;
- if (yych != 'o') goto yy18;
-yy38:
- yych = *++YYCURSOR;
- if (yych == '"') goto yy18;
- goto yy48;
-yy39:
- yych = *++YYCURSOR;
- if (yych == 'n') goto yy49;
- goto yy18;
-yy40:
yych = *++YYCURSOR;
if (yych <= '@') {
if (yych <= '\t') {
- if (yych <= 0x08) goto yy18;
- goto yy40;
+ if (yych <= 0x08) goto yy11;
+ goto yy32;
} else {
- if (yych == ' ') goto yy40;
- goto yy18;
+ if (yych == ' ') goto yy32;
+ goto yy11;
}
} else {
if (yych <= '_') {
if (yych <= 'Z') {
yyt1 = YYCURSOR;
- goto yy50;
+ goto yy41;
}
- if (yych <= '^') goto yy18;
+ if (yych <= '^') goto yy11;
yyt1 = YYCURSOR;
- goto yy50;
+ goto yy41;
} else {
- if (yych <= '`') goto yy18;
+ if (yych <= '`') goto yy11;
if (yych <= 'z') {
yyt1 = YYCURSOR;
- goto yy50;
+ goto yy41;
}
- goto yy18;
+ goto yy11;
}
}
-yy42:
+yy33:
yych = *++YYCURSOR;
- if (yych == 'i') goto yy52;
- goto yy18;
-yy43:
+ if (yych == 'i') goto yy42;
+ goto yy11;
+yy34:
yych = *++YYCURSOR;
- if (yych == 'c') goto yy53;
- goto yy18;
-yy44:
+ if (yych == 'c') goto yy43;
+ goto yy11;
+yy35:
yych = *++YYCURSOR;
-yy45:
+yy36:
if (yych <= 0x1F) {
- if (yych == '\t') goto yy44;
- goto yy18;
+ if (yych == '\t') goto yy35;
+ goto yy11;
} else {
- if (yych <= ' ') goto yy44;
+ if (yych <= ' ') goto yy35;
if (yych == '"') {
yyt1 = YYCURSOR;
- goto yy54;
+ goto yy44;
}
- goto yy18;
+ goto yy11;
}
-yy46:
+yy37:
yych = *++YYCURSOR;
- if (yych == 'r') goto yy56;
- goto yy18;
-yy47:
+ if (yych == 'r') goto yy45;
+ goto yy11;
+yy38:
yych = *++YYCURSOR;
-yy48:
+yy39:
if (yych <= 0x1F) {
- if (yych == '\t') goto yy47;
- goto yy18;
+ if (yych == '\t') goto yy38;
+ goto yy11;
} else {
- if (yych <= ' ') goto yy47;
+ if (yych <= ' ') goto yy38;
if (yych == '"') {
yyt1 = YYCURSOR;
- goto yy57;
+ goto yy46;
}
- goto yy18;
+ goto yy11;
}
-yy49:
+yy40:
yych = *++YYCURSOR;
- if (yych == '"') goto yy18;
- if (yych == 'i') goto yy61;
- goto yy60;
-yy50:
+ if (yych == '"') goto yy11;
+ if (yych == 'i') goto yy49;
+ goto yy48;
+yy41:
yych = *++YYCURSOR;
if (yybm[0+yych] & 32) {
- goto yy50;
+ goto yy41;
}
if (yych == '\t') {
yyt2 = YYCURSOR;
- goto yy62;
+ goto yy50;
}
if (yych == ' ') {
yyt2 = YYCURSOR;
- goto yy62;
+ goto yy50;
}
- goto yy18;
-yy52:
+ goto yy11;
+yy42:
yych = *++YYCURSOR;
- if (yych == 't') goto yy64;
- goto yy18;
-yy53:
+ if (yych == 't') goto yy51;
+ goto yy11;
+yy43:
yych = *++YYCURSOR;
- if (yych == 'o') goto yy65;
- goto yy18;
-yy54:
+ if (yych == 'o') goto yy52;
+ goto yy11;
+yy44:
yych = *++YYCURSOR;
if (yybm[0+yych] & 64) {
- goto yy54;
+ goto yy44;
}
- if (yych <= '\r') goto yy18;
- if (yych <= '"') goto yy66;
- goto yy68;
-yy56:
+ if (yych <= '\r') goto yy11;
+ if (yych <= '"') goto yy53;
+ goto yy55;
+yy45:
yych = *++YYCURSOR;
- if (yych == '"') goto yy18;
- goto yy45;
-yy57:
+ if (yych == '"') goto yy11;
+ goto yy36;
+yy46:
yych = *++YYCURSOR;
if (yych <= '\r') {
- if (yych == '\n') goto yy18;
- if (yych <= '\f') goto yy57;
- goto yy18;
+ if (yych == '\n') goto yy11;
+ if (yych <= '\f') goto yy46;
+ goto yy11;
} else {
if (yych <= '"') {
- if (yych <= '!') goto yy57;
- goto yy70;
+ if (yych <= '!') goto yy46;
+ goto yy56;
} else {
- if (yych == '\\') goto yy72;
- goto yy57;
+ if (yych == '\\') goto yy58;
+ goto yy46;
}
}
-yy59:
+yy47:
yych = *++YYCURSOR;
-yy60:
+yy48:
if (yych <= 0x1F) {
- if (yych == '\t') goto yy59;
- goto yy18;
+ if (yych == '\t') goto yy47;
+ goto yy11;
} else {
- if (yych <= ' ') goto yy59;
+ if (yych <= ' ') goto yy47;
if (yych == '"') {
yyt1 = YYCURSOR;
- goto yy74;
+ goto yy59;
}
- goto yy18;
+ goto yy11;
}
-yy61:
+yy49:
yych = *++YYCURSOR;
- if (yych == 'n') goto yy76;
- goto yy18;
-yy62:
+ if (yych == 'n') goto yy60;
+ goto yy11;
+yy50:
yych = *++YYCURSOR;
if (yych <= 0x1F) {
- if (yych == '\t') goto yy62;
- goto yy18;
+ if (yych == '\t') goto yy50;
+ goto yy11;
} else {
- if (yych <= ' ') goto yy62;
+ if (yych <= ' ') goto yy50;
if (yych == '"') {
yyt3 = YYCURSOR;
- goto yy77;
+ goto yy61;
}
- goto yy18;
+ goto yy11;
}
-yy64:
+yy51:
yych = *++YYCURSOR;
- if (yych == 'i') goto yy79;
- goto yy18;
-yy65:
+ if (yych == 'i') goto yy62;
+ goto yy11;
+yy52:
yych = *++YYCURSOR;
- if (yych == 'n') goto yy80;
- goto yy18;
-yy66:
+ if (yych == 'n') goto yy63;
+ goto yy11;
+yy53:
yych = *++YYCURSOR;
yyt2 = YYCURSOR;
- if (yych == ';') goto yy81;
-yy67:
+ if (yych == ';') goto yy64;
+yy54:
t1 = yyt1;
t2 = yyt2;
{
@@ -590,19 +591,19 @@ yy67:
cs_log_error("[line %d]: %s", lineno, tmpstr);
goto out;
}
-yy68:
+yy55:
yych = *++YYCURSOR;
if (yybm[0+yych] & 64) {
- goto yy54;
+ goto yy44;
}
- if (yych <= '\r') goto yy18;
- if (yych <= '"') goto yy82;
- goto yy68;
-yy70:
+ if (yych <= '\r') goto yy11;
+ if (yych <= '"') goto yy65;
+ goto yy55;
+yy56:
yych = *++YYCURSOR;
yyt2 = YYCURSOR;
- if (yych == ';') goto yy83;
-yy71:
+ if (yych == ';') goto yy66;
+yy57:
t1 = yyt1;
t2 = yyt2;
{
@@ -611,126 +612,126 @@ yy71:
cs_log_info("[line %d]: %s", lineno, tmpstr);
goto yyc_init;
}
-yy72:
+yy58:
yych = *++YYCURSOR;
if (yych <= '\r') {
- if (yych == '\n') goto yy18;
- if (yych <= '\f') goto yy57;
- goto yy18;
+ if (yych == '\n') goto yy11;
+ if (yych <= '\f') goto yy46;
+ goto yy11;
} else {
if (yych <= '"') {
- if (yych <= '!') goto yy57;
- goto yy84;
+ if (yych <= '!') goto yy46;
+ goto yy67;
} else {
- if (yych == '\\') goto yy72;
- goto yy57;
+ if (yych == '\\') goto yy58;
+ goto yy46;
}
}
-yy74:
+yy59:
yych = *++YYCURSOR;
if (yych <= '\r') {
- if (yych == '\n') goto yy18;
- if (yych <= '\f') goto yy74;
- goto yy18;
+ if (yych == '\n') goto yy11;
+ if (yych <= '\f') goto yy59;
+ goto yy11;
} else {
if (yych <= '"') {
- if (yych <= '!') goto yy74;
- goto yy85;
+ if (yych <= '!') goto yy59;
+ goto yy68;
} else {
- if (yych == '\\') goto yy87;
- goto yy74;
+ if (yych == '\\') goto yy70;
+ goto yy59;
}
}
-yy76:
+yy60:
yych = *++YYCURSOR;
- if (yych == 'g') goto yy89;
- goto yy18;
-yy77:
+ if (yych == 'g') goto yy71;
+ goto yy11;
+yy61:
yych = *++YYCURSOR;
if (yych <= '\r') {
- if (yych == '\n') goto yy18;
- if (yych <= '\f') goto yy77;
- goto yy18;
+ if (yych == '\n') goto yy11;
+ if (yych <= '\f') goto yy61;
+ goto yy11;
} else {
if (yych <= '"') {
- if (yych <= '!') goto yy77;
- goto yy90;
+ if (yych <= '!') goto yy61;
+ goto yy72;
} else {
- if (yych == '\\') goto yy92;
- goto yy77;
+ if (yych == '\\') goto yy74;
+ goto yy61;
}
}
-yy79:
+yy62:
yych = *++YYCURSOR;
- if (yych == 'o') goto yy94;
- goto yy18;
-yy80:
+ if (yych == 'o') goto yy75;
+ goto yy11;
+yy63:
yych = *++YYCURSOR;
- if (yych == 'd') goto yy95;
- goto yy18;
-yy81:
+ if (yych == 'd') goto yy76;
+ goto yy11;
+yy64:
++YYCURSOR;
- goto yy67;
-yy82:
+ goto yy54;
+yy65:
yyaccept = 1;
yych = *(YYMARKER = ++YYCURSOR);
if (yybm[0+yych] & 128) {
- goto yy68;
+ goto yy55;
}
if (yych <= '\r') {
if (yych == '\n') {
yyt2 = YYCURSOR;
- goto yy67;
+ goto yy54;
}
- if (yych <= '\f') goto yy54;
+ if (yych <= '\f') goto yy44;
yyt2 = YYCURSOR;
- goto yy67;
+ goto yy54;
} else {
if (yych <= '"') {
- if (yych <= '!') goto yy54;
- goto yy66;
+ if (yych <= '!') goto yy44;
+ goto yy53;
} else {
if (yych == ';') {
yyt2 = YYCURSOR;
- goto yy96;
+ goto yy77;
}
- goto yy54;
+ goto yy44;
}
}
-yy83:
+yy66:
++YYCURSOR;
- goto yy71;
-yy84:
+ goto yy57;
+yy67:
yyaccept = 2;
yych = *(YYMARKER = ++YYCURSOR);
if (yych <= '!') {
if (yych <= '\n') {
- if (yych <= '\t') goto yy57;
+ if (yych <= '\t') goto yy46;
yyt2 = YYCURSOR;
- goto yy71;
+ goto yy57;
} else {
if (yych == '\r') {
yyt2 = YYCURSOR;
- goto yy71;
+ goto yy57;
}
- goto yy57;
+ goto yy46;
}
} else {
if (yych <= ';') {
- if (yych <= '"') goto yy70;
- if (yych <= ':') goto yy57;
+ if (yych <= '"') goto yy56;
+ if (yych <= ':') goto yy46;
yyt2 = YYCURSOR;
- goto yy97;
+ goto yy78;
} else {
- if (yych == '\\') goto yy72;
- goto yy57;
+ if (yych == '\\') goto yy58;
+ goto yy46;
}
}
-yy85:
+yy68:
yych = *++YYCURSOR;
yyt2 = YYCURSOR;
- if (yych == ';') goto yy98;
-yy86:
+ if (yych == ';') goto yy79;
+yy69:
t1 = yyt1;
t2 = yyt2;
{
@@ -739,30 +740,30 @@ yy86:
cs_log_warning("[line %d]: %s", lineno, tmpstr);
goto yyc_init;
}
-yy87:
+yy70:
yych = *++YYCURSOR;
if (yych <= '\r') {
- if (yych == '\n') goto yy18;
- if (yych <= '\f') goto yy74;
- goto yy18;
+ if (yych == '\n') goto yy11;
+ if (yych <= '\f') goto yy59;
+ goto yy11;
} else {
if (yych <= '"') {
- if (yych <= '!') goto yy74;
- goto yy99;
+ if (yych <= '!') goto yy59;
+ goto yy80;
} else {
- if (yych == '\\') goto yy87;
- goto yy74;
+ if (yych == '\\') goto yy70;
+ goto yy59;
}
}
-yy89:
+yy71:
yych = *++YYCURSOR;
- if (yych == '"') goto yy18;
- goto yy60;
-yy90:
+ if (yych == '"') goto yy11;
+ goto yy48;
+yy72:
yych = *++YYCURSOR;
yyt4 = YYCURSOR;
- goto yy101;
-yy91:
+ goto yy82;
+yy73:
t1 = yyt1;
t2 = yyt2;
t3 = yyt3;
@@ -779,213 +780,213 @@ yy91:
zend_hash_str_add_ptr(&vars, key, keylen, tmp);
goto yyc_init;
}
-yy92:
+yy74:
yych = *++YYCURSOR;
if (yych <= '\r') {
- if (yych == '\n') goto yy18;
- if (yych <= '\f') goto yy77;
- goto yy18;
+ if (yych == '\n') goto yy11;
+ if (yych <= '\f') goto yy61;
+ goto yy11;
} else {
if (yych <= '"') {
- if (yych <= '!') goto yy77;
- goto yy103;
+ if (yych <= '!') goto yy61;
+ goto yy83;
} else {
- if (yych == '\\') goto yy92;
- goto yy77;
+ if (yych == '\\') goto yy74;
+ goto yy61;
}
}
-yy94:
+yy75:
yych = *++YYCURSOR;
- if (yych == 'n') goto yy104;
- goto yy18;
-yy95:
+ if (yych == 'n') goto yy84;
+ goto yy11;
+yy76:
yych = *++YYCURSOR;
- if (yych == 'i') goto yy105;
- goto yy18;
-yy96:
+ if (yych == 'i') goto yy85;
+ goto yy11;
+yy77:
yyaccept = 3;
yych = *(YYMARKER = ++YYCURSOR);
if (yybm[0+yych] & 64) {
- goto yy54;
+ goto yy44;
}
- if (yych <= '\r') goto yy67;
- if (yych <= '"') goto yy66;
- goto yy68;
-yy97:
+ if (yych <= '\r') goto yy54;
+ if (yych <= '"') goto yy53;
+ goto yy55;
+yy78:
yyaccept = 4;
yych = *(YYMARKER = ++YYCURSOR);
if (yych <= '\r') {
- if (yych == '\n') goto yy71;
- if (yych <= '\f') goto yy57;
- goto yy71;
+ if (yych == '\n') goto yy57;
+ if (yych <= '\f') goto yy46;
+ goto yy57;
} else {
if (yych <= '"') {
- if (yych <= '!') goto yy57;
- goto yy70;
+ if (yych <= '!') goto yy46;
+ goto yy56;
} else {
- if (yych == '\\') goto yy72;
- goto yy57;
+ if (yych == '\\') goto yy58;
+ goto yy46;
}
}
-yy98:
+yy79:
++YYCURSOR;
- goto yy86;
-yy99:
+ goto yy69;
+yy80:
yyaccept = 5;
yych = *(YYMARKER = ++YYCURSOR);
if (yych <= '!') {
if (yych <= '\n') {
- if (yych <= '\t') goto yy74;
+ if (yych <= '\t') goto yy59;
yyt2 = YYCURSOR;
- goto yy86;
+ goto yy69;
} else {
if (yych == '\r') {
yyt2 = YYCURSOR;
- goto yy86;
+ goto yy69;
}
- goto yy74;
+ goto yy59;
}
} else {
if (yych <= ';') {
- if (yych <= '"') goto yy85;
- if (yych <= ':') goto yy74;
+ if (yych <= '"') goto yy68;
+ if (yych <= ':') goto yy59;
yyt2 = YYCURSOR;
- goto yy106;
+ goto yy86;
} else {
- if (yych == '\\') goto yy87;
- goto yy74;
+ if (yych == '\\') goto yy70;
+ goto yy59;
}
}
-yy100:
+yy81:
yych = *++YYCURSOR;
-yy101:
+yy82:
if (yych <= 0x1F) {
- if (yych == '\t') goto yy100;
- goto yy91;
+ if (yych == '\t') goto yy81;
+ goto yy73;
} else {
- if (yych <= ' ') goto yy100;
- if (yych != ';') goto yy91;
+ if (yych <= ' ') goto yy81;
+ if (yych != ';') goto yy73;
}
++YYCURSOR;
- goto yy91;
-yy103:
+ goto yy73;
+yy83:
yyaccept = 6;
yych = *(YYMARKER = ++YYCURSOR);
if (yych <= ' ') {
if (yych <= '\n') {
- if (yych <= 0x08) goto yy77;
+ if (yych <= 0x08) goto yy61;
if (yych <= '\t') {
yyt4 = YYCURSOR;
- goto yy107;
+ goto yy87;
}
yyt4 = YYCURSOR;
- goto yy91;
+ goto yy73;
} else {
if (yych == '\r') {
yyt4 = YYCURSOR;
- goto yy91;
+ goto yy73;
}
- if (yych <= 0x1F) goto yy77;
+ if (yych <= 0x1F) goto yy61;
yyt4 = YYCURSOR;
- goto yy107;
+ goto yy87;
}
} else {
if (yych <= ':') {
- if (yych == '"') goto yy90;
- goto yy77;
+ if (yych == '"') goto yy72;
+ goto yy61;
} else {
if (yych <= ';') {
yyt4 = YYCURSOR;
- goto yy109;
+ goto yy88;
}
- if (yych == '\\') goto yy92;
- goto yy77;
+ if (yych == '\\') goto yy74;
+ goto yy61;
}
}
-yy104:
+yy84:
yych = *++YYCURSOR;
- if (yych == '\t') goto yy110;
- if (yych == ' ') goto yy110;
- goto yy18;
-yy105:
+ if (yych == '\t') goto yy89;
+ if (yych == ' ') goto yy89;
+ goto yy11;
+yy85:
yych = *++YYCURSOR;
- if (yych == 't') goto yy113;
- goto yy18;
-yy106:
+ if (yych == 't') goto yy90;
+ goto yy11;
+yy86:
yyaccept = 7;
yych = *(YYMARKER = ++YYCURSOR);
if (yych <= '\r') {
- if (yych == '\n') goto yy86;
- if (yych <= '\f') goto yy74;
- goto yy86;
+ if (yych == '\n') goto yy69;
+ if (yych <= '\f') goto yy59;
+ goto yy69;
} else {
if (yych <= '"') {
- if (yych <= '!') goto yy74;
- goto yy85;
+ if (yych <= '!') goto yy59;
+ goto yy68;
} else {
- if (yych == '\\') goto yy87;
- goto yy74;
+ if (yych == '\\') goto yy70;
+ goto yy59;
}
}
-yy107:
+yy87:
yyaccept = 8;
yych = *(YYMARKER = ++YYCURSOR);
if (yych <= ' ') {
if (yych <= '\n') {
- if (yych <= 0x08) goto yy77;
- if (yych <= '\t') goto yy107;
- goto yy91;
+ if (yych <= 0x08) goto yy61;
+ if (yych <= '\t') goto yy87;
+ goto yy73;
} else {
- if (yych == '\r') goto yy91;
- if (yych <= 0x1F) goto yy77;
- goto yy107;
+ if (yych == '\r') goto yy73;
+ if (yych <= 0x1F) goto yy61;
+ goto yy87;
}
} else {
if (yych <= ':') {
- if (yych == '"') goto yy90;
- goto yy77;
+ if (yych == '"') goto yy72;
+ goto yy61;
} else {
- if (yych <= ';') goto yy109;
- if (yych == '\\') goto yy92;
- goto yy77;
+ if (yych <= ';') goto yy88;
+ if (yych == '\\') goto yy74;
+ goto yy61;
}
}
-yy109:
+yy88:
yyaccept = 8;
yych = *(YYMARKER = ++YYCURSOR);
if (yych <= '\r') {
- if (yych == '\n') goto yy91;
- if (yych <= '\f') goto yy77;
- goto yy91;
+ if (yych == '\n') goto yy73;
+ if (yych <= '\f') goto yy61;
+ goto yy73;
} else {
if (yych <= '"') {
- if (yych <= '!') goto yy77;
- goto yy90;
+ if (yych <= '!') goto yy61;
+ goto yy72;
} else {
- if (yych == '\\') goto yy92;
- goto yy77;
+ if (yych == '\\') goto yy74;
+ goto yy61;
}
}
-yy110:
+yy89:
yych = *++YYCURSOR;
- if (yych == '\t') goto yy110;
- if (yych == ' ') goto yy110;
+ if (yych == '\t') goto yy89;
+ if (yych == ' ') goto yy89;
{ cond_res_i = 0; goto yyc_cond; }
-yy113:
+yy90:
yych = *++YYCURSOR;
- if (yych != 'i') goto yy18;
+ if (yych != 'i') goto yy11;
yych = *++YYCURSOR;
- if (yych != 'o') goto yy18;
+ if (yych != 'o') goto yy11;
yych = *++YYCURSOR;
- if (yych != 'n') goto yy18;
-yy116:
+ if (yych != 'n') goto yy11;
+yy91:
yych = *++YYCURSOR;
if (yych <= 0x1F) {
- if (yych == '\t') goto yy116;
- goto yy18;
+ if (yych == '\t') goto yy91;
+ goto yy11;
} else {
- if (yych <= ' ') goto yy116;
- if (yych != ';') goto yy18;
+ if (yych <= ' ') goto yy91;
+ if (yych != ';') goto yy11;
}
++YYCURSOR;
{ cond_res[0] = 1; cond_res_i = 0; goto yyc_init; }
@@ -1029,85 +1030,85 @@ yyc_cond:
};
yych = *YYCURSOR;
if (yybm[0+yych] & 8) {
- goto yy124;
+ goto yy95;
}
if (yych <= '(') {
if (yych <= '\r') {
- if (yych <= 0x08) goto yy122;
- if (yych <= '\n') goto yy127;
- if (yych >= '\r') goto yy129;
+ if (yych <= 0x08) goto yy93;
+ if (yych <= '\n') goto yy96;
+ if (yych >= '\r') goto yy97;
} else {
- if (yych <= 0x1F) goto yy122;
- if (yych <= '!') goto yy130;
- if (yych >= '(') goto yy132;
+ if (yych <= 0x1F) goto yy93;
+ if (yych <= '!') goto yy98;
+ if (yych >= '(') goto yy99;
}
} else {
if (yych <= 'Z') {
- if (yych <= '/') goto yy122;
+ if (yych <= '/') goto yy93;
if (yych <= '9') {
yyt1 = YYCURSOR;
- goto yy134;
+ goto yy100;
}
if (yych >= 'A') {
yyt1 = YYCURSOR;
- goto yy137;
+ goto yy101;
}
} else {
if (yych <= '_') {
if (yych >= '_') {
yyt1 = YYCURSOR;
- goto yy137;
+ goto yy101;
}
} else {
- if (yych <= '`') goto yy122;
+ if (yych <= '`') goto yy93;
if (yych <= 'z') {
yyt1 = YYCURSOR;
- goto yy137;
+ goto yy101;
}
}
}
}
-yy122:
+yy93:
++YYCURSOR;
-yy123:
+yy94:
{ cs_log_error("Syntax error in condition on line %d", lineno); goto out; }
-yy124:
+yy95:
yych = *++YYCURSOR;
if (yybm[0+yych] & 8) {
- goto yy124;
+ goto yy95;
}
{ goto yyc_cond; }
-yy127:
+yy96:
++YYCURSOR;
{ lineno++; goto yyc_cond; }
-yy129:
+yy97:
yych = *++YYCURSOR;
- if (yych == '\n') goto yy127;
- goto yy123;
-yy130:
+ if (yych == '\n') goto yy96;
+ goto yy94;
+yy98:
++YYCURSOR;
t1 = YYCURSOR - 1;
{ sy_op_push(*t1); goto yyc_cond; }
-yy132:
+yy99:
++YYCURSOR;
t1 = YYCURSOR - 1;
{ sy_op_push(*t1); goto yyc_cond; }
-yy134:
+yy100:
yych = *++YYCURSOR;
if (yybm[0+yych] & 16) {
- goto yy134;
+ goto yy100;
}
t1 = yyt1;
t2 = YYCURSOR;
{ sy_res_push(atoi(t1)); goto yyc_cond_op; }
-yy137:
+yy101:
yyaccept = 0;
yych = *(YYMARKER = ++YYCURSOR);
if (yybm[0+yych] & 32) {
- goto yy137;
+ goto yy101;
}
- if (yych == '(') goto yy140;
-yy139:
+ if (yych == '(') goto yy103;
+yy102:
t1 = yyt1;
t2 = YYCURSOR;
{
@@ -1119,34 +1120,34 @@ yy139:
sy_res_push(atoi(ZSTR_VAL(tmp)));
goto yyc_cond_op;
}
-yy140:
+yy103:
yych = *++YYCURSOR;
if (yych == '"') {
yyt2 = YYCURSOR;
- goto yy142;
+ goto yy105;
}
if (yych == ')') {
yyt2 = YYCURSOR;
- goto yy144;
+ goto yy106;
}
-yy141:
+yy104:
YYCURSOR = YYMARKER;
if (yyaccept == 0) {
- goto yy139;
+ goto yy102;
} else {
- goto yy145;
+ goto yy107;
}
-yy142:
+yy105:
yych = *++YYCURSOR;
if (yybm[0+yych] & 64) {
- goto yy142;
+ goto yy105;
}
- if (yych <= '\r') goto yy141;
- if (yych <= '"') goto yy146;
- goto yy147;
-yy144:
+ if (yych <= '\r') goto yy104;
+ if (yych <= '"') goto yy108;
+ goto yy109;
+yy106:
++YYCURSOR;
-yy145:
+yy107:
t1 = yyt1;
t3 = yyt2;
t2 = yyt2 - 1;
@@ -1161,41 +1162,41 @@ yy145:
}
goto yyc_cond_op;
}
-yy146:
+yy108:
yych = *++YYCURSOR;
- if (yych == ')') goto yy144;
- goto yy141;
-yy147:
+ if (yych == ')') goto yy106;
+ goto yy104;
+yy109:
yych = *++YYCURSOR;
if (yybm[0+yych] & 64) {
- goto yy142;
+ goto yy105;
}
- if (yych <= '\r') goto yy141;
- if (yych >= '#') goto yy147;
+ if (yych <= '\r') goto yy104;
+ if (yych >= '#') goto yy109;
yych = *++YYCURSOR;
if (yybm[0+yych] & 128) {
- goto yy147;
+ goto yy109;
}
if (yych <= '\r') {
- if (yych == '\n') goto yy141;
- if (yych <= '\f') goto yy142;
- goto yy141;
+ if (yych == '\n') goto yy104;
+ if (yych <= '\f') goto yy105;
+ goto yy104;
} else {
if (yych <= '"') {
- if (yych <= '!') goto yy142;
- goto yy146;
+ if (yych <= '!') goto yy105;
+ goto yy108;
} else {
- if (yych != ')') goto yy142;
+ if (yych != ')') goto yy105;
}
}
yyaccept = 1;
yych = *(YYMARKER = ++YYCURSOR);
if (yybm[0+yych] & 64) {
- goto yy142;
+ goto yy105;
}
- if (yych <= '\r') goto yy145;
- if (yych <= '"') goto yy146;
- goto yy147;
+ if (yych <= '\r') goto yy107;
+ if (yych <= '"') goto yy108;
+ goto yy109;
}
/* *********************************** */
yyc_cond_op:
@@ -1236,63 +1237,63 @@ yyc_cond_op:
};
yych = *YYCURSOR;
if (yybm[0+yych] & 128) {
- goto yy155;
+ goto yy113;
}
if (yych <= ')') {
if (yych <= '\r') {
- if (yych <= 0x08) goto yy153;
- if (yych <= '\n') goto yy158;
- if (yych >= '\r') goto yy160;
+ if (yych <= 0x08) goto yy111;
+ if (yych <= '\n') goto yy114;
+ if (yych >= '\r') goto yy115;
} else {
if (yych == '&') {
yyt1 = YYCURSOR;
- goto yy161;
+ goto yy116;
}
- if (yych >= ')') goto yy162;
+ if (yych >= ')') goto yy117;
}
} else {
if (yych <= '=') {
- if (yych <= ':') goto yy153;
- if (yych <= ';') goto yy164;
+ if (yych <= ':') goto yy111;
+ if (yych <= ';') goto yy118;
if (yych <= '<') {
yyt1 = YYCURSOR;
- goto yy166;
+ goto yy119;
}
yyt1 = YYCURSOR;
- goto yy168;
+ goto yy121;
} else {
if (yych <= '>') {
yyt1 = YYCURSOR;
- goto yy166;
+ goto yy119;
}
if (yych == '|') {
yyt1 = YYCURSOR;
- goto yy169;
+ goto yy122;
}
}
}
-yy153:
+yy111:
++YYCURSOR;
-yy154:
+yy112:
{ cs_log_error("Syntax error in condition on line %d", lineno); goto out; }
-yy155:
+yy113:
yych = *++YYCURSOR;
if (yybm[0+yych] & 128) {
- goto yy155;
+ goto yy113;
}
{ goto yyc_cond_op; }
-yy158:
+yy114:
++YYCURSOR;
{ lineno++; goto yyc_cond_op; }
-yy160:
+yy115:
yych = *++YYCURSOR;
- if (yych == '\n') goto yy158;
- goto yy154;
-yy161:
+ if (yych == '\n') goto yy114;
+ goto yy112;
+yy116:
yych = *++YYCURSOR;
- if (yych == '&') goto yy170;
- goto yy154;
-yy162:
+ if (yych == '&') goto yy123;
+ goto yy112;
+yy117:
++YYCURSOR;
{
while (cond_op_i && sy_op_peek() != '(') {
@@ -1304,7 +1305,7 @@ yy162:
cond_op_i--;
goto yyc_cond_op;
}
-yy164:
+yy118:
++YYCURSOR;
{
while (cond_op_i) {
@@ -1314,10 +1315,10 @@ yy164:
if (cond_res_i > 1) { cs_log_error("invalid condition on line %d", lineno); goto out; }
goto yyc_init;
}
-yy166:
+yy119:
yych = *++YYCURSOR;
- if (yych == '=') goto yy170;
-yy167:
+ if (yych == '=') goto yy123;
+yy120:
t1 = yyt1;
t2 = YYCURSOR;
{
@@ -1334,16 +1335,16 @@ yy167:
sy_op_push(*t1);
goto yyc_cond;
}
-yy168:
+yy121:
yych = *++YYCURSOR;
- if (yych == '=') goto yy170;
- goto yy154;
-yy169:
+ if (yych == '=') goto yy123;
+ goto yy112;
+yy122:
yych = *++YYCURSOR;
- if (yych != '|') goto yy154;
-yy170:
+ if (yych != '|') goto yy112;
+yy123:
++YYCURSOR;
- goto yy167;
+ goto yy120;
}
/* *********************************** */
yyc_rule:
@@ -1384,77 +1385,77 @@ yyc_rule:
};
yych = *YYCURSOR;
if (yybm[0+yych] & 8) {
- goto yy175;
+ goto yy127;
}
if (yych <= '\r') {
- if (yych <= 0x08) goto yy173;
- if (yych <= '\n') goto yy178;
- if (yych >= '\r') goto yy179;
+ if (yych <= 0x08) goto yy125;
+ if (yych <= '\n') goto yy128;
+ if (yych >= '\r') goto yy129;
} else {
if (yych <= '.') {
- if (yych >= '.') goto yy180;
+ if (yych >= '.') goto yy130;
} else {
- if (yych == ';') goto yy181;
+ if (yych == ';') goto yy131;
}
}
-yy173:
+yy125:
++YYCURSOR;
-yy174:
+yy126:
{ goto end_of_rule; }
-yy175:
+yy127:
yych = *++YYCURSOR;
if (yybm[0+yych] & 8) {
- goto yy175;
+ goto yy127;
}
{ goto yyc_rule; }
-yy178:
+yy128:
yyaccept = 0;
yych = *(YYMARKER = ++YYCURSOR);
if (yych <= '\r') {
- if (yych <= 0x08) goto yy174;
+ if (yych <= 0x08) goto yy126;
if (yych <= '\n') {
yyt1 = YYCURSOR;
- goto yy183;
+ goto yy132;
}
- if (yych <= '\f') goto yy174;
+ if (yych <= '\f') goto yy126;
yyt1 = YYCURSOR;
- goto yy186;
+ goto yy134;
} else {
if (yych <= ' ') {
- if (yych <= 0x1F) goto yy174;
+ if (yych <= 0x1F) goto yy126;
yyt1 = YYCURSOR;
- goto yy183;
+ goto yy132;
} else {
if (yych == '.') {
yyt1 = YYCURSOR;
- goto yy187;
+ goto yy135;
}
- goto yy174;
+ goto yy126;
}
}
-yy179:
+yy129:
yyaccept = 0;
yych = *(YYMARKER = ++YYCURSOR);
- if (yych == '\n') goto yy189;
- goto yy174;
-yy180:
+ if (yych == '\n') goto yy136;
+ goto yy126;
+yy130:
yych = *++YYCURSOR;
if (yych <= '^') {
- if (yych <= '@') goto yy174;
+ if (yych <= '@') goto yy126;
if (yych <= 'Z') {
yyt1 = YYCURSOR;
- goto yy190;
+ goto yy137;
}
- goto yy174;
+ goto yy126;
} else {
- if (yych == '`') goto yy174;
+ if (yych == '`') goto yy126;
if (yych <= 'z') {
yyt1 = YYCURSOR;
- goto yy190;
+ goto yy137;
}
- goto yy174;
+ goto yy126;
}
-yy181:
+yy131:
++YYCURSOR;
{
end_of_rule:
@@ -1465,71 +1466,71 @@ yy181:
}
goto yyc_init;
}
-yy183:
+yy132:
yych = *++YYCURSOR;
if (yybm[0+yych] & 16) {
- goto yy183;
+ goto yy132;
}
- if (yych == '\r') goto yy186;
- if (yych == '.') goto yy187;
-yy185:
+ if (yych == '\r') goto yy134;
+ if (yych == '.') goto yy135;
+yy133:
YYCURSOR = YYMARKER;
if (yyaccept <= 1) {
if (yyaccept == 0) {
- goto yy174;
+ goto yy126;
} else {
yyt3 = yyt4 = NULL;
yyt2 = YYCURSOR;
- goto yy192;
+ goto yy138;
}
} else {
- goto yy192;
+ goto yy138;
}
-yy186:
+yy134:
yych = *++YYCURSOR;
- if (yych == '\n') goto yy183;
- goto yy185;
-yy187:
+ if (yych == '\n') goto yy132;
+ goto yy133;
+yy135:
++YYCURSOR;
YYCURSOR = yyt1;
{ lineno++; goto yyc_rule; }
-yy189:
+yy136:
yych = *++YYCURSOR;
if (yych <= '\r') {
- if (yych <= 0x08) goto yy185;
+ if (yych <= 0x08) goto yy133;
if (yych <= '\n') {
yyt1 = YYCURSOR;
- goto yy183;
+ goto yy132;
}
- if (yych <= '\f') goto yy185;
+ if (yych <= '\f') goto yy133;
yyt1 = YYCURSOR;
- goto yy186;
+ goto yy134;
} else {
if (yych <= ' ') {
- if (yych <= 0x1F) goto yy185;
+ if (yych <= 0x1F) goto yy133;
yyt1 = YYCURSOR;
- goto yy183;
+ goto yy132;
} else {
if (yych == '.') {
yyt1 = YYCURSOR;
- goto yy187;
+ goto yy135;
}
- goto yy185;
+ goto yy133;
}
}
-yy190:
+yy137:
yyaccept = 1;
yych = *(YYMARKER = ++YYCURSOR);
if (yybm[0+yych] & 32) {
- goto yy190;
+ goto yy137;
}
if (yych == '(') {
yyt2 = YYCURSOR;
- goto yy193;
+ goto yy139;
}
yyt3 = yyt4 = NULL;
yyt2 = YYCURSOR;
-yy192:
+yy138:
t1 = yyt1;
t2 = yyt2;
t3 = yyt3;
@@ -1564,114 +1565,114 @@ yy192:
parsed_rule[kw_i++] = kw;
goto yyc_rule;
}
-yy193:
+yy139:
yych = *++YYCURSOR;
if (yych <= '@') {
if (yych <= '"') {
- if (yych <= '!') goto yy185;
+ if (yych <= '!') goto yy133;
yyt3 = YYCURSOR;
} else {
if (yych == ')') {
yyt3 = yyt4 = YYCURSOR;
- goto yy196;
+ goto yy141;
}
- goto yy185;
+ goto yy133;
}
} else {
if (yych <= '_') {
if (yych <= 'Z') {
yyt3 = YYCURSOR;
- goto yy197;
+ goto yy142;
}
- if (yych <= '^') goto yy185;
+ if (yych <= '^') goto yy133;
yyt3 = YYCURSOR;
- goto yy197;
+ goto yy142;
} else {
- if (yych <= '`') goto yy185;
+ if (yych <= '`') goto yy133;
if (yych <= 'z') {
yyt3 = YYCURSOR;
- goto yy197;
+ goto yy142;
}
- goto yy185;
+ goto yy133;
}
}
-yy194:
+yy140:
yych = *++YYCURSOR;
if (yybm[0+yych] & 64) {
- goto yy194;
+ goto yy140;
}
- if (yych <= '\r') goto yy185;
- if (yych <= '"') goto yy199;
- goto yy200;
-yy196:
+ if (yych <= '\r') goto yy133;
+ if (yych <= '"') goto yy143;
+ goto yy144;
+yy141:
++YYCURSOR;
- goto yy192;
-yy197:
+ goto yy138;
+yy142:
yych = *++YYCURSOR;
if (yych <= '@') {
if (yych <= ')') {
- if (yych <= '(') goto yy185;
+ if (yych <= '(') goto yy133;
yyt4 = YYCURSOR;
- goto yy196;
+ goto yy141;
} else {
- if (yych <= '/') goto yy185;
- if (yych <= '9') goto yy197;
- goto yy185;
+ if (yych <= '/') goto yy133;
+ if (yych <= '9') goto yy142;
+ goto yy133;
}
} else {
if (yych <= '_') {
- if (yych <= 'Z') goto yy197;
- if (yych <= '^') goto yy185;
- goto yy197;
+ if (yych <= 'Z') goto yy142;
+ if (yych <= '^') goto yy133;
+ goto yy142;
} else {
- if (yych <= '`') goto yy185;
- if (yych <= 'z') goto yy197;
- goto yy185;
+ if (yych <= '`') goto yy133;
+ if (yych <= 'z') goto yy142;
+ goto yy133;
}
}
-yy199:
+yy143:
yych = *++YYCURSOR;
if (yych == ')') {
yyt4 = YYCURSOR;
- goto yy196;
+ goto yy141;
}
- goto yy185;
-yy200:
+ goto yy133;
+yy144:
yych = *++YYCURSOR;
if (yybm[0+yych] & 64) {
- goto yy194;
+ goto yy140;
}
- if (yych <= '\r') goto yy185;
- if (yych >= '#') goto yy200;
+ if (yych <= '\r') goto yy133;
+ if (yych >= '#') goto yy144;
yych = *++YYCURSOR;
if (yybm[0+yych] & 128) {
- goto yy200;
+ goto yy144;
}
if (yych <= '\r') {
- if (yych == '\n') goto yy185;
- if (yych <= '\f') goto yy194;
- goto yy185;
+ if (yych == '\n') goto yy133;
+ if (yych <= '\f') goto yy140;
+ goto yy133;
} else {
if (yych <= '"') {
- if (yych <= '!') goto yy194;
- goto yy199;
+ if (yych <= '!') goto yy140;
+ goto yy143;
} else {
- if (yych != ')') goto yy194;
+ if (yych != ')') goto yy140;
yyt4 = YYCURSOR;
}
}
yyaccept = 2;
yych = *(YYMARKER = ++YYCURSOR);
if (yybm[0+yych] & 64) {
- goto yy194;
+ goto yy140;
}
- if (yych <= '\r') goto yy192;
- if (yych <= '"') goto yy199;
- goto yy200;
+ if (yych <= '\r') goto yy138;
+ if (yych <= '"') goto yy143;
+ goto yy144;
}
}
out:
zend_hash_destroy(&vars);
return ret;
-}
\ No newline at end of file
+}
--
cgit v1.3
From 618e675b5d1cb2099464a198a568a129616164b0 Mon Sep 17 00:00:00 2001
From: jvoisin
Date: Fri, 6 May 2022 21:20:44 +0200
Subject: Silence a compiler warning
---
src/sp_utils.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/sp_utils.c b/src/sp_utils.c
index 6161859..df2f0d6 100644
--- a/src/sp_utils.c
+++ b/src/sp_utils.c
@@ -448,6 +448,7 @@ void unhook_functions(HashTable *ht) {
if (func && func->type == ZEND_INTERNAL_FUNCTION && orig_handler) {
func->internal_function.handler = orig_handler;
}
+ (void)idx;//silence a -Wunused-but-set-variable
ZEND_HASH_FOREACH_END_DEL();
}
--
cgit v1.3
From 6e853a21c008f1a8a366e41cf25a24cf97f54764 Mon Sep 17 00:00:00 2001
From: jvoisin
Date: Sun, 15 May 2022 16:48:48 +0200
Subject: Silence a false positive in gcc
---
src/sp_config_scanner.cached.c | 2 ++
src/sp_config_scanner.re | 2 ++
2 files changed, 4 insertions(+)
diff --git a/src/sp_config_scanner.cached.c b/src/sp_config_scanner.cached.c
index dfcf25f..3114918 100644
--- a/src/sp_config_scanner.cached.c
+++ b/src/sp_config_scanner.cached.c
@@ -1,6 +1,8 @@
/* Generated by re2c */
#include "php_snuffleupagus.h"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+
enum YYCONDTYPE {
yycinit,
yyccond,
diff --git a/src/sp_config_scanner.re b/src/sp_config_scanner.re
index 9f1ac2b..6a14a11 100644
--- a/src/sp_config_scanner.re
+++ b/src/sp_config_scanner.re
@@ -1,5 +1,7 @@
#include "php_snuffleupagus.h"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+
/*!types:re2c*/
#define cs_log_error(fmt, ...) sp_log_err("config", fmt, ##__VA_ARGS__)
--
cgit v1.3
From b3f52547fb2a3a1192711c54315590b2b108c280 Mon Sep 17 00:00:00 2001
From: jvoisin
Date: Sun, 15 May 2022 17:12:28 +0200
Subject: Fix a possible null-pointer dereference
---
src/sp_disabled_functions.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/src/sp_disabled_functions.c b/src/sp_disabled_functions.c
index 2e659da..10a9466 100644
--- a/src/sp_disabled_functions.c
+++ b/src/sp_disabled_functions.c
@@ -515,7 +515,11 @@ ZEND_FUNCTION(eval_blacklist_callback) {
zif_handler orig_handler;
char* current_function_name = get_complete_function_path(EG(current_execute_data));
- if (!current_function_name || true == check_is_in_eval_whitelist(current_function_name)) {
+ if (!current_function_name) {
+ return;
+ }
+
+ if( true == check_is_in_eval_whitelist(current_function_name)) {
goto whitelisted;
}
--
cgit v1.3
From c0e72a25f32e4916ac5eda8cb47888fd0a200b23 Mon Sep 17 00:00:00 2001
From: jvoisin
Date: Sun, 15 May 2022 18:07:23 +0200
Subject: Bump the changelog
---
debian/changelog | 22 ++++++++++++++++++++
doc/source/changelog.rst | 52 ++++++++++++++++++++++++++++++++++--------------
src/php_snuffleupagus.h | 2 +-
3 files changed, 60 insertions(+), 16 deletions(-)
diff --git a/debian/changelog b/debian/changelog
index 51ca43d..831a0f2 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,25 @@
+snuffleupagus (0.8.0) UNRELEASED; urgency=low
+ [ jvoisin ]
+ * Compatibility with PHP8.1
+ * Check for unsupported PHP version
+ * Backport of Suhosin-ng patches:
+ * Maximum stack depth/recursion limit
+ * Maximum length for session id
+ * $_SERVER strip/encode
+ * Configuration dump
+ * Support for conditional rules
+ * INI settings protection
+ * Output SP logs to stderr
+ * Ported Suhosin rules to SP
+ * Massive simplification of the configuration parser
+ * Better memory management
+ * Removal of internal calls to `call_user_func`
+ * Increased portability of the default rules access different version of PHP
+ * Start SP as late as possible, to hook as many things as possible
+ * XML and Session support are now checked at runtime instead of at compile time
+
+ -- jvoisin Sun, 15 Apr 2022 18:00:00 +0200
+
snuffleupagus (0.7.1) UNRELEASED; urgency=low
[ jvoisin ]
* Fixed possible memory-leaks when hooking via regular expressions
diff --git a/doc/source/changelog.rst b/doc/source/changelog.rst
index 6eaccd2..a69ec20 100644
--- a/doc/source/changelog.rst
+++ b/doc/source/changelog.rst
@@ -1,32 +1,54 @@
Changelog
=========
-0.8.0 - Woolly Mammoth
-----------------------
+0.8.0 - `Woolly Mammoth` `__ 2022/05/15
+-----------------------------------------------------------------------------------------------------
-- Massive simplification of the configuration parser
-- Better memory management
-- Removal of internal calls to `call_user_func`
-- Check for unsupported PHP version
-- Compatibility with PHP8.1
-- Suhosin features backports:
- - Maximum stack depth/recursion limit
- - Maximum length for session id
+New features
+^^^^^^^^^^^^
+* Compatibility with PHP8.1
+* Check for unsupported PHP version
+* Backport of Suhosin-ng patches:
+ * Maximum stack depth/recursion limit
+ * Maximum length for session id
+ * $_SERVER strip/encode
+ * Configuration dump
+ * Support for conditional rules
+ * INI settings protection
+ * Output SP logs to stderr
+ * Ported Suhosin rules to SP
+
+Improvements
+^^^^^^^^^^^^
+* Massive simplification of the configuration parser
+* Better memory management
+* Removal of internal calls to `call_user_func`
+* Increased portability of the default rules access different version of PHP
+* Start SP as late as possible, to hook as many things as possible
+
+Bug fixes
+^^^^^^^^^
+* XML and Session support are now checked at runtime instead of at compile time
0.7.1 - `Proboscidea `__ 2021/08/02
-------------------------------------------------------------------------------------------------
-* Fixed possible memory-leaks when hooking via regular expressions
-* Modernise the code by removing usage of `strtok`
-* Prevent a possible crash during configuration reloading
-* Fix the default rules to catch dangerous `chmod` calls
+Improvements
+^^^^^^^^^^^^
* Improve compatibility with various `libpcre` configurations/versions
+* Modernise the code by removing usage of `strtok`
* Improve the default rules' compatibility with php8
* Prevent XXE in php8 as well
* Improve a bit the verbosity of the logs
* Add a rules file for php8
+Bug fixes
+^^^^^^^^^
+* Prevent a possible crash during configuration reloading
+* Fix the default rules to catch dangerous `chmod` calls
+* Fixed possible memory-leaks when hooking via regular expressions
+
0.7.0 - `Los Elefantes `__ 2021/01/02
---------------------------------------------------------------------------------------------------
@@ -46,7 +68,7 @@ Improvements
Bug fixes
^^^^^^^^^
-* The strict mode is now disableable
+* The strict mode can now be disabled
0.6.0 - `Elephant in the room `__ 2020/11/06
diff --git a/src/php_snuffleupagus.h b/src/php_snuffleupagus.h
index 8dc7ccb..e40b31b 100644
--- a/src/php_snuffleupagus.h
+++ b/src/php_snuffleupagus.h
@@ -1,7 +1,7 @@
#ifndef PHP_SNUFFLEUPAGUS_H
#define PHP_SNUFFLEUPAGUS_H
-#define PHP_SNUFFLEUPAGUS_VERSION "0.8.0"
+#define PHP_SNUFFLEUPAGUS_VERSION "0.9.0"
#define PHP_SNUFFLEUPAGUS_EXTNAME "snuffleupagus"
#define PHP_SNUFFLEUPAGUS_AUTHOR "NBS System & Julien (jvoisin) Voisin & SektionEins GmbH"
#define PHP_SNUFFLEUPAGUS_URL "https://github.com/jvoisin/snuffleupagus"
--
cgit v1.3
From eabdc18da330b7f352e011f7640c94cb1b74b0d3 Mon Sep 17 00:00:00 2001
From: jvoisin
Date: Sun, 15 May 2022 18:23:50 +0200
Subject: Fix debian's control file
---
debian/control | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/debian/control b/debian/control
index 9e313b6..03fa0fd 100644
--- a/debian/control
+++ b/debian/control
@@ -1,7 +1,7 @@
Source: snuffleupagus
Priority: optional
Maintainer: Julien (jvoisin) Voisin
-Build-Depends: debhelper (>= 9), php-curl, php-xml, php7.0-dev | php7.1-dev | php7.2-dev | php7.3-dev | php7.4-dev | php8.0-dev
+Build-Depends: debhelper (>= 9), php-curl, php-xml, php7.0-dev | php7.1-dev | php7.2-dev | php7.3-dev | php7.4-dev | php8.0-dev | php8.1-dev
Standards-Version: 4.1.3
Homepage: https://github.com/jvoisin/snuffleupagus
Section: php
--
cgit v1.3
From a9d848d576083323ecb93caa5d5eee9bc3287b37 Mon Sep 17 00:00:00 2001
From: jvoisin
Date: Sun, 15 May 2022 18:25:11 +0200
Subject: Add some static analysers to the readme
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index b291628..2302d26 100644
--- a/README.md
+++ b/README.md
@@ -88,7 +88,7 @@ without having to touch the PHP code.
* Every commit is tested on [several distributions](https://gitlab.com/jvoisin/snuffleupagus/pipelines)
* An `clang-format`-enforced code style
* A [comprehensive documentation](https://snuffleupagus.rtfd.io)
- * Usage of [coverity](https://scan.coverity.com/projects/jvoisin-snuffleupagus)
+ * Usage of [coverity](https://scan.coverity.com/projects/jvoisin-snuffleupagus), codeql, [scan-build](https://clang-analyzer.llvm.org/scan-build.html), …
## Download
--
cgit v1.3
From 2a52388a05bdf4cdde302030cc591aebdbf29998 Mon Sep 17 00:00:00 2001
From: Giovanni
Date: Sun, 15 May 2022 22:29:16 +0200
Subject: Build release debs in CI
---
.github/workflows/release.yml | 71 +++++++++++++++++++++++++++++++++++++++++++
debian/rules | 4 +++
2 files changed, 75 insertions(+)
create mode 100644 .github/workflows/release.yml
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 0000000..6d8d3d7
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,71 @@
+name: Release Builder
+on:
+ push:
+ branches:
+ - "release-*"
+ tags:
+ - "v*"
+ pull_request:
+ branches:
+ - "release-*"
+
+jobs:
+ build-deb:
+ runs-on: ubuntu-latest
+ name: ${{ matrix.name }}
+ container: ${{ matrix.container }}
+ strategy:
+ fail-fast: false
+ matrix:
+ name:
+ [
+ "debian-buster",
+ "debian-stretch",
+ "debian-bullseye",
+ "debian-sid",
+ "debian-bookworm",
+ "ubuntu-bionic",
+ "ubuntu-focal",
+ "ubuntu-jammy",
+ "ubuntu-impish",
+ ]
+ include:
+ - name: debian-buster
+ container: debian:buster
+ - name: debian-stretch
+ container: debian:stretch
+ - name: debian-bullseye
+ container: debian:bullseye
+ - name: debian-sid
+ container: debian:sid
+ - name: debian-bookworm
+ container: debian:bookworm
+ - name: ubuntu-bionic
+ container: ubuntu:bionic
+ - name: ubuntu-focal
+ container: ubuntu:focal
+ - name: ubuntu-jammy
+ container: ubuntu:jammy
+ - name: ubuntu-impish
+ container: ubuntu:impish
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v2
+ - name: Set timezone
+ if: startsWith(matrix.container, 'ubuntu:')
+ run: ln -snf /usr/share/zoneinfo/Europe/Paris /etc/localtime && echo Europe/Paris > /etc/timezone
+ - name: Update OS
+ run: apt-get -qqy update
+ - name: Install deps
+ run: DEBIAN_FRONTEND=noninteractive apt-get -qqy --no-install-recommends install fakeroot php-xml php-curl dpkg-dev gcc make libpcre3-dev dh-php php-dev build-essential
+ - name: Build debs
+ run: DPKG_SKIP_TESTS=1 dpkg-buildpackage -i -us -uc -tc -I -rfakeroot
+ - name: Move built debs and rename
+ run: |
+ mv -v ../*.deb ./
+ ls *.deb | xargs -I % mv -v % ${{ matrix.name }}-%
+ - name: Upload artifacts
+ uses: actions/upload-artifact@v3
+ with:
+ name: snuffleupagus-${{ matrix.name }}
+ path: ./*.deb
diff --git a/debian/rules b/debian/rules
index 70965bb..40eb4ac 100755
--- a/debian/rules
+++ b/debian/rules
@@ -27,5 +27,9 @@ override_dh_auto_install:
install -m 644 -o root -g root config/snuffleupagus.ini debian/snuffleupagus/etc/php/$$(/usr/bin/php-config --version | cut -d '.' -f1-2)/mods-available/snuffleupagus.ini
override_dh_auto_test:
+ifeq ($(strip $(DPKG_SKIP_TESTS)),)
sed -i "s/\$$ext_params -d display_errors=0 -r/-d display_errors=0 -r/" src/run-tests.php
TEST_PHP_ARGS="-q" REPORT_EXIST_STATUS=1 make -C src test
+else
+ echo "skip tests"
+endif
\ No newline at end of file
--
cgit v1.3
From bee9da3cb2b47d7121ac3fe9cc945716aaaa5d21 Mon Sep 17 00:00:00 2001
From: jvoisin
Date: Mon, 16 May 2022 19:34:37 +0200
Subject: Don't run disabled_functions_param_str_representation_php8 on php7
---
.../disabled_functions_param_str_representation_php8.phpt | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/tests/disable_function/disabled_functions_param_str_representation_php8.phpt b/src/tests/disable_function/disabled_functions_param_str_representation_php8.phpt
index c06e612..aa5782b 100644
--- a/src/tests/disable_function/disabled_functions_param_str_representation_php8.phpt
+++ b/src/tests/disable_function/disabled_functions_param_str_representation_php8.phpt
@@ -2,6 +2,7 @@
Disable functions - casting various types to string internally in php8
--SKIPIF--
+
--INI--
sp.configuration_file={PWD}/config/config_disabled_functions_param_str_representation_php8.ini
--FILE--
--
cgit v1.3
From 3d206b9ae51680ae6c0f0eee3e11e667d343d3e4 Mon Sep 17 00:00:00 2001
From: jvoisin
Date: Mon, 16 May 2022 19:49:18 +0200
Subject: Bump the changelog
---
debian/changelog | 7 +++++++
doc/source/changelog.rst | 11 ++++++++++-
src/php_snuffleupagus.h | 2 +-
3 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/debian/changelog b/debian/changelog
index 831a0f2..3282469 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+snuffleupagus (0.8.1) UNRELEASED; urgency=low
+ [ jvoisin ]
+ * Fix the version number
+ * Fix a test on PHP7
+
+ -- jvoisin Sun, 16 Apr 2022 19:45:00 +0200
+
snuffleupagus (0.8.0) UNRELEASED; urgency=low
[ jvoisin ]
* Compatibility with PHP8.1
diff --git a/doc/source/changelog.rst b/doc/source/changelog.rst
index a69ec20..794afb8 100644
--- a/doc/source/changelog.rst
+++ b/doc/source/changelog.rst
@@ -1,7 +1,16 @@
Changelog
=========
-0.8.0 - `Woolly Mammoth` `__ 2022/05/15
+0.8.1 - `Batyr `__ 2022/05/16
+-------------------------------------------------------------------------------------------
+
+Bug fixes
+^^^^^^^^^
+* Fix the version number
+* Fix a test on PHP7
+
+
+0.8.0 - `Woolly Mammoth `__ 2022/05/15
-----------------------------------------------------------------------------------------------------
New features
diff --git a/src/php_snuffleupagus.h b/src/php_snuffleupagus.h
index e40b31b..8faaf3a 100644
--- a/src/php_snuffleupagus.h
+++ b/src/php_snuffleupagus.h
@@ -1,7 +1,7 @@
#ifndef PHP_SNUFFLEUPAGUS_H
#define PHP_SNUFFLEUPAGUS_H
-#define PHP_SNUFFLEUPAGUS_VERSION "0.9.0"
+#define PHP_SNUFFLEUPAGUS_VERSION "0.8.1"
#define PHP_SNUFFLEUPAGUS_EXTNAME "snuffleupagus"
#define PHP_SNUFFLEUPAGUS_AUTHOR "NBS System & Julien (jvoisin) Voisin & SektionEins GmbH"
#define PHP_SNUFFLEUPAGUS_URL "https://github.com/jvoisin/snuffleupagus"
--
cgit v1.3
From 90723b8c64a8f6c43313ad65d3401706e3f7ceb9 Mon Sep 17 00:00:00 2001
From: Remi Collet
Date: Tue, 17 May 2022 16:08:34 +0200
Subject: Only set orig_register_server_variables once
---
src/sp_ifilter.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/sp_ifilter.c b/src/sp_ifilter.c
index 8099882..9c46875 100644
--- a/src/sp_ifilter.c
+++ b/src/sp_ifilter.c
@@ -97,7 +97,7 @@ static void sp_register_server_variables(zval *track_vars_array) {
void sp_hook_register_server_variables()
{
- if (sapi_module.register_server_variables) {
+ if (sapi_module.register_server_variables && sapi_module.register_server_variables != sp_register_server_variables) {
orig_register_server_variables = sapi_module.register_server_variables;
sapi_module.register_server_variables = sp_register_server_variables;
}
--
cgit v1.3
From 5843e8ce000d7d41f34de37d3c4baadeb7b34f39 Mon Sep 17 00:00:00 2001
From: Luc Vieillescazes
Date: Tue, 17 May 2022 16:25:48 +0200
Subject: Fix ZTS build
Bug introduced in https://github.com/jvoisin/snuffleupagus/commit/7c2d1d7d2713c0fa6bda63c376baf25d9f3d712c---
src/sp_config.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/sp_config.c b/src/sp_config.c
index d29247b..dbccb1a 100644
--- a/src/sp_config.c
+++ b/src/sp_config.c
@@ -6,7 +6,7 @@
static zend_result sp_process_config_root(sp_parsed_keyword *parsed_rule) {
- static const sp_config_keyword sp_func[] = {
+ sp_config_keyword sp_func[] = {
{parse_unserialize, SP_TOKEN_UNSERIALIZE_HMAC, &(SPCFG(unserialize))},
{parse_enable, SP_TOKEN_HARDEN_RANDOM, &(SPCFG(random).enable)},
{parse_log_media, SP_TOKEN_LOG_MEDIA, &(SPCFG(log_media))},
--
cgit v1.3
From 79dc4956919f342a1bca3faa6c1b75293abe6663 Mon Sep 17 00:00:00 2001
From: jvoisin
Date: Tue, 17 May 2022 20:41:04 +0200
Subject: Document a breaking change
---
doc/source/changelog.rst | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/doc/source/changelog.rst b/doc/source/changelog.rst
index 794afb8..4bb0583 100644
--- a/doc/source/changelog.rst
+++ b/doc/source/changelog.rst
@@ -9,6 +9,10 @@ Bug fixes
* Fix the version number
* Fix a test on PHP7
+Breaking Changes
+^^^^^^^^^^^^^^^^
+* `disable_xxe` is changed to `xxe_protection`
+
0.8.0 - `Woolly Mammoth `__ 2022/05/15
-----------------------------------------------------------------------------------------------------
--
cgit v1.3
From a1a7d2030f40ce1f880e9944417c6ccbb48a3c13 Mon Sep 17 00:00:00 2001
From: jvoisin
Date: Fri, 20 May 2022 22:00:35 +0200
Subject: Bump the changelog
---
debian/changelog | 7 +++++++
doc/source/changelog.rst | 9 +++++++++
src/php_snuffleupagus.h | 2 +-
3 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/debian/changelog b/debian/changelog
index 3282469..034a34d 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+snuffleupagus (0.8.2) UNRELEASED; urgency=low
+ [ jvoisin ]
+ * Fix compilation when ZTS is used
+ * Fix a possible infinite loop
+
+ -- jvoisin Sun, 20 Apr 2022 22:00:00 +0200
+
snuffleupagus (0.8.1) UNRELEASED; urgency=low
[ jvoisin ]
* Fix the version number
diff --git a/doc/source/changelog.rst b/doc/source/changelog.rst
index 4bb0583..a406953 100644
--- a/doc/source/changelog.rst
+++ b/doc/source/changelog.rst
@@ -1,6 +1,15 @@
Changelog
=========
+0.8.2 - `Surus `__ 2022/05/20
+-------------------------------------------------------------------------------------------
+
+Bug fixes
+^^^^^^^^^
+* Fix compilation when ZTS is used
+* Fix a possible infinite loop
+
+
0.8.1 - `Batyr `__ 2022/05/16
-------------------------------------------------------------------------------------------
diff --git a/src/php_snuffleupagus.h b/src/php_snuffleupagus.h
index 8faaf3a..97fa0e4 100644
--- a/src/php_snuffleupagus.h
+++ b/src/php_snuffleupagus.h
@@ -1,7 +1,7 @@
#ifndef PHP_SNUFFLEUPAGUS_H
#define PHP_SNUFFLEUPAGUS_H
-#define PHP_SNUFFLEUPAGUS_VERSION "0.8.1"
+#define PHP_SNUFFLEUPAGUS_VERSION "0.8.2"
#define PHP_SNUFFLEUPAGUS_EXTNAME "snuffleupagus"
#define PHP_SNUFFLEUPAGUS_AUTHOR "NBS System & Julien (jvoisin) Voisin & SektionEins GmbH"
#define PHP_SNUFFLEUPAGUS_URL "https://github.com/jvoisin/snuffleupagus"
--
cgit v1.3
From 704299c25c0737f72d4d18e673be4ddd449508ca Mon Sep 17 00:00:00 2001
From: jvoisin
Date: Fri, 27 May 2022 19:26:25 +0200
Subject: No more php7 on Alpine!
---
.github/workflows/distributions_php7.yml | 25 -------------------------
1 file changed, 25 deletions(-)
diff --git a/.github/workflows/distributions_php7.yml b/.github/workflows/distributions_php7.yml
index 12fa207..60eedd2 100644
--- a/.github/workflows/distributions_php7.yml
+++ b/.github/workflows/distributions_php7.yml
@@ -94,28 +94,3 @@ jobs:
if: ${{ failure() }}
run: |
grep -r . --include='*.log' src/tests
-
- alpine:
- runs-on: ubuntu-latest
- container: alpine:latest
- steps:
- - name: Checkout code
- uses: actions/checkout@v2
- - name: Remove php8 tests for php7
- run: rm -rf src/tests/*php8*/ src/tests/*/*_php8.phpt
- - name: Remove tests failing on alpine for wathever reason
- run: rm -rf src/tests/cookies_encryption_warning src/tests/upload_validation/upload_validation.phpt /tests/broken_configuration/encrypt_regexp_cookies_bad_regexp.phpt
- - name: Install dependencies
- run: apk add php7-dev php7-cgi php7-simplexml php7-xml pcre-dev build-base php7-pear php7-openssl php7-session bash grep re2c
- - name: Install pecl
- continue-on-error: true
- run: pecl install vld-beta
- - name: Build SP and run the testsuite
- run: |
- make release
- ln -s $(php -r 'echo ini_get("extension_dir");')/* src/modules/
- make tests
- - name: Show logs in case of failure
- if: ${{ failure() }}
- run: |
- grep -r . --include='*.log' src/tests
--
cgit v1.3
From aef97b6b5cb130984ead1a0c3fbc3cdc2037320e Mon Sep 17 00:00:00 2001
From: jvoisin
Date: Mon, 13 Jun 2022 23:22:26 +0200
Subject: Fix the CI on PHP8.0 and PHP8.1
---
src/tests/ini/ini_min_policy_drop.phpt | 2 +-
src/tests/ini/ini_minmax.phpt | 2 +-
src/tests/ini/ini_null.phpt | 2 +-
src/tests/ini/ini_regexp.phpt | 2 +-
src/tests/ini/ini_regexp_drop.phpt | 2 +-
5 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/tests/ini/ini_min_policy_drop.phpt b/src/tests/ini/ini_min_policy_drop.phpt
index ef40ebc..1ec9f9a 100644
--- a/src/tests/ini/ini_min_policy_drop.phpt
+++ b/src/tests/ini/ini_min_policy_drop.phpt
@@ -10,4 +10,4 @@ var_dump(ini_set("max_execution_time", "29") === false);
var_dump(ini_get("max_execution_time"));
?>
--EXPECTF--
-Fatal error: [snuffleupagus][0.0.0.0][ini_protection][drop] INI value out of range in %a/ini_min_policy_drop.php on line 2
+Fatal error: [snuffleupagus][0.0.0.0][ini_protection][drop] INI value out of range in %a/ini_min_policy_drop.php on line 2%A
diff --git a/src/tests/ini/ini_minmax.phpt b/src/tests/ini/ini_minmax.phpt
index 4cd6bc4..facb73e 100644
--- a/src/tests/ini/ini_minmax.phpt
+++ b/src/tests/ini/ini_minmax.phpt
@@ -31,4 +31,4 @@ string(3) "300"
Warning: [snuffleupagus][0.0.0.0][ini_protection][log] INI value out of range in %a/ini_minmax.php on line 11
bool(true)
-string(3) "300"
\ No newline at end of file
+string(3) "300"%A
diff --git a/src/tests/ini/ini_null.phpt b/src/tests/ini/ini_null.phpt
index 32a12c1..dfc2555 100644
--- a/src/tests/ini/ini_null.phpt
+++ b/src/tests/ini/ini_null.phpt
@@ -23,4 +23,4 @@ string(0) ""
Warning: [snuffleupagus][0.0.0.0][ini_protection][log] new INI value must not be NULL or empty in %a/ini_null.php on line 8
bool(true)
-string(3) "def"
\ No newline at end of file
+string(3) "def"%A
diff --git a/src/tests/ini/ini_regexp.phpt b/src/tests/ini/ini_regexp.phpt
index f6c5198..c7cab35 100644
--- a/src/tests/ini/ini_regexp.phpt
+++ b/src/tests/ini/ini_regexp.phpt
@@ -16,4 +16,4 @@ var_dump(ini_get("highlight.comment"));
string(7) "#000aBc"
Warning: [snuffleupagus][0.0.0.0][ini_protection][log] INI value does not match regex in %a/ini_regexp.php on line 5
-string(7) "#000aBc"
+string(7) "#000aBc"%A
diff --git a/src/tests/ini/ini_regexp_drop.phpt b/src/tests/ini/ini_regexp_drop.phpt
index 9225470..432be8d 100644
--- a/src/tests/ini/ini_regexp_drop.phpt
+++ b/src/tests/ini/ini_regexp_drop.phpt
@@ -10,4 +10,4 @@ var_dump(ini_set("user_agent", "Foo") === false);
var_dump(ini_get("user_agent"));
?>
--EXPECTF--
-Fatal error: [snuffleupagus][0.0.0.0][ini_protection][drop] INI value does not match regex in %a/ini_regexp_drop.php on line 2
+Fatal error: [snuffleupagus][0.0.0.0][ini_protection][drop] INI value does not match regex in %a/ini_regexp_drop.php on line 2%A%A%A%A
--
cgit v1.3
From 30f1270c26edb6ced469eb302de2fa27befbdbec Mon Sep 17 00:00:00 2001
From: jvoisin
Date: Mon, 27 Jun 2022 20:12:47 +0200
Subject: Move compile_file and compile_string to sp_execute.c
---
src/sp_execute.c | 39 +++++++++++++++++++++++++++++++++++++++
src/sp_sloppy.c | 41 +----------------------------------------
src/sp_sloppy.h | 1 +
3 files changed, 41 insertions(+), 40 deletions(-)
diff --git a/src/sp_execute.c b/src/sp_execute.c
index f1ed8d0..b81f408 100644
--- a/src/sp_execute.c
+++ b/src/sp_execute.c
@@ -286,6 +286,34 @@ static zend_result sp_stream_open(zend_file_handle *handle) {
#endif
+ZEND_API zend_op_array* (*orig_zend_compile_file)(zend_file_handle* file_handle,
+ int type) = NULL;
+#if PHP_VERSION_ID >= 80000
+ZEND_API zend_op_array* (*orig_zend_compile_string)(
+ zend_string* source_string, const char* filename) = NULL;
+#else
+ZEND_API zend_op_array* (*orig_zend_compile_string)(zval* source_string,
+ char* filename) = NULL;
+#endif
+
+#if PHP_VERSION_ID >= 80000
+ZEND_API zend_op_array* sp_compile_string(zend_string* source_string,
+ const char* filename) {
+#else
+ZEND_API zend_op_array* sp_compile_string(zval* source_string, char* filename) {
+#endif
+ zend_op_array* opline = orig_zend_compile_string(source_string, filename);
+ sp_sloppy_modify_opcode(opline);
+ return opline;
+}
+
+ZEND_API zend_op_array* sp_compile_file(zend_file_handle* file_handle,
+ int type) {
+ zend_op_array* opline = orig_zend_compile_file(file_handle, type);
+ sp_sloppy_modify_opcode(opline);
+ return opline;
+}
+
int hook_execute(void) {
TSRMLS_FETCH();
@@ -309,5 +337,16 @@ int hook_execute(void) {
}
}
+ if (NULL == orig_zend_compile_file && zend_compile_file != sp_compile_file) {
+ orig_zend_compile_file = zend_compile_file;
+ zend_compile_file = sp_compile_file;
+ }
+
+ if (NULL == orig_zend_compile_string &&
+ zend_compile_string != sp_compile_string) {
+ orig_zend_compile_string = zend_compile_string;
+ zend_compile_string = sp_compile_string;
+ }
+
return SUCCESS;
}
diff --git a/src/sp_sloppy.c b/src/sp_sloppy.c
index fca4be5..2c6ef6a 100644
--- a/src/sp_sloppy.c
+++ b/src/sp_sloppy.c
@@ -1,16 +1,6 @@
#include "php_snuffleupagus.h"
-ZEND_API zend_op_array* (*orig_zend_compile_file)(zend_file_handle* file_handle,
- int type) = NULL;
-#if PHP_VERSION_ID >= 80000
-ZEND_API zend_op_array* (*orig_zend_compile_string)(
- zend_string* source_string, const char* filename) = NULL;
-#else
-ZEND_API zend_op_array* (*orig_zend_compile_string)(zval* source_string,
- char* filename) = NULL;
-#endif
-
-static void modify_opcode(zend_op_array* opline) {
+void sp_sloppy_modify_opcode(zend_op_array* opline) {
if (NULL != opline) {
for (size_t i = 0; i < opline->last; i++) {
zend_op* orig_opline = &(opline->opcodes[i]);
@@ -25,24 +15,6 @@ static void modify_opcode(zend_op_array* opline) {
}
}
-#if PHP_VERSION_ID >= 80000
-ZEND_API zend_op_array* sp_compile_string(zend_string* source_string,
- const char* filename) {
-#else
-ZEND_API zend_op_array* sp_compile_string(zval* source_string, char* filename) {
-#endif
- zend_op_array* opline = orig_zend_compile_string(source_string, filename);
- modify_opcode(opline);
- return opline;
-}
-
-ZEND_API zend_op_array* sp_compile_file(zend_file_handle* file_handle,
- int type) {
- zend_op_array* opline = orig_zend_compile_file(file_handle, type);
- modify_opcode(opline);
- return opline;
-}
-
static void array_handler(INTERNAL_FUNCTION_PARAMETERS, const char* name,
size_t size, zif_handler orig_handler,
const char* spec) {
@@ -99,17 +71,6 @@ PHP_FUNCTION(sp_array_keys) {
void hook_sloppy() {
TSRMLS_FETCH();
- if (NULL == orig_zend_compile_file && zend_compile_file != sp_compile_file) {
- orig_zend_compile_file = zend_compile_file;
- zend_compile_file = sp_compile_file;
- }
-
- if (NULL == orig_zend_compile_string &&
- zend_compile_string != sp_compile_string) {
- orig_zend_compile_string = zend_compile_string;
- zend_compile_string = sp_compile_string;
- }
-
HOOK_FUNCTION("in_array", sp_internal_functions_hook, PHP_FN(sp_in_array));
HOOK_FUNCTION("array_search", sp_internal_functions_hook,
PHP_FN(sp_array_search));
diff --git a/src/sp_sloppy.h b/src/sp_sloppy.h
index cd9f304..4c5d121 100644
--- a/src/sp_sloppy.h
+++ b/src/sp_sloppy.h
@@ -4,5 +4,6 @@
#include "zend_vm.h"
void hook_sloppy(void);
+void sp_sloppy_modify_opcode(zend_op_array* opline);
#endif
--
cgit v1.3
From a5f070cd7d982ae96ad72fb79420407574e7682a Mon Sep 17 00:00:00 2001
From: jvoisin
Date: Mon, 27 Jun 2022 20:55:20 +0200
Subject: Dump the eval'ed code
---
src/php_snuffleupagus.h | 7 +++++++
src/sp_execute.c | 2 ++
src/sp_utils.c | 9 +++++++++
src/tests/dump_request/dump_eval_blacklist.phpt | 2 ++
4 files changed, 20 insertions(+)
diff --git a/src/php_snuffleupagus.h b/src/php_snuffleupagus.h
index 97fa0e4..a4a0ed4 100644
--- a/src/php_snuffleupagus.h
+++ b/src/php_snuffleupagus.h
@@ -148,6 +148,13 @@ u_long execution_depth;
HashTable *disabled_functions_hook;
HashTable *sp_internal_functions_hook;
HashTable *sp_eval_blacklist_functions_hook;
+
+#if PHP_VERSION_ID >= 80000
+zend_string* eval_source_string;
+#else
+zval* eval_source_string;
+#endif
+
ZEND_END_MODULE_GLOBALS(snuffleupagus)
ZEND_EXTERN_MODULE_GLOBALS(snuffleupagus)
diff --git a/src/sp_execute.c b/src/sp_execute.c
index b81f408..a8798e4 100644
--- a/src/sp_execute.c
+++ b/src/sp_execute.c
@@ -302,6 +302,8 @@ ZEND_API zend_op_array* sp_compile_string(zend_string* source_string,
#else
ZEND_API zend_op_array* sp_compile_string(zval* source_string, char* filename) {
#endif
+ // TODO(jvoisin) handle recursive calls to `eval`
+ SPG(eval_source_string) = source_string;
zend_op_array* opline = orig_zend_compile_string(source_string, filename);
sp_sloppy_modify_opcode(opline);
return opline;
diff --git a/src/sp_utils.c b/src/sp_utils.c
index df2f0d6..d7200b1 100644
--- a/src/sp_utils.c
+++ b/src/sp_utils.c
@@ -177,6 +177,15 @@ int sp_log_request(const zend_string* restrict folder, const zend_string* restri
ZEND_HASH_FOREACH_END();
fputs("\n", file);
}
+
+ if (UNEXPECTED(0 != SPG(in_eval))) {
+#if PHP_VERSION_ID >= 80000
+ fprintf(file, "EVAL_CODE: %s\n", ZSTR_VAL(SPG(eval_source_string)));
+#else
+ fprintf(file, "EVAL_CODE: %s\n", ZSTR_VAL(zval_get_string(SPG(eval_source_string))));
+#endif
+ }
+
fclose(file);
return 0;
diff --git a/src/tests/dump_request/dump_eval_blacklist.phpt b/src/tests/dump_request/dump_eval_blacklist.phpt
index c9f48e4..a8c1618 100644
--- a/src/tests/dump_request/dump_eval_blacklist.phpt
+++ b/src/tests/dump_request/dump_eval_blacklist.phpt
@@ -38,6 +38,8 @@ if ($res[3] != "GET:get_a='data_get_a' get_b='data_get_b' \n") {
echo "Invalid POST";
} elseif ($res[5] != "COOKIE:cookie_a='data_cookie_a&cookie_b=data_cookie_b' \n") {
echo "Invalid COOKIE";
+} elseif ($res[6] != "EVAL_CODE: \$a = strtoupper(\"1234\");\n") {
+ echo "Invalid EVAL_CODE";
}
?>
--EXPECTF--
--
cgit v1.3
From 86407a7347963c4d6eb532a770d38df6223976e0 Mon Sep 17 00:00:00 2001
From: jvoisin
Date: Mon, 27 Jun 2022 22:47:20 +0200
Subject: Minor code simplification
---
src/sp_utils.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/sp_utils.c b/src/sp_utils.c
index d7200b1..2ec1750 100644
--- a/src/sp_utils.c
+++ b/src/sp_utils.c
@@ -182,7 +182,7 @@ int sp_log_request(const zend_string* restrict folder, const zend_string* restri
#if PHP_VERSION_ID >= 80000
fprintf(file, "EVAL_CODE: %s\n", ZSTR_VAL(SPG(eval_source_string)));
#else
- fprintf(file, "EVAL_CODE: %s\n", ZSTR_VAL(zval_get_string(SPG(eval_source_string))));
+ fprintf(file, "EVAL_CODE: %s\n", Z_STRVAL_P(SPG(eval_source_string)));
#endif
}
--
cgit v1.3
From d310283dd5b2dbd74d5077c436911fce4e2d2b7e Mon Sep 17 00:00:00 2001
From: jvoisin
Date: Mon, 27 Jun 2022 23:03:56 +0200
Subject: Add another user to the propaganda page
---
doc/source/papers.rst | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/doc/source/papers.rst b/doc/source/papers.rst
index eb63021..cf75311 100644
--- a/doc/source/papers.rst
+++ b/doc/source/papers.rst
@@ -123,8 +123,9 @@ Notable users
- `AdwCleaner `__'s backend- a notorious anti-pup
- `Alertot `__ - a Chilean continuous web security monitoring company
-- `NBS System `__ - a French hosting/security company and author of snuffleupagus
+- `Control Web Panel `__ - a free modern and intuitive control panel for servers and VPS
- `Mangadex `__ - a major manga website
+- `NBS System `__ - a French hosting/security company and author of snuffleupagus
- `Net4All `__ - a Swiss hosting company
- `Oceanet Technology `__ - a French hosting company
- `SwissCenter `__ - a Swiss datacenter & web hosting company
--
cgit v1.3
From 423e133c569b7d749cba3e1b97e9e138e5f0f892 Mon Sep 17 00:00:00 2001
From: jvoisin
Date: Tue, 12 Jul 2022 20:57:19 +0200
Subject: Log `eval` content when matching on its parameter
---
src/sp_execute.c | 8 +++++---
.../config/config_disabled_functions_eval_param.ini | 1 +
.../disable_function/disabled_functions_eval_param.phpt | 14 ++++++++++++++
3 files changed, 20 insertions(+), 3 deletions(-)
create mode 100644 src/tests/disable_function/config/config_disabled_functions_eval_param.ini
create mode 100644 src/tests/disable_function/disabled_functions_eval_param.phpt
diff --git a/src/sp_execute.c b/src/sp_execute.c
index a8798e4..2b8bb2e 100644
--- a/src/sp_execute.c
+++ b/src/sp_execute.c
@@ -136,9 +136,11 @@ static inline void sp_execute_handler(INTERNAL_FUNCTION_PARAMETERS, bool interna
if (UNEXPECTED(EX(func)->op_array.type == ZEND_EVAL_CODE)) {
const sp_list_node *config = zend_hash_str_find_ptr(SPCFG(disabled_functions), ZEND_STRL("eval"));
- zend_string *filename = get_eval_filename(zend_get_executed_filename());
- is_builtin_matching(filename, "eval", NULL, config, SPCFG(disabled_functions));
- zend_string_release(filename);
+#if PHP_VERSION_ID >= 80000
+ is_builtin_matching(SPG(eval_source_string), "eval", "code", config, SPCFG(disabled_functions));
+#else
+ is_builtin_matching(Z_STR_P(SPG(eval_source_string)), "eval", "code", config, SPCFG(disabled_functions));
+#endif
SPG(in_eval)++;
sp_orig_execute(execute_data);
diff --git a/src/tests/disable_function/config/config_disabled_functions_eval_param.ini b/src/tests/disable_function/config/config_disabled_functions_eval_param.ini
new file mode 100644
index 0000000..b43faf1
--- /dev/null
+++ b/src/tests/disable_function/config/config_disabled_functions_eval_param.ini
@@ -0,0 +1 @@
+sp.disable_function.function("eval").param("code").drop();
diff --git a/src/tests/disable_function/disabled_functions_eval_param.phpt b/src/tests/disable_function/disabled_functions_eval_param.phpt
new file mode 100644
index 0000000..4f3f1ef
--- /dev/null
+++ b/src/tests/disable_function/disabled_functions_eval_param.phpt
@@ -0,0 +1,14 @@
+--TEST--
+Disable functions - eval, on matching parameter
+--SKIPIF--
+
+--INI--
+sp.configuration_file={PWD}/config/config_disabled_functions_eval_param.ini
+--FILE--
+
+--EXPECTF--
+Fatal error: [snuffleupagus][0.0.0.0][disabled_function][drop] Aborted execution on call of the function 'eval', because its argument 'code' content ($var = 1337 + 1337;) matched a rule in %s/tests/disable_function/disabled_functions_eval_param.php(3) : eval()'d code on line 1
--
cgit v1.3
From 83014d7df165f8b8a9bf6dd4fde93fd1d42e4b7e Mon Sep 17 00:00:00 2001
From: jvoisin
Date: Tue, 12 Jul 2022 21:24:44 +0200
Subject: Minor refactorisation
---
src/php_snuffleupagus.h | 11 +++++++++--
src/snuffleupagus.c | 8 --------
2 files changed, 9 insertions(+), 10 deletions(-)
diff --git a/src/php_snuffleupagus.h b/src/php_snuffleupagus.h
index a4a0ed4..95caa65 100644
--- a/src/php_snuffleupagus.h
+++ b/src/php_snuffleupagus.h
@@ -11,6 +11,12 @@
#include "config.h"
#endif
+#ifdef PHP_WIN32
+#include "win32/glob.h"
+#else
+#include
+#endif
+
#include
#include
#include
@@ -41,6 +47,7 @@
#include "zend_extensions.h"
#include "zend_hash.h"
#include "zend_string.h"
+#include "zend_smart_str.h"
#include "zend_types.h"
#include "zend_vm.h"
@@ -150,9 +157,9 @@ HashTable *sp_internal_functions_hook;
HashTable *sp_eval_blacklist_functions_hook;
#if PHP_VERSION_ID >= 80000
-zend_string* eval_source_string;
+const zend_string* eval_source_string;
#else
-zval* eval_source_string;
+const zval* eval_source_string;
#endif
ZEND_END_MODULE_GLOBALS(snuffleupagus)
diff --git a/src/snuffleupagus.c b/src/snuffleupagus.c
index 06b93e1..4c9e904 100644
--- a/src/snuffleupagus.c
+++ b/src/snuffleupagus.c
@@ -1,11 +1,3 @@
-#ifdef PHP_WIN32
-#include "win32/glob.h"
-#else
-#include
-#endif
-
-#include "zend_smart_str.h"
-
#include "php_snuffleupagus.h"
#ifndef ZEND_EXT_API
--
cgit v1.3
From 8795ce1a92d226e31668db2f6cfbd33b40632109 Mon Sep 17 00:00:00 2001
From: jvoisin
Date: Tue, 12 Jul 2022 21:54:19 +0200
Subject: Constify some variables
---
src/snuffleupagus.c | 13 ++++++++-----
src/sp_ini.c | 11 +++++------
2 files changed, 13 insertions(+), 11 deletions(-)
diff --git a/src/snuffleupagus.c b/src/snuffleupagus.c
index 4c9e904..5bcd57c 100644
--- a/src/snuffleupagus.c
+++ b/src/snuffleupagus.c
@@ -254,7 +254,7 @@ PHP_MINFO_FUNCTION(snuffleupagus) {
#define ADD_ASSOC_ZSTR(arr, key, zstr) if (zstr) { add_assoc_str(arr, key, zstr); } else { add_assoc_null(arr, key); }
#define ADD_ASSOC_REGEXP(arr, key, regexp) if (regexp && regexp->pattern) { add_assoc_str(arr, key, regexp->pattern); } else { add_assoc_null(arr, key); }
-static void add_df_to_arr(zval *arr, sp_disabled_function *df) {
+static void add_df_to_arr(zval *arr, sp_disabled_function const *const df) {
zval arr_df;
array_init(&arr_df);
@@ -365,7 +365,7 @@ static void dump_config() {
if (splist) { \
zval arr_sp; \
array_init(&arr_sp); \
- for (sp_list_node *p = splist; p; p = p->next) { add_next_index_str(&arr_sp, p->data); } \
+ for (const sp_list_node *p = splist; p; p = p->next) { add_next_index_str(&arr_sp, p->data); } \
add_assoc_zval(arr, key, &arr_sp); \
} else { add_assoc_null(arr, key); }
@@ -381,6 +381,8 @@ static void dump_config() {
ADD_ASSOC_SPLIST(&arr, SP_TOKEN_ALLOW_WRAPPERS, SPCFG(wrapper).whitelist);
+#undef ADD_ASSOC_SPLIST
+
add_assoc_bool(&arr, SP_TOKEN_INI_PROTECTION "." SP_TOKEN_ENABLE, SPCFG(ini).enable);
add_assoc_bool(&arr, SP_TOKEN_INI_PROTECTION "." SP_TOKEN_SIM, SPCFG(ini).simulation);
add_assoc_bool(&arr, SP_TOKEN_INI_PROTECTION "." "policy_ro", SPCFG(ini).policy_readonly);
@@ -392,7 +394,7 @@ static void dump_config() {
zval arr_ini;
array_init(&arr_ini);
- sp_ini_entry *sp_entry;
+ const sp_ini_entry *sp_entry;
ZEND_HASH_FOREACH_PTR(SPCFG(ini).entries, sp_entry)
zval arr_ini_entry;
array_init(&arr_ini_entry);
@@ -442,7 +444,8 @@ static void dump_config() {
zval arr_dfs;
array_init(&arr_dfs);
size_t num_df = 0;
- sp_list_node *dflist, *dfp;
+ const sp_list_node *dflist;
+ const sp_list_node *dfp;
ZEND_HASH_FOREACH_PTR(SPCFG(disabled_functions), dflist)
for (dfp = dflist; dfp; dfp = dfp->next) {
add_df_to_arr(&arr_dfs, dfp->data);
@@ -597,7 +600,7 @@ static PHP_INI_MH(OnUpdateConfiguration) {
(SPCFG(disabled_functions_ret) && zend_hash_num_elements(SPCFG(disabled_functions_ret)));
if (SPCFG(show_old_php_warning) && getenv("SP_SKIP_OLD_PHP_CHECK") == NULL) {
- time_t ts = time(NULL);
+ const time_t ts = time(NULL);
if ((PHP_VERSION_ID < 70300) ||
(PHP_VERSION_ID < 70400 && ts >= (time_t)1638745200L) ||
(PHP_VERSION_ID < 80000 && ts >= (time_t)1669590000L) ||
diff --git a/src/sp_ini.c b/src/sp_ini.c
index 7fec297..ed23fb7 100644
--- a/src/sp_ini.c
+++ b/src/sp_ini.c
@@ -12,12 +12,12 @@
}
-static bool /* success */ sp_ini_check(zend_string *varname, zend_string *new_value, sp_ini_entry **sp_entry_p) {
+static bool /* success */ sp_ini_check(zend_string *const restrict varname, zend_string const *const restrict new_value, sp_ini_entry **sp_entry_p) {
if (!varname || ZSTR_LEN(varname) == 0) {
return false;
}
- sp_config_ini *cfg = &(SPCFG(ini));
+ sp_config_ini const* const cfg = &(SPCFG(ini));
sp_ini_entry *entry = zend_hash_find_ptr(cfg->entries, varname);
if (sp_entry_p) {
*sp_entry_p = entry;
@@ -76,10 +76,9 @@ static bool /* success */ sp_ini_check(zend_string *varname, zend_string *new_va
}
static PHP_INI_MH(sp_ini_onmodify) {
- zend_ini_entry *ini_entry = entry;
sp_ini_entry *sp_entry = NULL;
- if (!sp_ini_check(ini_entry->name, new_value, &sp_entry)) {
+ if (!sp_ini_check(entry->name, new_value, &sp_entry)) {
return FAILURE;
}
@@ -91,7 +90,7 @@ static PHP_INI_MH(sp_ini_onmodify) {
}
void sp_hook_ini() {
- sp_config_ini *cfg = &(SPCFG(ini));
+ sp_config_ini const* const cfg = &(SPCFG(ini));
sp_ini_entry *sp_entry;
zend_ini_entry *ini_entry;
ZEND_HASH_FOREACH_PTR(cfg->entries, sp_entry)
@@ -126,8 +125,8 @@ void sp_hook_ini() {
void sp_unhook_ini() {
sp_ini_entry *sp_entry;
- zend_ini_entry *ini_entry;
ZEND_HASH_FOREACH_PTR(SPCFG(ini).entries, sp_entry)
+ zend_ini_entry *ini_entry;
if (!sp_entry->orig_onmodify) {
// not hooked or no original onmodify
continue;
--
cgit v1.3
From 077e96b6319aaf26414d1d0eeb30eb4f144f0019 Mon Sep 17 00:00:00 2001
From: Ben Fuhrmannek
Date: Tue, 19 Apr 2022 12:43:18 +0200
Subject: allow file:// prefix in include() wich readonly_exec mode
---
src/sp_execute.c | 13 +++++++++----
src/tests/deny_writable/deny_writable_execution.phpt | 2 +-
2 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/src/sp_execute.c b/src/sp_execute.c
index 2b8bb2e..cc401aa 100644
--- a/src/sp_execute.c
+++ b/src/sp_execute.c
@@ -17,9 +17,9 @@ ZEND_COLD static inline void terminate_if_writable(const char *filename) {
sp_log_request(config_ro_exec->dump, config_ro_exec->textual_representation);
}
if (true == config_ro_exec->simulation) {
- sp_log_simulation("readonly_exec", "Attempted execution of a writable file (%s).", filename);
+ sp_log_simulation("readonly_exec", "Attempted execution of a writable file (%s)", filename);
} else {
- sp_log_drop("readonly_exec", "Attempted execution of a writable file (%s).", filename);
+ sp_log_drop("readonly_exec", "Attempted execution of a writable file (%s)", filename);
}
} else {
if (EACCES != errno) {
@@ -226,13 +226,18 @@ static inline void sp_stream_open_checks(zend_string *zend_filename, zend_file_h
return;
}
- // zend_string *zend_filename = zend_string_init(filename, strlen(filename), 0);
const HashTable *disabled_functions_hooked = SPCFG(disabled_functions_hooked);
switch (data->opline->opcode) {
case ZEND_INCLUDE_OR_EVAL:
if (SPCFG(readonly_exec).enable) {
- terminate_if_writable(ZSTR_VAL(zend_filename));
+ char *fn = ZSTR_VAL(zend_filename);
+ if (ZSTR_LEN(zend_filename) >= strlen("file://") && memcmp(fn, "file://", strlen("file://")) == 0) {
+ fn += strlen("file://");
+ } else if (!php_memnstr(ZSTR_VAL(zend_filename), "://", strlen("://"), ZSTR_VAL(zend_filename) + ZSTR_LEN(zend_filename))) {
+ // ignore stream wrappers other than file:// for now
+ terminate_if_writable(fn);
+ }
}
switch (data->opline->extended_value) {
case ZEND_INCLUDE:
diff --git a/src/tests/deny_writable/deny_writable_execution.phpt b/src/tests/deny_writable/deny_writable_execution.phpt
index e65dc32..a629479 100644
--- a/src/tests/deny_writable/deny_writable_execution.phpt
+++ b/src/tests/deny_writable/deny_writable_execution.phpt
@@ -40,4 +40,4 @@ unlink("$dir/non_writable_file.txt");
unlink("$dir/writable_file.txt");
?>
--EXPECTF--
-Fatal error: [snuffleupagus][0.0.0.0][readonly_exec][drop] Attempted execution of a writable file (%a/deny_writable_execution.php). in %a/deny_writable_execution.php on line 2
+Fatal error: [snuffleupagus][0.0.0.0][readonly_exec][drop] Attempted execution of a writable file (%a/deny_writable_execution.php) in %a/deny_writable_execution.php on line 2
--
cgit v1.3
From cd9031935ef2306f7ba2097856b20bf116f341ee Mon Sep 17 00:00:00 2001
From: Ben Fuhrmannek
Date: Tue, 19 Apr 2022 19:01:52 +0200
Subject: extended checks for readonly_exec, enabled by default
introduced config options:
readonly_exec.extended_checks() or xchecks()
readonly_exec.no_extended_checks() or noxchecks()
---
src/snuffleupagus.c | 2 +
src/sp_config.h | 1 +
src/sp_config_keywords.c | 7 +-
src/sp_execute.c | 77 ++++++++++++++++++----
.../deny_writable_execution_simulation.phpt | 10 ++-
5 files changed, 80 insertions(+), 17 deletions(-)
diff --git a/src/snuffleupagus.c b/src/snuffleupagus.c
index 5bcd57c..448fd76 100644
--- a/src/snuffleupagus.c
+++ b/src/snuffleupagus.c
@@ -340,6 +340,7 @@ static void dump_config() {
add_assoc_bool(&arr, "readonly_exec.enable", SPCFG(readonly_exec).enable);
add_assoc_bool(&arr, "readonly_exec.sim", SPCFG(readonly_exec).simulation);
ADD_ASSOC_ZSTR(&arr, SP_TOKEN_READONLY_EXEC "." SP_TOKEN_DUMP, SPCFG(readonly_exec).dump);
+ add_assoc_bool(&arr, "readonly_exec.extended_checks", SPCFG(readonly_exec).extended_checks);
add_assoc_bool(&arr, "global_strict.enable", SPCFG(global_strict).enable);
@@ -494,6 +495,7 @@ static PHP_INI_MH(OnUpdateConfiguration) {
// set some defaults
SPCFG(show_old_php_warning) = true;
+ SPCFG(readonly_exec).extended_checks = true;
char *str = new_value->val;
diff --git a/src/sp_config.h b/src/sp_config.h
index 3d92f2f..ec73310 100644
--- a/src/sp_config.h
+++ b/src/sp_config.h
@@ -35,6 +35,7 @@ typedef struct {
typedef struct {
bool enable;
bool simulation;
+ bool extended_checks;
zend_string *dump;
zend_string *textual_representation;
} sp_config_readonly_exec;
diff --git a/src/sp_config_keywords.c b/src/sp_config_keywords.c
index f7be731..e0e5166 100644
--- a/src/sp_config_keywords.c
+++ b/src/sp_config_keywords.c
@@ -96,7 +96,7 @@ SP_PARSE_FN(parse_unserialize) {
}
SP_PARSE_FN(parse_readonly_exec) {
- bool enable = false, disable = false;
+ bool enable = false, disable = false, xchecks = false, no_xchecks = false;
sp_config_readonly_exec *cfg = (sp_config_readonly_exec*)retval;
sp_config_keyword config_keywords[] = {
@@ -105,6 +105,10 @@ SP_PARSE_FN(parse_readonly_exec) {
{parse_empty, SP_TOKEN_SIMULATION, &(cfg->simulation)},
{parse_empty, SP_TOKEN_SIM, &(cfg->simulation)},
{parse_str, SP_TOKEN_DUMP, &(cfg->dump)},
+ {parse_empty, "extended_checks", &(xchecks)},
+ {parse_empty, "xchecks", &(xchecks)},
+ {parse_empty, "no_extended_checks", &(no_xchecks)},
+ {parse_empty, "noxchecks", &(no_xchecks)},
{0, 0, 0}};
SP_PROCESS_CONFIG_KEYWORDS_ERR();
@@ -112,6 +116,7 @@ SP_PARSE_FN(parse_readonly_exec) {
cfg->textual_representation = sp_get_textual_representation(parsed_rule);
SP_SET_ENABLE_DISABLE(enable, disable, cfg->enable);
+ if (xchecks) { cfg->extended_checks = true; } else if (no_xchecks) { cfg->extended_checks = false; }
return SP_PARSER_STOP;
}
diff --git a/src/sp_execute.c b/src/sp_execute.c
index cc401aa..56d25c5 100644
--- a/src/sp_execute.c
+++ b/src/sp_execute.c
@@ -1,4 +1,5 @@
#include "php_snuffleupagus.h"
+#include "ext/standard/php_string.h"
static void (*orig_execute_ex)(zend_execute_data *execute_data) = NULL;
static void (*orig_zend_execute_internal)(zend_execute_data *execute_data,
@@ -12,22 +13,72 @@ static zend_result (*orig_zend_stream_open)(zend_file_handle *handle) = NULL;
// FIXME handle symlink
ZEND_COLD static inline void terminate_if_writable(const char *filename) {
const sp_config_readonly_exec *config_ro_exec = &(SPCFG(readonly_exec));
+ char *errmsg = "unknown access problem";
+
+ // check write access
if (0 == access(filename, W_OK)) {
- if (config_ro_exec->dump) {
- sp_log_request(config_ro_exec->dump, config_ro_exec->textual_representation);
- }
- if (true == config_ro_exec->simulation) {
- sp_log_simulation("readonly_exec", "Attempted execution of a writable file (%s)", filename);
- } else {
- sp_log_drop("readonly_exec", "Attempted execution of a writable file (%s)", filename);
- }
+ errmsg = "Attempted execution of a writable file";
+ goto violation;
+ }
+ if (errno != EACCES) {
+ goto err;
+ }
+
+ // other checks are 'extended checks' that can be enabled/disabled via config
+ if (!config_ro_exec->extended_checks) {
+ return;
+ }
+
+ // check effective uid
+ struct stat buf;
+ if (0 != stat(filename, &buf)) {
+ goto err;
+ }
+ if (buf.st_uid == geteuid()) {
+ errmsg = "Attempted execution of file owned by process";
+ goto violation;
+ }
+
+ // check write access on directory
+ char *dirname = estrndup(filename, strlen(filename));
+ php_dirname(dirname, strlen(dirname));
+ if (0 == access(dirname, W_OK)) {
+ errmsg = "Attempted execution of file in writable directory";
+ efree(dirname);
+ goto violation;
+ }
+ if (errno != EACCES) {
+ efree(dirname);
+ goto err;
+ }
+
+ // check effecite uid of directory
+ if (0 != stat(dirname, &buf)) {
+ efree(dirname);
+ goto err;
+ }
+ efree(dirname);
+ if (buf.st_uid == geteuid()) {
+ errmsg = "Attempted execution of file in directory owned by process";
+ goto violation;
+ }
+
+ // we would actually need to check all parent directories as well, but that task is left for other tools
+ return;
+
+violation:
+ if (config_ro_exec->dump) {
+ sp_log_request(config_ro_exec->dump, config_ro_exec->textual_representation);
+ }
+ if (config_ro_exec->simulation) {
+ sp_log_simulation("readonly_exec", "%s (%s)", errmsg, filename);
} else {
- if (EACCES != errno) {
- // LCOV_EXCL_START
- sp_log_err("Writable execution", "Error while accessing %s: %s", filename, strerror(errno));
- // LCOV_EXCL_STOP
- }
+ sp_log_drop("readonly_exec", "%s (%s)", errmsg, filename);
}
+ return;
+
+err:
+ sp_log_err("readonly_exec", "Error while accessing %s: %s", filename, strerror(errno));
}
inline static void is_builtin_matching(
diff --git a/src/tests/deny_writable/deny_writable_execution_simulation.phpt b/src/tests/deny_writable/deny_writable_execution_simulation.phpt
index e3460e4..abc276f 100644
--- a/src/tests/deny_writable/deny_writable_execution_simulation.phpt
+++ b/src/tests/deny_writable/deny_writable_execution_simulation.phpt
@@ -41,10 +41,14 @@ unlink("$dir/non_writable_file.txt");
unlink("$dir/writable_file.txt");
?>
--EXPECTF--
-Warning: [snuffleupagus][0.0.0.0][readonly_exec][simulation] Attempted execution of a writable file (%a/deny_writable_execution_simulation.php). in %a/deny_writable_execution_simulation.php on line 2
+Warning: [snuffleupagus][0.0.0.0][readonly_exec][simulation] Attempted execution of a writable file (%a/deny_writable_execution_simulation.php) in %a/deny_writable_execution_simulation.php on line 2
-Warning: [snuffleupagus][0.0.0.0][readonly_exec][simulation] Attempted execution of a writable file (%a/writable_file.txt). in %a/deny_writable_execution_simulation.php on line 12
+Warning: [snuffleupagus][0.0.0.0][readonly_exec][simulation] Attempted execution of a writable file (%a/writable_file.txt) in %a/deny_writable_execution_simulation.php on line 12
-Warning: [snuffleupagus][0.0.0.0][readonly_exec][simulation] Attempted execution of a writable file (%a/writable_file.txt). in %a/writable_file.txt on line 1
+Warning: [snuffleupagus][0.0.0.0][readonly_exec][simulation] Attempted execution of a writable file (%a/writable_file.txt) in %a/writable_file.txt on line 1
Code execution within a writable file.
+
+Warning: [snuffleupagus][0.0.0.0][readonly_exec][simulation] Attempted execution of file owned by process (%s/tests/deny_writable/non_writable_file.txt) in %s/tests/deny_writable/deny_writable_execution_simulation.php on line 13
+
+Warning: [snuffleupagus][0.0.0.0][readonly_exec][simulation] Attempted execution of file owned by process (%s/tests/deny_writable/non_writable_file.txt) in %src/tests/deny_writable/non_writable_file.txt on line 1
Code execution within a non-writable file.
--
cgit v1.3
From 08e87202676a4676e66a27625522374faa70704c Mon Sep 17 00:00:00 2001
From: jvoisin
Date: Tue, 12 Jul 2022 22:52:13 +0200
Subject: Disable extended checks for readonly_exec by default
---
src/snuffleupagus.c | 1 -
src/tests/deny_writable/config/config_disable_writable_simulation.ini | 2 +-
2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/src/snuffleupagus.c b/src/snuffleupagus.c
index 448fd76..1f5b660 100644
--- a/src/snuffleupagus.c
+++ b/src/snuffleupagus.c
@@ -495,7 +495,6 @@ static PHP_INI_MH(OnUpdateConfiguration) {
// set some defaults
SPCFG(show_old_php_warning) = true;
- SPCFG(readonly_exec).extended_checks = true;
char *str = new_value->val;
diff --git a/src/tests/deny_writable/config/config_disable_writable_simulation.ini b/src/tests/deny_writable/config/config_disable_writable_simulation.ini
index 52a43ba..3aafe3f 100644
--- a/src/tests/deny_writable/config/config_disable_writable_simulation.ini
+++ b/src/tests/deny_writable/config/config_disable_writable_simulation.ini
@@ -1 +1 @@
- sp.readonly_exec.enable().simulation();
+ sp.readonly_exec.enable().extended_checks().simulation();
--
cgit v1.3
From 8d6496efcab420267a228c35f9f627fec209d031 Mon Sep 17 00:00:00 2001
From: jvoisin
Date: Tue, 12 Jul 2022 23:03:46 +0200
Subject: Refactoring of the previous commit
---
src/php_snuffleupagus.h | 1 +
src/sp_execute.c | 20 +++++++-------------
.../deny_writable_execution_simulation.phpt | 4 ++--
3 files changed, 10 insertions(+), 15 deletions(-)
diff --git a/src/php_snuffleupagus.h b/src/php_snuffleupagus.h
index 95caa65..3eeb9db 100644
--- a/src/php_snuffleupagus.h
+++ b/src/php_snuffleupagus.h
@@ -38,6 +38,7 @@
#include "ext/standard/head.h"
#include "ext/standard/info.h"
#include "ext/standard/url.h"
+#include "ext/standard/php_string.h"
#include "ext/standard/php_var.h"
#include "ext/session/php_session.h"
#include "php.h"
diff --git a/src/sp_execute.c b/src/sp_execute.c
index 56d25c5..65a32db 100644
--- a/src/sp_execute.c
+++ b/src/sp_execute.c
@@ -1,5 +1,4 @@
#include "php_snuffleupagus.h"
-#include "ext/standard/php_string.h"
static void (*orig_execute_ex)(zend_execute_data *execute_data) = NULL;
static void (*orig_zend_execute_internal)(zend_execute_data *execute_data,
@@ -11,11 +10,10 @@ static zend_result (*orig_zend_stream_open)(zend_file_handle *handle) = NULL;
#endif
// FIXME handle symlink
-ZEND_COLD static inline void terminate_if_writable(const char *filename) {
- const sp_config_readonly_exec *config_ro_exec = &(SPCFG(readonly_exec));
- char *errmsg = "unknown access problem";
+ZEND_COLD static inline void terminate_if_writable(char const* const filename) {
+ sp_config_readonly_exec const* const config_ro_exec = &(SPCFG(readonly_exec));
+ char const *errmsg = "unknown access problem";
- // check write access
if (0 == access(filename, W_OK)) {
errmsg = "Attempted execution of a writable file";
goto violation;
@@ -29,21 +27,19 @@ ZEND_COLD static inline void terminate_if_writable(const char *filename) {
return;
}
- // check effective uid
struct stat buf;
if (0 != stat(filename, &buf)) {
goto err;
}
if (buf.st_uid == geteuid()) {
- errmsg = "Attempted execution of file owned by process";
+ errmsg = "Attempted execution of a file owned by the PHP process";
goto violation;
}
- // check write access on directory
- char *dirname = estrndup(filename, strlen(filename));
+ char *const dirname = estrndup(filename, strlen(filename));
php_dirname(dirname, strlen(dirname));
if (0 == access(dirname, W_OK)) {
- errmsg = "Attempted execution of file in writable directory";
+ errmsg = "Attempted execution of a file in a writable directory";
efree(dirname);
goto violation;
}
@@ -52,18 +48,16 @@ ZEND_COLD static inline void terminate_if_writable(const char *filename) {
goto err;
}
- // check effecite uid of directory
if (0 != stat(dirname, &buf)) {
efree(dirname);
goto err;
}
efree(dirname);
if (buf.st_uid == geteuid()) {
- errmsg = "Attempted execution of file in directory owned by process";
+ errmsg = "Attempted execution of a file in directory owned by the PHP process";
goto violation;
}
- // we would actually need to check all parent directories as well, but that task is left for other tools
return;
violation:
diff --git a/src/tests/deny_writable/deny_writable_execution_simulation.phpt b/src/tests/deny_writable/deny_writable_execution_simulation.phpt
index abc276f..d4e4801 100644
--- a/src/tests/deny_writable/deny_writable_execution_simulation.phpt
+++ b/src/tests/deny_writable/deny_writable_execution_simulation.phpt
@@ -48,7 +48,7 @@ Warning: [snuffleupagus][0.0.0.0][readonly_exec][simulation] Attempted execution
Warning: [snuffleupagus][0.0.0.0][readonly_exec][simulation] Attempted execution of a writable file (%a/writable_file.txt) in %a/writable_file.txt on line 1
Code execution within a writable file.
-Warning: [snuffleupagus][0.0.0.0][readonly_exec][simulation] Attempted execution of file owned by process (%s/tests/deny_writable/non_writable_file.txt) in %s/tests/deny_writable/deny_writable_execution_simulation.php on line 13
+Warning: [snuffleupagus][0.0.0.0][readonly_exec][simulation] Attempted execution of a file owned by the PHP process (%s/tests/deny_writable/non_writable_file.txt) in %s/tests/deny_writable/deny_writable_execution_simulation.php on line 13
-Warning: [snuffleupagus][0.0.0.0][readonly_exec][simulation] Attempted execution of file owned by process (%s/tests/deny_writable/non_writable_file.txt) in %src/tests/deny_writable/non_writable_file.txt on line 1
+Warning: [snuffleupagus][0.0.0.0][readonly_exec][simulation] Attempted execution of a file owned by the PHP process (%s/tests/deny_writable/non_writable_file.txt) in %src/tests/deny_writable/non_writable_file.txt on line 1
Code execution within a non-writable file.
--
cgit v1.3
From eaba9e0e7421fec0bc7a0cd8745dc3fb4e2e72f1 Mon Sep 17 00:00:00 2001
From: jvoisin
Date: Tue, 12 Jul 2022 23:10:06 +0200
Subject: Document extended_checks for readonly_exec
---
doc/source/config.rst | 3 +++
1 file changed, 3 insertions(+)
diff --git a/doc/source/config.rst b/doc/source/config.rst
index 0b7b7fd..bbf3b91 100644
--- a/doc/source/config.rst
+++ b/doc/source/config.rst
@@ -261,6 +261,9 @@ readonly_exec
the execution of writeable PHP files.
It can either be ``enabled`` or ``disabled`` and can be used in ``simulation`` mode.
+``extended_checks`` can be specified to abort the execution if the executed
+file or the folder containing it is owned by the user the PHP process is
+running under.
::
--
cgit v1.3
From 3dbb2f3feeec54c4ab6b2efc53b5c5635dbd9129 Mon Sep 17 00:00:00 2001
From: jvoisin
Date: Wed, 13 Jul 2022 01:11:44 +0200
Subject: Mix the stacktrace in the sha256 for the filename of .dump()
This should make it easier to fuzz using Snuffleupagus.
---
src/sp_utils.c | 60 +++++++++++++++++++++++++++++++++++-----------------------
1 file changed, 36 insertions(+), 24 deletions(-)
diff --git a/src/sp_utils.c b/src/sp_utils.c
index 2ec1750..fdcdc99 100644
--- a/src/sp_utils.c
+++ b/src/sp_utils.c
@@ -93,32 +93,12 @@ int compute_hash(const char* const restrict filename,
static int construct_filename(char* filename,
const zend_string* restrict folder,
const zend_string* restrict textual) {
- PHP_SHA256_CTX context;
- unsigned char digest[SHA256_SIZE] = {0};
- char strhash[65] = {0};
-
- if (-1 == mkdir(ZSTR_VAL(folder), 0700) && errno != EEXIST) {
- sp_log_warn("request_logging", "Unable to create the folder '%s'",
- ZSTR_VAL(folder));
- return -1;
- }
-
- /* We're using the sha256 sum of the rule's textual representation
- * as filename, in order to only have one dump per rule, to mitigate
- * DoS attacks. */
- PHP_SHA256Init(&context);
- PHP_SHA256Update(&context, (const unsigned char*)ZSTR_VAL(textual),
- ZSTR_LEN(textual));
- PHP_SHA256Final(digest, &context);
- make_digest_ex(strhash, digest, SHA256_SIZE);
- snprintf(filename, PATH_MAX - 1, "%s/sp_dump.%s", ZSTR_VAL(folder), strhash);
-
return 0;
}
int sp_log_request(const zend_string* restrict folder, const zend_string* restrict text_repr) {
FILE* file;
- const char* current_filename = zend_get_executed_filename(TSRMLS_C);
+ char const* const current_filename = zend_get_executed_filename(TSRMLS_C);
const int current_line = zend_get_executed_lineno(TSRMLS_C);
char filename[PATH_MAX] = {0};
const struct {
@@ -128,9 +108,41 @@ int sp_log_request(const zend_string* restrict folder, const zend_string* restri
{"COOKIE", TRACK_VARS_COOKIE}, {"SERVER", TRACK_VARS_SERVER},
{"ENV", TRACK_VARS_ENV}, {NULL, 0}};
- if (0 != construct_filename(filename, folder, text_repr)) {
+ PHP_SHA256_CTX context;
+ unsigned char digest[SHA256_SIZE] = {0};
+ char strhash[65] = {0};
+
+ if (-1 == mkdir(ZSTR_VAL(folder), 0700) && errno != EEXIST) {
+ sp_log_warn("request_logging", "Unable to create the folder '%s'",
+ ZSTR_VAL(folder));
return -1;
}
+
+ /* We're using the sha256 sum of the rule's textual representation, as well
+ * as the stacktrace as filename, in order to only have one dump per rule, to
+ * mitigate DoS attacks. We're doing the walk-the-execution-context dance
+ * twice because it's easier than to cache it in a linked-list. It doesn't
+ * really matter, since this is a super-cold path anyway.
+ */
+ PHP_SHA256Init(&context);
+ PHP_SHA256Update(&context, (const unsigned char*)ZSTR_VAL(text_repr), ZSTR_LEN(text_repr));
+ zend_execute_data* orig_execute_data = EG(current_execute_data);
+ zend_execute_data* current = EG(current_execute_data);
+ while (current) {
+ EG(current_execute_data) = current;
+ char* const complete_path_function = get_complete_function_path(current);
+ if (complete_path_function) {
+ const int current_line = zend_get_executed_lineno(TSRMLS_C);
+ PHP_SHA256Update(&context, (const unsigned char*)complete_path_function, strlen(complete_path_function));
+ efree(complete_path_function);
+ }
+ current = current->prev_execute_data;
+ }
+ EG(current_execute_data) = orig_execute_data;
+ PHP_SHA256Final(digest, &context);
+ make_digest_ex(strhash, digest, SHA256_SIZE);
+ snprintf(filename, PATH_MAX - 1, "%s/sp_dump.%s", ZSTR_VAL(folder), strhash);
+
if (NULL == (file = fopen(filename, "w+"))) {
sp_log_warn("request_logging", "Unable to open %s: %s", filename,
strerror(errno));
@@ -141,8 +153,8 @@ int sp_log_request(const zend_string* restrict folder, const zend_string* restri
fprintf(file, "FILE: %s:%d\n", current_filename, current_line);
- zend_execute_data* orig_execute_data = EG(current_execute_data);
- zend_execute_data* current = EG(current_execute_data);
+ orig_execute_data = EG(current_execute_data);
+ current = EG(current_execute_data);
while (current) {
EG(current_execute_data) = current;
char* const complete_path_function = get_complete_function_path(current);
--
cgit v1.3
From a205a17fc49dfb6701fdc68c1f2b05f11cd1e56f Mon Sep 17 00:00:00 2001
From: jvoisin
Date: Wed, 13 Jul 2022 02:10:44 +0200
Subject: Remove some dead code
---
src/sp_utils.c | 7 -------
1 file changed, 7 deletions(-)
diff --git a/src/sp_utils.c b/src/sp_utils.c
index fdcdc99..a8c84f9 100644
--- a/src/sp_utils.c
+++ b/src/sp_utils.c
@@ -90,12 +90,6 @@ int compute_hash(const char* const restrict filename,
return SUCCESS;
}
-static int construct_filename(char* filename,
- const zend_string* restrict folder,
- const zend_string* restrict textual) {
- return 0;
-}
-
int sp_log_request(const zend_string* restrict folder, const zend_string* restrict text_repr) {
FILE* file;
char const* const current_filename = zend_get_executed_filename(TSRMLS_C);
@@ -132,7 +126,6 @@ int sp_log_request(const zend_string* restrict folder, const zend_string* restri
EG(current_execute_data) = current;
char* const complete_path_function = get_complete_function_path(current);
if (complete_path_function) {
- const int current_line = zend_get_executed_lineno(TSRMLS_C);
PHP_SHA256Update(&context, (const unsigned char*)complete_path_function, strlen(complete_path_function));
efree(complete_path_function);
}
--
cgit v1.3
From 7deb974c164d4f7cfbe13c5403d8cd36a0cbc2eb Mon Sep 17 00:00:00 2001
From: jvoisin
Date: Wed, 13 Jul 2022 02:10:49 +0200
Subject: Minor micro-optimization
---
src/sp_utils.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/sp_utils.c b/src/sp_utils.c
index a8c84f9..57ecf67 100644
--- a/src/sp_utils.c
+++ b/src/sp_utils.c
@@ -142,7 +142,9 @@ int sp_log_request(const zend_string* restrict folder, const zend_string* restri
return -1;
}
- fprintf(file, "RULE: %s\n", ZSTR_VAL(text_repr));
+ fputs("RULE: ", file);
+ fputs(ZSTR_VAL(text_repr), file);
+ fputc('\n', file);
fprintf(file, "FILE: %s:%d\n", current_filename, current_line);
--
cgit v1.3
From ce95c32c91c1d78cfb7603699b6b10e54e931f45 Mon Sep 17 00:00:00 2001
From: jvoisin
Date: Wed, 13 Jul 2022 02:26:56 +0200
Subject: More micro-optimizations
---
src/sp_utils.c | 30 +++++++++++++++++++-----------
1 file changed, 19 insertions(+), 11 deletions(-)
diff --git a/src/sp_utils.c b/src/sp_utils.c
index 57ecf67..3436328 100644
--- a/src/sp_utils.c
+++ b/src/sp_utils.c
@@ -95,7 +95,7 @@ int sp_log_request(const zend_string* restrict folder, const zend_string* restri
char const* const current_filename = zend_get_executed_filename(TSRMLS_C);
const int current_line = zend_get_executed_lineno(TSRMLS_C);
char filename[PATH_MAX] = {0};
- const struct {
+ static const struct {
char const* const str;
const int key;
} zones[] = {{"GET", TRACK_VARS_GET}, {"POST", TRACK_VARS_POST},
@@ -146,7 +146,9 @@ int sp_log_request(const zend_string* restrict folder, const zend_string* restri
fputs(ZSTR_VAL(text_repr), file);
fputc('\n', file);
- fprintf(file, "FILE: %s:%d\n", current_filename, current_line);
+ fputs("FILE: ", file);
+ fputs(current_filename, file);
+ fprintf(file, ":%d\n", current_line);
orig_execute_data = EG(current_execute_data);
current = EG(current_execute_data);
@@ -155,7 +157,9 @@ int sp_log_request(const zend_string* restrict folder, const zend_string* restri
char* const complete_path_function = get_complete_function_path(current);
if (complete_path_function) {
const int current_line = zend_get_executed_lineno(TSRMLS_C);
- fprintf(file, "STACKTRACE: %s:%d\n", complete_path_function, current_line);
+ fputs("STACKTRACE: ", file);
+ fputs(complete_path_function, file);
+ fprintf(file, ":%d\n", current_line);
efree(complete_path_function);
}
current = current->prev_execute_data;
@@ -171,26 +175,30 @@ int sp_log_request(const zend_string* restrict folder, const zend_string* restri
}
HashTable* ht = Z_ARRVAL(PG(http_globals)[zones[i].key]);
- fprintf(file, "%s:", zones[i].str);
+ fputs(zones[i].str, file);
+ fputc(':', file);
ZEND_HASH_FOREACH_STR_KEY_VAL(ht, variable_key, variable_value) {
- smart_str a;
-
- memset(&a, 0, sizeof(a));
+ smart_str a = {0};
php_var_export_ex(variable_value, 1, &a);
ZSTR_VAL(a.s)[ZSTR_LEN(a.s)] = '\0';
- fprintf(file, "%s=%s ", ZSTR_VAL(variable_key), ZSTR_VAL(a.s));
+ fputs(ZSTR_VAL(variable_key), file);
+ fputc('=', file);
+ fputs(ZSTR_VAL(a.s), file);
+ fputc(' ', file);
zend_string_release(a.s);
}
ZEND_HASH_FOREACH_END();
- fputs("\n", file);
+ fputc('\n', file);
}
if (UNEXPECTED(0 != SPG(in_eval))) {
+ fputs("EVAL_CODE: ", file);
#if PHP_VERSION_ID >= 80000
- fprintf(file, "EVAL_CODE: %s\n", ZSTR_VAL(SPG(eval_source_string)));
+ fputs(ZSTR_VAL(SPG(eval_source_string)), file);
#else
- fprintf(file, "EVAL_CODE: %s\n", Z_STRVAL_P(SPG(eval_source_string)));
+ fputs(Z_STRVAL_P(SPG(eval_source_string)), file);
#endif
+ fputc('\n', file);
}
fclose(file);
--
cgit v1.3
From ed87e551efd0160f1944a5e97158ab258db65eaf Mon Sep 17 00:00:00 2001
From: jvoisin
Date: Wed, 13 Jul 2022 21:25:04 +0200
Subject: Even more const!
---
src/sp_utils.c | 10 +++++-----
src/sp_utils.h | 6 +++---
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/src/sp_utils.c b/src/sp_utils.c
index 3436328..42f7871 100644
--- a/src/sp_utils.c
+++ b/src/sp_utils.c
@@ -1,6 +1,6 @@
#include "php_snuffleupagus.h"
-static const char* default_ipaddr = "0.0.0.0";
+static char const* const default_ipaddr = "0.0.0.0";
const char* get_ipaddr() {
const char* client_ip = getenv("REMOTE_ADDR");
if (client_ip) {
@@ -15,8 +15,8 @@ const char* get_ipaddr() {
return default_ipaddr;
}
-void sp_log_msgf(char const* restrict feature, int level, int type,
- const char* restrict fmt, ...) {
+void sp_log_msgf(char const* const restrict feature, int level, int type,
+ char const* const restrict fmt, ...) {
char* msg;
va_list args;
@@ -63,7 +63,7 @@ void sp_log_msgf(char const* restrict feature, int level, int type,
}
}
-int compute_hash(const char* const restrict filename,
+int compute_hash(char const* const restrict filename,
char* restrict file_hash) {
unsigned char buf[1024] = {0};
unsigned char digest[SHA256_SIZE] = {0};
@@ -90,7 +90,7 @@ int compute_hash(const char* const restrict filename,
return SUCCESS;
}
-int sp_log_request(const zend_string* restrict folder, const zend_string* restrict text_repr) {
+int sp_log_request(zend_string const* const restrict folder, zend_string const* const restrict text_repr) {
FILE* file;
char const* const current_filename = zend_get_executed_filename(TSRMLS_C);
const int current_line = zend_get_executed_lineno(TSRMLS_C);
diff --git a/src/sp_utils.h b/src/sp_utils.h
index 0e595d8..7bab4ba 100644
--- a/src/sp_utils.h
+++ b/src/sp_utils.h
@@ -71,8 +71,8 @@ extern int sp_debug_stderr;
#define GET_SUFFIX(x) (x == 1) ? "st" : ((x == 2) ? "nd" : "th")
const char *get_ipaddr(void);
-void sp_log_msgf(char const *restrict feature, int level, int type, const char *restrict fmt, ...);
-int compute_hash(const char *const restrict filename, char *restrict file_hash);
+void sp_log_msgf(char const* const restrict feature, int level, int type, char const* const restrict fmt, ...);
+int compute_hash(char const* const restrict filename, char *restrict file_hash);
const zend_string *sp_zval_to_zend_string(const zval *);
bool sp_match_value(const zend_string* value, const zend_string* to_match, const sp_regexp* rx);
bool sp_match_array_key(const zval *, const zend_string *, const sp_regexp *);
@@ -83,7 +83,7 @@ bool hook_function(const char *, HashTable *, zif_handler);
void unhook_functions(HashTable *ht);
int hook_regexp(const sp_pcre *, HashTable *, zif_handler);
bool check_is_in_eval_whitelist(const char* function_name);
-int sp_log_request(const zend_string *restrict folder, const zend_string *restrict text_repr);
+int sp_log_request(zend_string const* const restrict folder, zend_string const* const restrict text_repr);
#define sp_zend_string_equals(s1, s2) zend_string_equals((zend_string*)s1, (zend_string*)s2)
static inline bool sp_zend_string_equals_str(const zend_string* s1, const char *str, size_t len) {
return (ZSTR_LEN(s1) == len && !memcmp(ZSTR_VAL(s1), str, len));
--
cgit v1.3
From c235a9df483e556bead06a36a3b1af931262b059 Mon Sep 17 00:00:00 2001
From: jvoisin
Date: Wed, 13 Jul 2022 21:33:30 +0200
Subject: Remove some useless conditions
---
src/sp_crypt.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/src/sp_crypt.c b/src/sp_crypt.c
index c1d9403..a27cc67 100644
--- a/src/sp_crypt.c
+++ b/src/sp_crypt.c
@@ -115,10 +115,9 @@ int decrypt_zval(zval *pDest, bool simulation, zend_hash_key *hash_key) {
ret = ZEND_HASH_APPLY_KEEP;
out:
-
- if (debase64) { zend_string_efree(debase64); }
- if (decrypted) { efree(decrypted); }
- if (backup) { efree(backup); }
+ zend_string_efree(debase64);
+ efree(decrypted);
+ efree(backup);
return ret;
}
--
cgit v1.3
From 09a1e81ac9bb4c54cbf81ce00657afd991638cf0 Mon Sep 17 00:00:00 2001
From: jvoisin
Date: Thu, 14 Jul 2022 23:01:07 +0200
Subject: Minor refactoring
---
src/sp_execute.c | 36 +++++++++++++++---------------------
1 file changed, 15 insertions(+), 21 deletions(-)
diff --git a/src/sp_execute.c b/src/sp_execute.c
index 65a32db..81614f3 100644
--- a/src/sp_execute.c
+++ b/src/sp_execute.c
@@ -87,8 +87,8 @@ inline static void is_builtin_matching(
should_disable_ht(EG(current_execute_data), function_name, param_value, param_name, SPCFG(disabled_functions_reg).disabled_functions, ht);
}
-static void ZEND_HOT is_in_eval_and_whitelisted(const zend_execute_data *execute_data) {
- const sp_config_eval *config_eval = &(SPCFG(eval));
+static void ZEND_HOT is_in_eval_and_whitelisted(zend_execute_data const* const execute_data) {
+ sp_config_eval const* const config_eval = &(SPCFG(eval));
if (EXPECTED(0 == SPG(in_eval))) {
return;
@@ -107,18 +107,18 @@ static void ZEND_HOT is_in_eval_and_whitelisted(const zend_execute_data *execute
return;
}
- if (UNEXPECTED(false == check_is_in_eval_whitelist(function_name))) {
- if (config_eval->dump) {
- sp_log_request(config_eval->dump, config_eval->textual_representation);
- }
- if (config_eval->simulation) {
- sp_log_simulation("Eval_whitelist", "The function '%s' isn't in the eval whitelist, logging its call.", function_name);
- goto out;
- } else {
- sp_log_drop("Eval_whitelist", "The function '%s' isn't in the eval whitelist, dropping its call.", function_name);
- }
+ if (UNEXPECTED(false == check_is_in_eval_whitelist(function_name))) {
+ if (config_eval->dump) {
+ sp_log_request(config_eval->dump, config_eval->textual_representation);
}
- // }
+ if (config_eval->simulation) {
+ sp_log_simulation("Eval_whitelist", "The function '%s' isn't in the eval whitelist, logging its call.", function_name);
+ goto out;
+ } else {
+ sp_log_drop("Eval_whitelist", "The function '%s' isn't in the eval whitelist, dropping its call.", function_name);
+ }
+ }
+
out:
efree(function_name);
}
@@ -179,7 +179,7 @@ static inline void sp_execute_handler(INTERNAL_FUNCTION_PARAMETERS, bool interna
if (!internal) {
if (UNEXPECTED(EX(func)->op_array.type == ZEND_EVAL_CODE)) {
- const sp_list_node *config = zend_hash_str_find_ptr(SPCFG(disabled_functions), ZEND_STRL("eval"));
+ sp_list_node const* const config = zend_hash_str_find_ptr(SPCFG(disabled_functions), ZEND_STRL("eval"));
#if PHP_VERSION_ID >= 80000
is_builtin_matching(SPG(eval_source_string), "eval", "code", config, SPCFG(disabled_functions));
@@ -251,10 +251,8 @@ static inline void sp_execute_handler(INTERNAL_FUNCTION_PARAMETERS, bool interna
if (EX(return_value) == &ret_val) {
return_value = EX(return_value) = NULL;
}
-
}
-
static void sp_execute_ex(zend_execute_data *execute_data) {
sp_execute_handler(execute_data, execute_data ? EX(return_value) : NULL, false);
}
@@ -271,7 +269,7 @@ static inline void sp_stream_open_checks(zend_string *zend_filename, zend_file_h
return;
}
- const HashTable *disabled_functions_hooked = SPCFG(disabled_functions_hooked);
+ HashTable const* const disabled_functions_hooked = SPCFG(disabled_functions_hooked);
switch (data->opline->opcode) {
case ZEND_INCLUDE_OR_EVAL:
@@ -312,10 +310,6 @@ static inline void sp_stream_open_checks(zend_string *zend_filename, zend_file_h
EMPTY_SWITCH_DEFAULT_CASE(); // LCOV_EXCL_LINE
}
}
- // efree(zend_filename);
-
-// end:
- // return orig_zend_stream_open(filename, handle);
}
#if PHP_VERSION_ID < 80100
--
cgit v1.3
From 90bdf39000d2f09534b387d39203819995fb948e Mon Sep 17 00:00:00 2001
From: jvoisin
Date: Fri, 15 Jul 2022 19:32:56 +0200
Subject: Minor refactor
---
src/sp_config.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/src/sp_config.c b/src/sp_config.c
index dbccb1a..ff6cdd9 100644
--- a/src/sp_config.c
+++ b/src/sp_config.c
@@ -4,9 +4,7 @@
#include "php_snuffleupagus.h"
-
-static zend_result sp_process_config_root(sp_parsed_keyword *parsed_rule) {
- sp_config_keyword sp_func[] = {
+static const sp_config_keyword sp_func[] = {
{parse_unserialize, SP_TOKEN_UNSERIALIZE_HMAC, &(SPCFG(unserialize))},
{parse_enable, SP_TOKEN_HARDEN_RANDOM, &(SPCFG(random).enable)},
{parse_log_media, SP_TOKEN_LOG_MEDIA, &(SPCFG(log_media))},
@@ -25,7 +23,10 @@ static zend_result sp_process_config_root(sp_parsed_keyword *parsed_rule) {
{parse_wrapper_whitelist, SP_TOKEN_ALLOW_WRAPPERS, &(SPCFG(wrapper))},
{parse_ini_protection, SP_TOKEN_INI_PROTECTION, &(SPCFG(ini))},
{parse_ini_entry, SP_TOKEN_INI, NULL},
- {NULL, NULL, NULL}};
+ {NULL, NULL, NULL}
+};
+
+static zend_result sp_process_config_root(sp_parsed_keyword *parsed_rule) {
return sp_process_rule(parsed_rule, sp_func);
}
--
cgit v1.3
From b839c4629ec27821dd8ee2683fe7c7d9d8f6dd1a Mon Sep 17 00:00:00 2001
From: jvoisin
Date: Mon, 18 Jul 2022 20:45:58 +0200
Subject: Remove a superfluous condition
---
src/sp_config_keywords.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/src/sp_config_keywords.c b/src/sp_config_keywords.c
index e0e5166..ea4e1cd 100644
--- a/src/sp_config_keywords.c
+++ b/src/sp_config_keywords.c
@@ -394,10 +394,8 @@ SP_PARSE_FN(parse_disabled_functions) {
return SP_PARSER_STOP;
out:
- if (df) {
- sp_free_disabled_function(df);
- pefree(df, 1);
- }
+ sp_free_disabled_function(df);
+ pefree(df, 1);
if (param) { zend_string_release(param); }
if (var) { zend_string_release(var); }
--
cgit v1.3
From 06c72f58eb168de74150f6f5aa10f7f427f56c53 Mon Sep 17 00:00:00 2001
From: jvoisin
Date: Tue, 19 Jul 2022 21:22:45 +0200
Subject: Add a notable user
---
doc/source/papers.rst | 3 +++
1 file changed, 3 insertions(+)
diff --git a/doc/source/papers.rst b/doc/source/papers.rst
index cf75311..d13f33a 100644
--- a/doc/source/papers.rst
+++ b/doc/source/papers.rst
@@ -128,6 +128,9 @@ Notable users
- `NBS System `__ - a French hosting/security company and author of snuffleupagus
- `Net4All `__ - a Swiss hosting company
- `Oceanet Technology `__ - a French hosting company
+- The `Swedish team `__
+ of the `NATO `__'s `CCDCOE `__
+ `Locked Shields `__ exercise.
- `SwissCenter `__ - a Swiss datacenter & web hosting company
- `Toolslib `__ - an `Alexa top 10k `__ website
- `cPanel `__ - one of the most popular web hosting control panel
--
cgit v1.3
From cbf0a9be15e4345bbe0da0c6be305434928ea759 Mon Sep 17 00:00:00 2001
From: jvoisin
Date: Tue, 19 Jul 2022 21:26:26 +0200
Subject: Document conditions
---
doc/source/config.rst | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/doc/source/config.rst b/doc/source/config.rst
index bbf3b91..d7f7f24 100644
--- a/doc/source/config.rst
+++ b/doc/source/config.rst
@@ -75,6 +75,19 @@ The terminating ``;`` is optional for now, but it should be used for future comp
Miscellaneous
-------------
+conditions
+^^^^^^^^^^
+
+It's possible to use conditions to have configuration portables accross
+several setups.
+
+::
+ @condition PHP_VERSION_ID < 80000;
+ # some rules
+ @condition PHP_VERSION_ID >= 80000;
+ # some other rules
+ @end_condition;
+
global
^^^^^^
--
cgit v1.3