diff options
author | Simon McVittie <simon.mcvittie@collabora.co.uk> | 2011-03-14 11:53:09 +0000 |
---|---|---|
committer | Simon McVittie <simon.mcvittie@collabora.co.uk> | 2011-03-14 11:53:09 +0000 |
commit | 2adf484fb39853bfc4bc9a43fb73d0fc935e92c9 (patch) | |
tree | 326b92827be4104196d956d41e8263d8e58c5661 | |
parent | 2c34514620c4b79ea4ec71d1db583379138d01ac (diff) | |
download | dbus-2adf484fb39853bfc4bc9a43fb73d0fc935e92c9.tar.gz |
Revert merge of master (dbus-1.5) into dbus-1.4
This reverts commits d1d395774435..09c9d6406b75f, keeping Lennart's
addition of UnknownInterface etc.
-rw-r--r-- | NEWS | 8 | ||||
-rw-r--r-- | bus/driver.c | 179 | ||||
-rw-r--r-- | configure.ac | 46 | ||||
-rw-r--r-- | dbus/dbus-connection.c | 3 | ||||
-rw-r--r-- | dbus/dbus-marshal-basic.c | 38 | ||||
-rw-r--r-- | dbus/dbus-marshal-basic.h | 1 | ||||
-rw-r--r-- | dbus/dbus-marshal-validate.c | 4 | ||||
-rw-r--r-- | dbus/dbus-message-factory.c | 3 | ||||
-rw-r--r-- | dbus/dbus-signature.c | 53 | ||||
-rw-r--r-- | dbus/dbus-signature.h | 3 | ||||
-rw-r--r-- | dbus/dbus-string-util.c | 88 | ||||
-rw-r--r-- | dbus/dbus-string.c | 43 | ||||
-rw-r--r-- | test/break-loader.c | 2 |
13 files changed, 167 insertions, 304 deletions
@@ -1,11 +1,3 @@ -D-Bus 1.5.0 (UNRELEASED) -== - - • Let the bus daemon implement more than one interface (fd.o #33757, - Simon McVittie) - • Optimize _dbus_string_replace_len to reduce waste (fd.o #21261, - Roberto Guido) - D-Bus 1.4.8 (UNRELEASED) == diff --git a/bus/driver.c b/bus/driver.c index 1e9573ee..cc8d1f26 100644 --- a/bus/driver.c +++ b/bus/driver.c @@ -1644,7 +1644,11 @@ bus_driver_handle_get_id (DBusConnection *connection, return FALSE; } -typedef struct +/* For speed it might be useful to sort this in order of + * frequency of use (but doesn't matter with only a few items + * anyhow) + */ +static struct { const char *name; const char *in_args; @@ -1653,13 +1657,7 @@ typedef struct BusTransaction *transaction, DBusMessage *message, DBusError *error); -} MessageHandler; - -/* For speed it might be useful to sort this in order of - * frequency of use (but doesn't matter with only a few items - * anyhow) - */ -static const MessageHandler dbus_message_handlers[] = { +} message_handlers[] = { { "Hello", "", DBUS_TYPE_STRING_AS_STRING, @@ -1731,41 +1729,7 @@ static const MessageHandler dbus_message_handlers[] = { { "GetId", "", DBUS_TYPE_STRING_AS_STRING, - bus_driver_handle_get_id }, - { NULL, NULL, NULL, NULL } -}; - -static dbus_bool_t bus_driver_handle_introspect (DBusConnection *, - BusTransaction *, DBusMessage *, DBusError *); - -static const MessageHandler introspectable_message_handlers[] = { - { "Introspect", "", DBUS_TYPE_STRING_AS_STRING, bus_driver_handle_introspect }, - { NULL, NULL, NULL, NULL } -}; - -typedef struct { - const char *name; - const MessageHandler *message_handlers; - const char *extra_introspection; -} InterfaceHandler; - -/* These should ideally be sorted by frequency of use, although it - * probably doesn't matter with this few items */ -static InterfaceHandler interface_handlers[] = { - { DBUS_INTERFACE_DBUS, dbus_message_handlers, - " <signal name=\"NameOwnerChanged\">\n" - " <arg type=\"s\"/>\n" - " <arg type=\"s\"/>\n" - " <arg type=\"s\"/>\n" - " </signal>\n" - " <signal name=\"NameLost\">\n" - " <arg type=\"s\"/>\n" - " </signal>\n" - " <signal name=\"NameAcquired\">\n" - " <arg type=\"s\"/>\n" - " </signal>\n" }, - { DBUS_INTERFACE_INTROSPECTABLE, introspectable_message_handlers, NULL }, - { NULL, NULL, NULL } + bus_driver_handle_get_id } }; static dbus_bool_t @@ -1806,43 +1770,86 @@ write_args_for_direction (DBusString *xml, dbus_bool_t bus_driver_generate_introspect_string (DBusString *xml) { - const InterfaceHandler *ih; - const MessageHandler *mh; + int i; if (!_dbus_string_append (xml, DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE)) return FALSE; if (!_dbus_string_append (xml, "<node>\n")) return FALSE; + if (!_dbus_string_append_printf (xml, " <interface name=\"%s\">\n", DBUS_INTERFACE_INTROSPECTABLE)) + return FALSE; + if (!_dbus_string_append (xml, " <method name=\"Introspect\">\n")) + return FALSE; + if (!_dbus_string_append_printf (xml, " <arg name=\"data\" direction=\"out\" type=\"%s\"/>\n", DBUS_TYPE_STRING_AS_STRING)) + return FALSE; + if (!_dbus_string_append (xml, " </method>\n")) + return FALSE; + if (!_dbus_string_append (xml, " </interface>\n")) + return FALSE; + + if (!_dbus_string_append_printf (xml, " <interface name=\"%s\">\n", + DBUS_INTERFACE_DBUS)) + return FALSE; - for (ih = interface_handlers; ih->name != NULL; ih++) + i = 0; + while (i < _DBUS_N_ELEMENTS (message_handlers)) { - if (!_dbus_string_append_printf (xml, " <interface name=\"%s\">\n", - ih->name)) + + if (!_dbus_string_append_printf (xml, " <method name=\"%s\">\n", + message_handlers[i].name)) return FALSE; - for (mh = ih->message_handlers; mh->name != NULL; mh++) - { - if (!_dbus_string_append_printf (xml, " <method name=\"%s\">\n", - mh->name)) - return FALSE; + if (!write_args_for_direction (xml, message_handlers[i].in_args, TRUE)) + return FALSE; - if (!write_args_for_direction (xml, mh->in_args, TRUE)) - return FALSE; + if (!write_args_for_direction (xml, message_handlers[i].out_args, FALSE)) + return FALSE; - if (!write_args_for_direction (xml, mh->out_args, FALSE)) - return FALSE; + if (!_dbus_string_append (xml, " </method>\n")) + return FALSE; - if (!_dbus_string_append (xml, " </method>\n")) - return FALSE; - } + ++i; + } + + if (!_dbus_string_append_printf (xml, " <signal name=\"NameOwnerChanged\">\n")) + return FALSE; + + if (!_dbus_string_append_printf (xml, " <arg type=\"s\"/>\n")) + return FALSE; + + if (!_dbus_string_append_printf (xml, " <arg type=\"s\"/>\n")) + return FALSE; + + if (!_dbus_string_append_printf (xml, " <arg type=\"s\"/>\n")) + return FALSE; + + if (!_dbus_string_append_printf (xml, " </signal>\n")) + return FALSE; - if (ih->extra_introspection != NULL && - !_dbus_string_append (xml, ih->extra_introspection)) - return FALSE; - if (!_dbus_string_append (xml, " </interface>\n")) - return FALSE; - } + + if (!_dbus_string_append_printf (xml, " <signal name=\"NameLost\">\n")) + return FALSE; + + if (!_dbus_string_append_printf (xml, " <arg type=\"s\"/>\n")) + return FALSE; + + if (!_dbus_string_append_printf (xml, " </signal>\n")) + return FALSE; + + + + if (!_dbus_string_append_printf (xml, " <signal name=\"NameAcquired\">\n")) + return FALSE; + + if (!_dbus_string_append_printf (xml, " <arg type=\"s\"/>\n")) + return FALSE; + + if (!_dbus_string_append_printf (xml, " </signal>\n")) + return FALSE; + + if (!_dbus_string_append (xml, " </interface>\n")) + return FALSE; if (!_dbus_string_append (xml, "</node>\n")) return FALSE; @@ -1919,8 +1926,7 @@ bus_driver_handle_message (DBusConnection *connection, DBusError *error) { const char *name, *sender, *interface; - const InterfaceHandler *ih; - const MessageHandler *mh; + int i; _DBUS_ASSERT_ERROR_IS_CLEAR (error); @@ -1938,48 +1944,57 @@ bus_driver_handle_message (DBusConnection *connection, return TRUE; /* we just ignore this */ } - /* may be NULL, which means "any interface will do" */ + if (dbus_message_is_method_call (message, + DBUS_INTERFACE_INTROSPECTABLE, + "Introspect")) + return bus_driver_handle_introspect (connection, transaction, message, error); + interface = dbus_message_get_interface (message); + if (interface == NULL) + interface = DBUS_INTERFACE_DBUS; _dbus_assert (dbus_message_get_member (message) != NULL); name = dbus_message_get_member (message); sender = dbus_message_get_sender (message); + if (strcmp (interface, + DBUS_INTERFACE_DBUS) != 0) + { + _dbus_verbose ("Driver got message to unknown interface \"%s\"\n", + interface); + goto unknown; + } + _dbus_verbose ("Driver got a method call: %s\n", dbus_message_get_member (message)); /* security checks should have kept this from getting here */ _dbus_assert (sender != NULL || strcmp (name, "Hello") == 0); - for (ih = interface_handlers; ih->name != NULL; ih++) + i = 0; + while (i < _DBUS_N_ELEMENTS (message_handlers)) { - if (interface != NULL && strcmp (interface, ih->name) != 0) - continue; - - for (mh = ih->message_handlers; mh->name != NULL; mh++) + if (strcmp (message_handlers[i].name, name) == 0) { - if (strcmp (mh->name, name) != 0) - continue; - _dbus_verbose ("Found driver handler for %s\n", name); - if (!dbus_message_has_signature (message, mh->in_args)) + if (!dbus_message_has_signature (message, message_handlers[i].in_args)) { _DBUS_ASSERT_ERROR_IS_CLEAR (error); _dbus_verbose ("Call to %s has wrong args (%s, expected %s)\n", name, dbus_message_get_signature (message), - mh->in_args); + message_handlers[i].in_args); dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, "Call to %s has wrong args (%s, expected %s)\n", name, dbus_message_get_signature (message), - mh->in_args); + message_handlers[i].in_args); _DBUS_ASSERT_ERROR_IS_SET (error); return FALSE; } - if ((* mh->handler) (connection, transaction, message, error)) + if ((* message_handlers[i].handler) (connection, transaction, message, error)) { _DBUS_ASSERT_ERROR_IS_CLEAR (error); _dbus_verbose ("Driver handler succeeded\n"); @@ -1992,6 +2007,8 @@ bus_driver_handle_message (DBusConnection *connection, return FALSE; } } + + ++i; } unknown: diff --git a/configure.ac b/configure.ac index ced95e4b..03914e17 100644 --- a/configure.ac +++ b/configure.ac @@ -228,12 +228,6 @@ AC_CHECK_SIZEOF(void *) AC_CHECK_SIZEOF(long long) AC_CHECK_SIZEOF(__int64) -AC_ARG_WITH([64-bit], - [AS_HELP_STRING([--without-64-bit], - [If you have to use this option, please report it as a bug])], - [], - [with_64_bit=yes]) - ### See what our 64 bit type is called AC_MSG_CHECKING([64-bit integer type]) @@ -271,32 +265,13 @@ $ac_cv_sizeof___int64) ;; esac -AS_IF( - [test "x$with_64_bit" = xno], - [ +if test -z "$dbusint64" ; then DBUS_INT64_TYPE="no_int64_type_detected" DBUS_HAVE_INT64=0 DBUS_INT64_CONSTANT= DBUS_UINT64_CONSTANT= - AC_MSG_RESULT([disabled via --without-64-bit]) - ], - dnl else if - [test -z "$dbusint64"], - [AC_MSG_RESULT([not found]) - AC_MSG_ERROR([Could not find a 64-bit integer type. - -Please report a bug here with details of your platform and compiler: - - http://bugs.freedesktop.org/enter_bug.cgi?product=DBus&component=core - -To compile D-Bus with all 64-bit integer types removed (not recommended), use -the option "--without-64-bit". - -This option is likely to be removed in future, unless you report that your -platform needs it.]) - ], - dnl else - [ + AC_MSG_RESULT([none found]) +else DBUS_INT64_TYPE="$dbusint64" DBUS_HAVE_INT64=1 DBUS_INT64_CONSTANT="$dbusint64_constant" @@ -305,7 +280,7 @@ platform needs it.]) AC_DEFINE_UNQUOTED(DBUS_INT64_PRINTF_MODIFIER, [$dbusint64_printf_modifier], [Define to printf modifier for 64 bit integer type]) fi AC_MSG_RESULT($DBUS_INT64_TYPE) - ]) +fi AC_SUBST(DBUS_INT64_TYPE) AC_SUBST(DBUS_INT64_CONSTANT) @@ -1770,16 +1745,3 @@ if test x$dbus_use_libxml = xtrue; then echo echo "WARNING: You have chosen to use libxml as your xml parser however this code path is not maintained by the D-Bus developers and if it breaks you get to keep the pieces. If you have selected this option in err please reconfigure with expat (e.g. --with-xml=expat)." fi - -if test "x$DBUS_HAVE_INT64" = x0; then - AC_MSG_WARN([You have disabled 64-bit integers via --without-64-bit. - - This removes parts of the standard D-Bus API and ABI (the 't' and 'x' - typecodes, the dbus_int64_t and dbus_uint64_t types, etc.) and should only be - used if your compiler lacks support for 64-bit integers. Please report a bug - with details of your platform and compiler. - - This option is likely to be removed in future, unless the D-Bus developers - receive reports that it is still needed. - ]) -fi diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c index 526a7162..6779b6ae 100644 --- a/dbus/dbus-connection.c +++ b/dbus/dbus-connection.c @@ -38,7 +38,6 @@ #include "dbus-protocol.h" #include "dbus-dataslot.h" #include "dbus-string.h" -#include "dbus-signature.h" #include "dbus-pending-call.h" #include "dbus-object-tree.h" #include "dbus-threads-internal.h" @@ -3096,7 +3095,7 @@ dbus_connection_can_send_type(DBusConnection *connection, { _dbus_return_val_if_fail (connection != NULL, FALSE); - if (!dbus_type_is_valid (type)) + if (!_dbus_type_is_valid(type)) return FALSE; if (type != DBUS_TYPE_UNIX_FD) diff --git a/dbus/dbus-marshal-basic.c b/dbus/dbus-marshal-basic.c index 486f1c01..3cbc7216 100644 --- a/dbus/dbus-marshal-basic.c +++ b/dbus/dbus-marshal-basic.c @@ -1231,6 +1231,44 @@ _dbus_type_get_alignment (int typecode) } } + +/** + * Return #TRUE if the typecode is a valid typecode. + * #DBUS_TYPE_INVALID surprisingly enough is not considered valid, and + * random unknown bytes aren't either. This function is safe with + * untrusted data. + * + * @returns #TRUE if valid + */ +dbus_bool_t +_dbus_type_is_valid (int typecode) +{ + switch (typecode) + { + case DBUS_TYPE_BYTE: + case DBUS_TYPE_BOOLEAN: + case DBUS_TYPE_INT16: + case DBUS_TYPE_UINT16: + 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_OBJECT_PATH: + case DBUS_TYPE_SIGNATURE: + case DBUS_TYPE_ARRAY: + case DBUS_TYPE_STRUCT: + case DBUS_TYPE_DICT_ENTRY: + case DBUS_TYPE_VARIANT: + case DBUS_TYPE_UNIX_FD: + return TRUE; + + default: + return FALSE; + } +} + /** * Returns a string describing the given type. * diff --git a/dbus/dbus-marshal-basic.h b/dbus/dbus-marshal-basic.h index 3c448dff..0c27fc9e 100644 --- a/dbus/dbus-marshal-basic.h +++ b/dbus/dbus-marshal-basic.h @@ -254,6 +254,7 @@ dbus_uint32_t _dbus_marshal_read_uint32 (const DBusString *str, int pos, int byte_order, int *new_pos); +dbus_bool_t _dbus_type_is_valid (int typecode); int _dbus_type_get_alignment (int typecode); dbus_bool_t _dbus_type_is_fixed (int typecode); int _dbus_type_get_alignment (int typecode); diff --git a/dbus/dbus-marshal-validate.c b/dbus/dbus-marshal-validate.c index d87a27b9..4304467d 100644 --- a/dbus/dbus-marshal-validate.c +++ b/dbus/dbus-marshal-validate.c @@ -250,7 +250,7 @@ _dbus_validate_signature_with_reason (const DBusString *type_str, if (last == DBUS_DICT_ENTRY_BEGIN_CHAR) { - if (!(dbus_type_is_valid (*p) && dbus_type_is_basic (*p))) + if (!(_dbus_type_is_valid (*p) && dbus_type_is_basic (*p))) { result = DBUS_INVALID_DICT_KEY_MUST_BE_BASIC_TYPE; goto out; @@ -393,7 +393,7 @@ validate_body_helper (DBusTypeReader *reader, { int array_elem_type = _dbus_type_reader_get_element_type (reader); - if (!dbus_type_is_valid (array_elem_type)) + if (!_dbus_type_is_valid (array_elem_type)) { return DBUS_INVALID_UNKNOWN_TYPECODE; } diff --git a/dbus/dbus-message-factory.c b/dbus/dbus-message-factory.c index 7fae5833..7ecf8270 100644 --- a/dbus/dbus-message-factory.c +++ b/dbus/dbus-message-factory.c @@ -27,7 +27,6 @@ #ifdef DBUS_BUILD_TESTS #include "dbus-message-factory.h" #include "dbus-message-private.h" -#include "dbus-signature.h" #include "dbus-test.h" #include <stdio.h> @@ -979,7 +978,7 @@ find_next_typecode (DBusMessageDataIter *iter, _dbus_assert (byte_seq < _dbus_string_get_length (data)); - if (dbus_type_is_valid (_dbus_string_get_byte (data, byte_seq))) + if (_dbus_type_is_valid (_dbus_string_get_byte (data, byte_seq))) break; else iter_next (iter); diff --git a/dbus/dbus-signature.c b/dbus/dbus-signature.c index c130de5b..9c13ff43 100644 --- a/dbus/dbus-signature.c +++ b/dbus/dbus-signature.c @@ -284,8 +284,7 @@ dbus_signature_validate_single (const char *signature, * container types. #DBUS_TYPE_INVALID is not a container type. * * It is an error to pass an invalid type-code, other than DBUS_TYPE_INVALID, - * to this function. The valid type-codes are defined by dbus-protocol.h - * and can be checked with dbus_type_is_valid(). + * to this function. The valid type-codes are defined by dbus-protocol.h. * * @param typecode either a valid type-code or DBUS_TYPE_INVALID * @returns #TRUE if type is a container @@ -294,7 +293,7 @@ dbus_bool_t dbus_type_is_container (int typecode) { /* only reasonable (non-line-noise) typecodes are allowed */ - _dbus_return_val_if_fail (dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID, + _dbus_return_val_if_fail (_dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID, FALSE); return TYPE_IS_CONTAINER (typecode); } @@ -308,8 +307,7 @@ dbus_type_is_container (int typecode) * type. * * It is an error to pass an invalid type-code, other than DBUS_TYPE_INVALID, - * to this function. The valid type-codes are defined by dbus-protocol.h - * and can be checked with dbus_type_is_valid(). + * to this function. The valid type-codes are defined by dbus-protocol.h. * * @param typecode either a valid type-code or DBUS_TYPE_INVALID * @returns #TRUE if type is basic @@ -318,7 +316,7 @@ dbus_bool_t dbus_type_is_basic (int typecode) { /* only reasonable (non-line-noise) typecodes are allowed */ - _dbus_return_val_if_fail (dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID, + _dbus_return_val_if_fail (_dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID, FALSE); /* everything that isn't invalid or a container */ @@ -339,8 +337,7 @@ dbus_type_is_basic (int typecode) * function. * * It is an error to pass an invalid type-code, other than DBUS_TYPE_INVALID, - * to this function. The valid type-codes are defined by dbus-protocol.h - * and can be checked with dbus_type_is_valid(). + * to this function. The valid type-codes are defined by dbus-protocol.h. * * @param typecode either a valid type-code or DBUS_TYPE_INVALID * @returns #FALSE if the type can occupy different lengths @@ -349,7 +346,7 @@ dbus_bool_t dbus_type_is_fixed (int typecode) { /* only reasonable (non-line-noise) typecodes are allowed */ - _dbus_return_val_if_fail (dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID, + _dbus_return_val_if_fail (_dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID, FALSE); switch (typecode) @@ -370,44 +367,6 @@ dbus_type_is_fixed (int typecode) } } -/** - * Return #TRUE if the argument is a valid typecode. - * #DBUS_TYPE_INVALID surprisingly enough is not considered valid, and - * random unknown bytes aren't either. This function is safe with - * untrusted data. - * - * @param typecode a potential type-code - * @returns #TRUE if valid - */ -dbus_bool_t -dbus_type_is_valid (int typecode) -{ - switch (typecode) - { - case DBUS_TYPE_BYTE: - case DBUS_TYPE_BOOLEAN: - case DBUS_TYPE_INT16: - case DBUS_TYPE_UINT16: - 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_OBJECT_PATH: - case DBUS_TYPE_SIGNATURE: - case DBUS_TYPE_ARRAY: - case DBUS_TYPE_STRUCT: - case DBUS_TYPE_DICT_ENTRY: - case DBUS_TYPE_VARIANT: - case DBUS_TYPE_UNIX_FD: - return TRUE; - - default: - return FALSE; - } -} - /** @} */ /* end of DBusSignature group */ #ifdef DBUS_BUILD_TESTS diff --git a/dbus/dbus-signature.h b/dbus/dbus-signature.h index 443941c8..ebf00c1e 100644 --- a/dbus/dbus-signature.h +++ b/dbus/dbus-signature.h @@ -79,9 +79,6 @@ dbus_bool_t dbus_signature_validate_single (const char *signatur DBusError *error); DBUS_EXPORT -dbus_bool_t dbus_type_is_valid (int typecode); - -DBUS_EXPORT dbus_bool_t dbus_type_is_basic (int typecode); DBUS_EXPORT dbus_bool_t dbus_type_is_container (int typecode); diff --git a/dbus/dbus-string-util.c b/dbus/dbus-string-util.c index b31703ca..4d42bb0b 100644 --- a/dbus/dbus-string-util.c +++ b/dbus/dbus-string-util.c @@ -266,7 +266,7 @@ _dbus_string_test (void) { DBusString str; DBusString other; - int i, a, end; + int i, end; long v; double d; int lens[] = { 0, 1, 2, 3, 4, 5, 10, 16, 17, 18, 25, 31, 32, 33, 34, 35, 63, 64, 65, 66, 67, 68, 69, 70, 71, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136 }; @@ -513,94 +513,10 @@ _dbus_string_test (void) _dbus_assert (_dbus_string_get_length (&other) == i * 2 - 1); _dbus_assert (_dbus_string_equal_c_str (&other, "HelloHello WorldWorle")); - - _dbus_string_free (&str); - _dbus_string_free (&other); - - /* Different tests are provided because different behaviours are - * implemented in _dbus_string_replace_len() in function of replacing and - * replaced lengths - */ - - if (!_dbus_string_init (&str)) - _dbus_assert_not_reached ("failed to init string"); - - if (!_dbus_string_append (&str, "Hello World")) - _dbus_assert_not_reached ("could not append to string"); - - i = _dbus_string_get_length (&str); - if (!_dbus_string_init (&other)) - _dbus_assert_not_reached ("could not init string"); - - if (!_dbus_string_append (&other, "Foo String")) - _dbus_assert_not_reached ("could not append to string"); - - a = _dbus_string_get_length (&other); - - if (!_dbus_string_replace_len (&str, 0, 6, - &other, 4, 0)) - _dbus_assert_not_reached ("could not replace 0 length"); - - _dbus_assert (_dbus_string_get_length (&str) == i); - _dbus_assert (_dbus_string_get_length (&other) == a + 6); - _dbus_assert (_dbus_string_equal_c_str (&other, - "Foo Hello String")); - - if (!_dbus_string_replace_len (&str, 5, 6, - &other, - _dbus_string_get_length (&other), - 0)) - _dbus_assert_not_reached ("could not replace at the end"); - - _dbus_assert (_dbus_string_get_length (&str) == i); - _dbus_assert (_dbus_string_get_length (&other) == a + 6 + 6); - _dbus_assert (_dbus_string_equal_c_str (&other, - "Foo Hello String World")); - - if (!_dbus_string_replace_len (&str, 0, 5, - &other, - _dbus_string_get_length (&other) - 5, - 5)) - _dbus_assert_not_reached ("could not replace same length"); - - _dbus_assert (_dbus_string_get_length (&str) == i); - _dbus_assert (_dbus_string_get_length (&other) == a + 6 + 6); - _dbus_assert (_dbus_string_equal_c_str (&other, - "Foo Hello String Hello")); - - if (!_dbus_string_replace_len (&str, 6, 5, - &other, 4, 12)) - _dbus_assert_not_reached ("could not replace with shorter string"); - - _dbus_assert (_dbus_string_get_length (&str) == i); - _dbus_assert (_dbus_string_get_length (&other) == a + 5); - _dbus_assert (_dbus_string_equal_c_str (&other, - "Foo World Hello")); - - if (!_dbus_string_replace_len (&str, 0, 1, - &other, 0, 3)) - _dbus_assert_not_reached ("could not replace at the beginning"); - - _dbus_assert (_dbus_string_get_length (&str) == i); - _dbus_assert (_dbus_string_get_length (&other) == a + 3); - _dbus_assert (_dbus_string_equal_c_str (&other, - "H World Hello")); - - if (!_dbus_string_replace_len (&str, 6, 5, - &other, - _dbus_string_get_length (&other) - 5, - 5)) - _dbus_assert_not_reached ("could not replace same length"); - - _dbus_assert (_dbus_string_get_length (&str) == i); - _dbus_assert (_dbus_string_get_length (&other) == a + 3); - _dbus_assert (_dbus_string_equal_c_str (&other, - "H World World")); - _dbus_string_free (&str); _dbus_string_free (&other); - + /* Check append/get unichar */ if (!_dbus_string_init (&str)) diff --git a/dbus/dbus-string.c b/dbus/dbus-string.c index 2471f46d..e2eb93b9 100644 --- a/dbus/dbus-string.c +++ b/dbus/dbus-string.c @@ -1635,6 +1635,15 @@ _dbus_string_copy_len (const DBusString *source, /** * Replaces a segment of dest string with a segment of source string. * + * @todo optimize the case where the two lengths are the same, and + * avoid memmoving the data in the trailing part of the string twice. + * + * @todo avoid inserting the source into dest, then deleting + * the replaced chunk of dest (which creates a potentially large + * intermediate string). Instead, extend the replaced chunk + * of dest with padding to the same size as the source chunk, + * then copy in the source bytes. + * * @param source the source string * @param start where to start copying the source string * @param len length of segment to copy @@ -1660,37 +1669,11 @@ _dbus_string_replace_len (const DBusString *source, _dbus_assert (replace_at <= real_dest->len); _dbus_assert (replace_len <= real_dest->len - replace_at); - if (len == replace_len) - { - memmove (real_dest->str + replace_at, - real_source->str + start, len); - } - else if (len < replace_len) - { - memmove (real_dest->str + replace_at, - real_source->str + start, len); - delete (real_dest, replace_at + len, - replace_len - len); - } - else - { - int diff; - - _dbus_assert (len > replace_len); - - diff = len - replace_len; - - /* First of all we check if destination string can be enlarged as - * required, then we overwrite previous bytes - */ - - if (!copy (real_source, start + replace_len, diff, - real_dest, replace_at + replace_len)) - return FALSE; + if (!copy (real_source, start, len, + real_dest, replace_at)) + return FALSE; - memmove (real_dest->str + replace_at, - real_source->str + start, replace_len); - } + delete (real_dest, replace_at + len, replace_len); return TRUE; } diff --git a/test/break-loader.c b/test/break-loader.c index 542f36ff..7bfa7227 100644 --- a/test/break-loader.c +++ b/test/break-loader.c @@ -446,7 +446,7 @@ randomly_change_one_type (const DBusString *orig_data, { int b; b = _dbus_string_get_byte (mutated, i); - if (dbus_type_is_valid (b)) + if (_dbus_type_is_valid (b)) { _dbus_string_set_byte (mutated, i, random_type ()); return; |