Detect redefined rules

If a rule is defined more than once, an error is logged and the parsing
fails.
This commit is contained in:
Markus Mäkelä
2017-01-16 10:04:45 +02:00
parent c13a2eeb33
commit 08b5d5c957

View File

@ -966,6 +966,27 @@ void dbfw_yyerror(void* scanner, const char* error)
error, dbfw_yyget_text(scanner)); error, dbfw_yyget_text(scanner));
} }
/**
* @brief Find a rule by name
*
* @param rules List of all rules
* @param name Name of the rule
* @return Pointer to the rule or NULL if rule was not found
*/
static RULE* find_rule_by_name(RULE* rules, const char* name)
{
while (rules)
{
if (strcmp(rules->name, name) == 0)
{
return rules;
}
rules = rules->next;
}
return NULL;
}
/** /**
* Create a new rule * Create a new rule
* *
@ -976,25 +997,33 @@ void dbfw_yyerror(void* scanner, const char* error)
*/ */
bool create_rule(void* scanner, const char* name) bool create_rule(void* scanner, const char* name)
{ {
bool rval = true; bool rval = false;
struct parser_stack* rstack = dbfw_yyget_extra((yyscan_t)scanner);
ss_dassert(rstack);
if (find_rule_by_name(rstack->rule, name) == NULL)
{
RULE *ruledef = MXS_MALLOC(sizeof(RULE)); RULE *ruledef = MXS_MALLOC(sizeof(RULE));
if (ruledef && (ruledef->name = MXS_STRDUP(name))) if (ruledef && (ruledef->name = MXS_STRDUP(name)))
{ {
ruledef->type = RT_UNDEFINED; ruledef->type = RT_UNDEFINED;
ruledef->on_queries = QUERY_OP_UNDEFINED; ruledef->on_queries = QUERY_OP_UNDEFINED;
struct parser_stack* rstack = dbfw_yyget_extra((yyscan_t) scanner);
ss_dassert(rstack);
ruledef->next = rstack->rule; ruledef->next = rstack->rule;
ruledef->active = NULL; ruledef->active = NULL;
ruledef->times_matched = 0; ruledef->times_matched = 0;
ruledef->data = NULL; ruledef->data = NULL;
rstack->rule = ruledef; rstack->rule = ruledef;
rval = true;
} }
else else
{ {
MXS_FREE(ruledef); MXS_FREE(ruledef);
rval = false; }
}
else
{
MXS_ERROR("Redefinition of rule '%s' on line %d.", name, dbfw_yyget_lineno(scanner));
} }
return rval; return rval;
@ -1310,27 +1339,6 @@ bool define_regex_rule(void* scanner, char* pattern)
return re != NULL; return re != NULL;
} }
/**
* @brief Find a rule by name
*
* @param rules List of all rules
* @param name Name of the rule
* @return Pointer to the rule or NULL if rule was not found
*/
static RULE* find_rule_by_name(RULE* rules, const char* name)
{
while (rules)
{
if (strcmp(rules->name, name) == 0)
{
return rules;
}
rules = rules->next;
}
return NULL;
}
/** /**
* @brief Process the user templates into actual user definitions * @brief Process the user templates into actual user definitions
* *