diff options
| -rw-r--r-- | src/sp_disabled_functions.c | 59 | ||||
| -rw-r--r-- | src/sp_utils.c | 21 | ||||
| -rw-r--r-- | src/sp_utils.h | 3 | ||||
| -rw-r--r-- | src/tests/config/config_disabled_functions_called_file_r.ini | 1 | ||||
| -rw-r--r-- | src/tests/disabled_functions_called_file_r.phpt | 34 |
5 files changed, 97 insertions, 21 deletions
diff --git a/src/sp_disabled_functions.c b/src/sp_disabled_functions.c index 0e05f4e..eeee007 100644 --- a/src/sp_disabled_functions.c +++ b/src/sp_disabled_functions.c | |||
| @@ -213,12 +213,53 @@ static bool is_param_matching(zend_execute_data* execute_data, | |||
| 213 | return false; | 213 | return false; |
| 214 | } | 214 | } |
| 215 | 215 | ||
| 216 | static zend_execute_data* is_file_matching( | ||
| 217 | zend_execute_data* const execute_data, | ||
| 218 | sp_disabled_function const* const config_node, | ||
| 219 | char const* const current_filename) { | ||
| 220 | #define ITERATE(ex) \ | ||
| 221 | ex = ex->prev_execute_data; \ | ||
| 222 | while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) \ | ||
| 223 | ex = ex->prev_execute_data; \ | ||
| 224 | if (!ex) return NULL; | ||
| 225 | |||
| 226 | zend_execute_data* ex = execute_data; | ||
| 227 | if (config_node->filename) { | ||
| 228 | if (0 == strcmp(current_filename, config_node->filename)) { | ||
| 229 | return ex; | ||
| 230 | } | ||
| 231 | ITERATE(ex); | ||
| 232 | if (0 == | ||
| 233 | strcmp(ZSTR_VAL(ex->func->op_array.filename), config_node->filename)) { | ||
| 234 | return ex; | ||
| 235 | } | ||
| 236 | } else if (config_node->r_filename) { | ||
| 237 | if (true == | ||
| 238 | sp_is_regexp_matching(config_node->r_filename, current_filename)) { | ||
| 239 | return ex; | ||
| 240 | } | ||
| 241 | ITERATE(ex); | ||
| 242 | if (true == sp_is_regexp_matching(config_node->r_filename, | ||
| 243 | ZSTR_VAL(ex->func->op_array.filename))) { | ||
| 244 | return ex; | ||
| 245 | } | ||
| 246 | } | ||
| 247 | return NULL; | ||
| 248 | #undef ITERATE | ||
| 249 | } | ||
| 250 | |||
| 216 | bool should_disable(zend_execute_data* execute_data, const char* builtin_name, | 251 | bool should_disable(zend_execute_data* execute_data, const char* builtin_name, |
| 217 | const char* builtin_param, const char* builtin_param_name) { | 252 | const char* builtin_param, const char* builtin_param_name) { |
| 218 | char current_file_hash[SHA256_SIZE * 2 + 1] = {0}; | 253 | char current_file_hash[SHA256_SIZE * 2 + 1] = {0}; |
| 219 | const sp_list_node* config = get_config_node(builtin_name); | 254 | const sp_list_node* config = get_config_node(builtin_name); |
| 220 | char* complete_path_function = NULL; | 255 | char* complete_path_function = NULL; |
| 221 | const char* current_filename = NULL; | 256 | const char* current_filename = NULL; |
| 257 | unsigned int line = 0; | ||
| 258 | char* filename = NULL; | ||
| 259 | |||
| 260 | if (!execute_data) { | ||
| 261 | return false; | ||
| 262 | } | ||
| 222 | 263 | ||
| 223 | if (!config || !config->data) { | 264 | if (!config || !config->data) { |
| 224 | return false; | 265 | return false; |
| @@ -269,14 +310,14 @@ bool should_disable(zend_execute_data* execute_data, const char* builtin_name, | |||
| 269 | } | 310 | } |
| 270 | } | 311 | } |
| 271 | 312 | ||
| 272 | if (config_node->filename) { /* Check the current file name. */ | 313 | if (config_node->filename || config_node->r_filename) { |
| 273 | if (0 != strcmp(current_filename, config_node->filename)) { | 314 | zend_execute_data* ex = |
| 274 | goto next; | 315 | is_file_matching(execute_data, config_node, current_filename); |
| 275 | } | 316 | if (!ex) { |
| 276 | } else if (config_node->r_filename) { | ||
| 277 | if (false == | ||
| 278 | sp_is_regexp_matching(config_node->r_filename, current_filename)) { | ||
| 279 | goto next; | 317 | goto next; |
| 318 | } else if (ex != execute_data) { | ||
| 319 | line = ex->opline->lineno; | ||
| 320 | filename = ZSTR_VAL(ex->func->op_array.filename); | ||
| 280 | } | 321 | } |
| 281 | } | 322 | } |
| 282 | 323 | ||
| @@ -327,10 +368,10 @@ bool should_disable(zend_execute_data* execute_data, const char* builtin_name, | |||
| 327 | 368 | ||
| 328 | if (config_node->functions_list) { | 369 | if (config_node->functions_list) { |
| 329 | sp_log_disable(config_node->function, arg_name, arg_value_str, | 370 | sp_log_disable(config_node->function, arg_name, arg_value_str, |
| 330 | config_node); | 371 | config_node, line, filename); |
| 331 | } else { | 372 | } else { |
| 332 | sp_log_disable(complete_path_function, arg_name, arg_value_str, | 373 | sp_log_disable(complete_path_function, arg_name, arg_value_str, |
| 333 | config_node); | 374 | config_node, line, filename); |
| 334 | } | 375 | } |
| 335 | if (true == config_node->simulation) { | 376 | if (true == config_node->simulation) { |
| 336 | goto next; | 377 | goto next; |
diff --git a/src/sp_utils.c b/src/sp_utils.c index 54a8e1b..5f34ccc 100644 --- a/src/sp_utils.c +++ b/src/sp_utils.c | |||
| @@ -189,39 +189,38 @@ bool sp_match_value(const char* value, const char* to_match, | |||
| 189 | 189 | ||
| 190 | void sp_log_disable(const char* restrict path, const char* restrict arg_name, | 190 | void sp_log_disable(const char* restrict path, const char* restrict arg_name, |
| 191 | const char* restrict arg_value, | 191 | const char* restrict arg_value, |
| 192 | const sp_disabled_function* config_node) { | 192 | const sp_disabled_function* config_node, unsigned int line, |
| 193 | const char* restrict filename) { | ||
| 193 | const char* dump = config_node->dump; | 194 | const char* dump = config_node->dump; |
| 194 | const char* alias = config_node->alias; | 195 | const char* alias = config_node->alias; |
| 195 | const int sim = config_node->simulation; | 196 | const int sim = config_node->simulation; |
| 197 | |||
| 198 | filename = filename ? filename : zend_get_executed_filename(TSRMLS_C); | ||
| 199 | line = line ? line : zend_get_executed_lineno(TSRMLS_C); | ||
| 200 | |||
| 196 | if (arg_name) { | 201 | if (arg_name) { |
| 197 | if (alias) { | 202 | if (alias) { |
| 198 | sp_log_msg( | 203 | sp_log_msg( |
| 199 | "disabled_function", sim ? SP_LOG_SIMULATION : SP_LOG_DROP, | 204 | "disabled_function", sim ? SP_LOG_SIMULATION : SP_LOG_DROP, |
| 200 | "The call to the function '%s' in %s:%d has been disabled, " | 205 | "The call to the function '%s' in %s:%d has been disabled, " |
| 201 | "because its argument '%s' content (%s) matched the rule '%s'.", | 206 | "because its argument '%s' content (%s) matched the rule '%s'.", |
| 202 | path, zend_get_executed_filename(TSRMLS_C), | 207 | path, filename, line, arg_name, arg_value ? arg_value : "?", alias); |
| 203 | zend_get_executed_lineno(TSRMLS_C), arg_name, | ||
| 204 | arg_value ? arg_value : "?", alias); | ||
| 205 | } else { | 208 | } else { |
| 206 | sp_log_msg("disabled_function", sim ? SP_LOG_SIMULATION : SP_LOG_DROP, | 209 | sp_log_msg("disabled_function", sim ? SP_LOG_SIMULATION : SP_LOG_DROP, |
| 207 | "The call to the function '%s' in %s:%d has been disabled, " | 210 | "The call to the function '%s' in %s:%d has been disabled, " |
| 208 | "because its argument '%s' content (%s) matched a rule.", | 211 | "because its argument '%s' content (%s) matched a rule.", |
| 209 | path, zend_get_executed_filename(TSRMLS_C), | 212 | path, filename, line, arg_name, arg_value ? arg_value : "?"); |
| 210 | zend_get_executed_lineno(TSRMLS_C), arg_name, | ||
| 211 | arg_value ? arg_value : "?"); | ||
| 212 | } | 213 | } |
| 213 | } else { | 214 | } else { |
| 214 | if (alias) { | 215 | if (alias) { |
| 215 | sp_log_msg("disabled_function", sim ? SP_LOG_SIMULATION : SP_LOG_DROP, | 216 | sp_log_msg("disabled_function", sim ? SP_LOG_SIMULATION : SP_LOG_DROP, |
| 216 | "The call to the function '%s' in %s:%d has been disabled, " | 217 | "The call to the function '%s' in %s:%d has been disabled, " |
| 217 | "because of the the rule '%s'.", | 218 | "because of the the rule '%s'.", |
| 218 | path, zend_get_executed_filename(TSRMLS_C), | 219 | path, filename, line, alias); |
| 219 | zend_get_executed_lineno(TSRMLS_C), alias); | ||
| 220 | } else { | 220 | } else { |
| 221 | sp_log_msg("disabled_function", sim ? SP_LOG_SIMULATION : SP_LOG_DROP, | 221 | sp_log_msg("disabled_function", sim ? SP_LOG_SIMULATION : SP_LOG_DROP, |
| 222 | "The call to the function '%s' in %s:%d has been disabled.", | 222 | "The call to the function '%s' in %s:%d has been disabled.", |
| 223 | path, zend_get_executed_filename(TSRMLS_C), | 223 | path, filename, line); |
| 224 | zend_get_executed_lineno(TSRMLS_C)); | ||
| 225 | } | 224 | } |
| 226 | } | 225 | } |
| 227 | if (dump) { | 226 | if (dump) { |
diff --git a/src/sp_utils.h b/src/sp_utils.h index b92f16d..61a23f9 100644 --- a/src/sp_utils.h +++ b/src/sp_utils.h | |||
| @@ -49,7 +49,8 @@ bool sp_match_value(const char *, const char *, const sp_pcre *); | |||
| 49 | bool sp_match_array_key(const zval *, const char *, const sp_pcre *); | 49 | bool sp_match_array_key(const zval *, const char *, const sp_pcre *); |
| 50 | bool sp_match_array_value(const zval *, const char *, const sp_pcre *); | 50 | bool sp_match_array_value(const zval *, const char *, const sp_pcre *); |
| 51 | void sp_log_disable(const char *restrict, const char *restrict, | 51 | void sp_log_disable(const char *restrict, const char *restrict, |
| 52 | const char *restrict, const sp_disabled_function *); | 52 | const char *restrict, const sp_disabled_function *, |
| 53 | unsigned int, const char*restrict); | ||
| 53 | void sp_log_disable_ret(const char *restrict, const char *restrict, | 54 | void sp_log_disable_ret(const char *restrict, const char *restrict, |
| 54 | const sp_disabled_function *); | 55 | const sp_disabled_function *); |
| 55 | int hook_function(const char *, HashTable *, | 56 | int hook_function(const char *, HashTable *, |
diff --git a/src/tests/config/config_disabled_functions_called_file_r.ini b/src/tests/config/config_disabled_functions_called_file_r.ini new file mode 100644 index 0000000..17b019a --- /dev/null +++ b/src/tests/config/config_disabled_functions_called_file_r.ini | |||
| @@ -0,0 +1 @@ | |||
| sp.disable_function.function_r("test").filename_r("file_r\\.php$").drop(); \ No newline at end of file | |||
diff --git a/src/tests/disabled_functions_called_file_r.phpt b/src/tests/disabled_functions_called_file_r.phpt new file mode 100644 index 0000000..45e57a9 --- /dev/null +++ b/src/tests/disabled_functions_called_file_r.phpt | |||
| @@ -0,0 +1,34 @@ | |||
| 1 | --TEST-- | ||
| 2 | Disable functions by matching on the filename_r where the function is called, and not defined | ||
| 3 | --SKIPIF-- | ||
| 4 | <?php if (!extension_loaded("snuffleupagus")) die "skip"; ?> | ||
| 5 | --INI-- | ||
| 6 | sp.configuration_file={PWD}/config/config_disabled_functions_called_file_r.ini | ||
| 7 | --FILE-- | ||
| 8 | <?php | ||
| 9 | $dir = __DIR__; | ||
| 10 | |||
| 11 | @unlink("$dir/myfunc.php"); | ||
| 12 | |||
| 13 | $mycode = <<< EOD | ||
| 14 | <?php | ||
| 15 | function test() { | ||
| 16 | echo "TOTO"; | ||
| 17 | } | ||
| 18 | ?> | ||
| 19 | EOD; | ||
| 20 | |||
| 21 | file_put_contents("$dir/myfunc.php", $mycode); | ||
| 22 | |||
| 23 | include "$dir/myfunc.php"; | ||
| 24 | |||
| 25 | test(); | ||
| 26 | |||
| 27 | ?> | ||
| 28 | --EXPECTF-- | ||
| 29 | [snuffleupagus][0.0.0.0][disabled_function][drop] The call to the function 'test' in %a/disabled_functions_called_file_r.php:18 has been disabled. | ||
| 30 | --CLEAN-- | ||
| 31 | <?php | ||
| 32 | $dir = __DIR__; | ||
| 33 | @unlink("$dir/myfunc.php"); | ||
| 34 | ?> | ||
