diff --git a/src/bus/match.c b/src/bus/match.c index abf7c66b..dfa8832d 100644 --- a/src/bus/match.c +++ b/src/bus/match.c @@ -422,12 +422,12 @@ static bool match_keys_match_metadata(MatchKeys *keys, MessageMetadata *metadata return false; for (unsigned int i = 0; i < keys->filter.n_args || i < keys->filter.n_argpaths; i ++) { - if (keys->filter.args[i] && !(metadata->args[0].element == 's' && string_equal(keys->filter.args[i], metadata->args[i].value))) + if (keys->filter.args[i] && !(metadata->args[i].element == 's' && string_equal(keys->filter.args[i], metadata->args[i].value))) return false; if (keys->filter.argpaths[i]) { if (!match_string_prefix(metadata->args[i].value, keys->filter.argpaths[i], '/', true) && - !match_string_prefix(keys->filter.argpaths[i], metadata->args[0].value, '/', true)) + !match_string_prefix(keys->filter.argpaths[i], metadata->args[i].value, '/', true)) return false; } } diff --git a/src/bus/test-match.c b/src/bus/test-match.c index 349c460c..ec0e0388 100644 --- a/src/bus/test-match.c +++ b/src/bus/test-match.c @@ -254,6 +254,33 @@ static void test_individual_matches(void) { c_assert(!test_match("arg0=com.example.foobar", &metadata)); c_assert(!test_match("arg0=com.example", &metadata)); + /* arg1 */ + metadata = (MessageMetadata)MESSAGE_METADATA_INIT; + c_assert(!test_match("arg1=/com/example/foo/", &metadata)); + metadata.args[0].value = "unrelated string"; + metadata.args[0].element = 's'; + metadata.args[1].value = "/com/example/foo/"; + metadata.args[1].element = 's'; + metadata.n_args = 2; + c_assert(test_match("arg1=/com/example/foo/", &metadata)); + c_assert(!test_match("arg1=/com/example/foo/bar", &metadata)); + c_assert(!test_match("arg1=/com/example/foobar", &metadata)); + c_assert(!test_match("arg1=/com/example/", &metadata)); + c_assert(!test_match("arg1=/com/example", &metadata)); + metadata.args[1].value = "/com/example/foo"; + metadata.args[1].element = 's'; + c_assert(test_match("arg1=/com/example/foo", &metadata)); + c_assert(!test_match("arg1=/com/example/foo/bar", &metadata)); + c_assert(!test_match("arg1=/com/example/foobar", &metadata)); + c_assert(!test_match("arg1=/com/example/", &metadata)); + c_assert(!test_match("arg1=/com/example", &metadata)); + metadata.args[1].value = "com.example.foo"; + metadata.args[1].element = 's'; + c_assert(test_match("arg1=com.example.foo", &metadata)); + c_assert(!test_match("arg1=com.example.foo.bar", &metadata)); + c_assert(!test_match("arg1=com.example.foobar", &metadata)); + c_assert(!test_match("arg1=com.example", &metadata)); + /* arg0path - parent */ metadata = (MessageMetadata)MESSAGE_METADATA_INIT; c_assert(!test_match("arg0path=/com/example/foo/", &metadata)); @@ -278,6 +305,34 @@ static void test_individual_matches(void) { c_assert(test_match("arg0path=/com/example/", &metadata)); c_assert(!test_match("arg0path=/com/example", &metadata)); + /* arg1path - parent */ + metadata = (MessageMetadata)MESSAGE_METADATA_INIT; + c_assert(!test_match("arg1path=/com/example/foo/", &metadata)); + metadata.args[0].value = "unrelated string"; + metadata.args[0].element = 's'; + metadata.args[1].value = "/com/example/foo/"; + metadata.args[1].element = 'o'; + metadata.n_args = 2; + c_assert(test_match("arg1path=/com/example/foo/", &metadata)); + c_assert(test_match("arg1path=/com/example/foo/bar", &metadata)); + c_assert(!test_match("arg1path=/com/example/foobar", &metadata)); + c_assert(test_match("arg1path=/com/example/", &metadata)); + c_assert(!test_match("arg1path=/com/example", &metadata)); + + /* arg1path - child */ + metadata = (MessageMetadata)MESSAGE_METADATA_INIT; + c_assert(!test_match("arg1path=/com/example/foo", &metadata)); + metadata.args[0].value = "unrelated string"; + metadata.args[0].element = 's'; + metadata.args[1].value = "/com/example/foo"; + metadata.args[1].element = 'o'; + metadata.n_args = 2; + c_assert(test_match("arg1path=/com/example/foo", &metadata)); + c_assert(!test_match("arg1path=/com/example/foo/bar", &metadata)); + c_assert(!test_match("arg1path=/com/example/foobar", &metadata)); + c_assert(test_match("arg1path=/com/example/", &metadata)); + c_assert(!test_match("arg1path=/com/example", &metadata)); + /* arg0namespace */ metadata = (MessageMetadata)MESSAGE_METADATA_INIT; c_assert(!test_match("arg0namespace=com.example.foo", &metadata)); diff --git a/test/dbus/test-matches.c b/test/dbus/test-matches.c index 090222cb..9c46a643 100644 --- a/test/dbus/test-matches.c +++ b/test/dbus/test-matches.c @@ -258,6 +258,154 @@ static void test_noc_driver(void) { util_broker_terminate(broker); } +static void test_arg(void) { + _c_cleanup_(util_broker_freep) Broker *broker = NULL; + _c_cleanup_(sd_bus_flush_close_unrefp) sd_bus *sender = NULL; + _c_cleanup_(sd_bus_flush_close_unrefp) sd_bus *receiver = NULL; + int r; + + util_broker_new(&broker); + util_broker_spawn(broker); + + util_broker_connect(broker, &sender); + util_broker_connect(broker, &receiver); + + r = sd_bus_call_method(receiver, "org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", + "AddMatch", NULL, NULL, + "s", "arg3='done'"); + c_assert(r >= 0); + + /* does not match: not a string */ + r = sd_bus_emit_signal(sender, "/org/example", "org.example", "DoesNotMatch", "iiii", 0, 0, 0, 0); + c_assert(r >= 0); + + /* does not match: wrong value */ + r = sd_bus_emit_signal(sender, "/org/example", "org.example", "DoesNotMatch", "iiis", 0, 0, 0, "failed"); + c_assert(r >= 0); + + /* does not match: correct value in the wrong arguments */ + r = sd_bus_emit_signal(sender, "/org/example", "org.example", "DoesNotMatch", "sssss", + "done", "done", "done", "failed", "done"); + c_assert(r >= 0); + + r = sd_bus_emit_signal(sender, "/org/example", "org.example", "Matches", "iiis", 0, 0, 0, "done"); + c_assert(r >= 0); + + util_broker_consume_signal(receiver, "org.example", "Matches"); + + util_broker_terminate(broker); +} + +static void test_args(void) { + _c_cleanup_(util_broker_freep) Broker *broker = NULL; + _c_cleanup_(sd_bus_flush_close_unrefp) sd_bus *sender = NULL; + _c_cleanup_(sd_bus_flush_close_unrefp) sd_bus *receiver = NULL; + int r; + + util_broker_new(&broker); + util_broker_spawn(broker); + + util_broker_connect(broker, &sender); + util_broker_connect(broker, &receiver); + + r = sd_bus_call_method(receiver, "org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", + "AddMatch", NULL, NULL, + "s", "arg0='zero',arg1='one'"); + c_assert(r >= 0); + + /* does not match: too few arguments */ + r = sd_bus_emit_signal(sender, "/org/example", "org.example", "DoesNotMatch", "s", "zero"); + c_assert(r >= 0); + + /* does not match: one arg not a string */ + r = sd_bus_emit_signal(sender, "/org/example", "org.example", "DoesNotMatch", "si", "zero", 0); + c_assert(r >= 0); + r = sd_bus_emit_signal(sender, "/org/example", "org.example", "DoesNotMatch", "is", 0, "one"); + c_assert(r >= 0); + + /* does not match: incorrect value for one argument */ + r = sd_bus_emit_signal(sender, "/org/example", "org.example", "DoesNotMatch", "ss", "zero", "wrong"); + c_assert(r >= 0); + r = sd_bus_emit_signal(sender, "/org/example", "org.example", "DoesNotMatch", "ss", "wrong", "one"); + c_assert(r >= 0); + + /* does not match: correct values in the wrong arguments */ + r = sd_bus_emit_signal(sender, "/org/example", "org.example", "DoesNotMatch", "ss", "one", "zero"); + c_assert(r >= 0); + + r = sd_bus_emit_signal(sender, "/org/example", "org.example", "Matches", "ss", "zero", "one"); + c_assert(r >= 0); + + util_broker_consume_signal(receiver, "org.example", "Matches"); + + util_broker_terminate(broker); +} + +static void test_argpath(void) { + _c_cleanup_(util_broker_freep) Broker *broker = NULL; + _c_cleanup_(sd_bus_flush_close_unrefp) sd_bus *sender = NULL; + _c_cleanup_(sd_bus_flush_close_unrefp) sd_bus *receiver = NULL; + int r; + + util_broker_new(&broker); + util_broker_spawn(broker); + + util_broker_connect(broker, &sender); + util_broker_connect(broker, &receiver); + + /* example match rule, matches and nonmatches from D-Bus specification */ + r = sd_bus_call_method(receiver, "org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", + "AddMatch", NULL, NULL, + "s", "arg1path='/aa/bb/'"); + c_assert(r >= 0); + + /* does not match: arg not a string or object path */ + r = sd_bus_emit_signal(sender, "/org/example", "org.example", "DoesNotMatch", "si", "foo", 0); + c_assert(r >= 0); + + /* does not match: incorrect value */ + r = sd_bus_emit_signal(sender, "/org/example", "org.example", "DoesNotMatch", "ss", "foo", "/aa/b"); + c_assert(r >= 0); + r = sd_bus_emit_signal(sender, "/org/example", "org.example", "DoesNotMatch", "ss", "foo", "/aa"); + c_assert(r >= 0); + r = sd_bus_emit_signal(sender, "/org/example", "org.example", "DoesNotMatch", "ss", "foo", "/aa/bb"); + c_assert(r >= 0); + + /* does not match: correct value in the wrong argument */ + r = sd_bus_emit_signal(sender, "/org/example", "org.example", "DoesNotMatch", "ss", "/aa/bb/", "foo"); + c_assert(r >= 0); + + r = sd_bus_emit_signal(sender, "/org/example", "org.example", "Matches", "ss", "foo", "/"); + c_assert(r >= 0); + util_broker_consume_signal(receiver, "org.example", "Matches"); + + r = sd_bus_emit_signal(sender, "/org/example", "org.example", "Matches", "ss", "foo", "/aa/"); + c_assert(r >= 0); + util_broker_consume_signal(receiver, "org.example", "Matches"); + + r = sd_bus_emit_signal(sender, "/org/example", "org.example", "Matches", "ss", "foo", "/aa/bb/"); + c_assert(r >= 0); + util_broker_consume_signal(receiver, "org.example", "Matches"); + + r = sd_bus_emit_signal(sender, "/org/example", "org.example", "Matches", "ss", "foo", "/aa/bb/cc/"); + c_assert(r >= 0); + util_broker_consume_signal(receiver, "org.example", "Matches"); + + r = sd_bus_emit_signal(sender, "/org/example", "org.example", "Matches", "ss", "foo", "/aa/bb/cc"); + c_assert(r >= 0); + util_broker_consume_signal(receiver, "org.example", "Matches"); + + r = sd_bus_emit_signal(sender, "/org/example", "org.example", "Matches", "so", "foo", "/"); + c_assert(r >= 0); + util_broker_consume_signal(receiver, "org.example", "Matches"); + + r = sd_bus_emit_signal(sender, "/org/example", "org.example", "Matches", "so", "foo", "/aa/bb/cc"); + c_assert(r >= 0); + util_broker_consume_signal(receiver, "org.example", "Matches"); + + util_broker_terminate(broker); +} + int main(int argc, char **argv) { test_wildcard(); test_unique_name(); @@ -267,4 +415,7 @@ int main(int argc, char **argv) { test_noc_unique(); test_noc_well_known(); test_noc_driver(); + test_arg(); + test_args(); + test_argpath(); }