Validate arg0namespace matches' values.

I could be convinced that this is overkill, but it seems sensible to
forbid obviously-broken arg0namespace matches.
This commit is contained in:
Will Thompson 2010-11-21 16:34:51 +00:00
parent 2f7b11158b
commit 613ecbfba0
3 changed files with 119 additions and 18 deletions

View file

@ -771,7 +771,22 @@ bus_match_rule_parse_arg_match (BusMatchRule *rule,
}
else if (_dbus_string_equal_c_str (&key_str, "arg0namespace"))
{
int value_len = _dbus_string_get_length (value);
is_namespace = TRUE;
if (value_len > 0 &&
_dbus_string_get_byte (value, value_len - 1) == '.')
value_len--;
if (!_dbus_validate_bus_namespace (value, 0, value_len))
{
dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID,
"arg0namespace='%s' is not a valid (optionally "
"period-terminated) prefix of a bus name",
_dbus_string_get_const_data (value));
goto failed;
}
}
else
{
@ -2109,9 +2124,62 @@ test_parsing (void *data)
bus_match_rule_unref (rule);
}
rule = check_parse (TRUE, "arg0namespace='foo.'");
if (rule != NULL)
{
_dbus_assert (rule->flags == BUS_MATCH_ARGS);
_dbus_assert (rule->args != NULL);
_dbus_assert (rule->args_len == 1);
_dbus_assert (strcmp (rule->args[0], "foo.") == 0);
_dbus_assert ((rule->arg_lens[0] & BUS_MATCH_ARG_NAMESPACE)
== BUS_MATCH_ARG_NAMESPACE);
bus_match_rule_unref (rule);
}
rule = check_parse (TRUE, "arg0namespace='foo.bar'");
if (rule != NULL)
{
_dbus_assert (rule->flags == BUS_MATCH_ARGS);
_dbus_assert (rule->args != NULL);
_dbus_assert (rule->args_len == 1);
_dbus_assert (strcmp (rule->args[0], "foo.bar") == 0);
_dbus_assert ((rule->arg_lens[0] & BUS_MATCH_ARG_NAMESPACE)
== BUS_MATCH_ARG_NAMESPACE);
bus_match_rule_unref (rule);
}
rule = check_parse (TRUE, "arg0namespace='foo.bar.'");
if (rule != NULL)
{
_dbus_assert (rule->flags == BUS_MATCH_ARGS);
_dbus_assert (rule->args != NULL);
_dbus_assert (rule->args_len == 1);
_dbus_assert (strcmp (rule->args[0], "foo.bar.") == 0);
_dbus_assert ((rule->arg_lens[0] & BUS_MATCH_ARG_NAMESPACE)
== BUS_MATCH_ARG_NAMESPACE);
bus_match_rule_unref (rule);
}
/* Only arg0namespace is supported. */
rule = check_parse (FALSE, "arg1namespace='foo'");
_dbus_assert (rule == NULL);
/* An empty string isn't a valid namespace prefix (you should just not
* specify this key at all).
*/
rule = check_parse (FALSE, "arg0namespace=''");
_dbus_assert (rule == NULL);
/* Two trailing periods on otherwise-valid namespaces aren't allowed. */
rule = check_parse (FALSE, "arg0namespace='foo..'");
_dbus_assert (rule == NULL);
rule = check_parse (FALSE, "arg0namespace='foo.bar..'");
_dbus_assert (rule == NULL);
/* Too-large argN */
rule = check_parse (FALSE, "arg300='foo'");
_dbus_assert (rule == NULL);

View file

@ -1062,23 +1062,11 @@ _dbus_validate_error_name (const DBusString *str,
((c) >= 'a' && (c) <= 'z') || \
((c) == '_') || ((c) == '-'))
/**
* Checks that the given range of the string is a valid bus name in
* the D-Bus protocol. This includes a length restriction, etc., see
* the specification.
*
* @todo this is inconsistent with most of DBusString in that
* it allows a start,len range that extends past the string end.
*
* @param str the string
* @param start first byte index to check
* @param len number of bytes to check
* @returns #TRUE if the byte range exists and is a valid name
*/
dbus_bool_t
_dbus_validate_bus_name (const DBusString *str,
int start,
int len)
static dbus_bool_t
_dbus_validate_bus_name_full (const DBusString *str,
int start,
int len,
dbus_bool_t is_namespace)
{
const unsigned char *s;
const unsigned char *end;
@ -1156,12 +1144,54 @@ _dbus_validate_bus_name (const DBusString *str,
++s;
}
if (_DBUS_UNLIKELY (last_dot == NULL))
if (!is_namespace && _DBUS_UNLIKELY (last_dot == NULL))
return FALSE;
return TRUE;
}
/**
* Checks that the given range of the string is a valid bus name in
* the D-Bus protocol. This includes a length restriction, etc., see
* the specification.
*
* @todo this is inconsistent with most of DBusString in that
* it allows a start,len range that extends past the string end.
*
* @param str the string
* @param start first byte index to check
* @param len number of bytes to check
* @returns #TRUE if the byte range exists and is a valid name
*/
dbus_bool_t
_dbus_validate_bus_name (const DBusString *str,
int start,
int len)
{
return _dbus_validate_bus_name_full (str, start, len, FALSE);
}
/**
* Checks that the given range of the string is a prefix of a valid bus name in
* the D-Bus protocol. Unlike _dbus_validate_bus_name(), this accepts strings
* with only one period-separated component.
*
* @todo this is inconsistent with most of DBusString in that
* it allows a start,len range that extends past the string end.
*
* @param str the string
* @param start first byte index to check
* @param len number of bytes to check
* @returns #TRUE if the byte range exists and is a valid name
*/
dbus_bool_t
_dbus_validate_bus_namespace (const DBusString *str,
int start,
int len)
{
return _dbus_validate_bus_name_full (str, start, len, TRUE);
}
/**
* Checks that the given range of the string is a valid message type
* signature in the D-Bus protocol.

View file

@ -143,6 +143,9 @@ dbus_bool_t _dbus_validate_error_name (const DBusString *str,
dbus_bool_t _dbus_validate_bus_name (const DBusString *str,
int start,
int len);
dbus_bool_t _dbus_validate_bus_namespace (const DBusString *str,
int start,
int len);
dbus_bool_t _dbus_validate_signature (const DBusString *str,
int start,
int len);