Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 46 additions & 3 deletions apache2/re.c
Original file line number Diff line number Diff line change
Expand Up @@ -986,12 +986,53 @@
return action;
}

/**
* Helper function for action_exists. It checks if "name=value" is present in table for supplied action.
*/
static int apr_table_action_exists(apr_pool_t* p, const apr_table_t* vartable, const char* action, const char* name, const char* value) {
if (strcmp(name, action) != 0) return 0;

const char* vars = apr_table_getm(p, vartable, name);
if (!vars) return 0;

char pattern[200];
apr_snprintf(pattern, sizeof(pattern), "(?:^|,)%.185s(?:,|$)", value);

char* error_msg = NULL;
msc_regex_t* regex = msc_pregcomp(p, pattern, 0, NULL, NULL);
if (regex == NULL) return 0;

return (msc_regexec(regex, vars, strlen(vars), &error_msg) >= 0);
}

/**
* Checks if "name=value" is present in table for tags, logdata (and others).
*/
static int action_exists(apr_pool_t* p, const apr_table_t* vartable, const char* name, const char* value) {
/* logdata & msg cannot be used because ',' is used as entries separators */
if (apr_table_action_exists(p, vartable, "capture", name, value)) return 1;
if (apr_table_action_exists(p, vartable, "chain", name, value)) return 1;
if (apr_table_action_exists(p, vartable, "initcol", name, value)) return 1;
if (apr_table_action_exists(p, vartable, "multiMatch", name, value)) return 1;
if (apr_table_action_exists(p, vartable, "phase", name, value)) return 1;
if (apr_table_action_exists(p, vartable, "sanitizeArg", name, value)) return 1;
if (apr_table_action_exists(p, vartable, "sanitizeMatched", name, value)) return 1;
if (apr_table_action_exists(p, vartable, "sanitizeMatchedBytes", name, value)) return 1;
if (apr_table_action_exists(p, vartable, "sanitizeRequestHeader", name, value)) return 1;
if (apr_table_action_exists(p, vartable, "sanitizeResponseHeader", name, value)) return 1;
if (apr_table_action_exists(p, vartable, "setrsc", name, value)) return 1;
if (apr_table_action_exists(p, vartable, "setsid", name, value)) return 1;
if (apr_table_action_exists(p, vartable, "setuid", name, value)) return 1;
if (apr_table_action_exists(p, vartable, "tag", name, value)) return 1;
return 0;
}

/**
* Generic parser that is used as basis for target and action parsing.
* It breaks up the input string into name-parameter pairs and places
* them into the given table.
*/
int msre_parse_generic(apr_pool_t *mp, const char *text, apr_table_t *vartable,

Check failure on line 1035 in apache2/re.c

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this function to reduce its Cognitive Complexity from 58 to the 25 allowed.

See more on https://sonarcloud.io/project/issues?id=owasp-modsecurity_ModSecurity&issues=AZ0Bnmhv7o15W-M7xHZi&open=AZ0Bnmhv7o15W-M7xHZi&pullRequest=3518
char **error_msg)
{
char *p = (char *)text;
Expand Down Expand Up @@ -1103,9 +1144,11 @@
value = apr_pstrmemdup(mp, value, p - value);
}

/* add to table */
apr_table_addn(vartable, name, value);
count++;
/* add to table (only if not already present) */
if (!action_exists(mp, vartable, name, value)) {
apr_table_addn(vartable, name, value);
count++;
}

/* move to the first character of the next name-value pair */
while(isspace(*p)||(*p == ',')||(*p == '|')) p++;
Expand Down