summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWaldo Bastian <bastian@kde.org>2005-09-12 08:19:33 +0000
committerWaldo Bastian <bastian@kde.org>2005-09-12 08:19:33 +0000
commit8b34c2c538f182fe29af58f5153b9dd7cdbaf7fa (patch)
treefa5deb39e5b291180a67947d98607809a2a5ff59
parent5e8110d79aa8c11ad76b3e77791e3e6daca0fa32 (diff)
* dbus/dbus-marshal-validate.c, doc/dbus-specification.xml,
test/Makefile.am, test/test-names.c: allow hyphens in bus names.
-rw-r--r--ChangeLog6
-rw-r--r--dbus/dbus-marshal-validate.c127
-rw-r--r--doc/dbus-specification.xml51
-rw-r--r--test/.cvsignore1
-rw-r--r--test/Makefile.am8
-rw-r--r--test/test-names.c79
6 files changed, 219 insertions, 53 deletions
diff --git a/ChangeLog b/ChangeLog
index ebb200fc..68507f6a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2005-09-12 Waldo Bastian <bastian@kde.org>
+
+ * dbus/dbus-marshal-validate.c,
+ doc/dbus-specification.xml, test/Makefile.am,
+ test/test-names.c: allow hyphens in bus names.
+
2005-09-11 Mark McLoughlin <mark@skynet.ie>
* test/data/auth/fallback.auth-script: we don't
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;
}
/**
diff --git a/doc/dbus-specification.xml b/doc/dbus-specification.xml
index 0ea43a87..0194ff42 100644
--- a/doc/dbus-specification.xml
+++ b/doc/dbus-specification.xml
@@ -974,7 +974,7 @@
additional restrictions that apply to interface names
specifically:
<itemizedlist>
- <listitem><para>They are composed of 1 or more elements separated by
+ <listitem><para>Interface names are composed of 1 or more elements separated by
a period ('.') character. All elements must contain at least
one character.
</para>
@@ -984,25 +984,54 @@
</para>
</listitem>
- <listitem><para>They must contain at least one '.' (period)
+ <listitem><para>Interface names must contain at least one '.' (period)
character (and thus at least two elements).
</para></listitem>
- <listitem><para>They must not begin with a '.' (period) character.</para></listitem>
- <listitem><para>They must not exceed the maximum name length.</para></listitem>
+ <listitem><para>Interface names must not begin with a '.' (period) character.</para></listitem>
+ <listitem><para>Interface names must not exceed the maximum name length.</para></listitem>
</itemizedlist>
</para>
</sect3>
<sect3 id="message-protocol-names-bus">
<title>Bus names</title>
<para>
- Bus names have the same restrictions as interface names, with a
- special exception for unique connection names. A unique name's first
- element must start with a colon (':') character. After the colon, any
- characters in "[A-Z][a-z][0-9]_" may appear. Elements after
- the first must follow the usual rules, except that they may start with
- a digit. Bus names not starting with a colon have none of these
- exceptions and follow the same rules as interface names.
+ Connections have one or more bus names associated with them.
+ A connection has exactly one bus name that is a unique connection
+ name. The unique connection name remains with the connection for
+ its entire lifetime.
+ A bus name is of type <literal>STRING</literal>,
+ meaning that it must be valid UTF-8. However, there are also
+ some additional restrictions that apply to bus names
+ specifically:
+ <itemizedlist>
+ <listitem><para>Bus names that start with a colon (':')
+ character are unique connection names.
+ </para>
+ </listitem>
+ <listitem><para>Bus names are composed of 1 or more elements separated by
+ a period ('.') character. All elements must contain at least
+ one character.
+ </para>
+ </listitem>
+ <listitem><para>Each element must only contain the ASCII characters
+ "[A-Z][a-z][0-9]_-". Only elements that are part of a unique
+ connection name may begin with a digit, elements in
+ other bus names must not begin with a digit.
+ </para>
+ </listitem>
+
+ <listitem><para>Bus names must contain at least one '.' (period)
+ character (and thus at least two elements).
+ </para></listitem>
+
+ <listitem><para>Bus names must not begin with a '.' (period) character.</para></listitem>
+ <listitem><para>Bus names must not exceed the maximum name length.</para></listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ Note that the hyphen ('-') character is allowed in bus names but
+ not in interface names.
</para>
</sect3>
<sect3 id="message-protocol-names-member">
diff --git a/test/.cvsignore b/test/.cvsignore
index 20de1a28..f7a65876 100644
--- a/test/.cvsignore
+++ b/test/.cvsignore
@@ -22,3 +22,4 @@ test-sleep-forever
decode-gcov
shell-test
test-shell-service
+test-names
diff --git a/test/Makefile.am b/test/Makefile.am
index e0a25aa4..5f904887 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -14,7 +14,7 @@ INCLUDES=-I$(top_srcdir) $(DBUS_TEST_CFLAGS)
if DBUS_BUILD_TESTS
## break-loader removed for now
-TEST_BINARIES=test-service test-shell-service shell-test spawn-test test-segfault test-exit test-sleep-forever
+TEST_BINARIES=test-service test-names test-shell-service shell-test spawn-test test-segfault test-exit test-sleep-forever
#enable stand alone make check test
TESTS=shell-test
@@ -36,6 +36,11 @@ test_service_SOURCES= \
test-utils.c \
test-utils.h
+test_names_SOURCES= \
+ test-names.c \
+ test-utils.c \
+ test-utils.h
+
##break_loader_SOURCES= \
## break-loader.c
@@ -65,6 +70,7 @@ decode_gcov_SOURCES= \
TEST_LIBS=$(DBUS_TEST_LIBS) $(top_builddir)/dbus/libdbus-convenience.la
test_service_LDADD=$(TEST_LIBS)
+test_names_LDADD=$(TEST_LIBS)
## break_loader_LDADD= $(TEST_LIBS)
test_shell_service_LDADD=$(TEST_LIBS)
shell_test_LDADD=$(TEST_LIBS)
diff --git a/test/test-names.c b/test/test-names.c
new file mode 100644
index 00000000..b29648dc
--- /dev/null
+++ b/test/test-names.c
@@ -0,0 +1,79 @@
+
+#include "test-utils.h"
+
+static DBusLoop *loop;
+
+static void
+die (const char *message)
+{
+ fprintf (stderr, "*** test-names: %s", message);
+ exit (1);
+}
+
+static void
+TestName(DBusConnection *connection, const char *name, int expectedSuccess)
+{
+ DBusError error;
+ dbus_error_init (&error);
+
+ (void) dbus_bus_request_name (connection, name, 0, &error);
+ if (dbus_error_is_set (&error))
+ {
+ if (expectedSuccess)
+ fprintf (stderr, "Error acquiring name '%s': %s\n", name, error.message);
+ else
+ fprintf (stdout, "Expected Error acquiring name '%s': %s\n", name, error.message);
+ _dbus_verbose ("*** Failed to acquire name '%s': %s\n", name,
+ error.message);
+ dbus_error_free (&error);
+ if (expectedSuccess)
+ exit (1);
+ }
+ else
+ {
+ if (!expectedSuccess)
+ fprintf (stderr, "Unexpected Success acquiring name '%s'\n", name);
+ else
+ fprintf (stdout, "Successfully acquired name '%s'\n", name);
+ _dbus_verbose ("*** Managed to acquire name '%s'\n", name);
+ if (!expectedSuccess)
+ exit (1);
+ }
+}
+
+int
+main (int argc,
+ char **argv)
+{
+ DBusError error;
+ int result;
+ DBusConnection *connection;
+
+ dbus_error_init (&error);
+ connection = dbus_bus_get (DBUS_BUS_SESSION, &error);
+ if (connection == NULL)
+ {
+ fprintf (stderr, "*** Failed to open connection to system bus: %s\n",
+ error.message);
+ dbus_error_free (&error);
+ return 1;
+ }
+
+ loop = _dbus_loop_new ();
+ if (loop == NULL)
+ die ("No memory\n");
+
+ if (!test_connection_setup (loop, connection))
+ die ("No memory\n");
+
+ TestName(connection, "org.freedesktop.DBus.Test", TRUE);
+ TestName(connection, "org.freedesktop.DBus.Test-2", TRUE);
+ TestName(connection, "org.freedesktop.DBus.Test_2", TRUE);
+#if 0
+ TestName(connection, "Test_2", TRUE);
+#endif
+
+ _dbus_verbose ("*** Test service name exiting\n");
+
+ return 0;
+}