diff options
Diffstat (limited to 'src/libsystemd')
-rw-r--r-- | src/libsystemd/sd-bus/bus-kernel.c | 77 | ||||
-rw-r--r-- | src/libsystemd/sd-bus/test-bus-kernel-bloom.c | 51 |
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; } |