diff options
author | Dmitry V. Levin <ldv@strace.io> | 2023-03-20 09:00:00 +0100 |
---|---|---|
committer | Yu Watanabe <watanabe.yu+github@gmail.com> | 2023-03-21 01:34:50 +0100 |
commit | f0a16c9ae8cc9fd7719e58cc3b858ced64bd67da (patch) | |
tree | 661d37eb1ca60f461a58776e02b99d86b6e1c863 /src/udev/udev-rules.c | |
parent | compare-operator: added unit tests (diff) | |
download | systemd-f0a16c9ae8cc9fd7719e58cc3b858ced64bd67da.tar.xz systemd-f0a16c9ae8cc9fd7719e58cc3b858ced64bd67da.zip |
udev-rules: add another check for conflicting expressions
Log an error when a rule line contains the following kind of conflicting
match expressions:
KEY=="foo", KEY=="bar"
Diffstat (limited to 'src/udev/udev-rules.c')
-rw-r--r-- | src/udev/udev-rules.c | 42 |
1 files changed, 37 insertions, 5 deletions
diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c index f708f79c9a..4859a142da 100644 --- a/src/udev/udev-rules.c +++ b/src/udev/udev-rules.c @@ -1409,6 +1409,28 @@ static bool tokens_eq(const UdevRuleToken *a, const UdevRuleToken *b) { token_type_and_data_eq(a, b); } +static bool nulstr_tokens_conflict(const UdevRuleToken *a, const UdevRuleToken *b) { + assert(a); + assert(b); + + if (!(a->type == b->type && + type_has_nulstr_value(a->type) && + a->op == b->op && + a->op == OP_MATCH && + a->match_type == b->match_type && + a->match_type == MATCH_TYPE_PLAIN && + a->attr_subst_type == b->attr_subst_type && + a->attr_match_remove_trailing_whitespace == b->attr_match_remove_trailing_whitespace && + token_type_and_data_eq(a, b))) + return false; + + NULSTR_FOREACH(i, a->value) + if (nulstr_contains(b->value, i)) + return false; + + return true; +} + static void udev_check_unused_labels(UdevRuleLine *line) { assert(line); @@ -1424,14 +1446,24 @@ static void udev_check_conflicts_duplicates(UdevRuleLine *line) { LIST_FOREACH(tokens, token, line->tokens) LIST_FOREACH(tokens, i, token->tokens_next) { - if (!tokens_eq(token, i)) + bool new_conflicts = false, new_duplicates = false; + + if (tokens_eq(token, i)) { + if (!duplicates && token->op == i->op) + new_duplicates = true; + if (!conflicts && conflicting_op(token->op, i->op)) + new_conflicts = true; + } else if (!conflicts && nulstr_tokens_conflict(token, i)) + new_conflicts = true; + else continue; - if (!duplicates && token->op == i->op) { - duplicates = true; + + if (new_duplicates) { + duplicates = new_duplicates; log_line_warning(line, "duplicate expressions"); } - if (!conflicts && conflicting_op(token->op, i->op)) { - conflicts = true; + if (new_conflicts) { + conflicts = new_conflicts; log_line_error(line, "conflicting match expressions, the line takes no effect"); } if (conflicts && duplicates) |