From a8ab6484c1cf08bb5669b2f46f933845cc81f077 Mon Sep 17 00:00:00 2001 From: jvoisin Date: Mon, 23 Oct 2017 22:47:46 +0200 Subject: [PATCH] Implement the .line filter Close #48 --- doc/source/config.rst | 1 + src/sp_config.h | 2 ++ src/sp_config_keywords.c | 13 +++++++++++++ src/sp_disabled_functions.c | 6 ++++++ .../config/disabled_functions_broken_line.ini | 1 + src/tests/config/disabled_functions_line.ini | 1 + .../disabled_functions_param_broken_line.phpt | 15 +++++++++++++++ src/tests/disabled_functions_param_line.phpt | 14 ++++++++++++++ 8 files changed, 53 insertions(+) create mode 100644 src/tests/config/disabled_functions_broken_line.ini create mode 100644 src/tests/config/disabled_functions_line.ini create mode 100644 src/tests/disabled_functions_param_broken_line.phpt create mode 100644 src/tests/disabled_functions_param_line.phpt diff --git a/doc/source/config.rst b/doc/source/config.rst index 3f0115b..ad031fd 100644 --- a/doc/source/config.rst +++ b/doc/source/config.rst @@ -237,6 +237,7 @@ Filters - ``function(name)``: match on function ``name`` - ``function_r(regexp)``: the function matching the ``regexp`` - ``hash(sha256)``: match on the file's `sha256 `_ sum +- ``line(line_number)``: match on the file's line. - ``param(name)``: match on the function's parameter ``name`` - ``param_r(regexp)``: match on the function's parameter ``regexp`` - ``param_type(type)``: match on the function's parameter ``type`` diff --git a/src/sp_config.h b/src/sp_config.h index c005206..c6de8ba 100644 --- a/src/sp_config.h +++ b/src/sp_config.h @@ -78,6 +78,7 @@ typedef struct { pcre *r_param; sp_php_type param_type; int pos; + unsigned int line; char *ret; pcre *r_ret; @@ -185,6 +186,7 @@ typedef struct { #define SP_TOKEN_VALUE ".value(" #define SP_TOKEN_VALUE_REGEXP ".value_r(" #define SP_TOKEN_VALUE_ARG_POS ".pos(" +#define SP_TOKEN_LINE_NUMBER ".line(" // cookies encryption #define SP_TOKEN_NAME ".cookie(" diff --git a/src/sp_config_keywords.c b/src/sp_config_keywords.c index 097d08b..168ee1c 100644 --- a/src/sp_config_keywords.c +++ b/src/sp_config_keywords.c @@ -145,6 +145,7 @@ int parse_disabled_functions(char *line) { int ret = 0; bool enable = true, disable = false; char *pos = NULL; + char *line_number = NULL; sp_disabled_function *df = pecalloc(sizeof(*df), 1, 1); df->pos = -1; @@ -172,6 +173,7 @@ int parse_disabled_functions(char *line) { {parse_php_type, SP_TOKEN_RET_TYPE, &(df->ret_type)}, {parse_str, SP_TOKEN_LOCAL_VAR, &(df->var)}, {parse_str, SP_TOKEN_VALUE_ARG_POS, &(pos)}, + {parse_str, SP_TOKEN_LINE_NUMBER, &(line_number)}, {0}}; ret = parse_keywords(sp_config_funcs_disabled_functions, line); @@ -252,6 +254,17 @@ int parse_disabled_functions(char *line) { } } + if (line_number) { + errno = 0; + char *endptr; + df->line = strtoul(line_number, &endptr, 10); + if (errno != 0 || endptr == line_number) { + sp_log_err("config", "Failed to parse arg '%s' of `line` on line %zu.", + line_number, sp_line_no); + return -1; + } + } + if (df->function) { df->functions_list = parse_functions_list(df->function); } diff --git a/src/sp_disabled_functions.c b/src/sp_disabled_functions.c index 54a1906..f089c25 100644 --- a/src/sp_disabled_functions.c +++ b/src/sp_disabled_functions.c @@ -172,6 +172,12 @@ bool should_disable(zend_execute_data* execute_data) { } } + if (config_node->line) { + if (config_node->line != zend_get_executed_lineno()) { + goto next; + } + } + if (client_ip && config_node->cidr && (false == cidr_match(client_ip, config_node->cidr))) { goto next; diff --git a/src/tests/config/disabled_functions_broken_line.ini b/src/tests/config/disabled_functions_broken_line.ini new file mode 100644 index 0000000..01229c5 --- /dev/null +++ b/src/tests/config/disabled_functions_broken_line.ini @@ -0,0 +1 @@ +sp.disable_function.function("system").line("qwe").drop(); diff --git a/src/tests/config/disabled_functions_line.ini b/src/tests/config/disabled_functions_line.ini new file mode 100644 index 0000000..b00cab6 --- /dev/null +++ b/src/tests/config/disabled_functions_line.ini @@ -0,0 +1 @@ +sp.disable_function.function("system").line("3").drop(); diff --git a/src/tests/disabled_functions_param_broken_line.phpt b/src/tests/disabled_functions_param_broken_line.phpt new file mode 100644 index 0000000..cca001f --- /dev/null +++ b/src/tests/disabled_functions_param_broken_line.phpt @@ -0,0 +1,15 @@ +--TEST-- +Disable functions - match on a specific line - broken configuration +--SKIPIF-- + +--INI-- +sp.configuration_file={PWD}/config/disabled_functions_broken_line.ini +--FILE-- + +--EXPECTF-- +[snuffleupagus][0.0.0.0][config][error] Failed to parse arg 'qwe' of `line` on line 1. +1337 +1338 diff --git a/src/tests/disabled_functions_param_line.phpt b/src/tests/disabled_functions_param_line.phpt new file mode 100644 index 0000000..cf7495f --- /dev/null +++ b/src/tests/disabled_functions_param_line.phpt @@ -0,0 +1,14 @@ +--TEST-- +Disable functions - match on a specific line +--SKIPIF-- + +--INI-- +sp.configuration_file={PWD}/config/disabled_functions_line.ini +--FILE-- + +--EXPECTF-- +1337 +[snuffleupagus][0.0.0.0][disabled_function][drop] The call to the function 'system' in %a/disabled_functions_param_line.php:3 has been disabled.