diff options
Diffstat (limited to 'dbus/dbus-marshal-validate.c')
-rw-r--r-- | dbus/dbus-marshal-validate.c | 127 |
1 files changed, 86 insertions, 41 deletions
diff --git a/dbus/dbus-marshal-validate.c b/dbus/dbus-marshal-validate.c index 92050a59..e9aa26a8 100644 --- a/dbus/dbus-marshal-validate.c +++ b/dbus/dbus-marshal-validate.c @@ -677,7 +677,7 @@ _dbus_validate_body_with_reason (const DBusString *expected_signature, } /** - * Determine wether the given charater is valid as the first charater + * Determine wether the given character is valid as the first character * in a name. */ #define VALID_INITIAL_NAME_CHARACTER(c) \ @@ -686,7 +686,7 @@ _dbus_validate_body_with_reason (const DBusString *expected_signature, ((c) == '_') ) /** - * Determine wether the given charater is valid as a second or later + * Determine wether the given character is valid as a second or later * character in a name */ #define VALID_NAME_CHARACTER(c) \ @@ -922,15 +922,47 @@ _dbus_validate_error_name (const DBusString *str, return _dbus_validate_interface (str, start, len); } -/* This assumes the first char exists and is ':' */ -static dbus_bool_t -_dbus_validate_unique_name (const DBusString *str, - int start, - int len) +/** + * Determine wether the given character is valid as the first character + * in a bus name. + */ +#define VALID_INITIAL_BUS_NAME_CHARACTER(c) \ + ( ((c) >= 'A' && (c) <= 'Z') || \ + ((c) >= 'a' && (c) <= 'z') || \ + ((c) == '_') || ((c) == '-')) + +/** + * Determine wether the given character is valid as a second or later + * character in a bus name + */ +#define VALID_BUS_NAME_CHARACTER(c) \ + ( ((c) >= '0' && (c) <= '9') || \ + ((c) >= 'A' && (c) <= 'Z') || \ + ((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) { const unsigned char *s; const unsigned char *end; - const unsigned char *name; + const unsigned char *iface; + const unsigned char *last_dot; _dbus_assert (start >= 0); _dbus_assert (len >= 0); @@ -942,12 +974,47 @@ _dbus_validate_unique_name (const DBusString *str, if (len > DBUS_MAXIMUM_NAME_LENGTH) return FALSE; - _dbus_assert (len > 0); + if (len == 0) + return FALSE; - name = _dbus_string_get_const_data (str) + start; - end = name + len; - _dbus_assert (*name == ':'); - s = name + 1; + last_dot = NULL; + iface = _dbus_string_get_const_data (str) + start; + end = iface + len; + s = iface; + + /* check special cases of first char so it doesn't have to be done + * in the loop. Note we know len > 0 + */ + if (*s == ':') + { + /* unique name */ + ++s; + while (s != end) + { + if (*s == '.') + { + if (_DBUS_UNLIKELY ((s + 1) == end)) + return FALSE; + if (_DBUS_UNLIKELY (!VALID_BUS_NAME_CHARACTER (*(s + 1)))) + return FALSE; + ++s; /* we just validated the next char, so skip two */ + } + else if (_DBUS_UNLIKELY (!VALID_BUS_NAME_CHARACTER (*s))) + { + return FALSE; + } + + ++s; + } + + return TRUE; + } + else if (_DBUS_UNLIKELY (*s == '.')) /* disallow starting with a . */ + return FALSE; + else if (_DBUS_UNLIKELY (!VALID_INITIAL_BUS_NAME_CHARACTER (*s))) + return FALSE; + else + ++s; while (s != end) { @@ -955,11 +1022,12 @@ _dbus_validate_unique_name (const DBusString *str, { if (_DBUS_UNLIKELY ((s + 1) == end)) return FALSE; - if (_DBUS_UNLIKELY (!VALID_NAME_CHARACTER (*(s + 1)))) + else if (_DBUS_UNLIKELY (!VALID_INITIAL_BUS_NAME_CHARACTER (*(s + 1)))) return FALSE; + last_dot = s; ++s; /* we just validated the next char, so skip two */ } - else if (_DBUS_UNLIKELY (!VALID_NAME_CHARACTER (*s))) + else if (_DBUS_UNLIKELY (!VALID_BUS_NAME_CHARACTER (*s))) { return FALSE; } @@ -967,33 +1035,10 @@ _dbus_validate_unique_name (const DBusString *str, ++s; } - 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) -{ - if (_DBUS_UNLIKELY (len == 0)) + if (_DBUS_UNLIKELY (last_dot == NULL)) return FALSE; - if (_dbus_string_get_byte (str, start) == ':') - return _dbus_validate_unique_name (str, start, len); - else - return _dbus_validate_interface (str, start, len); + + return TRUE; } /** |