summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/sp_config.c23
-rw-r--r--src/sp_config.h16
-rw-r--r--src/sp_disabled_functions.c15
-rw-r--r--src/sp_ini.c2
-rw-r--r--src/sp_pcre_compat.c14
-rw-r--r--src/sp_pcre_compat.h38
-rw-r--r--src/sp_utils.c26
-rw-r--r--src/sp_utils.h15
-rw-r--r--src/sp_var_parser.c4
9 files changed, 75 insertions, 78 deletions
diff --git a/src/sp_config.c b/src/sp_config.c
index bc9aa0d..7294b0e 100644
--- a/src/sp_config.c
+++ b/src/sp_config.c
@@ -228,20 +228,17 @@ SP_PARSEKW_FN(parse_cidr) {
228} 228}
229 229
230SP_PARSEKW_FN(parse_regexp) { 230SP_PARSEKW_FN(parse_regexp) {
231 /* TODO: Do we want to use pcre_study?
232 * (http://www.pcre.org/original/doc/html/pcre_study.html)
233 * maybe not: http://sljit.sourceforge.net/pcre.html*/
234 CHECK_DUPLICATE_KEYWORD(retval); 231 CHECK_DUPLICATE_KEYWORD(retval);
235 SP_PARSE_ARG(value); 232 SP_PARSE_ARG(value);
236 233
237 sp_pcre *compiled_re = sp_pcre_compile(ZSTR_VAL(value)); 234 sp_regexp *compiled_re = sp_regexp_compile(value);
238 if (!compiled_re) { 235 if (!compiled_re) {
239 sp_log_err("config", "Invalid regexp '%s' for '.%s()' on line %zu", ZSTR_VAL(value), token, kw->lineno); 236 sp_log_err("config", "Invalid regexp '%s' for '.%s()' on line %zu", ZSTR_VAL(value), token, kw->lineno);
240 zend_string_release_ex(value, 1); 237 zend_string_release_ex(value, 1);
241 return SP_PARSER_ERROR; 238 return SP_PARSER_ERROR;
242 } 239 }
243 240
244 *(sp_pcre **)retval = compiled_re; 241 *(sp_regexp **)retval = compiled_re;
245 242
246 return SP_PARSER_SUCCESS; 243 return SP_PARSER_SUCCESS;
247} 244}
@@ -252,24 +249,24 @@ void sp_free_disabled_function(void *data) {
252 sp_free_zstr(df->textual_representation); 249 sp_free_zstr(df->textual_representation);
253 250
254 sp_free_zstr(df->filename); 251 sp_free_zstr(df->filename);
255 sp_pcre_free(df->r_filename); 252 sp_regexp_free(df->r_filename);
256 253
257 sp_free_zstr(df->function); 254 sp_free_zstr(df->function);
258 sp_pcre_free(df->r_function); 255 sp_regexp_free(df->r_function);
259 sp_list_free(df->functions_list, free); 256 sp_list_free(df->functions_list, free);
260 257
261 sp_free_zstr(df->hash); 258 sp_free_zstr(df->hash);
262 259
263 sp_tree_free(df->param); 260 sp_tree_free(df->param);
264 sp_pcre_free(df->r_param); 261 sp_regexp_free(df->r_param);
265 262
266 sp_pcre_free(df->r_ret); 263 sp_regexp_free(df->r_ret);
267 sp_free_zstr(df->ret); 264 sp_free_zstr(df->ret);
268 265
269 sp_pcre_free(df->r_value); 266 sp_regexp_free(df->r_value);
270 sp_free_zstr(df->value); 267 sp_free_zstr(df->value);
271 268
272 sp_pcre_free(df->r_key); 269 sp_regexp_free(df->r_key);
273 sp_free_zstr(df->key); 270 sp_free_zstr(df->key);
274 271
275 sp_free_zstr(df->dump); 272 sp_free_zstr(df->dump);
@@ -287,7 +284,7 @@ void sp_free_cookie(void *data) {
287 sp_cookie *c = data; 284 sp_cookie *c = data;
288 if (c->name) 285 if (c->name)
289 zend_string_release_ex(c->name, 1); 286 zend_string_release_ex(c->name, 1);
290 sp_pcre_free(c->name_r); 287 sp_regexp_free(c->name_r);
291} 288}
292 289
293void sp_free_zstr(void *data) { 290void sp_free_zstr(void *data) {
@@ -302,7 +299,7 @@ void sp_free_ini_entry(void *data) {
302 sp_free_zstr(entry->key); 299 sp_free_zstr(entry->key);
303 sp_free_zstr(entry->min); 300 sp_free_zstr(entry->min);
304 sp_free_zstr(entry->max); 301 sp_free_zstr(entry->max);
305 sp_pcre_free(entry->regexp); 302 sp_regexp_free(entry->regexp);
306 sp_free_zstr(entry->msg); 303 sp_free_zstr(entry->msg);
307 sp_free_zstr(entry->set); 304 sp_free_zstr(entry->set);
308} 305}
diff --git a/src/sp_config.h b/src/sp_config.h
index 1a891c1..6d48240 100644
--- a/src/sp_config.h
+++ b/src/sp_config.h
@@ -63,7 +63,7 @@ typedef struct {
63 enum samesite_type { strict = 1, lax = 2 } samesite; 63 enum samesite_type { strict = 1, lax = 2 } samesite;
64 bool encrypt; 64 bool encrypt;
65 zend_string *name; 65 zend_string *name;
66 sp_pcre *name_r; 66 sp_regexp *name_r;
67 bool simulation; 67 bool simulation;
68} sp_cookie; 68} sp_cookie;
69 69
@@ -91,29 +91,29 @@ typedef struct {
91 zend_string *textual_representation; 91 zend_string *textual_representation;
92 92
93 zend_string *filename; 93 zend_string *filename;
94 sp_pcre *r_filename; 94 sp_regexp *r_filename;
95 95
96 zend_string *function; 96 zend_string *function;
97 sp_pcre *r_function; 97 sp_regexp *r_function;
98 sp_list_node *functions_list; 98 sp_list_node *functions_list;
99 99
100 zend_string *hash; 100 zend_string *hash;
101 int simulation; 101 int simulation;
102 102
103 sp_tree *param; 103 sp_tree *param;
104 sp_pcre *r_param; 104 sp_regexp *r_param;
105 sp_php_type param_type; 105 sp_php_type param_type;
106 int pos; 106 int pos;
107 unsigned int line; 107 unsigned int line;
108 108
109 sp_pcre *r_ret; 109 sp_regexp *r_ret;
110 zend_string *ret; 110 zend_string *ret;
111 sp_php_type ret_type; 111 sp_php_type ret_type;
112 112
113 sp_pcre *r_value; 113 sp_regexp *r_value;
114 zend_string *value; 114 zend_string *value;
115 115
116 sp_pcre *r_key; 116 sp_regexp *r_key;
117 zend_string *key; 117 zend_string *key;
118 118
119 zend_string *dump; 119 zend_string *dump;
@@ -157,7 +157,7 @@ typedef struct {
157 sp_ini_permission access; 157 sp_ini_permission access;
158 zend_string *min; 158 zend_string *min;
159 zend_string *max; 159 zend_string *max;
160 sp_pcre *regexp; 160 sp_regexp *regexp;
161 zend_string *msg; 161 zend_string *msg;
162 zend_string *set; 162 zend_string *set;
163 bool allow_null; 163 bool allow_null;
diff --git a/src/sp_disabled_functions.c b/src/sp_disabled_functions.c
index 0ff859c..95e19ad 100644
--- a/src/sp_disabled_functions.c
+++ b/src/sp_disabled_functions.c
@@ -210,17 +210,15 @@ static zend_execute_data* is_file_matching(
210 return ex; // LCOV_EXCL_LINE 210 return ex; // LCOV_EXCL_LINE
211 } 211 }
212 ITERATE(ex); 212 ITERATE(ex);
213 if (zend_string_equals(ex->func->op_array.filename, 213 if (zend_string_equals(ex->func->op_array.filename, config_node->filename)) {
214 config_node->filename)) {
215 return ex; // LCOV_EXCL_LINE 214 return ex; // LCOV_EXCL_LINE
216 } 215 }
217 } else if (config_node->r_filename) { 216 } else if (config_node->r_filename) {
218 if (sp_is_regexp_matching_zend(config_node->r_filename, current_filename)) { 217 if (sp_is_regexp_matching_zstr(config_node->r_filename, current_filename)) {
219 return ex; 218 return ex;
220 } 219 }
221 ITERATE(ex); 220 ITERATE(ex);
222 if (sp_is_regexp_matching_zend(config_node->r_filename, 221 if (sp_is_regexp_matching_zstr(config_node->r_filename, ex->func->op_array.filename)) {
223 ex->func->op_array.filename)) {
224 return ex; 222 return ex;
225 } 223 }
226 } 224 }
@@ -481,10 +479,9 @@ ZEND_FUNCTION(check_disabled_function) {
481 479
482static int hook_functions_regexp(const sp_list_node* config) { 480static int hook_functions_regexp(const sp_list_node* config) {
483 while (config && config->data) { 481 while (config && config->data) {
484 const zend_string* function_name = 482 const zend_string* function_name = ((sp_disabled_function*)config->data)->function;
485 ((sp_disabled_function*)config->data)->function; 483 sp_regexp *function_name_sp_regexp = ((sp_disabled_function*)config->data)->r_function;
486 const sp_pcre* function_name_regexp = 484 const sp_pcre* function_name_regexp = function_name_sp_regexp ? function_name_sp_regexp->re : NULL;
487 ((sp_disabled_function*)config->data)->r_function;
488 485
489 assert(function_name || function_name_regexp); 486 assert(function_name || function_name_regexp);
490 487
diff --git a/src/sp_ini.c b/src/sp_ini.c
index 62bd181..7fec297 100644
--- a/src/sp_ini.c
+++ b/src/sp_ini.c
@@ -66,7 +66,7 @@ static bool /* success */ sp_ini_check(zend_string *varname, zend_string *new_va
66 } 66 }
67 67
68 if (entry->regexp) { 68 if (entry->regexp) {
69 if (!sp_is_regexp_matching_len(entry->regexp, ZSTR_VAL(new_value), ZSTR_LEN(new_value))) { 69 if (!sp_is_regexp_matching_zstr(entry->regexp, new_value)) {
70 sp_log_ini_check_violation("%s", (entry->msg ? ZSTR_VAL(entry->msg) : "INI value does not match regex")); 70 sp_log_ini_check_violation("%s", (entry->msg ? ZSTR_VAL(entry->msg) : "INI value does not match regex"));
71 return simulation; 71 return simulation;
72 } 72 }
diff --git a/src/sp_pcre_compat.c b/src/sp_pcre_compat.c
index 375a708..81c51fd 100644
--- a/src/sp_pcre_compat.c
+++ b/src/sp_pcre_compat.c
@@ -1,10 +1,5 @@
1#include "php_snuffleupagus.h" 1#include "php_snuffleupagus.h"
2 2
3inline void sp_pcre_free(sp_pcre* regexp) {
4#ifdef SP_HAS_PCRE2
5 pcre2_code_free(regexp);
6#endif
7}
8 3
9sp_pcre* sp_pcre_compile(const char* const pattern) { 4sp_pcre* sp_pcre_compile(const char* const pattern) {
10 assert(NULL != pattern); 5 assert(NULL != pattern);
@@ -14,8 +9,7 @@ sp_pcre* sp_pcre_compile(const char* const pattern) {
14 unsigned char pcre_error[128] = {0}; 9 unsigned char pcre_error[128] = {0};
15 int errornumber; 10 int errornumber;
16 PCRE2_SIZE erroroffset; 11 PCRE2_SIZE erroroffset;
17 ret = pcre2_compile((PCRE2_SPTR)pattern, PCRE2_ZERO_TERMINATED, 12 ret = pcre2_compile((PCRE2_SPTR)pattern, PCRE2_ZERO_TERMINATED, PCRE2_CASELESS, &errornumber, &erroroffset, NULL);
18 PCRE2_CASELESS, &errornumber, &erroroffset, NULL);
19 pcre2_get_error_message(errornumber, pcre_error, sizeof(pcre_error)-1); 13 pcre2_get_error_message(errornumber, pcre_error, sizeof(pcre_error)-1);
20#else 14#else
21 const char* pcre_error = NULL; 15 const char* pcre_error = NULL;
@@ -29,16 +23,14 @@ sp_pcre* sp_pcre_compile(const char* const pattern) {
29 return ret; 23 return ret;
30} 24}
31 25
32bool ZEND_HOT sp_is_regexp_matching_len(const sp_pcre* regexp, const char* str, 26bool ZEND_HOT sp_is_regexp_matching_len(const sp_pcre* regexp, const char* str, size_t len) {
33 size_t len) {
34 int ret = 0; 27 int ret = 0;
35 28
36 assert(NULL != regexp); 29 assert(NULL != regexp);
37 assert(NULL != str); 30 assert(NULL != str);
38 31
39#ifdef SP_HAS_PCRE2 32#ifdef SP_HAS_PCRE2
40 pcre2_match_data* match_data = 33 pcre2_match_data* match_data = pcre2_match_data_create_from_pattern(regexp, NULL);
41 pcre2_match_data_create_from_pattern(regexp, NULL);
42 if (NULL == match_data) { 34 if (NULL == match_data) {
43 sp_log_err("regexp", "Unable to get memory for a regxp."); 35 sp_log_err("regexp", "Unable to get memory for a regxp.");
44 } 36 }
diff --git a/src/sp_pcre_compat.h b/src/sp_pcre_compat.h
index 725004d..6e9d91a 100644
--- a/src/sp_pcre_compat.h
+++ b/src/sp_pcre_compat.h
@@ -17,12 +17,36 @@
17#endif 17#endif
18 18
19sp_pcre* sp_pcre_compile(const char* str); 19sp_pcre* sp_pcre_compile(const char* str);
20void sp_pcre_free(sp_pcre* regexp); 20static inline void sp_pcre_free(sp_pcre* regexp) {
21#define sp_is_regexp_matching_zend(regexp, zstr) \ 21#ifdef SP_HAS_PCRE2
22 sp_is_regexp_matching_len(regexp, ZSTR_VAL(zstr), ZSTR_LEN(zstr)) 22 pcre2_code_free(regexp);
23#define sp_is_regexp_matching(regexp, str) \ 23#endif
24 sp_is_regexp_matching_len(regexp, str, strlen(str)) 24}
25bool sp_is_regexp_matching_len(const sp_pcre* regexp, const char* str, 25bool sp_is_regexp_matching_len(const sp_pcre* regexp, const char* str, size_t len);
26 size_t len); 26
27
28typedef struct {
29 sp_pcre *re;
30 zend_string *pattern;
31} sp_regexp;
32
33#define sp_is_regexp_matching_zstr(regexp, zstr) sp_is_regexp_matching_len(regexp->re, ZSTR_VAL(zstr), ZSTR_LEN(zstr))
34#define sp_is_regexp_matching(regexp, str) sp_is_regexp_matching_len(regexp->re, str, strlen(str))
35static inline sp_regexp* sp_regexp_compile(zend_string *zstr) {
36 sp_pcre *re = sp_pcre_compile(ZSTR_VAL(zstr));
37 if (!re) { return NULL; }
38 sp_regexp *ret = pecalloc(sizeof(sp_regexp), 1, 1);
39 ret->re = re;
40 ret->pattern = zstr;
41 return ret;
42}
43static inline void sp_regexp_free(sp_regexp *regexp) {
44 if (regexp) {
45 if (regexp->re) { sp_pcre_free(regexp->re); }
46 if (regexp->pattern) { zend_string_release(regexp->pattern); }
47 pefree(regexp, 1);
48 }
49}
50
27 51
28#endif // SP_PCRE_COMPAT_H 52#endif // SP_PCRE_COMPAT_H
diff --git a/src/sp_utils.c b/src/sp_utils.c
index 034aaf4..6161859 100644
--- a/src/sp_utils.c
+++ b/src/sp_utils.c
@@ -253,15 +253,11 @@ const zend_string* sp_zval_to_zend_string(const zval* zv) {
253 } 253 }
254} 254}
255 255
256bool sp_match_value(const zend_string* value, const zend_string* to_match, 256bool sp_match_value(const zend_string* value, const zend_string* to_match, const sp_regexp* rx) {
257 const sp_pcre* rx) {
258 if (to_match) { 257 if (to_match) {
259 return (sp_zend_string_equals(to_match, value)); 258 return (sp_zend_string_equals(to_match, value));
260 } else if (rx) { 259 } else if (rx) {
261 char* tmp = zend_string_to_char(value); 260 return sp_is_regexp_matching_zstr(rx, value);
262 bool ret = sp_is_regexp_matching(rx, tmp);
263 efree(tmp);
264 return ret;
265 } 261 }
266 return true; 262 return true;
267} 263}
@@ -338,8 +334,7 @@ void sp_log_disable_ret(const char* restrict path,
338 efree(char_repr); 334 efree(char_repr);
339} 335}
340 336
341bool sp_match_array_key(const zval* zv, const zend_string* to_match, 337bool sp_match_array_key(const zval* zv, const zend_string* to_match, const sp_regexp* rx) {
342 const sp_pcre* rx) {
343 zend_string* key; 338 zend_string* key;
344 zend_ulong idx; 339 zend_ulong idx;
345 340
@@ -363,8 +358,7 @@ bool sp_match_array_key(const zval* zv, const zend_string* to_match,
363 return false; 358 return false;
364} 359}
365 360
366bool sp_match_array_value(const zval* arr, const zend_string* to_match, 361bool sp_match_array_value(const zval* arr, const zend_string* to_match, const sp_regexp* rx) {
367 const sp_pcre* rx) {
368 zval* value; 362 zval* value;
369 363
370 ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(arr), value) { 364 ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(arr), value) {
@@ -380,8 +374,7 @@ bool sp_match_array_value(const zval* arr, const zend_string* to_match,
380 return false; 374 return false;
381} 375}
382 376
383bool /* success */ _hook_function(const char* original_name, HashTable* hook_table, 377bool /* success */ _hook_function(const char* original_name, HashTable* hook_table, zif_handler new_function) {
384 zif_handler new_function) {
385 zend_function* func; 378 zend_function* func;
386 if ((func = zend_hash_str_find_ptr(CG(function_table), VAR_AND_LEN(original_name)))) { 379 if ((func = zend_hash_str_find_ptr(CG(function_table), VAR_AND_LEN(original_name)))) {
387 if (func->type != ZEND_INTERNAL_FUNCTION) { 380 if (func->type != ZEND_INTERNAL_FUNCTION) {
@@ -393,8 +386,7 @@ bool /* success */ _hook_function(const char* original_name, HashTable* hook_tab
393 if (zend_hash_str_add_new_ptr((hook_table), VAR_AND_LEN(original_name), 386 if (zend_hash_str_add_new_ptr((hook_table), VAR_AND_LEN(original_name),
394 func->internal_function.handler) == NULL) { 387 func->internal_function.handler) == NULL) {
395 // LCOV_EXCL_START 388 // LCOV_EXCL_START
396 sp_log_err("function_pointer_saving", 389 sp_log_err("function_pointer_saving", "Could not save function pointer for %s", original_name);
397 "Could not save function pointer for %s", original_name);
398 return false; 390 return false;
399 // LCOV_EXCL_STOP 391 // LCOV_EXCL_STOP
400 } 392 }
@@ -404,8 +396,7 @@ bool /* success */ _hook_function(const char* original_name, HashTable* hook_tab
404 return false; 396 return false;
405} 397}
406 398
407bool hook_function(const char* original_name, HashTable* hook_table, 399bool hook_function(const char* original_name, HashTable* hook_table, zif_handler new_function) {
408 zif_handler new_function) {
409 bool ret = _hook_function(original_name, hook_table, new_function); 400 bool ret = _hook_function(original_name, hook_table, new_function);
410 401
411#if PHP_VERSION_ID < 80000 402#if PHP_VERSION_ID < 80000
@@ -433,8 +424,7 @@ bool hook_function(const char* original_name, HashTable* hook_table,
433 return ret; 424 return ret;
434} 425}
435 426
436int hook_regexp(const sp_pcre* regexp, HashTable* hook_table, 427int hook_regexp(const sp_pcre* regexp, HashTable* hook_table, zif_handler new_function) {
437 zif_handler new_function) {
438 zend_string* key; 428 zend_string* key;
439 429
440 ZEND_HASH_FOREACH_STR_KEY(CG(function_table), key) 430 ZEND_HASH_FOREACH_STR_KEY(CG(function_table), key)
diff --git a/src/sp_utils.h b/src/sp_utils.h
index 0581363..0e595d8 100644
--- a/src/sp_utils.h
+++ b/src/sp_utils.h
@@ -71,17 +71,14 @@ extern int sp_debug_stderr;
71#define GET_SUFFIX(x) (x == 1) ? "st" : ((x == 2) ? "nd" : "th") 71#define GET_SUFFIX(x) (x == 1) ? "st" : ((x == 2) ? "nd" : "th")
72 72
73const char *get_ipaddr(void); 73const char *get_ipaddr(void);
74void sp_log_msgf(char const *restrict feature, int level, int type, 74void sp_log_msgf(char const *restrict feature, int level, int type, const char *restrict fmt, ...);
75 const char *restrict fmt, ...);
76int compute_hash(const char *const restrict filename, char *restrict file_hash); 75int compute_hash(const char *const restrict filename, char *restrict file_hash);
77const zend_string *sp_zval_to_zend_string(const zval *); 76const zend_string *sp_zval_to_zend_string(const zval *);
78bool sp_match_value(const zend_string *, const zend_string *, const sp_pcre *); 77bool sp_match_value(const zend_string* value, const zend_string* to_match, const sp_regexp* rx);
79bool sp_match_array_key(const zval *, const zend_string *, const sp_pcre *); 78bool sp_match_array_key(const zval *, const zend_string *, const sp_regexp *);
80bool sp_match_array_value(const zval *, const zend_string *, const sp_pcre *); 79bool sp_match_array_value(const zval *, const zend_string *, const sp_regexp *);
81void sp_log_disable(const char *restrict, const char *restrict, 80void sp_log_disable(const char *restrict, const char *restrict, const zend_string *restrict, const sp_disabled_function *);
82 const zend_string *restrict, const sp_disabled_function *); 81void sp_log_disable_ret(const char *restrict, const zend_string *restrict, const sp_disabled_function *);
83void sp_log_disable_ret(const char *restrict, const zend_string *restrict,
84 const sp_disabled_function *);
85bool hook_function(const char *, HashTable *, zif_handler); 82bool hook_function(const char *, HashTable *, zif_handler);
86void unhook_functions(HashTable *ht); 83void unhook_functions(HashTable *ht);
87int hook_regexp(const sp_pcre *, HashTable *, zif_handler); 84int hook_regexp(const sp_pcre *, HashTable *, zif_handler);
diff --git a/src/sp_var_parser.c b/src/sp_var_parser.c
index cc75d83..2639991 100644
--- a/src/sp_var_parser.c
+++ b/src/sp_var_parser.c
@@ -33,8 +33,8 @@ static bool is_var_name_valid(const char *const name) {
33 if (NULL == regexp_var || NULL == regexp_const) { 33 if (NULL == regexp_var || NULL == regexp_const) {
34 return false; // LCOV_EXCL_LINE 34 return false; // LCOV_EXCL_LINE
35 } 35 }
36 if ((false == sp_is_regexp_matching(regexp_var, name)) && 36 if ((false == sp_is_regexp_matching_len(regexp_var, VAR_AND_LEN(name))) &&
37 (false == sp_is_regexp_matching(regexp_const, name))) { 37 (false == sp_is_regexp_matching_len(regexp_const, VAR_AND_LEN(name)))) {
38 return false; 38 return false;
39 } 39 }
40 return true; 40 return true;