summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.frag2
-rw-r--r--src/config.m45
-rw-r--r--src/php_snuffleupagus.h1
-rw-r--r--src/sp_config.c305
-rw-r--r--src/sp_config.h165
-rw-r--r--src/sp_config_keywords.c606
-rw-r--r--src/sp_config_keywords.h31
-rw-r--r--src/sp_config_scanner.h25
-rw-r--r--src/sp_config_scanner.re139
-rw-r--r--src/sp_config_utils.c103
-rw-r--r--src/sp_config_utils.h3
-rw-r--r--src/sp_disabled_functions.c33
-rw-r--r--src/sp_execute.c6
-rw-r--r--src/sp_network_utils.c6
-rw-r--r--src/sp_pcre_compat.c3
-rw-r--r--src/sp_unserialize.c3
-rw-r--r--src/sp_utils.c13
-rw-r--r--src/sp_utils.h4
-rw-r--r--src/tests/broken_configuration/encrypt_regexp_cookies_bad_regexp.phpt4
-rw-r--r--src/tests/broken_configuration_php8/broken_conf.phpt3
-rw-r--r--src/tests/broken_configuration_php8/broken_conf2.phpt3
-rw-r--r--src/tests/broken_configuration_php8/broken_conf_allow_broken_disabled.phpt2
-rw-r--r--src/tests/broken_configuration_php8/broken_conf_allow_broken_enabled.phpt2
-rw-r--r--src/tests/broken_configuration_php8/broken_conf_config_regexp.phpt5
-rw-r--r--src/tests/broken_configuration_php8/broken_conf_config_regexp_no_closing_paren.phpt5
-rw-r--r--src/tests/broken_configuration_php8/broken_conf_cookie_encryption_without_encryption_key.phpt3
-rw-r--r--src/tests/broken_configuration_php8/broken_conf_cookie_encryption_without_env_var.phpt3
-rw-r--r--src/tests/broken_configuration_php8/broken_conf_eval.phpt2
-rw-r--r--src/tests/broken_configuration_php8/broken_conf_expecting_bool.phpt3
-rw-r--r--src/tests/broken_configuration_php8/broken_conf_invalid_cidr_value.phpt5
-rw-r--r--src/tests/broken_configuration_php8/broken_conf_invalid_filename.phpt3
-rw-r--r--src/tests/broken_configuration_php8/broken_conf_invalid_log_media.phpt3
-rw-r--r--src/tests/broken_configuration_php8/broken_conf_invalid_type.phpt3
-rw-r--r--src/tests/broken_configuration_php8/broken_conf_key_value.phpt4
-rw-r--r--src/tests/broken_configuration_php8/broken_conf_line_empty_string.phpt3
-rw-r--r--src/tests/broken_configuration_php8/broken_conf_line_no_closing.phpt3
-rw-r--r--src/tests/broken_configuration_php8/broken_conf_lots_of_quotes.phpt3
-rw-r--r--src/tests/broken_configuration_php8/broken_conf_missing_script.phpt3
-rw-r--r--src/tests/broken_configuration_php8/broken_conf_mutually_exclusive.phpt5
-rw-r--r--src/tests/broken_configuration_php8/broken_conf_mutually_exclusive11.phpt5
-rw-r--r--src/tests/broken_configuration_php8/broken_conf_mutually_exclusive12.phpt5
-rw-r--r--src/tests/broken_configuration_php8/broken_conf_mutually_exclusive2.phpt5
-rw-r--r--src/tests/broken_configuration_php8/broken_conf_mutually_exclusive3.phpt5
-rw-r--r--src/tests/broken_configuration_php8/broken_conf_mutually_exclusive4.phpt4
-rw-r--r--src/tests/broken_configuration_php8/broken_conf_mutually_exclusive5.phpt4
-rw-r--r--src/tests/broken_configuration_php8/broken_conf_mutually_exclusive6.phpt5
-rw-r--r--src/tests/broken_configuration_php8/broken_conf_mutually_exclusive7.phpt5
-rw-r--r--src/tests/broken_configuration_php8/broken_conf_mutually_exclusive8.phpt5
-rw-r--r--src/tests/broken_configuration_php8/broken_conf_readonly_exec.phpt3
-rw-r--r--src/tests/broken_configuration_php8/broken_conf_samesite.phpt3
-rw-r--r--src/tests/broken_configuration_php8/broken_conf_session_encryption.phpt3
-rw-r--r--src/tests/broken_configuration_php8/broken_conf_shown_in_phpinfo.phpt5
-rw-r--r--src/tests/broken_configuration_php8/broken_conf_truncated.phpt3
-rw-r--r--src/tests/broken_configuration_php8/broken_conf_unserialize.phpt5
-rw-r--r--src/tests/broken_configuration_php8/broken_conf_upload_validation.phpt3
-rw-r--r--src/tests/broken_configuration_php8/broken_conf_weird_keyword.phpt3
-rw-r--r--src/tests/broken_configuration_php8/broken_conf_wrapper_whitelist.phpt3
-rw-r--r--src/tests/broken_configuration_php8/broken_conf_wrong_quotes.phpt3
-rw-r--r--src/tests/broken_configuration_php8/broken_regexp.phpt5
-rw-r--r--src/tests/broken_configuration_php8/encrypt_regexp_cookies_bad_regexp.phpt4
-rw-r--r--src/tests/cookies_encryption_warning/encrypt_cookies_no_env.phpt2
-rw-r--r--src/tests/cookies_encryption_warning/encrypt_cookies_no_key.phpt2
-rw-r--r--src/tests/cookies_encryption_warning/encrypt_regexp_cookies_no_env.phpt2
-rw-r--r--src/tests/cookies_encryption_warning/encrypt_regexp_cookies_no_key.phpt2
-rw-r--r--src/tests/dump_request/dump_eval_blacklist.phpt2
-rw-r--r--src/tests/eval_blacklist/eval_backlist.phpt2
-rw-r--r--src/tests/eval_blacklist/eval_backlist_call_user_func.phpt2
-rw-r--r--src/tests/eval_blacklist/eval_backlist_chained.phpt2
-rw-r--r--src/tests/eval_blacklist/eval_backlist_list.phpt2
-rw-r--r--src/tests/eval_blacklist/eval_backlist_simulation.phpt2
-rw-r--r--src/tests/eval_blacklist/nested_eval_blacklist.phpt2
-rw-r--r--src/tests/eval_blacklist/nested_eval_blacklist2.phpt2
72 files changed, 760 insertions, 873 deletions
diff --git a/src/Makefile.frag b/src/Makefile.frag
new file mode 100644
index 0000000..c8458ea
--- /dev/null
+++ b/src/Makefile.frag
@@ -0,0 +1,2 @@
1$(srcdir)/sp_config_scanner.c: $(srcdir)/sp_config_scanner.re
2 @$(RE2C) $(RE2C_FLAGS) --no-generation-date -bc -o $@ $<
diff --git a/src/config.m4 b/src/config.m4
index 9778820..6f462af 100644
--- a/src/config.m4
+++ b/src/config.m4
@@ -7,7 +7,7 @@ sources="$sources sp_disabled_functions.c sp_execute.c sp_upload_validation.c"
7sources="$sources sp_cookie_encryption.c sp_network_utils.c tweetnacl.c" 7sources="$sources sp_cookie_encryption.c sp_network_utils.c tweetnacl.c"
8sources="$sources sp_config_keywords.c sp_var_parser.c sp_var_value.c sp_tree.c" 8sources="$sources sp_config_keywords.c sp_var_parser.c sp_var_value.c sp_tree.c"
9sources="$sources sp_pcre_compat.c sp_crypt.c sp_session.c sp_sloppy.c sp_wrapper.c" 9sources="$sources sp_pcre_compat.c sp_crypt.c sp_session.c sp_sloppy.c sp_wrapper.c"
10sources="$sources sp_ini.c sp_php_compat.c" 10sources="$sources sp_ini.c sp_php_compat.c sp_config_scanner.c"
11 11
12PHP_ARG_ENABLE(snuffleupagus, whether to enable snuffleupagus support, 12PHP_ARG_ENABLE(snuffleupagus, whether to enable snuffleupagus support,
13[ --enable-snuffleupagus Enable snuffleupagus support]) 13[ --enable-snuffleupagus Enable snuffleupagus support])
@@ -40,3 +40,6 @@ if test "$PHP_SNUFFLEUPAGUS" = "yes"; then
40 fi 40 fi
41 PHP_NEW_EXTENSION(snuffleupagus, $sources, $ext_shared,-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1) 41 PHP_NEW_EXTENSION(snuffleupagus, $sources, $ext_shared,-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1)
42fi 42fi
43
44PHP_PROG_RE2C()
45PHP_ADD_MAKEFILE_FRAGMENT()
diff --git a/src/php_snuffleupagus.h b/src/php_snuffleupagus.h
index 928095d..91ee8a6 100644
--- a/src/php_snuffleupagus.h
+++ b/src/php_snuffleupagus.h
@@ -70,6 +70,7 @@ typedef void (*zif_handler)(INTERNAL_FUNCTION_PARAMETERS);
70#include "sp_list.h" 70#include "sp_list.h"
71#include "sp_tree.h" 71#include "sp_tree.h"
72#include "sp_var_parser.h" 72#include "sp_var_parser.h"
73#include "sp_config_scanner.h"
73#include "sp_config.h" 74#include "sp_config.h"
74#include "sp_config_utils.h" 75#include "sp_config_utils.h"
75#include "sp_config_keywords.h" 76#include "sp_config_keywords.h"
diff --git a/src/sp_config.c b/src/sp_config.c
index 37c749b..4d96bbe 100644
--- a/src/sp_config.c
+++ b/src/sp_config.c
@@ -4,102 +4,140 @@
4 4
5#include "php_snuffleupagus.h" 5#include "php_snuffleupagus.h"
6 6
7size_t sp_line_no;
8 7
9static sp_config_tokens const sp_func[] = { 8static zend_result sp_process_config_root(sp_parsed_keyword *parsed_rule) {
10 {.func = parse_unserialize, .token = SP_TOKEN_UNSERIALIZE_HMAC}, 9 sp_config_keyword sp_func[] = {
11 {.func = parse_random, .token = SP_TOKEN_HARDEN_RANDOM}, 10 {parse_unserialize, SP_TOKEN_UNSERIALIZE_HMAC, SNUFFLEUPAGUS_G(config).config_unserialize},
12 {.func = parse_log_media, .token = SP_TOKEN_LOG_MEDIA}, 11 {parse_enable, SP_TOKEN_HARDEN_RANDOM, &(SNUFFLEUPAGUS_G(config).config_random->enable)},
13 {.func = parse_disabled_functions, .token = SP_TOKEN_DISABLE_FUNC}, 12 {parse_log_media, SP_TOKEN_LOG_MEDIA, &(SNUFFLEUPAGUS_G(config).log_media)},
14 {.func = parse_readonly_exec, .token = SP_TOKEN_READONLY_EXEC}, 13 {parse_disabled_functions, SP_TOKEN_DISABLE_FUNC, NULL},
15 {.func = parse_global_strict, .token = SP_TOKEN_GLOBAL_STRICT}, 14 {parse_readonly_exec, SP_TOKEN_READONLY_EXEC, SNUFFLEUPAGUS_G(config).config_readonly_exec},
16 {.func = parse_upload_validation, .token = SP_TOKEN_UPLOAD_VALIDATION}, 15 {parse_enable, SP_TOKEN_GLOBAL_STRICT, &(SNUFFLEUPAGUS_G(config).config_global_strict->enable)},
17 {.func = parse_cookie, .token = SP_TOKEN_COOKIE_ENCRYPTION}, 16 {parse_upload_validation, SP_TOKEN_UPLOAD_VALIDATION, SNUFFLEUPAGUS_G(config).config_upload_validation},
18 {.func = parse_global, .token = SP_TOKEN_GLOBAL}, 17 {parse_cookie, SP_TOKEN_COOKIE_ENCRYPTION, NULL},
19 {.func = parse_auto_cookie_secure, .token = SP_TOKEN_AUTO_COOKIE_SECURE}, 18 {parse_global, SP_TOKEN_GLOBAL, NULL},
20 {.func = parse_disable_xxe, .token = SP_TOKEN_DISABLE_XXE}, 19 {parse_enable, SP_TOKEN_AUTO_COOKIE_SECURE, &(SNUFFLEUPAGUS_G(config).config_auto_cookie_secure->enable)},
21 {.func = parse_eval_blacklist, .token = SP_TOKEN_EVAL_BLACKLIST}, 20 {parse_enable, SP_TOKEN_DISABLE_XXE, &(SNUFFLEUPAGUS_G(config).config_disable_xxe->enable)},
22 {.func = parse_eval_whitelist, .token = SP_TOKEN_EVAL_WHITELIST}, 21 {parse_eval_filter_conf, SP_TOKEN_EVAL_BLACKLIST, &(SNUFFLEUPAGUS_G(config).config_eval->blacklist)},
23 {.func = parse_session, .token = SP_TOKEN_SESSION_ENCRYPTION}, 22 {parse_eval_filter_conf, SP_TOKEN_EVAL_WHITELIST, &(SNUFFLEUPAGUS_G(config).config_eval->whitelist)},
24 {.func = parse_sloppy_comparison, .token = SP_TOKEN_SLOPPY_COMPARISON}, 23 {parse_session, SP_TOKEN_SESSION_ENCRYPTION, SNUFFLEUPAGUS_G(config).config_session},
25 {.func = parse_wrapper_whitelist, .token = SP_TOKEN_ALLOW_WRAPPERS}, 24 {parse_enable, SP_TOKEN_SLOPPY_COMPARISON, &(SNUFFLEUPAGUS_G(config).config_sloppy->enable)},
26 {.func = parse_ini_protection, .token = ".ini_protection"}, 25 {parse_wrapper_whitelist, SP_TOKEN_ALLOW_WRAPPERS, SNUFFLEUPAGUS_G(config).config_wrapper},
27 {.func = parse_ini_entry, .token = ".ini"}, 26 {parse_ini_protection, SP_TOKEN_INI_PROTECTION, SNUFFLEUPAGUS_G(config).config_ini},
28 {NULL, NULL}}; 27 {parse_ini_entry, SP_TOKEN_INI, SNUFFLEUPAGUS_G(config).config_unserialize},
28 {NULL, NULL, NULL}};
29 return sp_process_rule(parsed_rule, sp_func);
30}
29 31
30/* Top level keyword parsing */ 32zend_result sp_parse_config(const char *filename) {
33 FILE *fd = fopen(filename, "rb");
34 if (fd == NULL) {
35 sp_log_err("config", "Could not open configuration file %s : %s", filename, strerror(errno));
36 return FAILURE;
37 }
31 38
32static int parse_line(char *line) { 39 size_t step = 8192;
33 char *ptr = line; 40 size_t max_len = step, len = 0;
41 zend_string *data = zend_string_alloc(max_len, 0);
42 char *ptr = ZSTR_VAL(data);
34 43
35 while (*ptr == ' ' || *ptr == '\t') { 44 size_t bytes;
36 ++ptr; 45 while ((bytes = fread(ptr, 1, max_len - len, fd))) {
46 len += bytes;
47 if (max_len - len <= 0) {
48 max_len += step;
49 data = zend_string_extend(data, max_len, 0);
50 ptr = ZSTR_VAL(data) + len;
51 } else {
52 ptr += bytes;
53 }
37 } 54 }
55 fclose(fd);
38 56
39 if (!*ptr || *ptr == '#' || *ptr == ';') { 57 data = zend_string_truncate(data, len, 0);
40 return 0; 58 ZSTR_VAL(data)[len] = 0;
41 } 59
60 int ret = sp_config_scan(ZSTR_VAL(data), sp_process_config_root);
61
62 zend_string_release_ex(data, 0);
63
64 return ret;
65}
42 66
43 if (strncmp(ptr, SP_TOKEN_BASE, strlen(SP_TOKEN_BASE))) {
44 sp_log_err("config", "Invalid configuration prefix for '%s' on line %zu",
45 line, sp_line_no);
46 return -1;
47 }
48 ptr += strlen(SP_TOKEN_BASE);
49 67
50 for (size_t i = 0; sp_func[i].func; i++) { 68zend_result sp_process_rule(sp_parsed_keyword *parsed_rule, sp_config_keyword *config_keywords) {
51 if (!strncmp(sp_func[i].token, ptr, strlen(sp_func[i].token))) { 69 for (sp_parsed_keyword *kw = parsed_rule; kw->kw; kw++) {
52 return sp_func[i].func(ptr + strlen(sp_func[i].token)); 70 bool found_kw = false;
71 for (sp_config_keyword *ckw = config_keywords; ckw->func; ckw++) {
72 if (kw->kwlen == strlen(ckw->token) && !strncmp(kw->kw, ckw->token, kw->kwlen)) {
73 if (ckw->func) {
74 int ret = ckw->func(ckw->token, kw, ckw->retval);
75 switch (ret) {
76 case SP_PARSER_SUCCESS:
77 break;
78 case SP_PARSER_ERROR:
79 return FAILURE;
80 case SP_PARSER_STOP:
81 return SUCCESS;
82 }
83 }
84 found_kw = true;
85 break;
86 }
87 }
88
89 if (!found_kw) {
90 zend_string *kwname = zend_string_init(kw->kw, kw->kwlen, 0);
91 sp_log_err("config", "Unexpected keyword '%s' on line %d", ZSTR_VAL(kwname), kw->lineno);
92 zend_string_release_ex(kwname, 0);
93 return FAILURE;
53 } 94 }
54 } 95 }
55 sp_log_err("config", "Invalid configuration section '%s' on line %zu", line, 96 return SUCCESS;
56 sp_line_no);
57 return -1;
58} 97}
59 98
60/* keyword parsing */
61#define CHECK_DUPLICATE_KEYWORD(retval) \ 99#define CHECK_DUPLICATE_KEYWORD(retval) \
62 if (*(void**)(retval)) { \ 100 if (*(void**)(retval)) { \
63 sp_log_err("config", "duplicate %s) on line %zu near `%s`", keyword, sp_line_no, line); \ 101 sp_log_err("config", "duplicate keyword '%s' on line %zu", token, kw->lineno); \
64 return -1; } 102 return SP_PARSER_ERROR; }
65 103
66 104
67int parse_empty(char *restrict line, char *restrict keyword, void *retval) { 105SP_PARSEKW_FN(parse_empty) {
106 if (kw->arglen) {
107 sp_log_err("config", "Unexpected argument for keyword '%s' - it should be '%s()' on line %zu", token, token, kw->lineno);
108 return SP_PARSER_ERROR;
109 }
110 if (kw->argtype != SP_ARGTYPE_EMPTY) {
111 sp_log_err("config", "Missing paranthesis for keyword '%s' - it should be '%s()' on line %zu", token, token, kw->lineno);
112 return SP_PARSER_ERROR;
113 }
68 *(bool *)retval = true; 114 *(bool *)retval = true;
69 return 0; 115 return SP_PARSER_SUCCESS;
70} 116}
71 117
72int parse_list(char *restrict line, char *restrict keyword, void *list_ptr) { 118SP_PARSEKW_FN(parse_list) {
73 CHECK_DUPLICATE_KEYWORD(list_ptr); 119 CHECK_DUPLICATE_KEYWORD(retval);
74 zend_string *value = NULL;
75 sp_list_node **list = list_ptr;
76 char *token, *tmp;
77 120
78 size_t consumed = 0; 121 sp_list_node **list = retval;
79 value = get_param(&consumed, line, SP_TYPE_STR, keyword); 122 char *tok, *tmp;
80 if (!value) { 123
81 return -1; 124 SP_PARSE_ARG(value);
82 }
83 125
84 tmp = ZSTR_VAL(value); 126 tmp = ZSTR_VAL(value);
85 while (1) { 127 while (1) {
86 token = strsep(&tmp, ","); 128 tok = strsep(&tmp, ",");
87 if (token == NULL) { 129 if (tok == NULL) {
88 break; 130 break;
89 } 131 }
90 *list = sp_list_insert(*list, zend_string_init(token, strlen(token), 1)); 132 *list = sp_list_insert(*list, zend_string_init(tok, strlen(tok), 1));
91 } 133 }
134 zend_string_release(value);
92 135
93 pefree(value, 1); 136 return SP_PARSER_SUCCESS;
94 return consumed;
95} 137}
96 138
97int parse_php_type(char *restrict line, char *restrict keyword, void *retval) { 139SP_PARSEKW_FN(parse_php_type) {
98 size_t consumed = 0; 140 SP_PARSE_ARG(value);
99 zend_string *value = get_param(&consumed, line, SP_TYPE_STR, keyword);
100 if (!value) {
101 return -1;
102 }
103 141
104 if (zend_string_equals_literal_ci(value, "undef")) { 142 if (zend_string_equals_literal_ci(value, "undef")) {
105 *(sp_php_type *)retval = SP_PHP_TYPE_UNDEF; 143 *(sp_php_type *)retval = SP_PHP_TYPE_UNDEF;
@@ -124,113 +162,88 @@ int parse_php_type(char *restrict line, char *restrict keyword, void *retval) {
124 } else if (zend_string_equals_literal_ci(value, "reference")) { 162 } else if (zend_string_equals_literal_ci(value, "reference")) {
125 *(sp_php_type *)retval = SP_PHP_TYPE_REFERENCE; 163 *(sp_php_type *)retval = SP_PHP_TYPE_REFERENCE;
126 } else { 164 } else {
127 pefree(value, 1); 165 zend_string_release(value);
128 sp_log_err("error", 166 sp_log_err("error", ".%s() is expecting a valid php type ('false', 'true',"
129 "%s) is expecting a valid php type ('false', 'true',"
130 " 'array'. 'object', 'long', 'double', 'null', 'resource', " 167 " 'array'. 'object', 'long', 'double', 'null', 'resource', "
131 "'reference', 'undef') on line %zu", 168 "'reference', 'undef') on line %zu", token, kw->lineno);
132 keyword, sp_line_no); 169 return SP_PARSER_ERROR;
133 return -1;
134 } 170 }
135 pefree(value, 1); 171 zend_string_release(value);
136 return consumed; 172 return SP_PARSER_SUCCESS;
137} 173}
138 174
139int parse_str(char *restrict line, char *restrict keyword, void *retval) { 175
176SP_PARSEKW_FN(parse_str) {
140 CHECK_DUPLICATE_KEYWORD(retval); 177 CHECK_DUPLICATE_KEYWORD(retval);
141 zend_string *value = NULL; 178 SP_PARSE_ARG(value);
142 179
143 size_t consumed = 0; 180 *(zend_string **)retval = value;
144 value = get_param(&consumed, line, SP_TYPE_STR, keyword); 181
145 if (value) { 182 return SP_PARSER_SUCCESS;
146 *(zend_string **)retval = value;
147 return consumed;
148 }
149 return -1;
150} 183}
151 184
152int parse_cidr(char *restrict line, char *restrict keyword, void *retval) { 185SP_PARSEKW_FN(parse_int) {
153 CHECK_DUPLICATE_KEYWORD(retval); 186 int ret = SP_PARSER_SUCCESS;
187 SP_PARSE_ARG(value);
188
189 char *endptr;
190 errno = 0;
191 *(int*)retval = (int)strtoimax(ZSTR_VAL(value), &endptr, 10);
192 if (errno != 0 || !endptr || endptr == ZSTR_VAL(value)) {
193 sp_log_err("config", "Failed to parse arg '%s' of `%s` on line %zu", ZSTR_VAL(value), token, kw->lineno);
194 ret = SP_PARSER_ERROR;
195 }
196 zend_string_release(value);
197 return ret;
198}
154 199
155 size_t consumed = 0; 200SP_PARSEKW_FN(parse_ulong) {
156 zend_string *value = get_param(&consumed, line, SP_TYPE_STR, keyword); 201 int ret = SP_PARSER_SUCCESS;
202 SP_PARSE_ARG(value);
157 203
158 if (!value) { 204 char *endptr;
159 sp_log_err("config", "%s doesn't contain a valid cidr on line %zu", line, sp_line_no); 205 errno = 0;
160 return -1; 206 *(u_long*)retval = (u_long)strtoul(ZSTR_VAL(value), &endptr, 10);
207 if (errno != 0 || !endptr || endptr == ZSTR_VAL(value)) {
208 sp_log_err("config", "Failed to parse arg '%s' of `%s` on line %zu", ZSTR_VAL(value), token, kw->lineno);
209 ret = SP_PARSER_ERROR;
161 } 210 }
211 zend_string_release(value);
212 return ret;
213}
214
215SP_PARSEKW_FN(parse_cidr) {
216 CHECK_DUPLICATE_KEYWORD(retval);
217 SP_PARSE_ARG(value);
162 218
163 sp_cidr *cidr = pecalloc(sizeof(sp_cidr), 1, 1); 219 sp_cidr *cidr = pecalloc(sizeof(sp_cidr), 1, 1);
164 220
165 if (0 != get_ip_and_cidr(ZSTR_VAL(value), cidr)) { 221 if (0 != get_ip_and_cidr(ZSTR_VAL(value), cidr)) {
166 pefree(cidr, 1); 222 pefree(cidr, 1);
167 *(sp_cidr **)retval = NULL; 223 cidr = NULL;
168 return -1;
169 } 224 }
170 225
171 *(sp_cidr **)retval = cidr; 226 *(sp_cidr **)retval = cidr;
172 return consumed; 227 return cidr ? SP_PARSER_SUCCESS : SP_PARSER_ERROR;
173} 228}
174 229
175int parse_regexp(char *restrict line, char *restrict keyword, void *retval) { 230SP_PARSEKW_FN(parse_regexp) {
176 /* TODO: Do we want to use pcre_study? 231 /* TODO: Do we want to use pcre_study?
177 * (http://www.pcre.org/original/doc/html/pcre_study.html) 232 * (http://www.pcre.org/original/doc/html/pcre_study.html)
178 * maybe not: http://sljit.sourceforge.net/pcre.html*/ 233 * maybe not: http://sljit.sourceforge.net/pcre.html*/
179 CHECK_DUPLICATE_KEYWORD(retval); 234 CHECK_DUPLICATE_KEYWORD(retval);
235 SP_PARSE_ARG(value);
180 236
181 size_t consumed = 0; 237 sp_pcre *compiled_re = sp_pcre_compile(ZSTR_VAL(value));
182 zend_string *value = get_param(&consumed, line, SP_TYPE_STR, keyword); 238 if (!compiled_re) {
183 239 sp_log_err("config", "Invalid regexp '%s' for '.%s()' on line %zu", ZSTR_VAL(value), token, kw->lineno);
184 if (value) { 240 zend_string_release_ex(value, 1);
185 sp_pcre *compiled_re = sp_pcre_compile(ZSTR_VAL(value)); 241 return SP_PARSER_ERROR;
186 if (NULL != compiled_re) {
187 *(sp_pcre **)retval = compiled_re;
188 return consumed;
189 }
190 }
191 char *closing_paren = strchr(line, ')');
192 if (NULL != closing_paren) {
193 closing_paren[0] = '\0';
194 } 242 }
195 sp_log_err("config",
196 "'%s)' is expecting a valid regexp, and not '%s' on line %zu",
197 keyword, line, sp_line_no);
198 return -1;
199}
200 243
201int sp_parse_config(const char *conf_file) { 244 *(sp_pcre **)retval = compiled_re;
202 FILE *fd = fopen(conf_file, "r");
203 char *lineptr = NULL;
204 size_t n = 0;
205 sp_line_no = 1;
206 245
207 if (fd == NULL) { 246 return SP_PARSER_SUCCESS;
208 sp_log_err("config", "Could not open configuration file %s : %s", conf_file,
209 strerror(errno));
210 return FAILURE;
211 }
212
213 while (getline(&lineptr, &n, fd) > 0) {
214 /* We trash the terminal `\n`. This simplify the display of logs. */
215 if (lineptr[strlen(lineptr) - 1] == '\n') {
216 if (strlen(lineptr) >= 2 && lineptr[strlen(lineptr) - 2] == '\r') {
217 lineptr[strlen(lineptr) - 2] = '\0';
218 } else {
219 lineptr[strlen(lineptr) - 1] = '\0';
220 }
221 }
222 if (parse_line(lineptr) == -1) {
223 fclose(fd);
224 free(lineptr);
225 return FAILURE;
226 }
227 free(lineptr);
228 lineptr = NULL;
229 n = 0;
230 sp_line_no++;
231 }
232 fclose(fd);
233 return SUCCESS;
234} 247}
235 248
236void sp_free_disabled_function(void *data) { 249void sp_free_disabled_function(void *data) {
@@ -292,4 +305,4 @@ void sp_free_ini_entry(void *data) {
292 sp_pcre_free(entry->regexp); 305 sp_pcre_free(entry->regexp);
293 sp_free_zstr(entry->msg); 306 sp_free_zstr(entry->msg);
294 sp_free_zstr(entry->set); 307 sp_free_zstr(entry->set);
295} \ No newline at end of file 308}
diff --git a/src/sp_config.h b/src/sp_config.h
index 0ba2e7f..fd6dc15 100644
--- a/src/sp_config.h
+++ b/src/sp_config.h
@@ -5,15 +5,6 @@
5#include <netinet/in.h> 5#include <netinet/in.h>
6#include <sys/socket.h> 6#include <sys/socket.h>
7 7
8extern size_t sp_line_no;
9
10typedef enum {
11 SP_TYPE_STR = 0,
12 SP_TYPE_REGEXP,
13 SP_TYPE_INT,
14 SP_TYPE_EMPTY
15} sp_type;
16
17typedef enum { 8typedef enum {
18 SP_PHP_TYPE_UNDEF = IS_UNDEF, 9 SP_PHP_TYPE_UNDEF = IS_UNDEF,
19 SP_PHP_TYPE_NULL = IS_NULL, 10 SP_PHP_TYPE_NULL = IS_NULL,
@@ -214,99 +205,115 @@ typedef struct {
214 sp_config_disabled_functions *config_disabled_functions_reg_ret; 205 sp_config_disabled_functions *config_disabled_functions_reg_ret;
215} sp_config; 206} sp_config;
216 207
208#define SP_PARSE_FN_(fname, kwvar) int fname(char *token, sp_parsed_keyword *kwvar, void *retval)
209#define SP_PARSE_FN(fname) SP_PARSE_FN_(fname, parsed_rule)
210#define SP_PARSEKW_FN(fname) SP_PARSE_FN_(fname, kw)
211
217typedef struct { 212typedef struct {
218 int (*func)(char *, char *, void *); 213 SP_PARSE_FN((*func));
219 char *token; 214 char *token;
220 void *retval; 215 void *retval;
221} sp_config_functions; 216} sp_config_keyword;
222 217
223typedef struct { 218#define SP_PARSER_SUCCESS 0
224 int (*func)(char *); 219#define SP_PARSER_ERROR -1
225 char *token; 220#define SP_PARSER_STOP 1
226} sp_config_tokens;
227 221
228#define SP_TOKEN_BASE "sp" 222// #define SP_TOKEN_BASE "sp"
229 223
230#define SP_TOKEN_AUTO_COOKIE_SECURE ".auto_cookie_secure" 224#define SP_TOKEN_AUTO_COOKIE_SECURE "auto_cookie_secure"
231#define SP_TOKEN_COOKIE_ENCRYPTION ".cookie" 225#define SP_TOKEN_COOKIE_ENCRYPTION "cookie"
232#define SP_TOKEN_SESSION_ENCRYPTION ".session" 226#define SP_TOKEN_SESSION_ENCRYPTION "session"
233#define SP_TOKEN_DISABLE_FUNC ".disable_function" 227#define SP_TOKEN_DISABLE_FUNC "disable_function"
234#define SP_TOKEN_GLOBAL ".global" 228#define SP_TOKEN_GLOBAL "global"
235#define SP_TOKEN_GLOBAL_STRICT ".global_strict" 229#define SP_TOKEN_GLOBAL_STRICT "global_strict"
236#define SP_TOKEN_HARDEN_RANDOM ".harden_random" 230#define SP_TOKEN_HARDEN_RANDOM "harden_random"
237#define SP_TOKEN_READONLY_EXEC ".readonly_exec" 231#define SP_TOKEN_READONLY_EXEC "readonly_exec"
238#define SP_TOKEN_UNSERIALIZE_HMAC ".unserialize_hmac" 232#define SP_TOKEN_UNSERIALIZE_HMAC "unserialize_hmac"
239#define SP_TOKEN_UPLOAD_VALIDATION ".upload_validation" 233#define SP_TOKEN_UPLOAD_VALIDATION "upload_validation"
240#define SP_TOKEN_DISABLE_XXE ".disable_xxe" 234#define SP_TOKEN_DISABLE_XXE "disable_xxe"
241#define SP_TOKEN_EVAL_BLACKLIST ".eval_blacklist" 235#define SP_TOKEN_EVAL_BLACKLIST "eval_blacklist"
242#define SP_TOKEN_EVAL_WHITELIST ".eval_whitelist" 236#define SP_TOKEN_EVAL_WHITELIST "eval_whitelist"
243#define SP_TOKEN_SLOPPY_COMPARISON ".sloppy_comparison" 237#define SP_TOKEN_SLOPPY_COMPARISON "sloppy_comparison"
244#define SP_TOKEN_ALLOW_WRAPPERS ".wrappers_whitelist" 238#define SP_TOKEN_ALLOW_WRAPPERS "wrappers_whitelist"
245#define SP_TOKEN_INI ".ini" 239#define SP_TOKEN_INI_PROTECTION "ini_protection"
240#define SP_TOKEN_INI "ini"
246 241
247// common tokens 242// common tokens
248#define SP_TOKEN_ENABLE ".enable(" 243#define SP_TOKEN_ENABLE "enable"
249#define SP_TOKEN_DISABLE ".disable(" 244#define SP_TOKEN_DISABLE "disable"
250#define SP_TOKEN_SIMULATION ".simulation(" 245#define SP_TOKEN_SIMULATION "simulation"
251#define SP_TOKEN_TRUE "1" 246#define SP_TOKEN_SIM "sim"
252#define SP_TOKEN_FALSE "0" 247// #define SP_TOKEN_TRUE "1"
253#define SP_TOKEN_DUMP ".dump(" 248// #define SP_TOKEN_FALSE "0"
254#define SP_TOKEN_ALIAS ".alias(" 249#define SP_TOKEN_DUMP "dump"
255#define SP_TOKEN_ALLOW ".allow(" 250#define SP_TOKEN_ALIAS "alias"
256#define SP_TOKEN_DROP ".drop(" 251#define SP_TOKEN_ALLOW "allow"
257 252#define SP_TOKEN_DROP "drop"
258#define SP_TOKEN_END_PARAM ')'
259 253
260// disable_function 254// disable_function
261#define SP_TOKEN_CIDR ".cidr(" 255#define SP_TOKEN_CIDR "cidr"
262#define SP_TOKEN_FILENAME ".filename(" 256#define SP_TOKEN_FILENAME "filename"
263#define SP_TOKEN_FILENAME_REGEXP ".filename_r(" 257#define SP_TOKEN_FILENAME_REGEXP "filename_r"
264#define SP_TOKEN_FUNCTION ".function(" 258#define SP_TOKEN_FUNCTION "function"
265#define SP_TOKEN_FUNCTION_REGEXP ".function_r(" 259#define SP_TOKEN_FUNCTION_REGEXP "function_r"
266#define SP_TOKEN_HASH ".hash(" 260#define SP_TOKEN_HASH "hash"
267#define SP_TOKEN_LOCAL_VAR ".var(" 261#define SP_TOKEN_LOCAL_VAR "var"
268#define SP_TOKEN_PARAM ".param(" 262#define SP_TOKEN_PARAM "param"
269#define SP_TOKEN_PARAM_REGEXP ".param_r(" 263#define SP_TOKEN_PARAM_REGEXP "param_r"
270#define SP_TOKEN_PARAM_TYPE ".param_type(" 264#define SP_TOKEN_PARAM_TYPE "param_type"
271#define SP_TOKEN_RET ".ret(" 265#define SP_TOKEN_RET "ret"
272#define SP_TOKEN_RET_REGEXP ".ret_r(" 266#define SP_TOKEN_RET_REGEXP "ret_r"
273#define SP_TOKEN_RET_TYPE ".ret_type(" 267#define SP_TOKEN_RET_TYPE "ret_type"
274#define SP_TOKEN_VALUE ".value(" 268#define SP_TOKEN_VALUE "value"
275#define SP_TOKEN_VALUE_REGEXP ".value_r(" 269#define SP_TOKEN_VALUE_REGEXP "value_r"
276#define SP_TOKEN_KEY ".key(" 270#define SP_TOKEN_KEY "key"
277#define SP_TOKEN_KEY_REGEXP ".key_r(" 271#define SP_TOKEN_KEY_REGEXP "key_r"
278#define SP_TOKEN_VALUE_ARG_POS ".pos(" 272#define SP_TOKEN_VALUE_ARG_POS "pos"
279#define SP_TOKEN_LINE_NUMBER ".line(" 273#define SP_TOKEN_LINE_NUMBER "line"
280 274
281// cookies encryption 275// cookies encryption
282#define SP_TOKEN_NAME ".name(" 276#define SP_TOKEN_NAME "name"
283#define SP_TOKEN_NAME_REGEXP ".name_r(" 277#define SP_TOKEN_NAME_REGEXP "name_r"
284 278
285// cookies samesite 279// cookies samesite
286#define SP_TOKEN_SAMESITE ".samesite(" 280#define SP_TOKEN_SAMESITE "samesite"
287#define SP_TOKEN_ENCRYPT ".encrypt(" 281#define SP_TOKEN_ENCRYPT "encrypt"
288#define SP_TOKEN_SAMESITE_LAX "Lax" 282#define SP_TOKEN_SAMESITE_LAX "Lax"
289#define SP_TOKEN_SAMESITE_STRICT "Strict" 283#define SP_TOKEN_SAMESITE_STRICT "Strict"
290 284
291// Global configuration options 285// Global configuration options
292#define SP_TOKEN_ENCRYPTION_KEY ".secret_key(" 286#define SP_TOKEN_ENCRYPTION_KEY "secret_key"
293#define SP_TOKEN_ENV_VAR ".cookie_env_var(" 287#define SP_TOKEN_ENV_VAR "cookie_env_var"
294#define SP_TOKEN_LOG_MEDIA ".log_media(" 288#define SP_TOKEN_LOG_MEDIA "log_media"
295 289
296// upload_validator 290// upload_validator
297#define SP_TOKEN_UPLOAD_SCRIPT ".script(" 291#define SP_TOKEN_UPLOAD_SCRIPT "script"
292
293#define SP_TOKEN_LIST "list"
294
295zend_result sp_process_rule(sp_parsed_keyword *parsed_rule, sp_config_keyword *config_keywords);
296
297zend_result sp_parse_config(const char *filename);
298 298
299#define SP_TOKEN_LIST ".list(" 299#define SP_PARSE_CHECK_ARG_EXISTS(value) \
300if (!value) { \
301 sp_log_err("config", "Missing argument to keyword '%s' - it should be '%s(\"...\")' on line %zu", token, token, kw->lineno); \
302 return SP_PARSER_ERROR; \
303}
300 304
301int sp_parse_config(const char *); 305#define SP_PARSE_ARG(value) \
302int parse_array(sp_disabled_function *); 306 zend_string *value = sp_get_arg_string(kw); \
307 SP_PARSE_CHECK_ARG_EXISTS(value);
303 308
304int parse_str(char *restrict, char *restrict, void *); 309SP_PARSEKW_FN(parse_str);
305int parse_regexp(char *restrict, char *restrict, void *); 310SP_PARSEKW_FN(parse_regexp);
306int parse_empty(char *restrict, char *restrict, void *); 311SP_PARSEKW_FN(parse_empty);
307int parse_cidr(char *restrict, char *restrict, void *); 312SP_PARSEKW_FN(parse_int);
308int parse_php_type(char *restrict, char *restrict, void *); 313SP_PARSEKW_FN(parse_ulong);
309int parse_list(char *restrict, char *restrict, void *); 314SP_PARSEKW_FN(parse_php_type);
315SP_PARSEKW_FN(parse_cidr);
316SP_PARSEKW_FN(parse_list);
310 317
311// cleanup 318// cleanup
312void sp_free_disabled_function(void *data); 319void sp_free_disabled_function(void *data);
diff --git a/src/sp_config_keywords.c b/src/sp_config_keywords.c
index a177a5e..8084698 100644
--- a/src/sp_config_keywords.c
+++ b/src/sp_config_keywords.c
@@ -2,311 +2,236 @@
2 2
3#define SP_SET_ENABLE_DISABLE(enable, disable, varname) \ 3#define SP_SET_ENABLE_DISABLE(enable, disable, varname) \
4 if (((varname) || enable) && disable) { \ 4 if (((varname) || enable) && disable) { \
5 sp_log_err("config", "A rule can't be enabled and disabled on line %zu", sp_line_no); \ 5 sp_log_err("config", "A rule can't be enabled and disabled on line %zu", parsed_rule->lineno); \
6 return -1; \ 6 return SP_PARSER_ERROR; \
7 } \ 7 } \
8 if (enable || disable) { \ 8 if (enable || disable) { \
9 (varname) = (enable || !disable); \ 9 (varname) = (enable || !disable); \
10 } 10 }
11 11
12static int parse_enable(char *line, bool *restrict retval, 12#define SP_PROCESS_CONFIG_KEYWORDS(CMD) if (sp_process_rule(&(parsed_rule[1]), config_keywords) != SUCCESS) { CMD; }
13 bool *restrict simulation) { 13#define SP_PROCESS_CONFIG_KEYWORDS_ERR() SP_PROCESS_CONFIG_KEYWORDS(return SP_PARSER_ERROR)
14
15SP_PARSE_FN(parse_enable) {
14 bool enable = false, disable = false; 16 bool enable = false, disable = false;
15 sp_config_functions sp_config_funcs[] = { 17 sp_config_keyword config_keywords[] = {
16 {parse_empty, SP_TOKEN_ENABLE, &(enable)}, 18 {parse_empty, SP_TOKEN_ENABLE, &(enable)},
17 {parse_empty, SP_TOKEN_DISABLE, &(disable)}, 19 {parse_empty, SP_TOKEN_DISABLE, &(disable)},
18 {parse_empty, SP_TOKEN_SIMULATION, simulation},
19 {0, 0, 0}}; 20 {0, 0, 0}};
20 21
21 int ret = parse_keywords(sp_config_funcs, line); 22 SP_PROCESS_CONFIG_KEYWORDS_ERR();
22
23 if (0 != ret) {
24 return ret;
25 }
26 23
27 SP_SET_ENABLE_DISABLE(enable, disable, *retval); 24 SP_SET_ENABLE_DISABLE(enable, disable, *(bool*)retval);
28 25
29 return ret; 26 return SP_PARSER_STOP;
30} 27}
31 28
32int parse_session(char *line) { 29SP_PARSE_FN(parse_session) {
33 sp_config_session *session = pecalloc(sizeof(sp_config_session), 1, 0); 30 sp_config_session *cfg = retval;
34 31
35 sp_config_functions sp_config_funcs_session_encryption[] = { 32 sp_config_keyword config_keywords[] = {
36 {parse_empty, SP_TOKEN_ENCRYPT, &(session->encrypt)}, 33 {parse_empty, SP_TOKEN_ENCRYPT, &(cfg->encrypt)},
37 {parse_empty, SP_TOKEN_SIMULATION, &(session->simulation)}, 34 {parse_empty, SP_TOKEN_SIMULATION, &(cfg->simulation)},
35 {parse_empty, SP_TOKEN_SIM, &(cfg->simulation)},
38 {0, 0, 0}}; 36 {0, 0, 0}};
39 int ret = parse_keywords(sp_config_funcs_session_encryption, line); 37
40 if (0 != ret) { 38 SP_PROCESS_CONFIG_KEYWORDS_ERR();
41 return ret;
42 }
43 39
44#if (!HAVE_PHP_SESSION || defined(COMPILE_DL_SESSION)) 40#if (!HAVE_PHP_SESSION || defined(COMPILE_DL_SESSION))
45 sp_log_err( 41 sp_log_err("config",
46 "config",
47 "You're trying to use the session cookie encryption feature " 42 "You're trying to use the session cookie encryption feature "
48 "on line %zu without having session support statically built into PHP. " 43 "on line %zu without having session support statically built into PHP. "
49 "This isn't supported, see " 44 "This isn't supported, see "
50 "https://github.com/jvoisin/snuffleupagus/issues/278 for details.", 45 "https://github.com/jvoisin/snuffleupagus/issues/278 for details.", parsed_rule->lineno);
51 sp_line_no); 46 return SP_PARSER_ERROR;
52 pefree(session, 0);
53 return -1;
54#endif 47#endif
55 48
56 if (session->encrypt) { 49 if (cfg->encrypt) {
57 if (0 == (SNUFFLEUPAGUS_G(config).config_snuffleupagus->cookies_env_var)) { 50 if (!SNUFFLEUPAGUS_G(config).config_snuffleupagus->cookies_env_var) {
58 sp_log_err( 51 sp_log_err("config", "You're trying to use the session cookie encryption feature "
59 "config", 52 "on line %zu without having set the `.cookie_env_var` option in "
60 "You're trying to use the session cookie encryption feature " 53 "`sp.global`: please set it first", parsed_rule->lineno);
61 "on line %zu without having set the `.cookie_env_var` option in" 54 return SP_PARSER_ERROR;
62 "`sp.global`: please set it first", 55 } else if (!SNUFFLEUPAGUS_G(config).config_snuffleupagus->encryption_key) {
63 sp_line_no); 56 sp_log_err("config", "You're trying to use the session cookie encryption feature "
64 pefree(session, 0); 57 "on line %zu without having set the `.secret_key` option in "
65 return -1; 58 "`sp.global`: please set it first", parsed_rule->lineno);
66 } else if (0 == 59 return SP_PARSER_ERROR;
67 (SNUFFLEUPAGUS_G(config).config_snuffleupagus->encryption_key)) {
68 sp_log_err("config",
69 "You're trying to use the session cookie encryption feature "
70 "on line %zu without having set the `.secret_key` option in"
71 "`sp.global`: please set it first",
72 sp_line_no);
73 pefree(session, 0);
74 return -1;
75 } 60 }
76 } 61 }
77 62
78 SNUFFLEUPAGUS_G(config).config_session->encrypt = session->encrypt; 63 return SP_PARSER_STOP;
79 SNUFFLEUPAGUS_G(config).config_session->simulation = session->simulation;
80 pefree(session, 0);
81 return ret;
82}
83
84int parse_random(char *line) {
85 return parse_enable(line, &(SNUFFLEUPAGUS_G(config).config_random->enable),
86 NULL);
87} 64}
88 65
89int parse_log_media(char *line) { 66SP_PARSEKW_FN(parse_log_media) {
90 size_t consumed = 0; 67 SP_PARSE_ARG(value);
91 zend_string *value = 68
92 get_param(&consumed, line, SP_TYPE_STR, SP_TOKEN_LOG_MEDIA); 69 if (!strcmp(ZSTR_VAL(value), "php")) {
93 70 *(char*)retval = SP_ZEND;
94 if (value) { 71 zend_string_release_ex(value, 1);
95 if (!strcmp(ZSTR_VAL(value), "php")) { 72 return SP_PARSER_SUCCESS;
96 SNUFFLEUPAGUS_G(config).log_media = SP_ZEND; 73 } else if (!strcmp(ZSTR_VAL(value), "syslog")) {
97 return 0; 74 *(char*)retval = SP_SYSLOG;
98 } else if (!strcmp(ZSTR_VAL(value), "syslog")) { 75 zend_string_release_ex(value, 1);
99 SNUFFLEUPAGUS_G(config).log_media = SP_SYSLOG; 76 return SP_PARSER_SUCCESS;
100 return 0;
101 }
102 } 77 }
103 sp_log_err("config", "%s) only supports 'syslog' or 'php', on line %zu",
104 SP_TOKEN_LOG_MEDIA, sp_line_no);
105 return -1;
106}
107 78
108int parse_sloppy_comparison(char *line) { 79 sp_log_err("config", "." SP_TOKEN_LOG_MEDIA "() only supports 'syslog' or 'php' on line %zu", kw->lineno);
109 return parse_enable(line, &(SNUFFLEUPAGUS_G(config).config_sloppy->enable),
110 NULL);
111}
112 80
113int parse_disable_xxe(char *line) { 81 return SP_PARSER_ERROR;
114 return parse_enable(
115 line, &(SNUFFLEUPAGUS_G(config).config_disable_xxe->enable), NULL);
116} 82}
117 83
118int parse_auto_cookie_secure(char *line) { 84SP_PARSE_FN(parse_unserialize) {
119 return parse_enable(
120 line, &(SNUFFLEUPAGUS_G(config).config_auto_cookie_secure->enable), NULL);
121}
122
123int parse_global_strict(char *line) {
124 return parse_enable(
125 line, &(SNUFFLEUPAGUS_G(config).config_global_strict->enable), NULL);
126}
127
128int parse_unserialize(char *line) {
129 bool enable = false, disable = false; 85 bool enable = false, disable = false;
130 sp_config_unserialize *unserialize = 86 sp_config_unserialize *cfg = (sp_config_unserialize*)retval;
131 SNUFFLEUPAGUS_G(config).config_unserialize;
132 87
133 sp_config_functions sp_config_funcs[] = { 88 sp_config_keyword config_keywords[] = {
134 {parse_empty, SP_TOKEN_ENABLE, &(enable)}, 89 {parse_empty, SP_TOKEN_ENABLE, &(enable)},
135 {parse_empty, SP_TOKEN_DISABLE, &(disable)}, 90 {parse_empty, SP_TOKEN_DISABLE, &(disable)},
136 {parse_empty, SP_TOKEN_SIMULATION, &(unserialize->simulation)}, 91 {parse_empty, SP_TOKEN_SIMULATION, &(cfg->simulation)},
137 {parse_str, SP_TOKEN_DUMP, &(unserialize->dump)}, 92 {parse_empty, SP_TOKEN_SIM, &(cfg->simulation)},
93 {parse_str, SP_TOKEN_DUMP, &(cfg->dump)},
138 {0, 0, 0}}; 94 {0, 0, 0}};
139 95
140 unserialize->textual_representation = zend_string_init(line, strlen(line), 1); 96 SP_PROCESS_CONFIG_KEYWORDS_ERR();
141 97
142 int ret = parse_keywords(sp_config_funcs, line); 98 SP_SET_ENABLE_DISABLE(enable, disable, cfg->enable);
143 if (0 != ret) {
144 return ret;
145 }
146 99
147 SP_SET_ENABLE_DISABLE(enable, disable, SNUFFLEUPAGUS_G(config).config_unserialize->enable); 100 cfg->textual_representation = sp_get_textual_representation(parsed_rule);
148 101
149 return ret; 102 return SP_PARSER_STOP;
150} 103}
151 104
152int parse_readonly_exec(char *line) { 105SP_PARSE_FN(parse_readonly_exec) {
153 bool enable = false, disable = false; 106 bool enable = false, disable = false;
154 sp_config_readonly_exec *readonly_exec = 107 sp_config_readonly_exec *cfg = (sp_config_readonly_exec*)retval;
155 SNUFFLEUPAGUS_G(config).config_readonly_exec;
156 108
157 sp_config_functions sp_config_funcs[] = { 109 sp_config_keyword config_keywords[] = {
158 {parse_empty, SP_TOKEN_ENABLE, &(enable)}, 110 {parse_empty, SP_TOKEN_ENABLE, &(enable)},
159 {parse_empty, SP_TOKEN_DISABLE, &(disable)}, 111 {parse_empty, SP_TOKEN_DISABLE, &(disable)},
160 {parse_empty, SP_TOKEN_SIMULATION, &(readonly_exec->simulation)}, 112 {parse_empty, SP_TOKEN_SIMULATION, &(cfg->simulation)},
161 {parse_str, SP_TOKEN_DUMP, &(readonly_exec->dump)}, 113 {parse_empty, SP_TOKEN_SIM, &(cfg->simulation)},
114 {parse_str, SP_TOKEN_DUMP, &(cfg->dump)},
162 {0, 0, 0}}; 115 {0, 0, 0}};
163 116
164 readonly_exec->textual_representation = 117 SP_PROCESS_CONFIG_KEYWORDS_ERR();
165 zend_string_init(line, strlen(line), 1);
166 int ret = parse_keywords(sp_config_funcs, line);
167 118
168 if (0 != ret) { 119 cfg->textual_representation = sp_get_textual_representation(parsed_rule);
169 return ret;
170 }
171 120
172 SP_SET_ENABLE_DISABLE(enable, disable, SNUFFLEUPAGUS_G(config).config_readonly_exec->enable); 121 SP_SET_ENABLE_DISABLE(enable, disable, cfg->enable);
173 122
174 return ret; 123 return SP_PARSER_STOP;
175} 124}
176 125
177int parse_global(char *line) { 126SP_PARSE_FN(parse_global) {
178 sp_config_functions sp_config_funcs_global[] = { 127 sp_config_keyword config_keywords[] = {
179 {parse_str, SP_TOKEN_ENCRYPTION_KEY, 128 {parse_str, SP_TOKEN_ENCRYPTION_KEY, &(SNUFFLEUPAGUS_G(config).config_snuffleupagus->encryption_key)},
180 &(SNUFFLEUPAGUS_G(config).config_snuffleupagus->encryption_key)}, 129 {parse_str, SP_TOKEN_ENV_VAR, &(SNUFFLEUPAGUS_G(config).config_snuffleupagus->cookies_env_var)},
181 {parse_str, SP_TOKEN_ENV_VAR, 130 {parse_log_media, SP_TOKEN_LOG_MEDIA, &(SNUFFLEUPAGUS_G(config).log_media)},
182 &(SNUFFLEUPAGUS_G(config).config_snuffleupagus->cookies_env_var)},
183 {0, 0, 0}}; 131 {0, 0, 0}};
184 return parse_keywords(sp_config_funcs_global, line); 132
133 SP_PROCESS_CONFIG_KEYWORDS_ERR();
134 return SP_PARSER_STOP;
185} 135}
186 136
187static int parse_eval_filter_conf(char *line, sp_list_node **list) { 137SP_PARSE_FN(parse_eval_filter_conf) {
188 sp_config_eval *eval = SNUFFLEUPAGUS_G(config).config_eval; 138 sp_config_eval *cfg = SNUFFLEUPAGUS_G(config).config_eval;
189 139
190 sp_config_functions sp_config_funcs[] = { 140 sp_config_keyword config_keywords[] = {
191 {parse_list, SP_TOKEN_LIST, list}, 141 {parse_list, SP_TOKEN_LIST, retval},
192 {parse_empty, SP_TOKEN_SIMULATION, 142 {parse_empty, SP_TOKEN_SIMULATION, &(cfg->simulation)},
193 &(SNUFFLEUPAGUS_G(config).config_eval->simulation)}, 143 {parse_empty, SP_TOKEN_SIM, &(cfg->simulation)},
194 {parse_str, SP_TOKEN_DUMP, &(SNUFFLEUPAGUS_G(config).config_eval->dump)}, 144 {parse_str, SP_TOKEN_DUMP, &(cfg->dump)},
195 {0, 0, 0}}; 145 {0, 0, 0}};
196 146
197 eval->textual_representation = zend_string_init(line, strlen(line), 1); 147 SP_PROCESS_CONFIG_KEYWORDS_ERR();
198 148
199 int ret = parse_keywords(sp_config_funcs, line); 149 cfg->textual_representation = sp_get_textual_representation(parsed_rule);
200 if (0 != ret) {
201 return ret;
202 }
203 150
204 return SUCCESS; 151 return SP_PARSER_STOP;
205} 152}
206 153
207int parse_wrapper_whitelist(char *line) { 154SP_PARSE_FN(parse_wrapper_whitelist) {
208 SNUFFLEUPAGUS_G(config).config_wrapper->enabled = true; 155 sp_config_wrapper *cfg = (sp_config_wrapper*)retval;
209 sp_config_functions sp_config_funcs[] = { 156
210 {parse_list, SP_TOKEN_LIST, 157 sp_config_keyword config_keywords[] = {
211 &SNUFFLEUPAGUS_G(config).config_wrapper->whitelist}, 158 {parse_list, SP_TOKEN_LIST, &cfg->whitelist},
212 {0, 0, 0}}; 159 {0, 0, 0}};
213 int ret = parse_keywords(sp_config_funcs, line);
214 if (0 != ret) {
215 return ret;
216 }
217 return SUCCESS;
218}
219 160
220int parse_eval_blacklist(char *line) { 161 SP_PROCESS_CONFIG_KEYWORDS_ERR();
221 return parse_eval_filter_conf( 162
222 line, &SNUFFLEUPAGUS_G(config).config_eval->blacklist); 163 cfg->enabled = true;
223}
224 164
225int parse_eval_whitelist(char *line) { 165 return SP_PARSER_STOP;
226 return parse_eval_filter_conf(
227 line, &SNUFFLEUPAGUS_G(config).config_eval->whitelist);
228} 166}
229 167
230int parse_cookie(char *line) { 168SP_PARSE_FN(parse_cookie) {
231 int ret = 0; 169 int ret = 0;
232 zend_string *samesite = NULL; 170 zend_string *samesite = NULL;
233 sp_cookie *cookie = pecalloc(sizeof(sp_cookie), 1, 1); 171 sp_cookie *cookie = pecalloc(sizeof(sp_cookie), 1, 1);
234 172
235 sp_config_functions sp_config_funcs_cookie_encryption[] = { 173 sp_config_keyword config_keywords[] = {
236 {parse_str, SP_TOKEN_NAME, &(cookie->name)}, 174 {parse_str, SP_TOKEN_NAME, &(cookie->name)},
237 {parse_regexp, SP_TOKEN_NAME_REGEXP, &(cookie->name_r)}, 175 {parse_regexp, SP_TOKEN_NAME_REGEXP, &(cookie->name_r)},
238 {parse_str, SP_TOKEN_SAMESITE, &samesite}, 176 {parse_str, SP_TOKEN_SAMESITE, &samesite},
239 {parse_empty, SP_TOKEN_ENCRYPT, &cookie->encrypt}, 177 {parse_empty, SP_TOKEN_ENCRYPT, &cookie->encrypt},
240 {parse_empty, SP_TOKEN_SIMULATION, &cookie->simulation}, 178 {parse_empty, SP_TOKEN_SIMULATION, &cookie->simulation},
179 {parse_empty, SP_TOKEN_SIM, &cookie->simulation},
241 {0, 0, 0}}; 180 {0, 0, 0}};
242 181
243 ret = parse_keywords(sp_config_funcs_cookie_encryption, line); 182 SP_PROCESS_CONFIG_KEYWORDS(goto err);
244 if (0 != ret) {
245 return ret;
246 }
247 183
248 if (cookie->encrypt) { 184 if (cookie->encrypt) {
249 if (0 == (SNUFFLEUPAGUS_G(config).config_snuffleupagus->cookies_env_var)) { 185 if (!SNUFFLEUPAGUS_G(config).config_snuffleupagus->cookies_env_var) {
250 sp_log_err( 186 sp_log_err("config", "You're trying to use the cookie encryption feature on line %zu "
251 "config", 187 "without having set the `." SP_TOKEN_ENV_VAR "` option in`sp.global`: please set it first", parsed_rule->lineno);
252 "You're trying to use the cookie encryption feature" 188 goto err;
253 "on line %zu without having set the `.cookie_env_var` option in" 189 } else if (!SNUFFLEUPAGUS_G(config).config_snuffleupagus->encryption_key) {
254 "`sp.global`: please set it first", 190 sp_log_err("config", "You're trying to use the cookie encryption feature "
255 sp_line_no); 191 "on line %zu without having set the `." SP_TOKEN_ENCRYPTION_KEY "` option in "
256 return -1; 192 "`sp." SP_TOKEN_GLOBAL "`: please set it first", parsed_rule->lineno);
257 } else if (0 == 193 goto err;
258 (SNUFFLEUPAGUS_G(config).config_snuffleupagus->encryption_key)) {
259 sp_log_err(
260 "config",
261 "You're trying to use the cookie encryption feature"
262 "on line %zu without having set the `.encryption_key` option in"
263 "`sp.global`: please set it first",
264 sp_line_no);
265 return -1;
266 } 194 }
267 } else if (!samesite) { 195 } else if (!samesite) {
268 sp_log_err("config", 196 sp_log_err("config", "You must specify a at least one action to a cookie on line %zu", parsed_rule->lineno);
269 "You must specify a at least one action to a cookie on line " 197 goto err;
270 "%zu",
271 sp_line_no);
272 return -1;
273 } 198 }
274 if ((!cookie->name || 0 == ZSTR_LEN(cookie->name)) && !cookie->name_r) { 199 if ((!cookie->name || 0 == ZSTR_LEN(cookie->name)) && !cookie->name_r) {
275 sp_log_err("config", 200 sp_log_err("config", "You must specify a cookie name/regexp on line %zu", parsed_rule->lineno);
276 "You must specify a cookie name/regexp on line " 201 goto err;
277 "%zu",
278 sp_line_no);
279 return -1;
280 } 202 }
281 if (cookie->name && cookie->name_r) { 203 if (cookie->name && cookie->name_r) {
282 sp_log_err("config", 204 sp_log_err("config", "name and name_r are mutually exclusive on line %zu", parsed_rule->lineno);
283 "name and name_r are mutually exclusive on line " 205 goto err;
284 "%zu",
285 sp_line_no);
286 return -1;
287 } 206 }
288 if (samesite) { 207 if (samesite) {
289 if (zend_string_equals_literal_ci(samesite, SP_TOKEN_SAMESITE_LAX)) { 208 if (zend_string_equals_literal_ci(samesite, SP_TOKEN_SAMESITE_LAX)) {
290 cookie->samesite = lax; 209 cookie->samesite = lax;
291 } else if (zend_string_equals_literal_ci(samesite, 210 } else if (zend_string_equals_literal_ci(samesite, SP_TOKEN_SAMESITE_STRICT)) {
292 SP_TOKEN_SAMESITE_STRICT)) {
293 cookie->samesite = strict; 211 cookie->samesite = strict;
294 } else { 212 } else {
295 sp_log_err( 213 sp_log_err("config", "'%s' is an invalid value to samesite (expected " SP_TOKEN_SAMESITE_LAX " or " SP_TOKEN_SAMESITE_STRICT ") on line %zu",
296 "config", 214 ZSTR_VAL(samesite), parsed_rule->lineno);
297 "%s is an invalid value to samesite (expected %s or %s) on line " 215 goto err;
298 "%zu",
299 ZSTR_VAL(samesite), SP_TOKEN_SAMESITE_LAX, SP_TOKEN_SAMESITE_STRICT,
300 sp_line_no);
301 return -1;
302 } 216 }
303 } 217 }
304 SNUFFLEUPAGUS_G(config).config_cookie->cookies = 218
305 sp_list_insert(SNUFFLEUPAGUS_G(config).config_cookie->cookies, cookie); 219 SNUFFLEUPAGUS_G(config).config_cookie->cookies = sp_list_insert(SNUFFLEUPAGUS_G(config).config_cookie->cookies, cookie);
306 return SUCCESS; 220
221 return SP_PARSER_STOP;
222
223err:
224 if (samesite) {
225 zend_string_release(samesite);
226 }
227 if (cookie) {
228 sp_free_cookie(cookie);
229 pefree(cookie, 1);
230 }
231 return SP_PARSER_ERROR;
307} 232}
308 233
309int add_df_to_hashtable(HashTable *ht, sp_disabled_function *df) { 234static int add_df_to_hashtable(HashTable *ht, sp_disabled_function *df) {
310 zval *list = zend_hash_find(ht, df->function); 235 zval *list = zend_hash_find(ht, df->function);
311 236
312 if (NULL == list) { 237 if (NULL == list) {
@@ -317,19 +242,19 @@ int add_df_to_hashtable(HashTable *ht, sp_disabled_function *df) {
317 return SUCCESS; 242 return SUCCESS;
318} 243}
319 244
320int parse_disabled_functions(char *line) { 245SP_PARSE_FN(parse_disabled_functions) {
321 int ret = 0; 246 int ret = SP_PARSER_ERROR;
322 bool enable = true, disable = false, allow = false, drop = false; 247 bool enable = false, disable = false, allow = false, drop = false;
323 zend_string *pos = NULL, *var = NULL, *param = NULL; 248 zend_string *var = NULL, *param = NULL;
324 zend_string *line_number = NULL;
325 sp_disabled_function *df = pecalloc(sizeof(*df), 1, 1); 249 sp_disabled_function *df = pecalloc(sizeof(*df), 1, 1);
326 df->pos = -1; 250 df->pos = -1;
327 251
328 sp_config_functions sp_config_funcs_disabled_functions[] = { 252 sp_config_keyword config_keywords[] = {
329 {parse_empty, SP_TOKEN_ENABLE, &(enable)}, 253 {parse_empty, SP_TOKEN_ENABLE, &(enable)},
330 {parse_empty, SP_TOKEN_DISABLE, &(disable)}, 254 {parse_empty, SP_TOKEN_DISABLE, &(disable)},
331 {parse_str, SP_TOKEN_ALIAS, &(df->alias)}, 255 {parse_str, SP_TOKEN_ALIAS, &(df->alias)},
332 {parse_empty, SP_TOKEN_SIMULATION, &(df->simulation)}, 256 {parse_empty, SP_TOKEN_SIMULATION, &(df->simulation)},
257 {parse_empty, SP_TOKEN_SIM, &(df->simulation)},
333 {parse_str, SP_TOKEN_FILENAME, &(df->filename)}, 258 {parse_str, SP_TOKEN_FILENAME, &(df->filename)},
334 {parse_regexp, SP_TOKEN_FILENAME_REGEXP, &(df->r_filename)}, 259 {parse_regexp, SP_TOKEN_FILENAME_REGEXP, &(df->r_filename)},
335 {parse_str, SP_TOKEN_FUNCTION, &(df->function)}, 260 {parse_str, SP_TOKEN_FUNCTION, &(df->function)},
@@ -350,23 +275,21 @@ int parse_disabled_functions(char *line) {
350 {parse_regexp, SP_TOKEN_RET_REGEXP, &(df->r_ret)}, 275 {parse_regexp, SP_TOKEN_RET_REGEXP, &(df->r_ret)},
351 {parse_php_type, SP_TOKEN_RET_TYPE, &(df->ret_type)}, 276 {parse_php_type, SP_TOKEN_RET_TYPE, &(df->ret_type)},
352 {parse_str, SP_TOKEN_LOCAL_VAR, &(var)}, 277 {parse_str, SP_TOKEN_LOCAL_VAR, &(var)},
353 {parse_str, SP_TOKEN_VALUE_ARG_POS, &(pos)}, 278 {parse_int, SP_TOKEN_VALUE_ARG_POS, &(df->pos)},
354 {parse_str, SP_TOKEN_LINE_NUMBER, &(line_number)}, 279 {parse_ulong, SP_TOKEN_LINE_NUMBER, &(df->line)},
355 {0, 0, 0}}; 280 {0, 0, 0}};
356 281
357 ret = parse_keywords(sp_config_funcs_disabled_functions, line); 282 SP_PROCESS_CONFIG_KEYWORDS(goto out);
358 283
359 if (0 != ret) { 284 SP_SET_ENABLE_DISABLE(enable, disable, enable);
360 goto out; 285 if (disable) {
286 ret = SP_PARSER_STOP; goto out;
361 } 287 }
362 288
363#define MUTUALLY_EXCLUSIVE(X, Y, STR1, STR2) \ 289#define MUTUALLY_EXCLUSIVE(X, Y, STR1, STR2) \
364 if (X && Y) { \ 290 if (X && Y) { \
365 sp_log_err("config", \ 291 sp_log_err("config", "Invalid configuration line for 'sp.disabled_functions': '.%s' and '.%s' are mutually exclusive on line %zu", STR1, STR2, parsed_rule->lineno); \
366 "Invalid configuration line: 'sp.disabled_functions%s': " \ 292 goto out; \
367 "'.%s' and '.%s' are mutually exclusive on line %zu", \
368 line, STR1, STR2, sp_line_no); \
369 ret = -1; goto out; \
370 } 293 }
371 294
372 MUTUALLY_EXCLUSIVE(df->value, df->r_value, "value", "value_r"); 295 MUTUALLY_EXCLUSIVE(df->value, df->r_value, "value", "value_r");
@@ -374,8 +297,8 @@ int parse_disabled_functions(char *line) {
374 MUTUALLY_EXCLUSIVE(df->filename, df->r_filename, "filename", "filename_r"); 297 MUTUALLY_EXCLUSIVE(df->filename, df->r_filename, "filename", "filename_r");
375 MUTUALLY_EXCLUSIVE(df->ret, df->r_ret, "ret", "ret_r"); 298 MUTUALLY_EXCLUSIVE(df->ret, df->r_ret, "ret", "ret_r");
376 MUTUALLY_EXCLUSIVE(df->key, df->r_key, "key", "key_r"); 299 MUTUALLY_EXCLUSIVE(df->key, df->r_key, "key", "key_r");
377 MUTUALLY_EXCLUSIVE(pos, param, "pos", "param"); 300 MUTUALLY_EXCLUSIVE((df->pos >= 0), param, "pos", "param");
378 MUTUALLY_EXCLUSIVE(pos, df->r_param, "pos", "param_r"); 301 MUTUALLY_EXCLUSIVE((df->pos >= 0), df->r_param, "pos", "param_r");
379 MUTUALLY_EXCLUSIVE(param, df->r_param, "param", "param_r"); 302 MUTUALLY_EXCLUSIVE(param, df->r_param, "param", "param_r");
380 MUTUALLY_EXCLUSIVE((df->r_key || df->key), (df->r_value || df->value), "key", "value"); 303 MUTUALLY_EXCLUSIVE((df->r_key || df->key), (df->r_value || df->value), "key", "value");
381 MUTUALLY_EXCLUSIVE((df->r_ret || df->ret || df->ret_type), (df->r_param || param), "ret", "param"); 304 MUTUALLY_EXCLUSIVE((df->r_ret || df->ret || df->ret_type), (df->r_param || param), "ret", "param");
@@ -385,52 +308,21 @@ int parse_disabled_functions(char *line) {
385#undef MUTUALLY_EXCLUSIVE 308#undef MUTUALLY_EXCLUSIVE
386 309
387 if (!(df->r_function || df->function)) { 310 if (!(df->r_function || df->function)) {
388 sp_log_err("config", 311 sp_log_err("config", "Invalid configuration line: 'sp.disabled_functions': must take a function name on line %zu", parsed_rule->lineno);
389 "Invalid configuration line: 'sp.disabled_functions%s':" 312 goto out;
390 " must take a function name on line %zu",
391 line, sp_line_no);
392 ret = -1; goto out;
393 } 313 }
394 if (df->filename && (*ZSTR_VAL(df->filename) != '/') && 314 if (df->filename && (*ZSTR_VAL(df->filename) != '/') &&
395 (0 != strncmp(ZSTR_VAL(df->filename), "phar://", strlen("phar://")))) { 315 (0 != strncmp(ZSTR_VAL(df->filename), "phar://", strlen("phar://")))) {
396 sp_log_err( 316 sp_log_err("config", "Invalid configuration line: 'sp.disabled_functions': '.filename' must be an absolute path or a phar archive on line %zu", parsed_rule->lineno);
397 "config", 317 goto out;
398 "Invalid configuration line: 'sp.disabled_functions%s':"
399 "'.filename' must be an absolute path or a phar archive on line %zu",
400 line, sp_line_no);
401 ret = -1; goto out;
402 } 318 }
403 if (!(allow ^ drop)) { 319 if (!(allow ^ drop)) {
404 sp_log_err("config", 320 sp_log_err("config", "Invalid configuration line: 'sp.disabled_functions': The rule must either be a `drop` or `allow` one on line %zu", parsed_rule->lineno);
405 "Invalid configuration line: 'sp.disabled_functions%s': The " 321 goto out;
406 "rule must either be a `drop` or `allow` one on line %zu",
407 line, sp_line_no);
408 ret = -1; goto out;
409 }
410
411 if (pos) {
412 errno = 0;
413 char *endptr;
414 df->pos = (int)strtol(ZSTR_VAL(pos), &endptr, 10);
415 if (errno != 0 || endptr == ZSTR_VAL(pos)) {
416 sp_log_err("config", "Failed to parse arg '%s' of `pos` on line %zu",
417 ZSTR_VAL(pos), sp_line_no);
418 ret = -1; goto out;
419 }
420 } 322 }
421 323
422 if (line_number) {
423 errno = 0;
424 char *endptr;
425 df->line = (unsigned int)strtoul(ZSTR_VAL(line_number), &endptr, 10);
426 if (errno != 0 || endptr == ZSTR_VAL(line_number)) {
427 sp_log_err("config", "Failed to parse arg '%s' of `line` on line %zu",
428 ZSTR_VAL(line_number), sp_line_no);
429 ret = -1; goto out;
430 }
431 }
432 df->allow = allow; 324 df->allow = allow;
433 df->textual_representation = zend_string_init(line, strlen(line), 1); 325 df->textual_representation = sp_get_textual_representation(parsed_rule);
434 326
435 if (df->function) { 327 if (df->function) {
436 df->functions_list = parse_functions_list(ZSTR_VAL(df->function)); 328 df->functions_list = parse_functions_list(ZSTR_VAL(df->function));
@@ -450,33 +342,23 @@ int parse_disabled_functions(char *line) {
450 df->param = sp_parse_var(ZSTR_VAL(param)); 342 df->param = sp_parse_var(ZSTR_VAL(param));
451 } 343 }
452 if (!df->param) { 344 if (!df->param) {
453 sp_log_err("config", "Invalid value '%s' for `param` on line %zu", 345 sp_log_err("config", "Invalid value '%s' for `param` on line %zu", ZSTR_VAL(param), parsed_rule->lineno);
454 ZSTR_VAL(param), sp_line_no); 346 goto out;
455 ret = -1; goto out;
456 } 347 }
457 } 348 }
458
459 if (var) { 349 if (var) {
460 if (ZSTR_LEN(var)) { 350 if (ZSTR_LEN(var)) {
461 df->var = sp_parse_var(ZSTR_VAL(var)); 351 df->var = sp_parse_var(ZSTR_VAL(var));
462 if (!df->var) { 352 if (!df->var) {
463 sp_log_err("config", "Invalid value '%s' for `var` on line %zu", 353 sp_log_err("config", "Invalid value '%s' for `var` on line %zu", ZSTR_VAL(var), parsed_rule->lineno);
464 ZSTR_VAL(var), sp_line_no); 354 goto out;
465 ret = -1; goto out;
466 } 355 }
467 } else { 356 } else {
468 sp_log_err("config", "Empty value in `var` on line %zu", sp_line_no); 357 sp_log_err("config", "Empty value in `var` on line %zu", parsed_rule->lineno);
469 ret = -1; goto out; 358 goto out;
470 } 359 }
471 } 360 }
472 361
473 if (true == disable || 0 != ret) {
474 out:
475 sp_free_disabled_function(df);
476 pefree(df, 1);
477 return ret;
478 }
479
480 if (df->function && zend_string_equals_literal(df->function, "print")) { 362 if (df->function && zend_string_equals_literal(df->function, "print")) {
481 zend_string_release(df->function); 363 zend_string_release(df->function);
482 df->function = zend_string_init("echo", sizeof("echo") - 1, 1); 364 df->function = zend_string_init("echo", sizeof("echo") - 1, 1);
@@ -484,148 +366,136 @@ int parse_disabled_functions(char *line) {
484 366
485 if (df->function && !df->functions_list) { 367 if (df->function && !df->functions_list) {
486 if (df->ret || df->r_ret || df->ret_type) { 368 if (df->ret || df->r_ret || df->ret_type) {
487 add_df_to_hashtable(SNUFFLEUPAGUS_G(config).config_disabled_functions_ret, 369 add_df_to_hashtable(SNUFFLEUPAGUS_G(config).config_disabled_functions_ret, df);
488 df);
489 } else { 370 } else {
490 add_df_to_hashtable(SNUFFLEUPAGUS_G(config).config_disabled_functions, 371 add_df_to_hashtable(SNUFFLEUPAGUS_G(config).config_disabled_functions, df);
491 df);
492 } 372 }
493 } else { 373 } else {
494 if (df->ret || df->r_ret || df->ret_type) { 374 if (df->ret || df->r_ret || df->ret_type) {
495 SNUFFLEUPAGUS_G(config) 375 SNUFFLEUPAGUS_G(config).config_disabled_functions_reg_ret->disabled_functions = sp_list_insert(SNUFFLEUPAGUS_G(config).config_disabled_functions_reg_ret->disabled_functions, df);
496 .config_disabled_functions_reg_ret->disabled_functions =
497 sp_list_insert(
498 SNUFFLEUPAGUS_G(config)
499 .config_disabled_functions_reg_ret->disabled_functions,
500 df);
501 } else { 376 } else {
502 SNUFFLEUPAGUS_G(config) 377 SNUFFLEUPAGUS_G(config).config_disabled_functions_reg->disabled_functions = sp_list_insert(SNUFFLEUPAGUS_G(config).config_disabled_functions_reg->disabled_functions, df);
503 .config_disabled_functions_reg->disabled_functions =
504 sp_list_insert(SNUFFLEUPAGUS_G(config)
505 .config_disabled_functions_reg->disabled_functions,
506 df);
507 } 378 }
508 } 379 }
380 return SP_PARSER_STOP;
381
382out:
383 if (df) {
384 sp_free_disabled_function(df);
385 pefree(df, 1);
386 }
387 if (param) { zend_string_release(param); }
388 if (var) { zend_string_release(var); }
389
509 return ret; 390 return ret;
510} 391}
511 392
512int parse_upload_validation(char *line) { 393SP_PARSE_FN(parse_upload_validation) {
513 bool disable = false, enable = false; 394 bool disable = false, enable = false;
514 sp_config_functions sp_config_funcs_upload_validation[] = { 395 sp_config_upload_validation *cfg = (sp_config_upload_validation*)retval;
515 {parse_str, SP_TOKEN_UPLOAD_SCRIPT, 396
516 &(SNUFFLEUPAGUS_G(config).config_upload_validation->script)}, 397 sp_config_keyword config_keywords[] = {
517 {parse_empty, SP_TOKEN_SIMULATION,
518 &(SNUFFLEUPAGUS_G(config).config_upload_validation->simulation)},
519 {parse_empty, SP_TOKEN_ENABLE, &(enable)}, 398 {parse_empty, SP_TOKEN_ENABLE, &(enable)},
520 {parse_empty, SP_TOKEN_DISABLE, &(disable)}, 399 {parse_empty, SP_TOKEN_DISABLE, &(disable)},
400 {parse_str, SP_TOKEN_UPLOAD_SCRIPT, &(cfg->script)},
401 {parse_empty, SP_TOKEN_SIMULATION, &(cfg->simulation)},
402 {parse_empty, SP_TOKEN_SIM, &(cfg->simulation)},
521 {0, 0, 0}}; 403 {0, 0, 0}};
522 404
523 int ret = parse_keywords(sp_config_funcs_upload_validation, line); 405 SP_PROCESS_CONFIG_KEYWORDS_ERR();
524 406 SP_SET_ENABLE_DISABLE(enable, disable, cfg->enable);
525 if (0 != ret) {
526 return ret;
527 }
528
529 SP_SET_ENABLE_DISABLE(enable, disable, SNUFFLEUPAGUS_G(config).config_upload_validation->enable);
530
531 zend_string const *script =
532 SNUFFLEUPAGUS_G(config).config_upload_validation->script;
533 407
534 if (!script) { 408 if (!cfg->script) {
535 sp_log_err("config", 409 sp_log_err("config", "The `script` directive is mandatory in '.%s' on line %zu", token, parsed_rule->lineno);
536 "The `script` directive is mandatory in '%s' on line %zu", line, 410 return SP_PARSER_ERROR;
537 sp_line_no); 411 } else if (-1 == access(ZSTR_VAL(cfg->script), F_OK)) {
538 return -1; 412 sp_log_err("config", "The `script` (%s) doesn't exist on line %zu", ZSTR_VAL(cfg->script), parsed_rule->lineno);
539 } else if (-1 == access(ZSTR_VAL(script), F_OK)) { 413 return SP_PARSER_ERROR;
540 sp_log_err("config", "The `script` (%s) doesn't exist on line %zu", 414 } else if (-1 == access(ZSTR_VAL(cfg->script), X_OK)) {
541 ZSTR_VAL(script), sp_line_no); 415 sp_log_err("config", "The `script` (%s) isn't executable on line %zu", ZSTR_VAL(cfg->script), parsed_rule->lineno);
542 return -1; 416 return SP_PARSER_ERROR;
543 } else if (-1 == access(ZSTR_VAL(script), X_OK)) {
544 sp_log_err("config", "The `script` (%s) isn't executable on line %zu",
545 ZSTR_VAL(script), sp_line_no);
546 return -1;
547 } 417 }
548 418
549 return ret; 419 return SP_PARSER_STOP;
550} 420}
551 421
552int parse_ini_protection(char *line) { 422SP_PARSE_FN(parse_ini_protection) {
553 bool disable = false, enable = false; 423 bool disable = false, enable = false;
554 bool rw = false, ro = false; // rw is ignored, but declaring .policy_rw is valid for readability 424 bool rw = false, ro = false; // rw is ignored, but declaring .policy_rw is valid for readability
555 sp_config_ini *cfg = SNUFFLEUPAGUS_G(config).config_ini; 425 sp_config_ini *cfg = (sp_config_ini*)retval;
556 sp_config_functions sp_config_ini_protection[] = { 426 sp_config_keyword config_keywords[] = {
557 {parse_empty, SP_TOKEN_ENABLE, &(enable)}, 427 {parse_empty, "enable", &(enable)},
558 {parse_empty, SP_TOKEN_DISABLE, &(disable)}, 428 {parse_empty, "disable", &(disable)},
559 {parse_empty, SP_TOKEN_SIMULATION, &cfg->simulation}, 429 {parse_empty, "simulation", &cfg->simulation},
560 {parse_empty, ".policy_readonly(", &ro}, 430 {parse_empty, "sim", &cfg->simulation},
561 {parse_empty, ".policy_ro(", &ro}, 431 {parse_empty, "policy_readonly", &ro},
562 {parse_empty, ".policy_readwrite(", &rw}, 432 {parse_empty, "policy_ro", &ro},
563 {parse_empty, ".policy_rw(", &rw}, 433 {parse_empty, "policy_readwrite", &rw},
564 {parse_empty, ".policy_silent_ro(", &cfg->policy_silent_ro}, 434 {parse_empty, "policy_rw", &rw},
565 {parse_empty, ".policy_silent_fail(", &cfg->policy_silent_fail}, 435 {parse_empty, "policy_silent_ro", &cfg->policy_silent_ro},
566 {parse_empty, ".policy_no_log(", &cfg->policy_silent_fail}, 436 {parse_empty, "policy_silent_fail", &cfg->policy_silent_fail},
567 {parse_empty, ".policy_drop(", &cfg->policy_drop}, 437 {parse_empty, "policy_no_log", &cfg->policy_silent_fail},
438 {parse_empty, "policy_drop", &cfg->policy_drop},
568 {0, 0, 0}}; 439 {0, 0, 0}};
569 440
570 int ret = parse_keywords(sp_config_ini_protection, line); 441 SP_PROCESS_CONFIG_KEYWORDS_ERR();
571 if (ret) { return ret; }
572 442
573 SP_SET_ENABLE_DISABLE(enable, disable, cfg->enable); 443 SP_SET_ENABLE_DISABLE(enable, disable, cfg->enable);
574 444
575 if (ro && rw) { 445 if (ro && rw) {
576 sp_log_err("config", "rule cannot be both read-write and read-only on line %zu", sp_line_no); 446 sp_log_err("config", "rule cannot be both read-write and read-only on line %zu", parsed_rule->lineno);
577 return -1; 447 return SP_PARSER_ERROR;
578 } 448 }
579 cfg->policy_readonly = ro; 449 cfg->policy_readonly = ro;
580 450
581 if (cfg->policy_silent_fail && cfg->policy_drop) { 451 if (cfg->policy_silent_fail && cfg->policy_drop) {
582 sp_log_err("config", "policy cannot be drop and silent at the same time on line %zu", sp_line_no); 452 sp_log_err("config", "policy cannot be drop and silent at the same time on line %zu", parsed_rule->lineno);
583 return -1; 453 return SP_PARSER_ERROR;
584 } 454 }
585 return ret; 455 return SP_PARSER_STOP;
586} 456}
587 457
588int parse_ini_entry(char *line) { 458SP_PARSE_FN(parse_ini_entry) {
589 sp_ini_entry *entry = pecalloc(sizeof(sp_ini_entry), 1, 1); 459 sp_ini_entry *entry = pecalloc(sizeof(sp_ini_entry), 1, 1);
590 bool rw = false, ro = false; 460 bool rw = false, ro = false;
591 461
592 sp_config_functions sp_config_ini_protection[] = { 462 sp_config_keyword config_keywords[] = {
593 {parse_empty, SP_TOKEN_SIMULATION, &entry->simulation}, 463 {parse_empty, "simulation", &entry->simulation},
594 {parse_str, ".key(", &entry->key}, 464 {parse_empty, "sim", &entry->simulation},
595 {parse_str, ".msg(", &entry->msg}, 465 {parse_str, "key", &entry->key},
596 {parse_str, ".set(", &entry->set}, 466 {parse_str, "msg", &entry->msg},
597 {parse_str, ".min(", &entry->min}, 467 {parse_str, "set", &entry->set},
598 {parse_str, ".max(", &entry->max}, 468 {parse_str, "min", &entry->min},
599 {parse_regexp, ".regexp(", &entry->regexp}, 469 {parse_str, "max", &entry->max},
600 {parse_empty, ".readonly(", &ro}, 470 {parse_regexp, "regexp", &entry->regexp},
601 {parse_empty, ".ro(", &ro}, 471 {parse_empty, "readonly", &ro},
602 {parse_empty, ".readwrite(", &rw}, 472 {parse_empty, "ro", &ro},
603 {parse_empty, ".rw(", &rw}, 473 {parse_empty, "readwrite", &rw},
604 {parse_empty, ".drop(", &entry->drop}, 474 {parse_empty, "rw", &rw},
605 {parse_empty, ".allow_null(", &entry->allow_null}, 475 {parse_empty, "drop", &entry->drop},
476 {parse_empty, "allow_null", &entry->allow_null},
606 {0, 0, 0}}; 477 {0, 0, 0}};
607 478
608 int ret = parse_keywords(sp_config_ini_protection, line); 479 SP_PROCESS_CONFIG_KEYWORDS(goto err);
609 if (ret) { goto err; }
610 480
611 if (!entry->key) { 481 if (!entry->key) {
612 sp_log_err("config", "A .key() must be provided on line %zu", sp_line_no); 482 sp_log_err("config", "A .key() must be provided on line %zu", parsed_rule->lineno);
613 ret = -1; goto err; 483 goto err;
614 } 484 }
615 485
616 if (ro && rw) { 486 if (ro && rw) {
617 sp_log_err("config", "rule cannot be both read-write and read-only on line %zu", sp_line_no); 487 sp_log_err("config", "rule cannot be both read-write and read-only on line %zu", parsed_rule->lineno);
618 ret = -1; goto err; 488 goto err;
619 } 489 }
620 entry->access = ro - rw; 490 entry->access = ro - rw;
621 491
622 zend_hash_add_ptr(SNUFFLEUPAGUS_G(config).config_ini->entries, entry->key, entry); 492 zend_hash_add_ptr(SNUFFLEUPAGUS_G(config).config_ini->entries, entry->key, entry);
623 return ret; 493 return SP_PARSER_STOP;
624 494
625err: 495err:
626 if (entry) { 496 if (entry) {
627 sp_free_ini_entry(entry); 497 sp_free_ini_entry(entry);
628 pefree(entry, 1); 498 pefree(entry, 1);
629 } 499 }
630 return ret; 500 return SP_PARSER_ERROR;
631} \ No newline at end of file 501} \ No newline at end of file
diff --git a/src/sp_config_keywords.h b/src/sp_config_keywords.h
index b90c06c..01eb0d1 100644
--- a/src/sp_config_keywords.h
+++ b/src/sp_config_keywords.h
@@ -2,23 +2,18 @@
2#define SP_CONFIG_KEYWORDS_H 2#define SP_CONFIG_KEYWORDS_H
3#include "php_snuffleupagus.h" 3#include "php_snuffleupagus.h"
4 4
5int parse_random(char *line); 5SP_PARSE_FN(parse_enable);
6int parse_disable_xxe(char *line); 6SP_PARSE_FN(parse_global);
7int parse_auto_cookie_secure(char *line); 7SP_PARSE_FN(parse_cookie);
8int parse_global_strict(char *line); 8SP_PARSE_FN(parse_unserialize);
9int parse_global(char *line); 9SP_PARSE_FN(parse_readonly_exec);
10int parse_cookie(char *line); 10SP_PARSE_FN(parse_disabled_functions);
11int parse_unserialize(char *line); 11SP_PARSE_FN(parse_upload_validation);
12int parse_readonly_exec(char *line); 12SP_PARSE_FN(parse_eval_filter_conf);
13int parse_disabled_functions(char *line); 13SP_PARSE_FN(parse_session);
14int parse_upload_validation(char *line); 14SP_PARSE_FN(parse_wrapper_whitelist);
15int parse_eval_blacklist(char *line); 15SP_PARSE_FN(parse_log_media);
16int parse_eval_whitelist(char *line); 16SP_PARSE_FN(parse_ini_protection);
17int parse_session(char *line); 17SP_PARSE_FN(parse_ini_entry);
18int parse_sloppy_comparison(char *line);
19int parse_wrapper_whitelist(char *line);
20int parse_log_media(char *line);
21int parse_ini_protection(char *line);
22int parse_ini_entry(char *line);
23 18
24#endif // __SP_CONFIG_KEYWORDS_H 19#endif // __SP_CONFIG_KEYWORDS_H
diff --git a/src/sp_config_scanner.h b/src/sp_config_scanner.h
new file mode 100644
index 0000000..3284713
--- /dev/null
+++ b/src/sp_config_scanner.h
@@ -0,0 +1,25 @@
1
2#ifndef SP_CONFIG_SCANNER_H
3#define SP_CONFIG_SCANNER_H
4
5typedef enum {
6 SP_ARGTYPE_UNKNOWN = 0,
7 SP_ARGTYPE_NONE,
8 SP_ARGTYPE_EMPTY,
9 SP_ARGTYPE_STR
10} sp_argtype;
11
12typedef struct {
13 char *kw; // keyword points directly to the parsed input text and as such is not null-terminated
14 size_t kwlen;
15 char *arg; // optional argument / can be not null terminated
16 size_t arglen;
17 sp_argtype argtype;
18 long lineno;
19} sp_parsed_keyword;
20
21zend_result sp_config_scan(char *data, zend_result (*process_rule)(sp_parsed_keyword*));
22zend_string *sp_get_arg_string(sp_parsed_keyword *kw);
23zend_string *sp_get_textual_representation(sp_parsed_keyword *parsed_rule);
24
25#endif \ No newline at end of file
diff --git a/src/sp_config_scanner.re b/src/sp_config_scanner.re
new file mode 100644
index 0000000..075c343
--- /dev/null
+++ b/src/sp_config_scanner.re
@@ -0,0 +1,139 @@
1#include "php_snuffleupagus.h"
2
3/*!types:re2c*/
4
5#define cs_error_log(fmt, ...) sp_log_err("config", fmt, ##__VA_ARGS__)
6
7zend_string *sp_get_arg_string(sp_parsed_keyword *kw) {
8 if (!kw || !kw->arg) {
9 return NULL;
10 }
11 zend_string *ret = zend_string_init(kw->arg, kw->arglen, 1);
12 char *pin, *pout;
13 pin = pout = ZSTR_VAL(ret);
14 char *pend = pin + ZSTR_LEN(ret);
15
16 while (pin < pend) {
17 if (*pin == '\\') {
18 pin++;
19 }
20 *pout = *pin;
21 pin++; pout++;
22 }
23
24 if (pin != pout) {
25 size_t len = pout - ZSTR_VAL(ret);
26 ret = zend_string_truncate(ret, len, 1);
27 ZSTR_VAL(ret)[len] = 0;
28 }
29
30 return ret;
31}
32
33zend_string *sp_get_textual_representation(sp_parsed_keyword *parsed_rule) {
34 // a rule is "sp.keyword...keyword(arg);\0"
35 size_t len = 3; // sp + ;
36 sp_parsed_keyword *kw;
37 for (kw = parsed_rule; kw->kw; kw++) {
38 len++; // .
39 len += kw->kwlen;
40 if (kw->argtype == SP_ARGTYPE_EMPTY) {
41 len += 2; // ()
42 } else if (kw->argtype == SP_ARGTYPE_STR) {
43 len += 4;
44 len += kw->arglen;
45 }
46 }
47 zend_string *ret = zend_string_alloc(len, 1);
48 char *ptr = ZSTR_VAL(ret);
49 memcpy(ptr, "sp", 2); ptr += 2;
50 for (kw = parsed_rule; kw->kw; kw++) {
51 *ptr++ = '.';
52 memcpy(ptr, kw->kw, kw->kwlen); ptr += kw->kwlen;
53 if (kw->argtype == SP_ARGTYPE_EMPTY || kw->argtype == SP_ARGTYPE_STR || kw->argtype == SP_ARGTYPE_UNKNOWN) {
54 *ptr++ = '(';
55 }
56 if (kw->argtype == SP_ARGTYPE_STR && kw->arg) {
57 *ptr++ = '"';
58 memcpy(ptr, kw->arg, kw->arglen); ptr += kw->arglen;
59 *ptr++ = '"';
60 }
61 if (kw->argtype == SP_ARGTYPE_EMPTY || kw->argtype == SP_ARGTYPE_STR || kw->argtype == SP_ARGTYPE_UNKNOWN) {
62 *ptr++ = ')';
63 }
64 }
65 *ptr++ = ';';
66 *ptr = 0;
67 return ret;
68}
69
70zend_result sp_config_scan(char *data, zend_result (*process_rule)(sp_parsed_keyword*))
71{
72 const char *YYCURSOR = data;
73 const char *YYMARKER, *t1, *t2, *t3, *t4;
74 /*!stags:re2c format = 'const char *@@;\n'; */
75
76 const int max_keywords = 16;
77 sp_parsed_keyword parsed_rule[max_keywords+1];
78 int kw_i = 0;
79
80 int cond = yycinit;
81 long lineno = 1;
82
83 /*!re2c
84 re2c:define:YYCTYPE = char;
85 // re2c:define:YYCURSOR = data;
86 re2c:yyfill:enable = 0;
87 re2c:flags:tags = 1;
88 re2c:api:style = free-form;
89 re2c:define:YYGETCONDITION = "cond";
90 re2c:define:YYSETCONDITION = "cond = @@;";
91
92 end = "\x00";
93 nl = "\r"?"\n";
94 ws = [ \t];
95 keyword = [a-zA-Z_][a-zA-Z0-9_]*;
96 string = "\"" ("\\\"" | [^"\r\n])* "\"";
97
98 <init> * { cs_error_log("Parser error on line %d", lineno); return FAILURE; }
99 <init> ws+ { goto yyc_init; }
100 <init> [;#] .* { goto yyc_init; }
101 <init> nl { lineno++; goto yyc_init; }
102 <init> "sp" { kw_i = 0; goto yyc_rule; }
103 <init> end { return SUCCESS; }
104
105 <rule> ws+ { goto yyc_rule; }
106 <rule> nl / ( nl | ws )* "." { lineno++; goto yyc_rule; }
107 <rule> "." @t1 keyword @t2 ( "(" @t3 string? @t4 ")" )? {
108 if (kw_i == max_keywords) {
109 cs_error_log("Too many keywords in rule (more than %d) on line %d", max_keywords, lineno);
110 return FAILURE;
111 }
112 sp_parsed_keyword kw = {.kw = (char*)t1, .kwlen = t2-t1, .arg = (char*)t3, .arglen = t4-t3, .argtype = SP_ARGTYPE_UNKNOWN, .lineno = lineno};
113 if (t3 && t4) {
114 if (t3 == t4) {
115 kw.argtype = SP_ARGTYPE_EMPTY;
116 } else if (t4-t2 >= 2) {
117 kw.arg = (char*)t3 + 1;
118 kw.arglen = t4 - t3 - 2;
119 kw.argtype = SP_ARGTYPE_STR;
120 }
121 } else {
122 kw.argtype = SP_ARGTYPE_NONE;
123 }
124 parsed_rule[kw_i++] = kw;
125 goto yyc_rule;
126 }
127 <rule> ";" {
128 end_of_rule:
129 parsed_rule[kw_i++] = (sp_parsed_keyword){0, 0, 0, 0, 0, 0};
130 if (process_rule && process_rule(parsed_rule) != SUCCESS) {
131 return FAILURE;
132 }
133 goto yyc_init;
134 }
135 <rule> * { goto end_of_rule; }
136
137 */
138 return FAILURE;
139} \ No newline at end of file
diff --git a/src/sp_config_utils.c b/src/sp_config_utils.c
index bc7b405..e93ef31 100644
--- a/src/sp_config_utils.c
+++ b/src/sp_config_utils.c
@@ -1,108 +1,5 @@
1#include "php_snuffleupagus.h" 1#include "php_snuffleupagus.h"
2 2
3int parse_keywords(sp_config_functions *funcs, char *line) {
4 int value_len = 0;
5 const char *original_line = line;
6 for (size_t i = 0; funcs[i].func; i++) {
7 if (!strncmp(funcs[i].token, line, strlen(funcs[i].token))) {
8 line += strlen(funcs[i].token);
9 value_len = funcs[i].func(line, funcs[i].token, funcs[i].retval) + 1;
10 if (value_len == 0) { // bad parameter
11 return -1;
12 }
13 line += value_len;
14 i = -1; // we start the loop again
15 }
16 }
17 while (*line == ';' || *line == '\t' || *line == ' ') {
18 line++;
19 }
20
21 if (*line == '#') {
22 return 0;
23 }
24
25 if (*line) {
26 sp_log_err("config", "Trailing chars '%s' at the end of '%s' on line %zu",
27 line, original_line, sp_line_no);
28 return -1;
29 }
30 return 0;
31}
32
33zend_string *get_param(size_t *consumed, char *restrict line, sp_type type,
34 const char *restrict keyword) {
35 enum { IN_ESCAPE, NONE } state = NONE;
36 char *original_line = line;
37 size_t j = 0;
38
39 zend_string *ret = NULL;
40 if (NULL == line || '\0' == *line) {
41 goto err;
42 }
43
44 ret = zend_string_alloc(strlen(line) + 1, 1);
45
46 /* The first char of a string is always '"', since they MUST be quoted. */
47 if ('"' == *line) {
48 line++;
49 } else {
50 goto err;
51 }
52
53 for (size_t i = 0; line[i] && j < strlen(original_line) - 2; i++) {
54 switch (line[i]) {
55 case '"':
56 /* A double quote at this point is either:
57 - at the very end of the string.
58 - escaped
59 */
60 if ((state == NONE) && (line[i + 1] == SP_TOKEN_END_PARAM)) {
61 /* The `+2` if for
62 1. the terminal double-quote
63 2. the SP_TOKEN_END_PARAM
64 */
65 *consumed = i + 2;
66 // Make sure that the string we return is the right size,
67 // as it can be smaller than strlen(line)
68 ret = zend_string_truncate(ret, j, 1);
69 // truncate does not add a \0
70 ZSTR_VAL(ret)[ZSTR_LEN(ret)] = 0;
71 return ret;
72 } else if (state == IN_ESCAPE) {
73 break; // we're on an escped double quote
74 } else {
75 goto err;
76 }
77 case '\\':
78 if (state == NONE) {
79 state = IN_ESCAPE;
80 continue;
81 }
82 default:
83 break;
84 }
85 if (state == IN_ESCAPE) {
86 state = NONE;
87 }
88 ZSTR_VAL(ret)[j++] = line[i];
89 }
90err:
91 if (0 == j) {
92 sp_log_err("error", "A valid string as parameter is expected on line %zu",
93 sp_line_no);
94 } else {
95 sp_log_err("error",
96 "There is an issue with the parsing of '%s': it doesn't look "
97 "like a valid string on line %zu",
98 original_line ? original_line : "NULL", sp_line_no);
99 }
100 line = NULL;
101 if (ret) {
102 zend_string_release(ret);
103 }
104 return NULL;
105}
106 3
107sp_list_node *parse_functions_list(char *value) { 4sp_list_node *parse_functions_list(char *value) {
108 static const char *sep = ">"; 5 static const char *sep = ">";
diff --git a/src/sp_config_utils.h b/src/sp_config_utils.h
index a63cadc..64817a0 100644
--- a/src/sp_config_utils.h
+++ b/src/sp_config_utils.h
@@ -1,9 +1,6 @@
1#ifndef SP_CONFIG_UTILS 1#ifndef SP_CONFIG_UTILS
2#define SP_CONFIG_UTILS 2#define SP_CONFIG_UTILS
3 3
4int parse_keywords(sp_config_functions *, char *);
5zend_string *get_param(size_t *, char *restrict, sp_type, const char *restrict);
6int array_to_list(char **, sp_list_node **);
7sp_list_node *parse_functions_list(char *value); 4sp_list_node *parse_functions_list(char *value);
8 5
9#endif /* SP_CONFIG_UTILS */ 6#endif /* SP_CONFIG_UTILS */
diff --git a/src/sp_disabled_functions.c b/src/sp_disabled_functions.c
index 84d8acf..ebb7d3f 100644
--- a/src/sp_disabled_functions.c
+++ b/src/sp_disabled_functions.c
@@ -69,28 +69,22 @@ static bool is_functions_list_matching(zend_execute_data* execute_data,
69 return false; 69 return false;
70} 70}
71 71
72static bool is_local_var_matching( 72static bool is_local_var_matching(zend_execute_data* execute_data, const sp_disabled_function* const config_node) {
73 zend_execute_data* execute_data,
74 const sp_disabled_function* const config_node) {
75 zval* var_value = {0}; 73 zval* var_value = {0};
76 74
77 var_value = sp_get_var_value(execute_data, config_node->var, false); 75 var_value = sp_get_var_value(execute_data, config_node->var, false);
78 if (var_value) { 76 if (var_value) {
79 if (Z_TYPE_P(var_value) == IS_ARRAY) { 77 if (Z_TYPE_P(var_value) == IS_ARRAY) {
80 if (config_node->key || config_node->r_key) { 78 if (config_node->key || config_node->r_key) {
81 if (sp_match_array_key(var_value, config_node->key, 79 if (sp_match_array_key(var_value, config_node->key, config_node->r_key)) {
82 config_node->r_key)) {
83 return true; 80 return true;
84 } 81 }
85 } else if (sp_match_array_value(var_value, config_node->value, 82 } else if (sp_match_array_value(var_value, config_node->value, config_node->r_value)) {
86 config_node->r_value)) {
87 return true; 83 return true;
88 } 84 }
89 } else { 85 } else {
90 zend_string const* const var_value_str = 86 zend_string const* const var_value_str = sp_zval_to_zend_string(var_value);
91 sp_zval_to_zend_string(var_value); 87 bool match = sp_match_value(var_value_str, config_node->value, config_node->r_value);
92 bool match = sp_match_value(var_value_str, config_node->value,
93 config_node->r_value);
94 88
95 if (true == match) { 89 if (true == match) {
96 return true; 90 return true;
@@ -555,24 +549,19 @@ ZEND_FUNCTION(eval_blacklist_callback) {
555 zend_string_release(tmp); 549 zend_string_release(tmp);
556 550
557 if (SNUFFLEUPAGUS_G(in_eval) > 0) { 551 if (SNUFFLEUPAGUS_G(in_eval) > 0) {
558 zend_string* filename = get_eval_filename(zend_get_executed_filename()); 552 // zend_string* filename = get_eval_filename(zend_get_executed_filename());
559 const int line_number = zend_get_executed_lineno(TSRMLS_C); 553 // const int line_number = zend_get_executed_lineno(TSRMLS_C);
560 const sp_config_eval* config_eval = SNUFFLEUPAGUS_G(config).config_eval; 554 const sp_config_eval* config_eval = SNUFFLEUPAGUS_G(config).config_eval;
561 555
562 if (config_eval->dump) { 556 if (config_eval->dump) {
563 sp_log_request(config_eval->dump, config_eval->textual_representation, 557 sp_log_request(config_eval->dump, config_eval->textual_representation);
564 SP_TOKEN_EVAL_BLACKLIST);
565 } 558 }
566 if (config_eval->simulation) { 559 if (config_eval->simulation) {
567 sp_log_simulation("eval", 560 sp_log_simulation("eval", "A call to '%s' was tried in eval. logging it.", current_function_name);
568 "A call to %s was tried in eval, in %s:%d, logging it.",
569 current_function_name, ZSTR_VAL(filename), line_number);
570 } else { 561 } else {
571 sp_log_drop("eval", 562 sp_log_drop("eval", "A call to '%s' was tried in eval. dropping it.", current_function_name);
572 "A call to %s was tried in eval, in %s:%d, dropping it.",
573 current_function_name, ZSTR_VAL(filename), line_number);
574 } 563 }
575 efree(filename); 564 // efree(filename);
576 } 565 }
577 566
578whitelisted: 567whitelisted:
diff --git a/src/sp_execute.c b/src/sp_execute.c
index 7d078b0..8795e5f 100644
--- a/src/sp_execute.c
+++ b/src/sp_execute.c
@@ -14,8 +14,7 @@ ZEND_COLD static inline void terminate_if_writable(const char *filename) {
14 if (0 == access(filename, W_OK)) { 14 if (0 == access(filename, W_OK)) {
15 if (config_ro_exec->dump) { 15 if (config_ro_exec->dump) {
16 sp_log_request(config_ro_exec->dump, 16 sp_log_request(config_ro_exec->dump,
17 config_ro_exec->textual_representation, 17 config_ro_exec->textual_representation);
18 SP_TOKEN_READONLY_EXEC);
19 } 18 }
20 if (true == config_ro_exec->simulation) { 19 if (true == config_ro_exec->simulation) {
21 sp_log_simulation("readonly_exec", 20 sp_log_simulation("readonly_exec",
@@ -75,8 +74,7 @@ is_in_eval_and_whitelisted(const zend_execute_data *execute_data) {
75 if (EXPECTED(NULL != current_function)) { 74 if (EXPECTED(NULL != current_function)) {
76 if (UNEXPECTED(false == check_is_in_eval_whitelist(current_function))) { 75 if (UNEXPECTED(false == check_is_in_eval_whitelist(current_function))) {
77 if (config_eval->dump) { 76 if (config_eval->dump) {
78 sp_log_request(config_eval->dump, config_eval->textual_representation, 77 sp_log_request(config_eval->dump, config_eval->textual_representation);
79 SP_TOKEN_EVAL_WHITELIST);
80 } 78 }
81 if (config_eval->simulation) { 79 if (config_eval->simulation) {
82 sp_log_simulation( 80 sp_log_simulation(
diff --git a/src/sp_network_utils.c b/src/sp_network_utils.c
index 5b4fd95..0a26254 100644
--- a/src/sp_network_utils.c
+++ b/src/sp_network_utils.c
@@ -85,9 +85,7 @@ int get_ip_and_cidr(char *ip, sp_cidr *cidr) {
85 char *mask = strchr(ip, '/'); 85 char *mask = strchr(ip, '/');
86 86
87 if (NULL == mask) { 87 if (NULL == mask) {
88 sp_log_err( 88 sp_log_err("config", "'%s' isn't a valid network mask, it seems that you forgot a '/'.", ip);
89 "config",
90 "'%s' isn't a valid network mask, it seems that you forgot a '/'.", ip);
91 return -1; 89 return -1;
92 } 90 }
93 91
@@ -117,7 +115,7 @@ int get_ip_and_cidr(char *ip, sp_cidr *cidr) {
117 115
118 ip[mask - ip] = '/'; 116 ip[mask - ip] = '/';
119 if (cidr->ip_version < 0) { 117 if (cidr->ip_version < 0) {
120 sp_log_err("cidr_match", "Weird ip (%s) family", ip); 118 sp_log_err("config", "Weird ip (%s) family", ip);
121 return -1; 119 return -1;
122 } 120 }
123 121
diff --git a/src/sp_pcre_compat.c b/src/sp_pcre_compat.c
index 2b9f08d..657e650 100644
--- a/src/sp_pcre_compat.c
+++ b/src/sp_pcre_compat.c
@@ -24,8 +24,7 @@ sp_pcre* sp_pcre_compile(const char* const pattern) {
24#endif 24#endif
25 25
26 if (NULL == ret) { 26 if (NULL == ret) {
27 sp_log_err("config", "Failed to compile '%s': %s on line %zu.", pattern, 27 sp_log_err("config", "Failed to compile '%s': %s.", pattern, pcre_error);
28 pcre_error, sp_line_no);
29 } 28 }
30 return ret; 29 return ret;
31} 30}
diff --git a/src/sp_unserialize.c b/src/sp_unserialize.c
index 06636ad..82b2cef 100644
--- a/src/sp_unserialize.c
+++ b/src/sp_unserialize.c
@@ -89,8 +89,7 @@ PHP_FUNCTION(sp_unserialize) {
89 } else { 89 } else {
90 if (config_unserialize->dump) { 90 if (config_unserialize->dump) {
91 sp_log_request(config_unserialize->dump, 91 sp_log_request(config_unserialize->dump,
92 config_unserialize->textual_representation, 92 config_unserialize->textual_representation);
93 SP_TOKEN_UNSERIALIZE_HMAC);
94 } 93 }
95 if (true == config_unserialize->simulation) { 94 if (true == config_unserialize->simulation) {
96 sp_log_simulation("unserialize", "Invalid HMAC for %s", serialized_str); 95 sp_log_simulation("unserialize", "Invalid HMAC for %s", serialized_str);
diff --git a/src/sp_utils.c b/src/sp_utils.c
index 949d6ba..c4209de 100644
--- a/src/sp_utils.c
+++ b/src/sp_utils.c
@@ -123,9 +123,7 @@ static int construct_filename(char* filename,
123 return 0; 123 return 0;
124} 124}
125 125
126int sp_log_request(const zend_string* restrict folder, 126int sp_log_request(const zend_string* restrict folder, const zend_string* restrict text_repr) {
127 const zend_string* restrict text_repr,
128 char const* const from) {
129 FILE* file; 127 FILE* file;
130 const char* current_filename = zend_get_executed_filename(TSRMLS_C); 128 const char* current_filename = zend_get_executed_filename(TSRMLS_C);
131 const int current_line = zend_get_executed_lineno(TSRMLS_C); 129 const int current_line = zend_get_executed_lineno(TSRMLS_C);
@@ -146,7 +144,7 @@ int sp_log_request(const zend_string* restrict folder,
146 return -1; 144 return -1;
147 } 145 }
148 146
149 fprintf(file, "RULE: sp%s%s\n", from, ZSTR_VAL(text_repr)); 147 fprintf(file, "RULE: %s\n", ZSTR_VAL(text_repr));
150 148
151 fprintf(file, "FILE: %s:%d\n", current_filename, current_line); 149 fprintf(file, "FILE: %s:%d\n", current_filename, current_line);
152 150
@@ -285,8 +283,7 @@ void sp_log_disable(const char* restrict path, const char* restrict arg_name,
285 const int sim = config_node->simulation; 283 const int sim = config_node->simulation;
286 284
287 if (dump) { 285 if (dump) {
288 sp_log_request(config_node->dump, config_node->textual_representation, 286 sp_log_request(config_node->dump, config_node->textual_representation);
289 SP_TOKEN_DISABLE_FUNC);
290 } 287 }
291 if (arg_name) { 288 if (arg_name) {
292 char* char_repr = NULL; 289 char* char_repr = NULL;
@@ -329,8 +326,7 @@ void sp_log_disable_ret(const char* restrict path,
329 char* char_repr = NULL; 326 char* char_repr = NULL;
330 327
331 if (dump) { 328 if (dump) {
332 sp_log_request(dump, config_node->textual_representation, 329 sp_log_request(dump, config_node->textual_representation);
333 SP_TOKEN_DISABLE_FUNC);
334 } 330 }
335 if (ret_value) { 331 if (ret_value) {
336 char_repr = zend_string_to_char(ret_value); 332 char_repr = zend_string_to_char(ret_value);
@@ -479,7 +475,6 @@ void unhook_functions(HashTable *ht) {
479 475
480bool check_is_in_eval_whitelist(const zend_string* const function_name) { 476bool check_is_in_eval_whitelist(const zend_string* const function_name) {
481 const sp_list_node* it = SNUFFLEUPAGUS_G(config).config_eval->whitelist; 477 const sp_list_node* it = SNUFFLEUPAGUS_G(config).config_eval->whitelist;
482
483 if (!it) { 478 if (!it) {
484 return false; 479 return false;
485 } 480 }
diff --git a/src/sp_utils.h b/src/sp_utils.h
index c0ddbe4..ef626a3 100644
--- a/src/sp_utils.h
+++ b/src/sp_utils.h
@@ -85,9 +85,7 @@ bool hook_function(const char *, HashTable *, zif_handler);
85void unhook_functions(HashTable *ht); 85void unhook_functions(HashTable *ht);
86int hook_regexp(const sp_pcre *, HashTable *, zif_handler); 86int hook_regexp(const sp_pcre *, HashTable *, zif_handler);
87bool check_is_in_eval_whitelist(const zend_string *const function_name); 87bool check_is_in_eval_whitelist(const zend_string *const function_name);
88int sp_log_request(const zend_string *restrict folder, 88int sp_log_request(const zend_string *restrict folder, const zend_string *restrict text_repr);
89 const zend_string *restrict text_repr,
90 char const *const from);
91bool sp_zend_string_equals(const zend_string *s1, const zend_string *s2); 89bool sp_zend_string_equals(const zend_string *s1, const zend_string *s2);
92 90
93#endif /* SP_UTILS_H */ 91#endif /* SP_UTILS_H */
diff --git a/src/tests/broken_configuration/encrypt_regexp_cookies_bad_regexp.phpt b/src/tests/broken_configuration/encrypt_regexp_cookies_bad_regexp.phpt
index 7a8c909..5383df6 100644
--- a/src/tests/broken_configuration/encrypt_regexp_cookies_bad_regexp.phpt
+++ b/src/tests/broken_configuration/encrypt_regexp_cookies_bad_regexp.phpt
@@ -17,6 +17,6 @@ EOF;
17--EXPECT-- 17--EXPECT--
18Fatal error: [snuffleupagus][127.0.0.1][config][log] Invalid configuration file in Unknown on line 0 18Fatal error: [snuffleupagus][127.0.0.1][config][log] Invalid configuration file in Unknown on line 0
19 19
20Fatal error: [snuffleupagus][127.0.0.1][config][log] Failed to compile '^super_co[a-z+$': missing terminating ] for character class on line 2. in Unknown on line 0 20Fatal error: [snuffleupagus][127.0.0.1][config][log] Failed to compile '^super_co[a-z+$': missing terminating ] for character class. in Unknown on line 0
21 21
22Fatal error: [snuffleupagus][127.0.0.1][config][log] '.name_r()' is expecting a valid regexp, and not '"^super_co[a-z+$"' on line 2 in Unknown on line 0 22Fatal error: [snuffleupagus][127.0.0.1][config][log] Invalid regexp '^super_co[a-z+$' for '.name_r()' on line 2 in Unknown on line 0
diff --git a/src/tests/broken_configuration_php8/broken_conf.phpt b/src/tests/broken_configuration_php8/broken_conf.phpt
index 7dde7d6..9a5a5ab 100644
--- a/src/tests/broken_configuration_php8/broken_conf.phpt
+++ b/src/tests/broken_configuration_php8/broken_conf.phpt
@@ -7,8 +7,7 @@ Broken configuration
7sp.configuration_file={PWD}/config/broken_conf.ini 7sp.configuration_file={PWD}/config/broken_conf.ini
8--FILE-- 8--FILE--
9--EXPECT-- 9--EXPECT--
10 10Fatal error: [snuffleupagus][0.0.0.0][config][log] Parser error on line 1 in Unknown on line 0
11Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration prefix for 'this is a broken line' on line 1 in Unknown on line 0
12 11
13Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0 12Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0
14Could not startup. 13Could not startup.
diff --git a/src/tests/broken_configuration_php8/broken_conf2.phpt b/src/tests/broken_configuration_php8/broken_conf2.phpt
index bf337b4..94ebc01 100644
--- a/src/tests/broken_configuration_php8/broken_conf2.phpt
+++ b/src/tests/broken_configuration_php8/broken_conf2.phpt
@@ -7,8 +7,7 @@ Broken configuration
7sp.configuration_file={PWD}/config/broken_conf2.ini 7sp.configuration_file={PWD}/config/broken_conf2.ini
8--FILE-- 8--FILE--
9--EXPECT-- 9--EXPECT--
10 10Fatal error: [snuffleupagus][0.0.0.0][config][log] Unexpected keyword 'wrong' on line 1 in Unknown on line 0
11Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration section 'sp.wrong' on line 1 in Unknown on line 0
12 11
13Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0 12Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0
14Could not startup. 13Could not startup.
diff --git a/src/tests/broken_configuration_php8/broken_conf_allow_broken_disabled.phpt b/src/tests/broken_configuration_php8/broken_conf_allow_broken_disabled.phpt
index 9dd0c66..ad3aa08 100644
--- a/src/tests/broken_configuration_php8/broken_conf_allow_broken_disabled.phpt
+++ b/src/tests/broken_configuration_php8/broken_conf_allow_broken_disabled.phpt
@@ -12,7 +12,7 @@ echo 1337;
12?> 12?>
13--EXPECT-- 13--EXPECT--
14 14
15Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration prefix for 'this is a broken line' on line 1 in Unknown on line 0 15Fatal error: [snuffleupagus][0.0.0.0][config][log] Parser error on line 1 in Unknown on line 0
16 16
17Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0 17Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0
18Could not startup. 18Could not startup.
diff --git a/src/tests/broken_configuration_php8/broken_conf_allow_broken_enabled.phpt b/src/tests/broken_configuration_php8/broken_conf_allow_broken_enabled.phpt
index eccc8a8..0f71408 100644
--- a/src/tests/broken_configuration_php8/broken_conf_allow_broken_enabled.phpt
+++ b/src/tests/broken_configuration_php8/broken_conf_allow_broken_enabled.phpt
@@ -12,5 +12,5 @@ echo 1337;
12?> 12?>
13--EXPECT-- 13--EXPECT--
14 14
15Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration prefix for 'this is a broken line' on line 1 in Unknown on line 0 15Fatal error: [snuffleupagus][0.0.0.0][config][log] Parser error on line 1 in Unknown on line 0
161337 161337
diff --git a/src/tests/broken_configuration_php8/broken_conf_config_regexp.phpt b/src/tests/broken_configuration_php8/broken_conf_config_regexp.phpt
index 76ef208..c4eec17 100644
--- a/src/tests/broken_configuration_php8/broken_conf_config_regexp.phpt
+++ b/src/tests/broken_configuration_php8/broken_conf_config_regexp.phpt
@@ -7,10 +7,9 @@ Broken configuration
7sp.configuration_file={PWD}/config/broken_config_regexp.ini 7sp.configuration_file={PWD}/config/broken_config_regexp.ini
8--FILE-- 8--FILE--
9--EXPECTF-- 9--EXPECTF--
10Fatal error: [snuffleupagus][0.0.0.0][config][log] Failed to compile '*.': quantifier does not follow a repeatable item. in Unknown on line 0
10 11
11Fatal error: [snuffleupagus][0.0.0.0][config][log] Failed to compile '*.': %s on line 1. in Unknown on line 0 12Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid regexp '*.' for '.filename_r()' on line 1 in Unknown on line 0
12
13Fatal error: [snuffleupagus][0.0.0.0][config][log] '.filename_r()' is expecting a valid regexp, and not '"*."' on line 1 in Unknown on line 0
14 13
15Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0 14Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0
16Could not startup. 15Could not startup.
diff --git a/src/tests/broken_configuration_php8/broken_conf_config_regexp_no_closing_paren.phpt b/src/tests/broken_configuration_php8/broken_conf_config_regexp_no_closing_paren.phpt
index 5bdca06..2629ba5 100644
--- a/src/tests/broken_configuration_php8/broken_conf_config_regexp_no_closing_paren.phpt
+++ b/src/tests/broken_configuration_php8/broken_conf_config_regexp_no_closing_paren.phpt
@@ -7,10 +7,7 @@ Broken configuration - regexp without a closing parenthesis
7sp.configuration_file={PWD}/config/broken_config_regexp_no_closing_paren.ini 7sp.configuration_file={PWD}/config/broken_config_regexp_no_closing_paren.ini
8--FILE-- 8--FILE--
9--EXPECT-- 9--EXPECT--
10 10Fatal error: [snuffleupagus][0.0.0.0][config][log] Missing argument to keyword 'filename_r' - it should be 'filename_r("...")' on line 1 in Unknown on line 0
11Fatal error: [snuffleupagus][0.0.0.0][error][log] There is an issue with the parsing of '"*."': it doesn't look like a valid string on line 1 in Unknown on line 0
12
13Fatal error: [snuffleupagus][0.0.0.0][config][log] '.filename_r()' is expecting a valid regexp, and not '"*."' on line 1 in Unknown on line 0
14 11
15Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0 12Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0
16Could not startup. 13Could not startup.
diff --git a/src/tests/broken_configuration_php8/broken_conf_cookie_encryption_without_encryption_key.phpt b/src/tests/broken_configuration_php8/broken_conf_cookie_encryption_without_encryption_key.phpt
index 0447320..6213041 100644
--- a/src/tests/broken_configuration_php8/broken_conf_cookie_encryption_without_encryption_key.phpt
+++ b/src/tests/broken_configuration_php8/broken_conf_cookie_encryption_without_encryption_key.phpt
@@ -7,8 +7,7 @@ Broken configuration - encrypted cookie without encryption key
7sp.configuration_file={PWD}/config/broken_conf_cookie_encryption_without_encryption_key.ini 7sp.configuration_file={PWD}/config/broken_conf_cookie_encryption_without_encryption_key.ini
8--FILE-- 8--FILE--
9--EXPECT-- 9--EXPECT--
10 10Fatal error: [snuffleupagus][0.0.0.0][config][log] You're trying to use the cookie encryption feature on line 2 without having set the `.secret_key` option in `sp.global`: please set it first in Unknown on line 0
11Fatal error: [snuffleupagus][0.0.0.0][config][log] You're trying to use the cookie encryption featureon line 2 without having set the `.encryption_key` option in`sp.global`: please set it first in Unknown on line 0
12 11
13Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0 12Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0
14Could not startup. 13Could not startup.
diff --git a/src/tests/broken_configuration_php8/broken_conf_cookie_encryption_without_env_var.phpt b/src/tests/broken_configuration_php8/broken_conf_cookie_encryption_without_env_var.phpt
index 204430d..25371dd 100644
--- a/src/tests/broken_configuration_php8/broken_conf_cookie_encryption_without_env_var.phpt
+++ b/src/tests/broken_configuration_php8/broken_conf_cookie_encryption_without_env_var.phpt
@@ -7,8 +7,7 @@ Broken configuration - encrypted cookie with without cookie env var
7sp.configuration_file={PWD}/config/broken_conf_cookie_encryption_without_env_var.ini 7sp.configuration_file={PWD}/config/broken_conf_cookie_encryption_without_env_var.ini
8--FILE-- 8--FILE--
9--EXPECT-- 9--EXPECT--
10 10Fatal error: [snuffleupagus][0.0.0.0][config][log] You're trying to use the cookie encryption feature on line 2 without having set the `.cookie_env_var` option in`sp.global`: please set it first in Unknown on line 0
11Fatal error: [snuffleupagus][0.0.0.0][config][log] You're trying to use the cookie encryption featureon line 2 without having set the `.cookie_env_var` option in`sp.global`: please set it first in Unknown on line 0
12 11
13Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0 12Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0
14Could not startup. 13Could not startup.
diff --git a/src/tests/broken_configuration_php8/broken_conf_eval.phpt b/src/tests/broken_configuration_php8/broken_conf_eval.phpt
index 1a6ad4d..f45aabf 100644
--- a/src/tests/broken_configuration_php8/broken_conf_eval.phpt
+++ b/src/tests/broken_configuration_php8/broken_conf_eval.phpt
@@ -8,7 +8,7 @@ sp.configuration_file={PWD}/config/broken_conf_eval.ini
8--FILE-- 8--FILE--
9--EXPECT-- 9--EXPECT--
10 10
11Fatal error: [snuffleupagus][0.0.0.0][error][log] There is an issue with the parsing of '"cos,sin': it doesn't look like a valid string on line 1 in Unknown on line 0 11Fatal error: [snuffleupagus][0.0.0.0][config][log] Missing argument to keyword 'list' - it should be 'list("...")' on line 1 in Unknown on line 0
12 12
13Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0 13Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0
14Could not startup. 14Could not startup.
diff --git a/src/tests/broken_configuration_php8/broken_conf_expecting_bool.phpt b/src/tests/broken_configuration_php8/broken_conf_expecting_bool.phpt
index 682a4f5..419d687 100644
--- a/src/tests/broken_configuration_php8/broken_conf_expecting_bool.phpt
+++ b/src/tests/broken_configuration_php8/broken_conf_expecting_bool.phpt
@@ -7,8 +7,7 @@ Bad boolean value in configuration
7sp.configuration_file={PWD}/config/broken_conf_expecting_bool.ini 7sp.configuration_file={PWD}/config/broken_conf_expecting_bool.ini
8--FILE-- 8--FILE--
9--EXPECT-- 9--EXPECT--
10 10Fatal error: [snuffleupagus][0.0.0.0][config][log] Missing paranthesis for keyword 'enable' - it should be 'enable()' on line 5 in Unknown on line 0
11Fatal error: [snuffleupagus][0.0.0.0][config][log] Trailing chars '337);' at the end of '.enable(1337);' on line 5 in Unknown on line 0
12 11
13Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0 12Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0
14Could not startup. 13Could not startup.
diff --git a/src/tests/broken_configuration_php8/broken_conf_invalid_cidr_value.phpt b/src/tests/broken_configuration_php8/broken_conf_invalid_cidr_value.phpt
index dbe5414..31140dc 100644
--- a/src/tests/broken_configuration_php8/broken_conf_invalid_cidr_value.phpt
+++ b/src/tests/broken_configuration_php8/broken_conf_invalid_cidr_value.phpt
@@ -8,10 +8,7 @@ Broken configuration, invalid cidr value
8sp.configuration_file={PWD}/config/broken_conf_invalid_cidr_value.ini 8sp.configuration_file={PWD}/config/broken_conf_invalid_cidr_value.ini
9--FILE-- 9--FILE--
10--EXPECT-- 10--EXPECT--
11 11Fatal error: [snuffleupagus][0.0.0.0][config][log] Missing argument to keyword 'cidr' - it should be 'cidr("...")' on line 1 in Unknown on line 0
12Fatal error: [snuffleupagus][0.0.0.0][error][log] A valid string as parameter is expected on line 1 in Unknown on line 0
13
14Fatal error: [snuffleupagus][0.0.0.0][config][log] " doesn't contain a valid cidr on line 1 in Unknown on line 0
15 12
16Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0 13Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0
17Could not startup. 14Could not startup.
diff --git a/src/tests/broken_configuration_php8/broken_conf_invalid_filename.phpt b/src/tests/broken_configuration_php8/broken_conf_invalid_filename.phpt
index cb78f85..da40235 100644
--- a/src/tests/broken_configuration_php8/broken_conf_invalid_filename.phpt
+++ b/src/tests/broken_configuration_php8/broken_conf_invalid_filename.phpt
@@ -7,8 +7,7 @@ Broken configuration filename without absolute path
7sp.configuration_file={PWD}/config/broken_conf_invalid_filename.ini 7sp.configuration_file={PWD}/config/broken_conf_invalid_filename.ini
8--FILE-- 8--FILE--
9--EXPECTF-- 9--EXPECTF--
10 10Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration line%a: '.filename' must be an absolute path or a phar archive on line 1 in Unknown on line 0
11Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration line: 'sp.disabled_functions.function("sprintf").filename("wrong file name").drop();':'.filename' must be an absolute path or a phar archive on line 1 in Unknown on line 0
12 11
13Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0 12Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0
14Could not startup. 13Could not startup.
diff --git a/src/tests/broken_configuration_php8/broken_conf_invalid_log_media.phpt b/src/tests/broken_configuration_php8/broken_conf_invalid_log_media.phpt
index 68581b6..fda609d 100644
--- a/src/tests/broken_configuration_php8/broken_conf_invalid_log_media.phpt
+++ b/src/tests/broken_configuration_php8/broken_conf_invalid_log_media.phpt
@@ -7,8 +7,7 @@ Broken configuration filename with improper log media
7sp.configuration_file={PWD}/config/broken_conf_invalid_log_media.ini 7sp.configuration_file={PWD}/config/broken_conf_invalid_log_media.ini
8--FILE-- 8--FILE--
9--EXPECTF-- 9--EXPECTF--
10 10Fatal error: [snuffleupagus][0.0.0.0][config][log] .log_media() only supports 'syslog' or 'php' on line 1 in Unknown on line 0
11Fatal error: [snuffleupagus][0.0.0.0][config][log] .log_media() only supports 'syslog' or 'php', on line 1 in Unknown on line 0
12 11
13Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0 12Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0
14Could not startup. 13Could not startup.
diff --git a/src/tests/broken_configuration_php8/broken_conf_invalid_type.phpt b/src/tests/broken_configuration_php8/broken_conf_invalid_type.phpt
index 188d610..9e35170 100644
--- a/src/tests/broken_configuration_php8/broken_conf_invalid_type.phpt
+++ b/src/tests/broken_configuration_php8/broken_conf_invalid_type.phpt
@@ -7,8 +7,7 @@ Broken conf with wrong type
7sp.configuration_file={PWD}/config/broken_conf_invalid_type.ini 7sp.configuration_file={PWD}/config/broken_conf_invalid_type.ini
8--FILE-- 8--FILE--
9--EXPECTF-- 9--EXPECTF--
10 10Fatal error: [snuffleupagus][0.0.0.0][config][log] Missing argument to keyword 'ret_type' - it should be 'ret_type("...")' on line 1 in Unknown on line 0
11Fatal error: [snuffleupagus][0.0.0.0][error][log] There is an issue with the parsing of '"totally_wrong"_type")': it doesn't look like a valid string on line 1 in Unknown on line 0
12 11
13Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0 12Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0
14Could not startup. 13Could not startup.
diff --git a/src/tests/broken_configuration_php8/broken_conf_key_value.phpt b/src/tests/broken_configuration_php8/broken_conf_key_value.phpt
index 24c60bc..909aae1 100644
--- a/src/tests/broken_configuration_php8/broken_conf_key_value.phpt
+++ b/src/tests/broken_configuration_php8/broken_conf_key_value.phpt
@@ -6,8 +6,8 @@ Broken configuration
6--INI-- 6--INI--
7sp.configuration_file={PWD}/config/broken_conf_key_value.ini 7sp.configuration_file={PWD}/config/broken_conf_key_value.ini
8--FILE-- 8--FILE--
9--EXPECT-- 9--EXPECTF--
10Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration line: 'sp.disabled_functions.function("system").var("").value("").key("").drop();': '.key' and '.value' are mutually exclusive on line 1 in Unknown on line 0 10Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration line%a: '.key' and '.value' are mutually exclusive on line 1 in Unknown on line 0
11 11
12Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0 12Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0
13Could not startup. 13Could not startup.
diff --git a/src/tests/broken_configuration_php8/broken_conf_line_empty_string.phpt b/src/tests/broken_configuration_php8/broken_conf_line_empty_string.phpt
index 2d370ac..5702f43 100644
--- a/src/tests/broken_configuration_php8/broken_conf_line_empty_string.phpt
+++ b/src/tests/broken_configuration_php8/broken_conf_line_empty_string.phpt
@@ -7,8 +7,7 @@ Configuration line with an empty string
7sp.configuration_file={PWD}/config/broken_conf_line_empty_string.ini 7sp.configuration_file={PWD}/config/broken_conf_line_empty_string.ini
8--FILE-- 8--FILE--
9--EXPECT-- 9--EXPECT--
10 10Fatal error: [snuffleupagus][0.0.0.0][config][log] Missing argument to keyword 'name' - it should be 'name("...")' on line 1 in Unknown on line 0
11Fatal error: [snuffleupagus][0.0.0.0][error][log] A valid string as parameter is expected on line 1 in Unknown on line 0
12 11
13Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0 12Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0
14Could not startup. 13Could not startup.
diff --git a/src/tests/broken_configuration_php8/broken_conf_line_no_closing.phpt b/src/tests/broken_configuration_php8/broken_conf_line_no_closing.phpt
index d3c826f..1a0a392 100644
--- a/src/tests/broken_configuration_php8/broken_conf_line_no_closing.phpt
+++ b/src/tests/broken_configuration_php8/broken_conf_line_no_closing.phpt
@@ -7,8 +7,7 @@ Configuration line without closing parenthese
7sp.configuration_file={PWD}/config/broken_conf_line_no_closing.ini 7sp.configuration_file={PWD}/config/broken_conf_line_no_closing.ini
8--FILE-- 8--FILE--
9--EXPECT-- 9--EXPECT--
10 10Fatal error: [snuffleupagus][0.0.0.0][config][log] Missing argument to keyword 'name' - it should be 'name("...")' on line 1 in Unknown on line 0
11Fatal error: [snuffleupagus][0.0.0.0][error][log] There is an issue with the parsing of '"123"': it doesn't look like a valid string on line 1 in Unknown on line 0
12 11
13Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0 12Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0
14Could not startup. 13Could not startup.
diff --git a/src/tests/broken_configuration_php8/broken_conf_lots_of_quotes.phpt b/src/tests/broken_configuration_php8/broken_conf_lots_of_quotes.phpt
index e599e62..27135ca 100644
--- a/src/tests/broken_configuration_php8/broken_conf_lots_of_quotes.phpt
+++ b/src/tests/broken_configuration_php8/broken_conf_lots_of_quotes.phpt
@@ -7,8 +7,7 @@ Configuration line with too many quotes
7sp.configuration_file={PWD}/config/broken_conf_lots_of_quotes.ini 7sp.configuration_file={PWD}/config/broken_conf_lots_of_quotes.ini
8--FILE-- 8--FILE--
9--EXPECT-- 9--EXPECT--
10 10Fatal error: [snuffleupagus][0.0.0.0][config][log] Missing argument to keyword 'name' - it should be 'name("...")' on line 1 in Unknown on line 0
11Fatal error: [snuffleupagus][0.0.0.0][error][log] There is an issue with the parsing of '"this\"is a weird\"\"\"cookie\"name"");': it doesn't look like a valid string on line 1 in Unknown on line 0
12 11
13Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0 12Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0
14Could not startup. 13Could not startup.
diff --git a/src/tests/broken_configuration_php8/broken_conf_missing_script.phpt b/src/tests/broken_configuration_php8/broken_conf_missing_script.phpt
index 2ddb70f..bb44f15 100644
--- a/src/tests/broken_configuration_php8/broken_conf_missing_script.phpt
+++ b/src/tests/broken_configuration_php8/broken_conf_missing_script.phpt
@@ -10,8 +10,7 @@ sp.configuration_file={PWD}/config/broken_conf_missing_script.ini
10echo 1; 10echo 1;
11?> 11?>
12--EXPECTF-- 12--EXPECTF--
13 13Fatal error: [snuffleupagus][0.0.0.0][config][log] The `script` directive is mandatory in '.upload_validation' on line 1 in Unknown on line 0
14Fatal error: [snuffleupagus][0.0.0.0][config][log] The `script` directive is mandatory in '.enable();' on line 1 in Unknown on line 0
15 14
16Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0 15Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0
17Could not startup. 16Could not startup.
diff --git a/src/tests/broken_configuration_php8/broken_conf_mutually_exclusive.phpt b/src/tests/broken_configuration_php8/broken_conf_mutually_exclusive.phpt
index e362893..f331eee 100644
--- a/src/tests/broken_configuration_php8/broken_conf_mutually_exclusive.phpt
+++ b/src/tests/broken_configuration_php8/broken_conf_mutually_exclusive.phpt
@@ -6,9 +6,8 @@ Broken configuration
6--INI-- 6--INI--
7sp.configuration_file={PWD}/config/broken_conf_mutually_exclusive.ini 7sp.configuration_file={PWD}/config/broken_conf_mutually_exclusive.ini
8--FILE-- 8--FILE--
9--EXPECT-- 9--EXPECTF--
10 10Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration line%a: '.value' and '.value_r' are mutually exclusive on line 1 in Unknown on line 0
11Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration line: 'sp.disabled_functions.function("system").param("id").value("42").value_r("^id$").drop();': '.value' and '.value_r' are mutually exclusive on line 1 in Unknown on line 0
12 11
13Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0 12Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0
14Could not startup. 13Could not startup.
diff --git a/src/tests/broken_configuration_php8/broken_conf_mutually_exclusive11.phpt b/src/tests/broken_configuration_php8/broken_conf_mutually_exclusive11.phpt
index 39766e1..93fc581 100644
--- a/src/tests/broken_configuration_php8/broken_conf_mutually_exclusive11.phpt
+++ b/src/tests/broken_configuration_php8/broken_conf_mutually_exclusive11.phpt
@@ -6,9 +6,8 @@ Broken configuration - ret and var are mutually exclusives
6--INI-- 6--INI--
7sp.configuration_file={PWD}/config/broken_conf_mutually_exclusive11.ini 7sp.configuration_file={PWD}/config/broken_conf_mutually_exclusive11.ini
8--FILE-- 8--FILE--
9--EXPECT-- 9--EXPECTF--
10 10Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration line for '%a': '.ret' and '.var' are mutually exclusive on line 1 in Unknown on line 0
11Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration line: 'sp.disabled_functions.function("strcmp").drop().ret("hip").var("hop");': '.ret' and '.var' are mutually exclusive on line 1 in Unknown on line 0
12 11
13Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0 12Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0
14Could not startup. 13Could not startup.
diff --git a/src/tests/broken_configuration_php8/broken_conf_mutually_exclusive12.phpt b/src/tests/broken_configuration_php8/broken_conf_mutually_exclusive12.phpt
index ebca290..24162df 100644
--- a/src/tests/broken_configuration_php8/broken_conf_mutually_exclusive12.phpt
+++ b/src/tests/broken_configuration_php8/broken_conf_mutually_exclusive12.phpt
@@ -6,9 +6,8 @@ Broken configuration - ret and value are mutually exclusive
6--INI-- 6--INI--
7sp.configuration_file={PWD}/config/broken_conf_mutually_exclusive12.ini 7sp.configuration_file={PWD}/config/broken_conf_mutually_exclusive12.ini
8--FILE-- 8--FILE--
9--EXPECT-- 9--EXPECTF--
10 10Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration line for '%a': '.ret' and '.value' are mutually exclusive on line 1 in Unknown on line 0
11Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration line: 'sp.disabled_functions.function("strcmp").drop().ret("hip").value("hop");': '.ret' and '.value' are mutually exclusive on line 1 in Unknown on line 0
12 11
13Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0 12Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0
14Could not startup. 13Could not startup.
diff --git a/src/tests/broken_configuration_php8/broken_conf_mutually_exclusive2.phpt b/src/tests/broken_configuration_php8/broken_conf_mutually_exclusive2.phpt
index 52b36e0..35c4de1 100644
--- a/src/tests/broken_configuration_php8/broken_conf_mutually_exclusive2.phpt
+++ b/src/tests/broken_configuration_php8/broken_conf_mutually_exclusive2.phpt
@@ -6,9 +6,8 @@ Broken configuration
6--INI-- 6--INI--
7sp.configuration_file={PWD}/config/broken_conf_mutually_exclusive2.ini 7sp.configuration_file={PWD}/config/broken_conf_mutually_exclusive2.ini
8--FILE-- 8--FILE--
9--EXPECT-- 9--EXPECTF--
10 10Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration line%a: '.function' and '.function_r' are mutually exclusive on line 1 in Unknown on line 0
11Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration line: 'sp.disabled_functions.function("system").function_r("system").param("id").value("42").drop();': '.function' and '.function_r' are mutually exclusive on line 1 in Unknown on line 0
12 11
13Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0 12Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0
14Could not startup. 13Could not startup.
diff --git a/src/tests/broken_configuration_php8/broken_conf_mutually_exclusive3.phpt b/src/tests/broken_configuration_php8/broken_conf_mutually_exclusive3.phpt
index cf65e7d..fd6e0b4 100644
--- a/src/tests/broken_configuration_php8/broken_conf_mutually_exclusive3.phpt
+++ b/src/tests/broken_configuration_php8/broken_conf_mutually_exclusive3.phpt
@@ -6,9 +6,8 @@ Broken configuration
6--INI-- 6--INI--
7sp.configuration_file={PWD}/config/broken_conf_mutually_exclusive3.ini 7sp.configuration_file={PWD}/config/broken_conf_mutually_exclusive3.ini
8--FILE-- 8--FILE--
9--EXPECT-- 9--EXPECTF--
10 10Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration line%a: '.filename' and '.filename_r' are mutually exclusive on line 1 in Unknown on line 0
11Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration line: 'sp.disabled_functions.function("system").param("id").value("42").filename_r("^id$").filename("pouet.txt").drop();': '.filename' and '.filename_r' are mutually exclusive on line 1 in Unknown on line 0
12 11
13Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0 12Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0
14Could not startup. 13Could not startup.
diff --git a/src/tests/broken_configuration_php8/broken_conf_mutually_exclusive4.phpt b/src/tests/broken_configuration_php8/broken_conf_mutually_exclusive4.phpt
index 41dc60e..80370f6 100644
--- a/src/tests/broken_configuration_php8/broken_conf_mutually_exclusive4.phpt
+++ b/src/tests/broken_configuration_php8/broken_conf_mutually_exclusive4.phpt
@@ -6,9 +6,9 @@ Broken configuration
6--INI-- 6--INI--
7sp.configuration_file={PWD}/config/broken_conf_mutually_exclusive4.ini 7sp.configuration_file={PWD}/config/broken_conf_mutually_exclusive4.ini
8--FILE-- 8--FILE--
9--EXPECT-- 9--EXPECTF--
10 10
11Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration line: 'sp.disabled_functions.function("system").param("id").value("42").param_r("^id$").drop();': '.param' and '.param_r' are mutually exclusive on line 1 in Unknown on line 0 11Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration line%a: '.param' and '.param_r' are mutually exclusive on line 1 in Unknown on line 0
12 12
13Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0 13Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0
14Could not startup. 14Could not startup.
diff --git a/src/tests/broken_configuration_php8/broken_conf_mutually_exclusive5.phpt b/src/tests/broken_configuration_php8/broken_conf_mutually_exclusive5.phpt
index 9cab6cd..3087a17 100644
--- a/src/tests/broken_configuration_php8/broken_conf_mutually_exclusive5.phpt
+++ b/src/tests/broken_configuration_php8/broken_conf_mutually_exclusive5.phpt
@@ -6,9 +6,9 @@ Broken configuration
6--INI-- 6--INI--
7sp.configuration_file={PWD}/config/broken_conf_mutually_exclusive5.ini 7sp.configuration_file={PWD}/config/broken_conf_mutually_exclusive5.ini
8--FILE-- 8--FILE--
9--EXPECT-- 9--EXPECTF--
10 10
11Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration line: 'sp.disabled_functions.function("system").ret("0").drop().ret_r("^0$");': '.ret' and '.ret_r' are mutually exclusive on line 1 in Unknown on line 0 11Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration line%a: '.ret' and '.ret_r' are mutually exclusive on line 1 in Unknown on line 0
12 12
13Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0 13Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0
14Could not startup. 14Could not startup.
diff --git a/src/tests/broken_configuration_php8/broken_conf_mutually_exclusive6.phpt b/src/tests/broken_configuration_php8/broken_conf_mutually_exclusive6.phpt
index 406f818..2099a4b 100644
--- a/src/tests/broken_configuration_php8/broken_conf_mutually_exclusive6.phpt
+++ b/src/tests/broken_configuration_php8/broken_conf_mutually_exclusive6.phpt
@@ -6,9 +6,8 @@ Broken configuration
6--INI-- 6--INI--
7sp.configuration_file={PWD}/config/broken_conf_mutually_exclusive6.ini 7sp.configuration_file={PWD}/config/broken_conf_mutually_exclusive6.ini
8--FILE-- 8--FILE--
9--EXPECT-- 9--EXPECTF--
10 10Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration line for '%a': '.ret' and '.param' are mutually exclusive on line 1 in Unknown on line 0
11Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration line: 'sp.disabled_functions.function("system").param("id").value("42").ret_r("^0$").drop();': '.ret' and '.param' are mutually exclusive on line 1 in Unknown on line 0
12 11
13Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0 12Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0
14Could not startup. 13Could not startup.
diff --git a/src/tests/broken_configuration_php8/broken_conf_mutually_exclusive7.phpt b/src/tests/broken_configuration_php8/broken_conf_mutually_exclusive7.phpt
index ff7f415..f0b44da 100644
--- a/src/tests/broken_configuration_php8/broken_conf_mutually_exclusive7.phpt
+++ b/src/tests/broken_configuration_php8/broken_conf_mutually_exclusive7.phpt
@@ -6,9 +6,8 @@ Broken configuration
6--INI-- 6--INI--
7sp.configuration_file={PWD}/config/broken_conf_mutually_exclusive7.ini 7sp.configuration_file={PWD}/config/broken_conf_mutually_exclusive7.ini
8--FILE-- 8--FILE--
9--EXPECT-- 9--EXPECTF--
10 10Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration line: '%a': The rule must either be a `drop` or `allow` one on line 1 in Unknown on line 0
11Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration line: 'sp.disabled_functions.function("system").ret("0").drop().allow();': The rule must either be a `drop` or `allow` one on line 1 in Unknown on line 0
12 11
13Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0 12Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0
14Could not startup. 13Could not startup.
diff --git a/src/tests/broken_configuration_php8/broken_conf_mutually_exclusive8.phpt b/src/tests/broken_configuration_php8/broken_conf_mutually_exclusive8.phpt
index 6ccd508..8f6c246 100644
--- a/src/tests/broken_configuration_php8/broken_conf_mutually_exclusive8.phpt
+++ b/src/tests/broken_configuration_php8/broken_conf_mutually_exclusive8.phpt
@@ -6,9 +6,8 @@ Broken configuration
6--INI-- 6--INI--
7sp.configuration_file={PWD}/config/broken_conf_mutually_exclusive8.ini 7sp.configuration_file={PWD}/config/broken_conf_mutually_exclusive8.ini
8--FILE-- 8--FILE--
9--EXPECT-- 9--EXPECTF--
10 10Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration line: '%a': must take a function name on line 1 in Unknown on line 0
11Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration line: 'sp.disabled_functions.ret("0").drop();': must take a function name on line 1 in Unknown on line 0
12 11
13Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0 12Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0
14Could not startup. 13Could not startup.
diff --git a/src/tests/broken_configuration_php8/broken_conf_readonly_exec.phpt b/src/tests/broken_configuration_php8/broken_conf_readonly_exec.phpt
index 7e74683..5107ede 100644
--- a/src/tests/broken_configuration_php8/broken_conf_readonly_exec.phpt
+++ b/src/tests/broken_configuration_php8/broken_conf_readonly_exec.phpt
@@ -10,8 +10,7 @@ sp.configuration_file={PWD}/config/broken_conf_readonly_exec.ini
10echo 1; 10echo 1;
11?> 11?>
12--EXPECTF-- 12--EXPECTF--
13 13Fatal error: [snuffleupagus][0.0.0.0][config][log] Missing paranthesis for keyword 'enable' - it should be 'enable()' on line 1 in Unknown on line 0
14Fatal error: [snuffleupagus][0.0.0.0][config][log] Trailing chars '234);' at the end of '.enable(1234);' on line 1 in Unknown on line 0
15 14
16Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0 15Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0
17Could not startup. 16Could not startup.
diff --git a/src/tests/broken_configuration_php8/broken_conf_samesite.phpt b/src/tests/broken_configuration_php8/broken_conf_samesite.phpt
index c905fd8..63075d0 100644
--- a/src/tests/broken_configuration_php8/broken_conf_samesite.phpt
+++ b/src/tests/broken_configuration_php8/broken_conf_samesite.phpt
@@ -7,8 +7,7 @@ Bad config, invalid samesite type.
7sp.configuration_file={PWD}/config/broken_conf_cookie_samesite.ini 7sp.configuration_file={PWD}/config/broken_conf_cookie_samesite.ini
8--FILE-- 8--FILE--
9--EXPECT-- 9--EXPECT--
10 10Fatal error: [snuffleupagus][0.0.0.0][config][log] 'nop' is an invalid value to samesite (expected Lax or Strict) on line 1 in Unknown on line 0
11Fatal error: [snuffleupagus][0.0.0.0][config][log] nop is an invalid value to samesite (expected Lax or Strict) on line 1 in Unknown on line 0
12 11
13Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0 12Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0
14Could not startup. 13Could not startup.
diff --git a/src/tests/broken_configuration_php8/broken_conf_session_encryption.phpt b/src/tests/broken_configuration_php8/broken_conf_session_encryption.phpt
index 886eb13..cc7369a 100644
--- a/src/tests/broken_configuration_php8/broken_conf_session_encryption.phpt
+++ b/src/tests/broken_configuration_php8/broken_conf_session_encryption.phpt
@@ -7,8 +7,7 @@ Broken config, session encryption
7sp.configuration_file={PWD}/config/broken_conf_session_encryption.ini 7sp.configuration_file={PWD}/config/broken_conf_session_encryption.ini
8--FILE-- 8--FILE--
9--EXPECT-- 9--EXPECT--
10 10Fatal error: [snuffleupagus][0.0.0.0][config][log] Missing paranthesis for keyword 'encrypt' - it should be 'encrypt()' on line 1 in Unknown on line 0
11Fatal error: [snuffleupagus][0.0.0.0][config][log] Trailing chars 'nvalid value :/);' at the end of '.encrypt(invalid value :/);' on line 1 in Unknown on line 0
12 11
13Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0 12Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0
14Could not startup. 13Could not startup.
diff --git a/src/tests/broken_configuration_php8/broken_conf_shown_in_phpinfo.phpt b/src/tests/broken_configuration_php8/broken_conf_shown_in_phpinfo.phpt
index 2503943..23a8e53 100644
--- a/src/tests/broken_configuration_php8/broken_conf_shown_in_phpinfo.phpt
+++ b/src/tests/broken_configuration_php8/broken_conf_shown_in_phpinfo.phpt
@@ -18,10 +18,9 @@ if (strstr($info, 'Valid config => no') !== FALSE) {
18} 18}
19?> 19?>
20--EXPECTF-- 20--EXPECTF--
21Fatal error: [snuffleupagus][0.0.0.0][config][log] Failed to compile '*.': quantifier does not follow a repeatable item. in Unknown on line 0
21 22
22Fatal error: [snuffleupagus][0.0.0.0][config][log] Failed to compile '*.': %s on line 1. in Unknown on line 0 23Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid regexp '*.' for '.filename_r()' on line 1 in Unknown on line 0
23
24Fatal error: [snuffleupagus][0.0.0.0][config][log] '.filename_r()' is expecting a valid regexp, and not '"*."' on line 1 in Unknown on line 0
25 24
26Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0 25Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0
27Could not startup. 26Could not startup.
diff --git a/src/tests/broken_configuration_php8/broken_conf_truncated.phpt b/src/tests/broken_configuration_php8/broken_conf_truncated.phpt
index 059dcac..ff821f4 100644
--- a/src/tests/broken_configuration_php8/broken_conf_truncated.phpt
+++ b/src/tests/broken_configuration_php8/broken_conf_truncated.phpt
@@ -7,8 +7,7 @@ Bad boolean value in configuration
7sp.configuration_file={PWD}/config/config_broken_conf_truncated.ini 7sp.configuration_file={PWD}/config/config_broken_conf_truncated.ini
8--FILE-- 8--FILE--
9--EXPECT-- 9--EXPECT--
10 10Fatal error: [snuffleupagus][0.0.0.0][config][log] Missing argument to keyword 'param' - it should be 'param("...")' on line 1 in Unknown on line 0
11Fatal error: [snuffleupagus][0.0.0.0][error][log] A valid string as parameter is expected on line 1 in Unknown on line 0
12 11
13Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0 12Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0
14Could not startup. 13Could not startup.
diff --git a/src/tests/broken_configuration_php8/broken_conf_unserialize.phpt b/src/tests/broken_configuration_php8/broken_conf_unserialize.phpt
index 327b622..5e6c28e 100644
--- a/src/tests/broken_configuration_php8/broken_conf_unserialize.phpt
+++ b/src/tests/broken_configuration_php8/broken_conf_unserialize.phpt
@@ -9,9 +9,8 @@ sp.configuration_file={PWD}/config/broken_conf_unserialize.ini
9<?php 9<?php
10echo 1; 10echo 1;
11?> 11?>
12--EXPECTF-- 12--EXPECT--
13 13Fatal error: [snuffleupagus][0.0.0.0][config][log] Missing paranthesis for keyword 'enable' - it should be 'enable()' on line 1 in Unknown on line 0
14Fatal error: [snuffleupagus][0.0.0.0][config][log] Trailing chars '234);' at the end of '.enable(1234);' on line 1 in Unknown on line 0
15 14
16Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0 15Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0
17Could not startup. 16Could not startup.
diff --git a/src/tests/broken_configuration_php8/broken_conf_upload_validation.phpt b/src/tests/broken_configuration_php8/broken_conf_upload_validation.phpt
index d022e3e..31afff9 100644
--- a/src/tests/broken_configuration_php8/broken_conf_upload_validation.phpt
+++ b/src/tests/broken_configuration_php8/broken_conf_upload_validation.phpt
@@ -10,8 +10,7 @@ sp.configuration_file={PWD}/../broken_configuration/config/broken_conf_upload_va
10echo 1; 10echo 1;
11?> 11?>
12--EXPECTF-- 12--EXPECTF--
13 13Fatal error: [snuffleupagus][0.0.0.0][config][log] Missing argument to keyword 'script' - it should be 'script("...")' on line 1 in Unknown on line 0
14Fatal error: [snuffleupagus][0.0.0.0][error][log] A valid string as parameter is expected on line 1 in Unknown on line 0
15 14
16Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0 15Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0
17Could not startup. 16Could not startup.
diff --git a/src/tests/broken_configuration_php8/broken_conf_weird_keyword.phpt b/src/tests/broken_configuration_php8/broken_conf_weird_keyword.phpt
index 75c2e0e..6082f42 100644
--- a/src/tests/broken_configuration_php8/broken_conf_weird_keyword.phpt
+++ b/src/tests/broken_configuration_php8/broken_conf_weird_keyword.phpt
@@ -7,8 +7,7 @@ Bad config, unknown keyword
7sp.configuration_file={PWD}/config/broken_conf_weird_keyword.ini 7sp.configuration_file={PWD}/config/broken_conf_weird_keyword.ini
8--FILE-- 8--FILE--
9--EXPECT-- 9--EXPECT--
10 10Fatal error: [snuffleupagus][0.0.0.0][config][log] Unexpected keyword 'not_a_valid_keyword' on line 1 in Unknown on line 0
11Fatal error: [snuffleupagus][0.0.0.0][config][log] Trailing chars '.not_a_valid_keyword("test");' at the end of '.enable().not_a_valid_keyword("test");' on line 1 in Unknown on line 0
12 11
13Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0 12Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0
14Could not startup. 13Could not startup.
diff --git a/src/tests/broken_configuration_php8/broken_conf_wrapper_whitelist.phpt b/src/tests/broken_configuration_php8/broken_conf_wrapper_whitelist.phpt
index 0011a6e..1f2d9da 100644
--- a/src/tests/broken_configuration_php8/broken_conf_wrapper_whitelist.phpt
+++ b/src/tests/broken_configuration_php8/broken_conf_wrapper_whitelist.phpt
@@ -11,8 +11,7 @@ sp.allow_broken_configuration=Off
11echo 1337; 11echo 1337;
12?> 12?>
13--EXPECT-- 13--EXPECT--
14 14Fatal error: [snuffleupagus][0.0.0.0][config][log] Unexpected keyword 'invalid_param' on line 1 in Unknown on line 0
15Fatal error: [snuffleupagus][0.0.0.0][config][log] Trailing chars '.invalid_param();' at the end of '.invalid_param();' on line 1 in Unknown on line 0
16 15
17Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0 16Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0
18Could not startup. 17Could not startup.
diff --git a/src/tests/broken_configuration_php8/broken_conf_wrong_quotes.phpt b/src/tests/broken_configuration_php8/broken_conf_wrong_quotes.phpt
index b073369..d3cf9e0 100644
--- a/src/tests/broken_configuration_php8/broken_conf_wrong_quotes.phpt
+++ b/src/tests/broken_configuration_php8/broken_conf_wrong_quotes.phpt
@@ -7,8 +7,7 @@ Configuration line with too many quotes
7sp.configuration_file={PWD}/config/broken_conf_wrong_quotes.ini 7sp.configuration_file={PWD}/config/broken_conf_wrong_quotes.ini
8--FILE-- 8--FILE--
9--EXPECT-- 9--EXPECT--
10 10Fatal error: [snuffleupagus][0.0.0.0][config][log] Missing argument to keyword 'name' - it should be 'name("...")' on line 1 in Unknown on line 0
11Fatal error: [snuffleupagus][0.0.0.0][error][log] There is an issue with the parsing of '"\)': it doesn't look like a valid string on line 1 in Unknown on line 0
12 11
13Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0 12Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0
14Could not startup. 13Could not startup.
diff --git a/src/tests/broken_configuration_php8/broken_regexp.phpt b/src/tests/broken_configuration_php8/broken_regexp.phpt
index 877f801..7461d57 100644
--- a/src/tests/broken_configuration_php8/broken_regexp.phpt
+++ b/src/tests/broken_configuration_php8/broken_regexp.phpt
@@ -7,10 +7,9 @@ Broken regexp
7sp.configuration_file={PWD}/config/broken_regexp.ini 7sp.configuration_file={PWD}/config/broken_regexp.ini
8--FILE-- 8--FILE--
9--EXPECTF-- 9--EXPECTF--
10Fatal error: [snuffleupagus][0.0.0.0][config][log] Failed to compile '^$[': missing terminating ] for character class. in Unknown on line 0
10 11
11Fatal error: [snuffleupagus][0.0.0.0][config][log] Failed to compile '^$[': missing terminating ] for character class on line 1. in Unknown on line 0 12Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid regexp '^$[' for '.value_r()' on line 1 in Unknown on line 0
12
13Fatal error: [snuffleupagus][0.0.0.0][config][log] '.value_r()' is expecting a valid regexp, and not '"^$["' on line 1 in Unknown on line 0
14 13
15Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0 14Fatal error: [snuffleupagus][0.0.0.0][config][log] Invalid configuration file in Unknown on line 0
16Could not startup. 15Could not startup.
diff --git a/src/tests/broken_configuration_php8/encrypt_regexp_cookies_bad_regexp.phpt b/src/tests/broken_configuration_php8/encrypt_regexp_cookies_bad_regexp.phpt
index 7a8c909..5383df6 100644
--- a/src/tests/broken_configuration_php8/encrypt_regexp_cookies_bad_regexp.phpt
+++ b/src/tests/broken_configuration_php8/encrypt_regexp_cookies_bad_regexp.phpt
@@ -17,6 +17,6 @@ EOF;
17--EXPECT-- 17--EXPECT--
18Fatal error: [snuffleupagus][127.0.0.1][config][log] Invalid configuration file in Unknown on line 0 18Fatal error: [snuffleupagus][127.0.0.1][config][log] Invalid configuration file in Unknown on line 0
19 19
20Fatal error: [snuffleupagus][127.0.0.1][config][log] Failed to compile '^super_co[a-z+$': missing terminating ] for character class on line 2. in Unknown on line 0 20Fatal error: [snuffleupagus][127.0.0.1][config][log] Failed to compile '^super_co[a-z+$': missing terminating ] for character class. in Unknown on line 0
21 21
22Fatal error: [snuffleupagus][127.0.0.1][config][log] '.name_r()' is expecting a valid regexp, and not '"^super_co[a-z+$"' on line 2 in Unknown on line 0 22Fatal error: [snuffleupagus][127.0.0.1][config][log] Invalid regexp '^super_co[a-z+$' for '.name_r()' on line 2 in Unknown on line 0
diff --git a/src/tests/cookies_encryption_warning/encrypt_cookies_no_env.phpt b/src/tests/cookies_encryption_warning/encrypt_cookies_no_env.phpt
index 015c159..a01c352 100644
--- a/src/tests/cookies_encryption_warning/encrypt_cookies_no_env.phpt
+++ b/src/tests/cookies_encryption_warning/encrypt_cookies_no_env.phpt
@@ -18,4 +18,4 @@ EOF;
18--EXPECT-- 18--EXPECT--
19Fatal error: [snuffleupagus][127.0.0.1][config][log] Invalid configuration file in Unknown on line 0 19Fatal error: [snuffleupagus][127.0.0.1][config][log] Invalid configuration file in Unknown on line 0
20 20
21Fatal error: [snuffleupagus][127.0.0.1][config][log] You're trying to use the cookie encryption featureon line 2 without having set the `.cookie_env_var` option in`sp.global`: please set it first in Unknown on line 0 21Fatal error: [snuffleupagus][127.0.0.1][config][log] You're trying to use the cookie encryption feature on line 2 without having set the `.cookie_env_var` option in`sp.global`: please set it first in Unknown on line 0
diff --git a/src/tests/cookies_encryption_warning/encrypt_cookies_no_key.phpt b/src/tests/cookies_encryption_warning/encrypt_cookies_no_key.phpt
index 42f5509..c47389c 100644
--- a/src/tests/cookies_encryption_warning/encrypt_cookies_no_key.phpt
+++ b/src/tests/cookies_encryption_warning/encrypt_cookies_no_key.phpt
@@ -18,4 +18,4 @@ EOF;
18--EXPECT-- 18--EXPECT--
19Fatal error: [snuffleupagus][127.0.0.1][config][log] Invalid configuration file in Unknown on line 0 19Fatal error: [snuffleupagus][127.0.0.1][config][log] Invalid configuration file in Unknown on line 0
20 20
21Fatal error: [snuffleupagus][127.0.0.1][config][log] You're trying to use the cookie encryption featureon line 2 without having set the `.encryption_key` option in`sp.global`: please set it first in Unknown on line 0 21Fatal error: [snuffleupagus][127.0.0.1][config][log] You're trying to use the cookie encryption feature on line 2 without having set the `.secret_key` option in `sp.global`: please set it first in Unknown on line 0
diff --git a/src/tests/cookies_encryption_warning/encrypt_regexp_cookies_no_env.phpt b/src/tests/cookies_encryption_warning/encrypt_regexp_cookies_no_env.phpt
index 163cb26..1fe4074 100644
--- a/src/tests/cookies_encryption_warning/encrypt_regexp_cookies_no_env.phpt
+++ b/src/tests/cookies_encryption_warning/encrypt_regexp_cookies_no_env.phpt
@@ -18,4 +18,4 @@ EOF;
18--EXPECT-- 18--EXPECT--
19Fatal error: [snuffleupagus][127.0.0.1][config][log] Invalid configuration file in Unknown on line 0 19Fatal error: [snuffleupagus][127.0.0.1][config][log] Invalid configuration file in Unknown on line 0
20 20
21Fatal error: [snuffleupagus][127.0.0.1][config][log] You're trying to use the cookie encryption featureon line 2 without having set the `.cookie_env_var` option in`sp.global`: please set it first in Unknown on line 0 21Fatal error: [snuffleupagus][127.0.0.1][config][log] You're trying to use the cookie encryption feature on line 2 without having set the `.cookie_env_var` option in`sp.global`: please set it first in Unknown on line 0
diff --git a/src/tests/cookies_encryption_warning/encrypt_regexp_cookies_no_key.phpt b/src/tests/cookies_encryption_warning/encrypt_regexp_cookies_no_key.phpt
index df31f2e..0da0dbe 100644
--- a/src/tests/cookies_encryption_warning/encrypt_regexp_cookies_no_key.phpt
+++ b/src/tests/cookies_encryption_warning/encrypt_regexp_cookies_no_key.phpt
@@ -18,4 +18,4 @@ EOF;
18--EXPECT-- 18--EXPECT--
19Fatal error: [snuffleupagus][127.0.0.1][config][log] Invalid configuration file in Unknown on line 0 19Fatal error: [snuffleupagus][127.0.0.1][config][log] Invalid configuration file in Unknown on line 0
20 20
21Fatal error: [snuffleupagus][127.0.0.1][config][log] You're trying to use the cookie encryption featureon line 2 without having set the `.encryption_key` option in`sp.global`: please set it first in Unknown on line 0 21Fatal error: [snuffleupagus][127.0.0.1][config][log] You're trying to use the cookie encryption feature on line 2 without having set the `.secret_key` option in `sp.global`: please set it first in Unknown on line 0
diff --git a/src/tests/dump_request/dump_eval_blacklist.phpt b/src/tests/dump_request/dump_eval_blacklist.phpt
index 07c17f2..b8192a7 100644
--- a/src/tests/dump_request/dump_eval_blacklist.phpt
+++ b/src/tests/dump_request/dump_eval_blacklist.phpt
@@ -36,5 +36,5 @@ if ($res[3] != "GET:get_a='data_get_a' get_b='data_get_b' \n") {
36--EXPECTF-- 36--EXPECTF--
37Outside of eval: 1337 1337 1337 37Outside of eval: 1337 1337 1337
38 38
39Warning: [snuffleupagus][0.0.0.0][eval][simulation] A call to strtoupper was tried in eval, in %a/dump_eval_blacklist.php:1, logging it. in %a/dump_eval_blacklist.php(9) : eval()'d code on line 1 39Warning: [snuffleupagus][0.0.0.0][eval][simulation] A call to 'strtoupper' was tried in eval. logging it. in %a(9) : eval()'d code on line 1
40After eval: 1234 40After eval: 1234
diff --git a/src/tests/eval_blacklist/eval_backlist.phpt b/src/tests/eval_blacklist/eval_backlist.phpt
index fa32b4b..2953efc 100644
--- a/src/tests/eval_blacklist/eval_backlist.phpt
+++ b/src/tests/eval_blacklist/eval_backlist.phpt
@@ -14,4 +14,4 @@ echo "After eval: $a\n";
14--EXPECTF-- 14--EXPECTF--
15Outside of eval: 1337 1337 1337 15Outside of eval: 1337 1337 1337
16 16
17Fatal error: [snuffleupagus][0.0.0.0][eval][drop] A call to strtoupper was tried in eval, in %a/eval_backlist.php:1, dropping it. in %a/eval_backlist.php(4) : eval()'d code on line 1 17Fatal error: [snuffleupagus][0.0.0.0][eval][drop] A call to 'strtoupper' was tried in eval. dropping it. in %a/eval_backlist.php(4) : eval()'d code on line 1
diff --git a/src/tests/eval_blacklist/eval_backlist_call_user_func.phpt b/src/tests/eval_blacklist/eval_backlist_call_user_func.phpt
index 4c37263..546a53a 100644
--- a/src/tests/eval_blacklist/eval_backlist_call_user_func.phpt
+++ b/src/tests/eval_blacklist/eval_backlist_call_user_func.phpt
@@ -11,4 +11,4 @@ eval('
11') 11')
12?> 12?>
13--EXPECTF-- 13--EXPECTF--
14Fatal error: [snuffleupagus][0.0.0.0][eval][drop] A call to strtoupper was tried in eval, in %s/eval_backlist_call_user_func.php:%d, dropping it. in %s/eval_backlist_call_user_func.php(%d) : eval()'d code on line %d 14Fatal error: [snuffleupagus][0.0.0.0][eval][drop] A call to 'strtoupper' was tried in eval. dropping it. in %s/eval_backlist_call_user_func.php(%d) : eval()'d code on line %d
diff --git a/src/tests/eval_blacklist/eval_backlist_chained.phpt b/src/tests/eval_blacklist/eval_backlist_chained.phpt
index 820ef1d..1afb860 100644
--- a/src/tests/eval_blacklist/eval_backlist_chained.phpt
+++ b/src/tests/eval_blacklist/eval_backlist_chained.phpt
@@ -13,4 +13,4 @@ eval('
13') 13')
14?> 14?>
15--EXPECTF-- 15--EXPECTF--
16Fatal error: [snuffleupagus][0.0.0.0][eval][drop] A call to strtoupper was tried in eval, in %s/eval_backlist_chained.php:%d, dropping it. in %s/eval_backlist_chained.php(%d) : eval()'d code on line %d 16Fatal error: [snuffleupagus][0.0.0.0][eval][drop] A call to 'strtoupper' was tried in eval. dropping it. in %s/eval_backlist_chained.php(%d) : eval()'d code on line %d
diff --git a/src/tests/eval_blacklist/eval_backlist_list.phpt b/src/tests/eval_blacklist/eval_backlist_list.phpt
index 725a9bb..1efd453 100644
--- a/src/tests/eval_blacklist/eval_backlist_list.phpt
+++ b/src/tests/eval_blacklist/eval_backlist_list.phpt
@@ -14,4 +14,4 @@ echo "After eval: $a\n";
14--EXPECTF-- 14--EXPECTF--
15Outside of eval: 1337 1337 1337 15Outside of eval: 1337 1337 1337
16 16
17Fatal error: [snuffleupagus][0.0.0.0][eval][drop] A call to strtoupper was tried in eval, in %a/eval_backlist_list.php:1, dropping it. in %a/eval_backlist_list.php(4) : eval()'d code on line 1 17Fatal error: [snuffleupagus][0.0.0.0][eval][drop] A call to 'strtoupper' was tried in eval. dropping it. in %a/eval_backlist_list.php(4) : eval()'d code on line 1
diff --git a/src/tests/eval_blacklist/eval_backlist_simulation.phpt b/src/tests/eval_blacklist/eval_backlist_simulation.phpt
index f09370d..0cc02b2 100644
--- a/src/tests/eval_blacklist/eval_backlist_simulation.phpt
+++ b/src/tests/eval_blacklist/eval_backlist_simulation.phpt
@@ -14,5 +14,5 @@ echo "After eval: $a\n";
14--EXPECTF-- 14--EXPECTF--
15Outside of eval: 1337 1337 1337 15Outside of eval: 1337 1337 1337
16 16
17Warning: [snuffleupagus][0.0.0.0][eval][simulation] A call to strtoupper was tried in eval, in %a/eval_backlist_simulation.php:1, logging it. in %a/eval_backlist_simulation.php(4) : eval()'d code on line 1 17Warning: [snuffleupagus][0.0.0.0][eval][simulation] A call to 'strtoupper' was tried in eval. logging it. in %a/eval_backlist_simulation.php(4) : eval()'d code on line 1
18After eval: 1234 18After eval: 1234
diff --git a/src/tests/eval_blacklist/nested_eval_blacklist.phpt b/src/tests/eval_blacklist/nested_eval_blacklist.phpt
index 8ff0b6d..a06b66b 100644
--- a/src/tests/eval_blacklist/nested_eval_blacklist.phpt
+++ b/src/tests/eval_blacklist/nested_eval_blacklist.phpt
@@ -26,4 +26,4 @@ Inception lvl 1...
26Inception lvl 2... 26Inception lvl 2...
27Inception lvl 3... 27Inception lvl 3...
28 28
29Fatal error: [snuffleupagus][0.0.0.0][eval][drop] A call to strtoupper was tried in eval, in %a/nested_eval_blacklist.php(5) : eval()'d code(4) : eval()'d code:3, dropping it. in %a/nested_eval_blacklist.php(5) : eval()'d code(4) : eval()'d code(4) : eval()'d code on line 3 29Fatal error: [snuffleupagus][0.0.0.0][eval][drop] A call to 'strtoupper' was tried in eval. dropping it. in %a/nested_eval_blacklist.php(5) : eval()'d code(4) : eval()'d code(4) : eval()'d code on line 3
diff --git a/src/tests/eval_blacklist/nested_eval_blacklist2.phpt b/src/tests/eval_blacklist/nested_eval_blacklist2.phpt
index 37f8967..63e56b1 100644
--- a/src/tests/eval_blacklist/nested_eval_blacklist2.phpt
+++ b/src/tests/eval_blacklist/nested_eval_blacklist2.phpt
@@ -26,4 +26,4 @@ Inception lvl 1...
26Inception lvl 2... 26Inception lvl 2...
27Inception lvl 3... 27Inception lvl 3...
28 28
29Fatal error: [snuffleupagus][0.0.0.0][eval][drop] A call to strtoupper was tried in eval, in %a/nested_eval_blacklist2.php(5) : eval()'d code:7, dropping it. in %a/nested_eval_blacklist2.php(5) : eval()'d code(4) : eval()'d code on line 7 29Fatal error: [snuffleupagus][0.0.0.0][eval][drop] A call to 'strtoupper' was tried in eval. dropping it. in %a/nested_eval_blacklist2.php(5) : eval()'d code(4) : eval()'d code on line 7