summaryrefslogtreecommitdiff
path: root/src/libsystemd/sd-bus
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsystemd/sd-bus')
-rw-r--r--src/libsystemd/sd-bus/bus-kernel.c77
-rw-r--r--src/libsystemd/sd-bus/test-bus-kernel-bloom.c51
2 files changed, 82 insertions, 46 deletions
diff --git a/src/libsystemd/sd-bus/bus-kernel.c b/src/libsystemd/sd-bus/bus-kernel.c
index 58f011ff86..aaf44e3e75 100644
--- a/src/libsystemd/sd-bus/bus-kernel.c
+++ b/src/libsystemd/sd-bus/bus-kernel.c
@@ -135,6 +135,32 @@ static void append_fds(struct kdbus_item **d, const int fds[], unsigned n_fds) {
*d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size);
}
+static void add_bloom_arg(void *data, size_t size, unsigned n_hash, unsigned i, const char *t) {
+ char buf[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
+ char *e;
+
+ assert(data);
+ assert(size > 0);
+ assert(i < 64);
+ assert(t);
+
+ e = stpcpy(buf, "arg");
+ if (i < 10)
+ *(e++) = '0' + (char) i;
+ else {
+ *(e++) = '0' + (char) (i / 10);
+ *(e++) = '0' + (char) (i % 10);
+ }
+
+ *e = 0;
+ bloom_add_pair(data, size, n_hash, buf, t);
+
+ strcpy(e, "-dot-prefix");
+ bloom_add_prefixes(data, size, n_hash, buf, t, '.');
+ strcpy(e, "-slash-prefix");
+ bloom_add_prefixes(data, size, n_hash, buf, t, '/');
+}
+
static int bus_message_setup_bloom(sd_bus_message *m, struct kdbus_bloom_filter *bloom) {
void *data;
unsigned i;
@@ -164,39 +190,42 @@ static int bus_message_setup_bloom(sd_bus_message *m, struct kdbus_bloom_filter
return r;
for (i = 0; i < 64; i++) {
+ const char *t, *contents;
char type;
- const char *t;
- char buf[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
- char *e;
- r = sd_bus_message_peek_type(m, &type, NULL);
+ r = sd_bus_message_peek_type(m, &type, &contents);
if (r < 0)
return r;
- if (type != SD_BUS_TYPE_STRING &&
- type != SD_BUS_TYPE_OBJECT_PATH &&
- type != SD_BUS_TYPE_SIGNATURE)
- break;
+ if (IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH, SD_BUS_TYPE_SIGNATURE)) {
- r = sd_bus_message_read_basic(m, type, &t);
- if (r < 0)
- return r;
+ /* The bloom filter includes simple strings of any kind */
+ r = sd_bus_message_read_basic(m, type, &t);
+ if (r < 0)
+ return r;
- e = stpcpy(buf, "arg");
- if (i < 10)
- *(e++) = '0' + (char) i;
- else {
- *(e++) = '0' + (char) (i / 10);
- *(e++) = '0' + (char) (i % 10);
- }
+ add_bloom_arg(data, m->bus->bloom_size, m->bus->bloom_n_hash, i, t);
+ } if (type == SD_BUS_TYPE_ARRAY && STR_IN_SET(contents, "s", "o", "g")) {
- *e = 0;
- bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, buf, t);
+ /* As well as array of simple strings of any kinds */
+ r = sd_bus_message_enter_container(m, type, contents);
+ if (r < 0)
+ return r;
+
+ while ((r = sd_bus_message_read_basic(m, contents[0], &t)) > 0)
+ add_bloom_arg(data, m->bus->bloom_size, m->bus->bloom_n_hash, i, t);
+ if (r < 0)
+ return r;
- strcpy(e, "-dot-prefix");
- bloom_add_prefixes(data, m->bus->bloom_size, m->bus->bloom_n_hash, buf, t, '.');
- strcpy(e, "-slash-prefix");
- bloom_add_prefixes(data, m->bus->bloom_size, m->bus->bloom_n_hash, buf, t, '/');
+ r = sd_bus_message_exit_container(m);
+ if (r < 0)
+ return r;
+
+ } else
+ /* Stop adding to bloom filter as soon as we
+ * run into the first argument we cannot add
+ * to it. */
+ break;
}
return 0;
diff --git a/src/libsystemd/sd-bus/test-bus-kernel-bloom.c b/src/libsystemd/sd-bus/test-bus-kernel-bloom.c
index 5ee6eea0e8..071b7e0cf9 100644
--- a/src/libsystemd/sd-bus/test-bus-kernel-bloom.c
+++ b/src/libsystemd/sd-bus/test-bus-kernel-bloom.c
@@ -32,6 +32,7 @@ static void test_one(
const char *path,
const char *interface,
const char *member,
+ bool as_list,
const char *arg0,
const char *match,
bool good) {
@@ -76,7 +77,11 @@ static void test_one(
assert_se(r >= 0);
log_debug("signal");
- r = sd_bus_emit_signal(a, path, interface, member, "s", arg0);
+
+ if (as_list)
+ r = sd_bus_emit_signal(a, path, interface, member, "as", 1, arg0);
+ else
+ r = sd_bus_emit_signal(a, path, interface, member, "s", arg0);
assert_se(r >= 0);
r = sd_bus_process(b, &m);
@@ -89,27 +94,29 @@ static void test_one(
int main(int argc, char *argv[]) {
log_set_max_level(LOG_DEBUG);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "", true);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path='/foo/bar/waldo'", true);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path='/foo/bar/waldo/tuut'", false);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "interface='waldo.com'", true);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "member='Piep'", true);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "member='Pi_ep'", false);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "arg0='foobar'", true);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "arg0='foo_bar'", false);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path='/foo/bar/waldo',interface='waldo.com',member='Piep',arg0='foobar'", true);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path='/foo/bar/waldo',interface='waldo.com',member='Piep',arg0='foobar2'", false);
-
- test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path='/foo/bar/waldo'", true);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path='/foo/bar'", false);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path='/foo'", false);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path='/'", false);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path='/foo/bar/waldo/quux'", false);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path_namespace='/foo/bar/waldo'", true);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path_namespace='/foo/bar'", true);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path_namespace='/foo'", true);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path_namespace='/'", true);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", "foobar", "path_namespace='/quux'", false);
+ test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "", true);
+ test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path='/foo/bar/waldo'", true);
+ test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path='/foo/bar/waldo/tuut'", false);
+ test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "interface='waldo.com'", true);
+ test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "member='Piep'", true);
+ test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "member='Pi_ep'", false);
+ test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "arg0='foobar'", true);
+ test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "arg0='foo_bar'", false);
+ test_one("/foo/bar/waldo", "waldo.com", "Piep", true, "foobar", "arg0='foobar'", true);
+ test_one("/foo/bar/waldo", "waldo.com", "Piep", true, "foobar", "arg0='foo_bar'", false);
+ test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path='/foo/bar/waldo',interface='waldo.com',member='Piep',arg0='foobar'", true);
+ test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path='/foo/bar/waldo',interface='waldo.com',member='Piep',arg0='foobar2'", false);
+
+ test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path='/foo/bar/waldo'", true);
+ test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path='/foo/bar'", false);
+ test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path='/foo'", false);
+ test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path='/'", false);
+ test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path='/foo/bar/waldo/quux'", false);
+ test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path_namespace='/foo/bar/waldo'", true);
+ test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path_namespace='/foo/bar'", true);
+ test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path_namespace='/foo'", true);
+ test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path_namespace='/'", true);
+ test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path_namespace='/quux'", false);
return 0;
}