dbus/bus bus.c,1.39,1.40 config-parser.c,1.22,1.23 dispatch.c,1.51,1.52 policy.c,1.14,1.15 signals.c,1.2,1.3
Havoc Pennington
hp@pdx.freedesktop.org
Thu, 09 Oct 2003 19:42:23 -0700
Update of /cvs/dbus/dbus/bus
In directory pdx:/tmp/cvs-serv16249/bus
Modified Files:
bus.c config-parser.c dispatch.c policy.c signals.c
Log Message:
2003-10-09 Havoc Pennington <hp@redhat.com>
Make matching rules theoretically work (add parser).
* bus/bus.c (bus_context_check_security_policy): fix up to handle
the case where destination is explicitly specified as bus driver
and someone else is eavesdropping.
* bus/policy.c (bus_client_policy_check_can_receive): fix up
definition of eavesdropping and assertion
* tools/dbus-send.c (main): use dbus_message_type_from_string
* bus/signals.c (bus_match_rule_parse): implement
* dbus/dbus-message.c (dbus_message_type_from_string): new
* dbus/dbus-errors.h (DBUS_ERROR_MATCH_RULE_INVALID): add
Index: bus.c
===================================================================
RCS file: /cvs/dbus/dbus/bus/bus.c,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -d -r1.39 -r1.40
--- bus.c 30 Sep 2003 02:32:50 -0000 1.39
+++ bus.c 10 Oct 2003 02:42:20 -0000 1.40
@@ -872,6 +872,19 @@
return context->limits.max_match_rules_per_connection;
}
+/*
+ * addressed_recipient is the recipient specified in the message.
+ *
+ * proposed_recipient is the recipient we're considering sending
+ * to right this second, and may be an eavesdropper.
+ *
+ * sender is the sender of the message.
+ *
+ * NULL for proposed_recipient or sender definitely means the bus driver.
+ *
+ * NULL for addressed_recipient may mean the bus driver, or may mean
+ * no destination was specified in the message (e.g. a signal).
+ */
dbus_bool_t
bus_context_check_security_policy (BusContext *context,
DBusConnection *sender,
@@ -883,15 +896,9 @@
BusClientPolicy *sender_policy;
BusClientPolicy *recipient_policy;
- /* NULL sender, proposed_recipient means the bus driver. NULL
- * addressed_recipient means the message didn't specify an explicit
- * target. If proposed_recipient is NULL, then addressed_recipient
- * is also NULL but is implicitly the bus driver.
- */
-
- _dbus_assert (proposed_recipient == NULL ||
- (dbus_message_get_destination (message) == NULL ||
- addressed_recipient != NULL));
+ _dbus_assert (dbus_message_get_destination (message) == NULL || /* Signal */
+ (addressed_recipient != NULL ||
+ strcmp (dbus_message_get_destination (message), DBUS_SERVICE_ORG_FREEDESKTOP_DBUS) == 0)); /* Destination specified or is the bus driver */
if (sender != NULL)
{
Index: config-parser.c
===================================================================
RCS file: /cvs/dbus/dbus/bus/config-parser.c,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -d -r1.22 -r1.23
--- config-parser.c 30 Sep 2003 02:32:50 -0000 1.22
+++ config-parser.c 10 Oct 2003 02:42:20 -0000 1.23
@@ -813,21 +813,6 @@
}
}
-static int
-message_type_from_string (const char *type_str)
-{
- if (strcmp (type_str, "method_call") == 0)
- return DBUS_MESSAGE_TYPE_METHOD_CALL;
- if (strcmp (type_str, "method_return") == 0)
- return DBUS_MESSAGE_TYPE_METHOD_RETURN;
- else if (strcmp (type_str, "signal") == 0)
- return DBUS_MESSAGE_TYPE_SIGNAL;
- else if (strcmp (type_str, "error") == 0)
- return DBUS_MESSAGE_TYPE_ERROR;
- else
- return DBUS_MESSAGE_TYPE_INVALID;
-}
-
static dbus_bool_t
append_rule_from_element (BusConfigParser *parser,
const char *element_name,
@@ -1027,7 +1012,7 @@
message_type = DBUS_MESSAGE_TYPE_INVALID;
if (send_type != NULL)
{
- message_type = message_type_from_string (send_type);
+ message_type = dbus_message_type_from_string (send_type);
if (message_type == DBUS_MESSAGE_TYPE_INVALID)
{
dbus_set_error (error, DBUS_ERROR_FAILED,
@@ -1079,7 +1064,7 @@
message_type = DBUS_MESSAGE_TYPE_INVALID;
if (receive_type != NULL)
{
- message_type = message_type_from_string (receive_type);
+ message_type = dbus_message_type_from_string (receive_type);
if (message_type == DBUS_MESSAGE_TYPE_INVALID)
{
dbus_set_error (error, DBUS_ERROR_FAILED,
Index: dispatch.c
===================================================================
RCS file: /cvs/dbus/dbus/bus/dispatch.c,v
retrieving revision 1.51
retrieving revision 1.52
diff -u -d -r1.51 -r1.52
--- dispatch.c 30 Sep 2003 02:32:50 -0000 1.51
+++ dispatch.c 10 Oct 2003 02:42:20 -0000 1.52
@@ -920,7 +920,8 @@
if (message == NULL)
return TRUE;
- if (!dbus_message_append_args (message, DBUS_TYPE_STRING, "", /* FIXME */
+ /* empty string match rule matches everything */
+ if (!dbus_message_append_args (message, DBUS_TYPE_STRING, "",
DBUS_TYPE_INVALID))
{
dbus_message_unref (message);
Index: policy.c
===================================================================
RCS file: /cvs/dbus/dbus/bus/policy.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- policy.c 30 Sep 2003 02:32:50 -0000 1.14
+++ policy.c 10 Oct 2003 02:42:20 -0000 1.15
@@ -913,6 +913,9 @@
return allowed;
}
+/* See docs on what the args mean on bus_context_check_security_policy()
+ * comment
+ */
dbus_bool_t
bus_client_policy_check_can_receive (BusClientPolicy *policy,
BusRegistry *registry,
@@ -924,20 +927,10 @@
DBusList *link;
dbus_bool_t allowed;
dbus_bool_t eavesdropping;
-
- /* NULL sender, proposed_recipient means the bus driver. NULL
- * addressed_recipient means the message didn't specify an explicit
- * target. If proposed_recipient is NULL, then addressed_recipient
- * is also NULL but is implicitly the bus driver.
- */
- _dbus_assert (proposed_recipient == NULL ||
- (dbus_message_get_destination (message) == NULL ||
- addressed_recipient != NULL));
-
eavesdropping =
- (proposed_recipient == NULL || /* explicitly to bus driver */
- (addressed_recipient && addressed_recipient != proposed_recipient)); /* explicitly to a different recipient */
+ addressed_recipient != proposed_recipient &&
+ dbus_message_get_destination (message) != NULL;
/* policy->rules is in the order the rules appeared
* in the config file, i.e. last rule that applies wins
Index: signals.c
===================================================================
RCS file: /cvs/dbus/dbus/bus/signals.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- signals.c 30 Sep 2003 02:32:50 -0000 1.2
+++ signals.c 10 Oct 2003 02:42:20 -0000 1.3
@@ -52,6 +52,10 @@
rule->refcount = 1;
rule->matches_go_to = matches_go_to;
+#ifndef DBUS_BUILD_TESTS
+ _dbus_assert (rule->matches_go_to != NULL);
+#endif
+
return rule;
}
@@ -285,6 +289,285 @@
return TRUE;
}
+#define ISWHITE(c) (((c) == ' ') || ((c) == '\t') || ((c) == '\n') || ((c) == '\r'))
+
+static dbus_bool_t
+find_key (const DBusString *str,
+ int start,
+ DBusString *key,
+ int *value_pos,
+ DBusError *error)
+{
+ const char *p;
+ const char *s;
+ const char *key_start;
+ const char *key_end;
+
+ _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+
+ s = _dbus_string_get_const_data (str);
+
+ p = s + start;
+
+ while (*p && ISWHITE (*p))
+ ++p;
+
+ key_start = p;
+
+ while (*p && *p != '=' && !ISWHITE (*p))
+ ++p;
+
+ key_end = p;
+
+ while (*p && ISWHITE (*p))
+ ++p;
+
+ if (key_start == key_end)
+ {
+ /* Empty match rules or trailing whitespace are OK */
+ *value_pos = p - s;
+ return TRUE;
+ }
+
+ if (*p != '=')
+ {
+ dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID,
+ "Match rule has a key with no subsequent '=' character");
+ return FALSE;
+ }
+ ++p;
+
+ if (!_dbus_string_append_len (key, key_start, key_end - key_start))
+ {
+ BUS_SET_OOM (error);
+ return FALSE;
+ }
+
+ *value_pos = p - s;
+
+ return TRUE;
+}
+
+static dbus_bool_t
+find_value (const DBusString *str,
+ int start,
+ const char *key,
+ DBusString *value,
+ int *value_end,
+ DBusError *error)
+{
+ const char *p;
+ const char *s;
+ char quote_char;
+ int orig_len;
+
+ _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+
+ orig_len = _dbus_string_get_length (value);
+
+ s = _dbus_string_get_const_data (str);
+
+ p = s + start;
+
+ quote_char = '\0';
+
+ while (*p)
+ {
+ if (quote_char == '\0')
+ {
+ switch (*p)
+ {
+ case '\0':
+ goto done;
+
+ case '\'':
+ quote_char = '\'';
+ goto next;
+
+ case ',':
+ ++p;
+ goto done;
+
+ case '\\':
+ quote_char = '\\';
+ goto next;
+
+ default:
+ if (!_dbus_string_append_byte (value, *p))
+ {
+ BUS_SET_OOM (error);
+ goto failed;
+ }
+ }
+ }
+ else if (quote_char == '\\')
+ {
+ /* \ only counts as an escape if escaping a quote mark */
+ if (*p != '\'')
+ {
+ if (!_dbus_string_append_byte (value, '\\'))
+ {
+ BUS_SET_OOM (error);
+ goto failed;
+ }
+ }
+
+ if (!_dbus_string_append_byte (value, *p))
+ {
+ BUS_SET_OOM (error);
+ goto failed;
+ }
+
+ quote_char = '\0';
+ }
+ else
+ {
+ _dbus_assert (quote_char == '\'');
+
+ if (*p == '\'')
+ {
+ quote_char = '\0';
+ }
+ else
+ {
+ if (!_dbus_string_append_byte (value, *p))
+ {
+ BUS_SET_OOM (error);
+ goto failed;
+ }
+ }
+ }
+
+ next:
+ ++p;
+ }
+
+ done:
+
+ if (quote_char == '\\')
+ {
+ if (!_dbus_string_append_byte (value, '\\'))
+ {
+ BUS_SET_OOM (error);
+ goto failed;
+ }
+ }
+ else if (quote_char == '\'')
+ {
+ dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID,
+ "Unbalanced quotation marks in match rule");
+ goto failed;
+ }
+ else
+ _dbus_assert (quote_char == '\0');
+
+ /* Zero-length values are allowed */
+
+ *value_end = p - s;
+
+ return TRUE;
+
+ failed:
+ _DBUS_ASSERT_ERROR_IS_SET (error);
+ _dbus_string_set_length (value, orig_len);
+ return FALSE;
+}
+
+/* duplicates aren't allowed so the real legitimate max is only 6 or
+ * so. Leaving extra so we don't have to bother to update it.
+ */
+#define MAX_RULE_TOKENS 16
+
+/* this is slightly too high level to be termed a "token"
+ * but let's not be pedantic.
+ */
+typedef struct
+{
+ char *key;
+ char *value;
+} RuleToken;
+
+static dbus_bool_t
+tokenize_rule (const DBusString *rule_text,
+ RuleToken tokens[MAX_RULE_TOKENS],
+ DBusError *error)
+{
+ int i;
+ int pos;
+ DBusString key;
+ DBusString value;
+ dbus_bool_t retval;
+
+ retval = FALSE;
+
+ if (!_dbus_string_init (&key))
+ {
+ BUS_SET_OOM (error);
+ return FALSE;
+ }
+
+ if (!_dbus_string_init (&value))
+ {
+ _dbus_string_free (&key);
+ BUS_SET_OOM (error);
+ return FALSE;
+ }
+
+ i = 0;
+ pos = 0;
+ while (i < MAX_RULE_TOKENS &&
+ pos < _dbus_string_get_length (rule_text))
+ {
+ _dbus_assert (tokens[i].key == NULL);
+ _dbus_assert (tokens[i].value == NULL);
+
+ if (!find_key (rule_text, pos, &key, &pos, error))
+ goto out;
+
+ if (_dbus_string_get_length (&key) == 0)
+ goto next;
+
+ if (!_dbus_string_steal_data (&key, &tokens[i].key))
+ {
+ BUS_SET_OOM (error);
+ goto out;
+ }
+
+ if (!find_value (rule_text, pos, tokens[i].key, &value, &pos, error))
+ goto out;
+
+ if (!_dbus_string_steal_data (&value, &tokens[i].value))
+ {
+ BUS_SET_OOM (error);
+ goto out;
+ }
+
+ next:
+ ++i;
+ }
+
+ retval = TRUE;
+
+ out:
+ if (!retval)
+ {
+ i = 0;
+ while (tokens[i].key || tokens[i].value)
+ {
+ dbus_free (tokens[i].key);
+ dbus_free (tokens[i].value);
+ tokens[i].key = NULL;
+ tokens[i].value = NULL;
+ ++i;
+ }
+ }
+
+ _dbus_string_free (&key);
+ _dbus_string_free (&value);
+
+ return retval;
+}
+
/*
* The format is comma-separated with strings quoted with single quotes
* as for the shell (to escape a literal single quote, use '\'').
@@ -299,24 +582,157 @@
DBusError *error)
{
BusMatchRule *rule;
-
+ RuleToken tokens[MAX_RULE_TOKENS+1]; /* NULL termination + 1 */
+ int i;
+
+ _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+
+ memset (tokens, '\0', sizeof (tokens));
+
rule = bus_match_rule_new (matches_go_to);
if (rule == NULL)
- goto oom;
-
- /* FIXME implement for real */
+ {
+ BUS_SET_OOM (error);
+ goto failed;
+ }
- if (!bus_match_rule_set_message_type (rule,
- DBUS_MESSAGE_TYPE_SIGNAL))
- goto oom;
+ if (!tokenize_rule (rule_text, tokens, error))
+ goto failed;
- return rule;
+ i = 0;
+ while (tokens[i].key != NULL)
+ {
+ const char *key = tokens[i].key;
+ const char *value = tokens[i].value;
+
+ if (strcmp (key, "type") == 0)
+ {
+ int t;
+
+ if (rule->flags & BUS_MATCH_MESSAGE_TYPE)
+ {
+ dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID,
+ "Key %s specified twice in match rule\n", key);
+ goto failed;
+ }
+
+ t = dbus_message_type_from_string (value);
+
+ if (!bus_match_rule_set_message_type (rule, t))
+ {
+ BUS_SET_OOM (error);
+ goto failed;
+ }
+ }
+ else if (strcmp (key, "sender") == 0)
+ {
+ if (rule->flags & BUS_MATCH_SENDER)
+ {
+ dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID,
+ "Key %s specified twice in match rule\n", key);
+ goto failed;
+ }
+
+ if (!bus_match_rule_set_sender (rule, value))
+ {
+ BUS_SET_OOM (error);
+ goto failed;
+ }
+ }
+ else if (strcmp (key, "interface") == 0)
+ {
+ if (rule->flags & BUS_MATCH_INTERFACE)
+ {
+ dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID,
+ "Key %s specified twice in match rule\n", key);
+ goto failed;
+ }
+
+ if (!bus_match_rule_set_interface (rule, value))
+ {
+ BUS_SET_OOM (error);
+ goto failed;
+ }
+ }
+ else if (strcmp (key, "member") == 0)
+ {
+ if (rule->flags & BUS_MATCH_MEMBER)
+ {
+ dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID,
+ "Key %s specified twice in match rule\n", key);
+ goto failed;
+ }
+
+ if (!bus_match_rule_set_member (rule, value))
+ {
+ BUS_SET_OOM (error);
+ goto failed;
+ }
+ }
+ else if (strcmp (key, "path") == 0)
+ {
+ if (rule->flags & BUS_MATCH_PATH)
+ {
+ dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID,
+ "Key %s specified twice in match rule\n", key);
+ goto failed;
+ }
+
+ if (!bus_match_rule_set_path (rule, value))
+ {
+ BUS_SET_OOM (error);
+ goto failed;
+ }
+ }
+ else if (strcmp (key, "destination") == 0)
+ {
+ if (rule->flags & BUS_MATCH_DESTINATION)
+ {
+ dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID,
+ "Key %s specified twice in match rule\n", key);
+ goto failed;
+ }
+
+ if (!bus_match_rule_set_destination (rule, value))
+ {
+ BUS_SET_OOM (error);
+ goto failed;
+ }
+ }
+ else
+ {
+ dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID,
+ "Unknown key \"%s\" in match rule",
+ key);
+ goto failed;
+ }
+
+ ++i;
+ }
- oom:
+
+ goto out;
+
+ failed:
+ _DBUS_ASSERT_ERROR_IS_SET (error);
if (rule)
- bus_match_rule_unref (rule);
- BUS_SET_OOM (error);
- return NULL;
+ {
+ bus_match_rule_unref (rule);
+ rule = NULL;
+ }
+
+ out:
+
+ i = 0;
+ while (tokens[i].key || tokens[i].value)
+ {
+ _dbus_assert (i < MAX_RULE_TOKENS);
+ dbus_free (tokens[i].key);
+ dbus_free (tokens[i].value);
+ ++i;
+ }
+
+ return rule;
}
struct BusMatchmaker
@@ -760,6 +1176,186 @@
#ifdef DBUS_BUILD_TESTS
#include "test.h"
+#include <stdlib.h>
+
+static BusMatchRule*
+check_parse (dbus_bool_t should_succeed,
+ const char *text)
+{
+ BusMatchRule *rule;
+ DBusString str;
+ DBusError error;
+
+ dbus_error_init (&error);
+
+ _dbus_string_init_const (&str, text);
+
+ rule = bus_match_rule_parse (NULL, &str, &error);
+ if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
+ {
+ dbus_error_free (&error);
+ return NULL;
+ }
+
+ if (should_succeed && rule == NULL)
+ {
+ _dbus_warn ("Failed to parse: %s: %s: \"%s\"\n",
+ error.name, error.message,
+ _dbus_string_get_const_data (&str));
+ exit (1);
+ }
+
+ if (!should_succeed && rule != NULL)
+ {
+ _dbus_warn ("Failed to fail to parse: \"%s\"\n",
+ _dbus_string_get_const_data (&str));
+ exit (1);
+ }
+
+ dbus_error_free (&error);
+
+ return rule;
+}
+
+static void
+assert_large_rule (BusMatchRule *rule)
+{
+ _dbus_assert (rule->flags & BUS_MATCH_MESSAGE_TYPE);
+ _dbus_assert (rule->flags & BUS_MATCH_SENDER);
+ _dbus_assert (rule->flags & BUS_MATCH_INTERFACE);
+ _dbus_assert (rule->flags & BUS_MATCH_MEMBER);
+ _dbus_assert (rule->flags & BUS_MATCH_DESTINATION);
+ _dbus_assert (rule->flags & BUS_MATCH_PATH);
+
+ _dbus_assert (rule->message_type == DBUS_MESSAGE_TYPE_SIGNAL);
+ _dbus_assert (rule->interface != NULL);
+ _dbus_assert (rule->member != NULL);
+ _dbus_assert (rule->sender != NULL);
+ _dbus_assert (rule->destination != NULL);
+ _dbus_assert (rule->path != NULL);
+
+ _dbus_assert (strcmp (rule->interface, "org.freedesktop.DBusInterface") == 0);
+ _dbus_assert (strcmp (rule->sender, "org.freedesktop.DBusSender") == 0);
+ _dbus_assert (strcmp (rule->member, "Foo") == 0);
+ _dbus_assert (strcmp (rule->path, "/bar/foo") == 0);
+ _dbus_assert (strcmp (rule->destination, ":452345-34") == 0);
+}
+
+static dbus_bool_t
+test_parsing (void *data)
+{
+ BusMatchRule *rule;
+
+ rule = check_parse (TRUE, "type='signal',sender='org.freedesktop.DBusSender',interface='org.freedesktop.DBusInterface',member='Foo',path='/bar/foo',destination=':452345-34'");
+ if (rule != NULL)
+ {
+ assert_large_rule (rule);
+ bus_match_rule_unref (rule);
+ }
+
+ /* With extra whitespace and useless quotes */
+ rule = check_parse (TRUE, " type='signal', \tsender='org.freedes''ktop.DBusSender', interface='org.freedesktop.DBusInterface''''', \tmember='Foo',path='/bar/foo',destination=':452345-34'''''");
+ if (rule != NULL)
+ {
+ assert_large_rule (rule);
+ bus_match_rule_unref (rule);
+ }
+
+
+ /* A simple signal connection */
+ rule = check_parse (TRUE, "type='signal',path='/foo',interface='org.Bar'");
+ if (rule != NULL)
+ {
+ _dbus_assert (rule->flags & BUS_MATCH_MESSAGE_TYPE);
+ _dbus_assert (rule->flags & BUS_MATCH_INTERFACE);
+ _dbus_assert (rule->flags & BUS_MATCH_PATH);
+
+ _dbus_assert (rule->message_type == DBUS_MESSAGE_TYPE_SIGNAL);
+ _dbus_assert (rule->interface != NULL);
+ _dbus_assert (rule->path != NULL);
+
+ _dbus_assert (strcmp (rule->interface, "org.Bar") == 0);
+ _dbus_assert (strcmp (rule->path, "/foo") == 0);
+
+ bus_match_rule_unref (rule);
+ }
+
+ /* Reject duplicates */
+ rule = check_parse (FALSE, "type='signal',type='method_call'");
+ _dbus_assert (rule == NULL);
+
+ /* Reject broken keys */
+ rule = check_parse (FALSE, "blah='signal'");
+ _dbus_assert (rule == NULL);
+
+ /* Allow empty rule */
+ rule = check_parse (TRUE, "");
+ if (rule != NULL)
+ {
+ _dbus_assert (rule->flags == 0);
+
+ bus_match_rule_unref (rule);
+ }
+
+ /* All-whitespace rule is the same as empty */
+ rule = check_parse (TRUE, " \t");
+ if (rule != NULL)
+ {
+ _dbus_assert (rule->flags == 0);
+
+ bus_match_rule_unref (rule);
+ }
+
+ /* But with non-whitespace chars and no =value, it's not OK */
+ rule = check_parse (FALSE, "type");
+ _dbus_assert (rule == NULL);
+
+ /* Empty string values are allowed at the moment */
+ rule = check_parse (TRUE, "interface=");
+ if (rule != NULL)
+ {
+ _dbus_assert (rule->flags == BUS_MATCH_INTERFACE);
+ _dbus_assert (rule->interface);
+ _dbus_assert (strlen (rule->interface) == 0);
+
+ bus_match_rule_unref (rule);
+ }
+
+ /* Empty string expressed with quotes */
+ rule = check_parse (TRUE, "interface=''");
+ if (rule != NULL)
+ {
+ _dbus_assert (rule->flags == BUS_MATCH_INTERFACE);
+ _dbus_assert (rule->interface);
+ _dbus_assert (strlen (rule->interface) == 0);
+
+ bus_match_rule_unref (rule);
+ }
+
+ /* Check whitespace in a value */
+ rule = check_parse (TRUE, "interface= ");
+ if (rule != NULL)
+ {
+ _dbus_assert (rule->flags == BUS_MATCH_INTERFACE);
+ _dbus_assert (rule->interface);
+ _dbus_assert (strcmp (rule->interface, " ") == 0);
+
+ bus_match_rule_unref (rule);
+ }
+
+ /* Check whitespace mixed with non-whitespace in a value */
+ rule = check_parse (TRUE, "interface= foo ");
+ if (rule != NULL)
+ {
+ _dbus_assert (rule->flags == BUS_MATCH_INTERFACE);
+ _dbus_assert (rule->interface);
+ _dbus_assert (strcmp (rule->interface, " foo ") == 0);
+
+ bus_match_rule_unref (rule);
+ }
+
+ return TRUE;
+}
dbus_bool_t
bus_signals_test (const DBusString *test_data_dir)
@@ -770,6 +1366,9 @@
bus_matchmaker_ref (matchmaker);
bus_matchmaker_unref (matchmaker);
bus_matchmaker_unref (matchmaker);
+
+ if (!_dbus_test_oom_handling ("parsing match rules", test_parsing, NULL))
+ _dbus_assert_not_reached ("Parsing match rules test failed");
return TRUE;
}