From f690775e74614d5711a7a671e0eee9a003ab8aa2 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Fri, 6 Nov 2015 16:41:16 +0100 Subject: [PATCH 2/3] signals: factor out match_rule_matches_string_arg() Bug: https://bugs.freedesktop.org/show_bug.cgi?id=91755 Signed-off-by: Simon McVittie --- bus/signals.c | 123 ++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 69 insertions(+), 54 deletions(-) diff --git a/bus/signals.c b/bus/signals.c index e8def9f..f284355 100644 --- a/bus/signals.c +++ b/bus/signals.c @@ -1775,6 +1775,66 @@ str_has_prefix (const char *str, const char *prefix) } static dbus_bool_t +match_rule_matches_string_arg (const char *expected_arg, + int expected_length, + const char *actual_arg, + unsigned int flags) +{ + int actual_length; + + actual_length = strlen (actual_arg); + + if (flags & BUS_MATCH_ARG_IS_PATH) + { + if (actual_length < expected_length && + actual_arg[actual_length - 1] != '/') + return FALSE; + + if (expected_length < actual_length && + expected_arg[expected_length - 1] != '/') + return FALSE; + + if (memcmp (actual_arg, expected_arg, + MIN (actual_length, expected_length)) != 0) + return FALSE; + } + else if (flags & BUS_MATCH_ARG_NAMESPACE) + { + if (expected_length > actual_length) + return FALSE; + + /* If the actual argument doesn't start with the expected + * namespace, then we don't match. + */ + if (memcmp (expected_arg, actual_arg, expected_length) != 0) + return FALSE; + + if (expected_length < actual_length) + { + /* Check that the actual argument is within the expected + * namespace, rather than just starting with that string, + * by checking that the matched prefix ends in a '.'. + * + * This doesn't stop "foo.bar." matching "foo.bar..baz" + * which is an invalid namespace, but at some point the + * daemon can't cover up for broken services. + */ + if (actual_arg[expected_length] != '.') + return FALSE; + } + /* otherwise we had an exact match. */ + } + else + { + if (expected_length != actual_length || + memcmp (expected_arg, actual_arg, expected_length) != 0) + return FALSE; + } + + return TRUE; +} + +static dbus_bool_t match_rule_matches (BusMatchRule *rule, DBusConnection *sender, DBusConnection *addressed_recipient, @@ -1969,19 +2029,19 @@ match_rule_matches (BusMatchRule *rule, int current_type; const char *expected_arg; int expected_length; - dbus_bool_t is_path, is_namespace; + unsigned int flags; + dbus_bool_t is_path; expected_arg = rule->args[i]; expected_length = rule->arg_lens[i] & ~BUS_MATCH_ARG_FLAGS; - is_path = (rule->arg_lens[i] & BUS_MATCH_ARG_IS_PATH) != 0; - is_namespace = (rule->arg_lens[i] & BUS_MATCH_ARG_NAMESPACE) != 0; - + flags = rule->arg_lens[i] & BUS_MATCH_ARG_FLAGS; + is_path = ((flags & BUS_MATCH_ARG_IS_PATH) != 0); + current_type = dbus_message_iter_get_arg_type (&iter); if (expected_arg != NULL) { const char *actual_arg; - int actual_length; if (current_type != DBUS_TYPE_STRING && (!is_path || current_type != DBUS_TYPE_OBJECT_PATH)) @@ -1991,55 +2051,10 @@ match_rule_matches (BusMatchRule *rule, dbus_message_iter_get_basic (&iter, &actual_arg); _dbus_assert (actual_arg != NULL); - actual_length = strlen (actual_arg); - - if (is_path) - { - if (actual_length < expected_length && - actual_arg[actual_length - 1] != '/') - return FALSE; - - if (expected_length < actual_length && - expected_arg[expected_length - 1] != '/') - return FALSE; - - if (memcmp (actual_arg, expected_arg, - MIN (actual_length, expected_length)) != 0) - return FALSE; - } - else if (is_namespace) - { - if (expected_length > actual_length) - return FALSE; - - /* If the actual argument doesn't start with the expected - * namespace, then we don't match. - */ - if (memcmp (expected_arg, actual_arg, expected_length) != 0) - return FALSE; - - if (expected_length < actual_length) - { - /* Check that the actual argument is within the expected - * namespace, rather than just starting with that string, - * by checking that the matched prefix ends in a '.'. - * - * This doesn't stop "foo.bar." matching "foo.bar..baz" - * which is an invalid namespace, but at some point the - * daemon can't cover up for broken services. - */ - if (actual_arg[expected_length] != '.') - return FALSE; - } - /* otherwise we had an exact match. */ - } - else - { - if (expected_length != actual_length || - memcmp (expected_arg, actual_arg, expected_length) != 0) - return FALSE; - } - + if (!match_rule_matches_string_arg (expected_arg, + expected_length, + actual_arg, flags)) + return FALSE; } if (current_type != DBUS_TYPE_INVALID) -- 2.6.2