summaryrefslogtreecommitdiffstats
path: root/dbus/dbus-string.c
diff options
context:
space:
mode:
authorHavoc Pennington <hp@redhat.com>2004-11-26 01:53:13 +0000
committerHavoc Pennington <hp@redhat.com>2004-11-26 01:53:13 +0000
commitdbdea921b5967ed25b24a9e5af5d6a3db54c5ec7 (patch)
treee9224f077138d6e7d7c8ffe4dc4fb68ab6e0c355 /dbus/dbus-string.c
parent2ce2ab4368d9b037c51cd3cb4ef39e3f7ade8b00 (diff)
2004-11-25 Havoc Pennington <hp@redhat.com>
The primary change here is to always write() once before adding the write watch, which gives us about a 10% performance increase. * dbus/dbus-transport-unix.c: a number of modifications to cope with removing messages_pending (check_write_watch): properly handle DBUS_AUTH_STATE_WAITING_FOR_MEMORY; adapt to removal of messages_pending stuff (check_read_watch): properly handle WAITING_FOR_MEMORY and AUTHENTICATED cases (unix_handle_watch): after writing, see if the write watch can be removed (unix_do_iteration): assert that write_watch/read_watch are non-NULL rather than testing that they aren't, since they aren't allowed to be NULL. check_write_watch() at the end so we add the watch if we did not finish writing (e.g. got EAGAIN) * dbus/dbus-transport-protected.h: remove messages_pending call, since it resulted in too much inefficient watch adding/removing; instead we now require that the transport user does an iteration after queueing outgoing messages, and after trying the first write() we add a write watch if we got EAGAIN or exceeded our max bytes to write per iteration setting * dbus/dbus-string.c (_dbus_string_validate_signature): add this function * dbus/dbus-server-unix.c (unix_finalize): the socket name was freed and then accessed, valgrind flagged this bug, fix it * dbus/dbus-message.c: fix several bugs where HEADER_FIELD_LAST was taken as the last valid field plus 1, where really it is equal to the last valid field. Corrects some message corruption issues. * dbus/dbus-mainloop.c: verbosity changes * dbus/dbus-keyring.c (_dbus_keyring_new_homedir): handle OOM instead of aborting in one of the test codepaths * dbus/dbus-internals.c (_dbus_verbose_real): fix a bug that caused not printing the pid ever again if a verbose was missing the newline at the end (_dbus_header_field_to_string): add HEADER_FIELD_SIGNATURE * dbus/dbus-connection.c: verbosity changes; (dbus_connection_has_messages_to_send): new function (_dbus_connection_message_sent): no longer call transport->messages_pending (_dbus_connection_send_preallocated_unlocked): do one iteration to try to write() immediately, so we can avoid the write watch. This is the core purpose of this patchset (_dbus_connection_get_dispatch_status_unlocked): if disconnected, dump the outgoing message queue, so nobody will get confused trying to send them or thinking stuff is pending to be sent * bus/test.c: verbosity changes * bus/driver.c: verbosity/assertion changes * bus/dispatch.c: a bunch of little tweaks to get it working again because this patchset changes when/where you need to block.
Diffstat (limited to 'dbus/dbus-string.c')
-rw-r--r--dbus/dbus-string.c126
1 files changed, 117 insertions, 9 deletions
diff --git a/dbus/dbus-string.c b/dbus/dbus-string.c
index 1611ff02..87969912 100644
--- a/dbus/dbus-string.c
+++ b/dbus/dbus-string.c
@@ -1,7 +1,7 @@
/* -*- mode: C; c-file-style: "gnu" -*- */
/* dbus-string.c String utility class (internal to D-BUS implementation)
*
- * Copyright (C) 2002, 2003 Red Hat, Inc.
+ * Copyright (C) 2002, 2003, 2004 Red Hat, Inc.
*
* Licensed under the Academic Free License version 2.1
*
@@ -2362,7 +2362,7 @@ _dbus_string_hex_decode (const DBusString *source,
* string, returns #FALSE.
*
* @todo this is inconsistent with most of DBusString in that
- * it allows a start,len range that isn't in the string.
+ * it allows a start,len range that extends past the string end.
*
* @param str the string
* @param start first byte index to check
@@ -2406,7 +2406,7 @@ _dbus_string_validate_ascii (const DBusString *str,
* boundaries, returns #FALSE.
*
* @todo this is inconsistent with most of DBusString in that
- * it allows a start,len range that isn't in the string.
+ * it allows a start,len range that extends past the string end.
*
* @param str the string
* @param start first byte index to check
@@ -2504,7 +2504,7 @@ _dbus_string_validate_utf8 (const DBusString *str,
* #FALSE.
*
* @todo this is inconsistent with most of DBusString in that
- * it allows a start,len range that isn't in the string.
+ * it allows a start,len range that extends past the string end.
*
* @param str the string
* @param start first byte index to check
@@ -2545,7 +2545,7 @@ _dbus_string_validate_nul (const DBusString *str,
* to be done separately for now.
*
* @todo this is inconsistent with most of DBusString in that
- * it allows a start,len range that isn't in the string.
+ * it allows a start,len range that extends past the string end.
*
* @todo change spec to disallow more things, such as spaces in the
* path name
@@ -2631,7 +2631,7 @@ _dbus_string_validate_path (const DBusString *str,
* ASCII subset, see the specification.
*
* @todo this is inconsistent with most of DBusString in that
- * it allows a start,len range that isn't in the string.
+ * it allows a start,len range that extends past the string end.
*
* @param str the string
* @param start first byte index to check
@@ -2708,7 +2708,7 @@ _dbus_string_validate_interface (const DBusString *str,
* see the specification.
*
* @todo this is inconsistent with most of DBusString in that
- * it allows a start,len range that isn't in the string.
+ * it allows a start,len range that extends past the string end.
*
* @param str the string
* @param start first byte index to check
@@ -2770,7 +2770,7 @@ _dbus_string_validate_member (const DBusString *str,
* see the specification.
*
* @todo this is inconsistent with most of DBusString in that
- * it allows a start,len range that isn't in the string.
+ * it allows a start,len range that extends past the string end.
*
* @param str the string
* @param start first byte index to check
@@ -2841,7 +2841,7 @@ _dbus_string_validate_base_service (const DBusString *str,
* see the specification.
*
* @todo this is inconsistent with most of DBusString in that
- * it allows a start,len range that isn't in the string.
+ * it allows a start,len range that extends past the string end.
*
* @param str the string
* @param start first byte index to check
@@ -2862,6 +2862,64 @@ _dbus_string_validate_service (const DBusString *str,
}
/**
+ * Checks that the given range of the string is a valid message type
+ * signature in the D-BUS protocol.
+ *
+ * @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 signature
+ */
+dbus_bool_t
+_dbus_string_validate_signature (const DBusString *str,
+ int start,
+ int len)
+{
+ const unsigned char *s;
+ const unsigned char *end;
+ DBUS_CONST_STRING_PREAMBLE (str);
+ _dbus_assert (start >= 0);
+ _dbus_assert (start <= real->len);
+ _dbus_assert (len >= 0);
+
+ if (len > real->len - start)
+ return FALSE;
+
+ s = real->str + start;
+ end = s + len;
+ while (s != end)
+ {
+ switch (*s)
+ {
+ case DBUS_TYPE_NIL:
+ case DBUS_TYPE_BYTE:
+ case DBUS_TYPE_BOOLEAN:
+ case DBUS_TYPE_INT32:
+ case DBUS_TYPE_UINT32:
+ case DBUS_TYPE_INT64:
+ case DBUS_TYPE_UINT64:
+ case DBUS_TYPE_DOUBLE:
+ case DBUS_TYPE_STRING:
+ case DBUS_TYPE_CUSTOM:
+ case DBUS_TYPE_ARRAY:
+ case DBUS_TYPE_DICT:
+ case DBUS_TYPE_OBJECT_PATH:
+ break;
+
+ default:
+ return FALSE;
+ }
+
+ ++s;
+ }
+
+ return TRUE;
+}
+
+/**
* Clears all allocated bytes in the string to zero.
*
* @param str the string
@@ -3227,6 +3285,21 @@ _dbus_string_test (void)
" ",
"foo bar"
};
+
+ const char *valid_signatures[] = {
+ "",
+ "sss",
+ "i",
+ "b"
+ };
+
+ const char *invalid_signatures[] = {
+ " ",
+ "not a valid signature",
+ "123",
+ ".",
+ "("
+ };
i = 0;
while (i < _DBUS_N_ELEMENTS (lens))
@@ -3811,6 +3884,37 @@ _dbus_string_test (void)
++i;
}
+ /* Signature validation */
+ i = 0;
+ while (i < (int) _DBUS_N_ELEMENTS (valid_signatures))
+ {
+ _dbus_string_init_const (&str, valid_signatures[i]);
+
+ if (!_dbus_string_validate_signature (&str, 0,
+ _dbus_string_get_length (&str)))
+ {
+ _dbus_warn ("Signature \"%s\" should have been valid\n", valid_signatures[i]);
+ _dbus_assert_not_reached ("invalid signature");
+ }
+
+ ++i;
+ }
+
+ i = 0;
+ while (i < (int) _DBUS_N_ELEMENTS (invalid_signatures))
+ {
+ _dbus_string_init_const (&str, invalid_signatures[i]);
+
+ if (_dbus_string_validate_signature (&str, 0,
+ _dbus_string_get_length (&str)))
+ {
+ _dbus_warn ("Signature \"%s\" should have been invalid\n", invalid_signatures[i]);
+ _dbus_assert_not_reached ("valid signature");
+ }
+
+ ++i;
+ }
+
/* Validate claimed length longer than real length */
_dbus_string_init_const (&str, "abc.efg");
if (_dbus_string_validate_service (&str, 0, 8))
@@ -3824,6 +3928,10 @@ _dbus_string_test (void)
if (_dbus_string_validate_member (&str, 0, 4))
_dbus_assert_not_reached ("validated too-long string");
+ _dbus_string_init_const (&str, "sss");
+ if (_dbus_string_validate_signature (&str, 0, 4))
+ _dbus_assert_not_reached ("validated too-long signature");
+
/* Validate string exceeding max name length */
if (!_dbus_string_init (&str))
_dbus_assert_not_reached ("no memory");