/** * 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 *iface; const unsigned char *last_dot; _dbus_assert (start >= 0); _dbus_assert (len >= 0); _dbus_assert (start <= _dbus_string_get_length (str)); if (len > _dbus_string_get_length (str) - start) return FALSE; if (len > DBUS_MAXIMUM_NAME_LENGTH) return FALSE; if (len == 0) return FALSE; 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) { if (*s == '.') { if (_DBUS_UNLIKELY ((s + 1) == end)) return FALSE; 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_BUS_NAME_CHARACTER (*s))) { return FALSE; } ++s; } if (_DBUS_UNLIKELY (last_dot == NULL)) return FALSE; return TRUE; }
static gboolean validate_bus_name (const char *name) { int len; const char *s; const char *end; const char *last_dot; gboolean ret; s = name; len = strlen (name); end = name + len; last_dot = NULL; ret = FALSE; /* 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 (G_UNLIKELY ((s + 1) == end)) goto error; if (G_UNLIKELY (!VALID_BUS_NAME_CHARACTER (*(s + 1)))) goto error; ++s; /* we just validated the next char, so skip two */ } else if (G_UNLIKELY (!VALID_BUS_NAME_CHARACTER (*s))) { goto error; } ++s; } return TRUE; } else if (G_UNLIKELY (*s == '.')) /* disallow starting with a . */ { goto error; } else if (G_UNLIKELY (!VALID_INITIAL_BUS_NAME_CHARACTER (*s))) { goto error; } else { ++s; } while (s != end) { if (*s == '.') { if (G_UNLIKELY ((s + 1) == end)) goto error; else if (G_UNLIKELY (!VALID_INITIAL_BUS_NAME_CHARACTER (*(s + 1)))) goto error; last_dot = s; ++s; /* we just validated the next char, so skip two */ } else if (G_UNLIKELY (!VALID_BUS_NAME_CHARACTER (*s))) { goto error; } ++s; } if (G_UNLIKELY (last_dot == NULL)) goto error; ret = TRUE; error: if (!ret) HAL_INFO (("name '%s' did not validate", name)); return ret; }