Skip to content

Commit

Permalink
bus/match: fix matching against arguments beyond the zeroth
Browse files Browse the repository at this point in the history
Reported-by: Tomas Korbar <[email protected]>
Signed-off-by: Jeffrey Bosboom <[email protected]>
Signed-off-by: David Rheinsberg <[email protected]>
  • Loading branch information
jbosboom authored and dvdhrm committed Jul 30, 2024
1 parent c1055ee commit 2d0940c
Show file tree
Hide file tree
Showing 3 changed files with 208 additions and 2 deletions.
4 changes: 2 additions & 2 deletions src/bus/match.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Expand Down
55 changes: 55 additions & 0 deletions src/bus/test-match.c
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand All @@ -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));
Expand Down
151 changes: 151 additions & 0 deletions test/dbus/test-matches.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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();
}

0 comments on commit 2d0940c

Please sign in to comment.