From 628b625b848d264a8c02a58085d7c6fb798b9692 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Tue, 12 Dec 2017 14:04:04 +0000 Subject: [PATCH 5/9] _dbus_message_remove_unknown_fields: Add Signed-off-by: Simon McVittie --- Don't advance the array-reader if we delete a header field: in this case, the beginning of the next header field has occupied the space previously used for the deleted header field, so advancing the pointer would incorrectly cause us to not delete it. --- dbus/dbus-marshal-header.c | 51 ++++++++++++++++++++++++++++++++++++++++++++ dbus/dbus-marshal-header.h | 3 +-- dbus/dbus-message-internal.h | 2 ++ dbus/dbus-message.c | 12 +++++++++++ 4 files changed, 66 insertions(+), 2 deletions(-) diff --git a/dbus/dbus-marshal-header.c b/dbus/dbus-marshal-header.c index a3d73f89..f9a33258 100644 --- a/dbus/dbus-marshal-header.c +++ b/dbus/dbus-marshal-header.c @@ -1514,4 +1514,55 @@ _dbus_header_byteswap (DBusHeader *header, _dbus_string_set_byte (&header->data, BYTE_ORDER_OFFSET, new_order); } +/** + * Remove every header field not known to this version of dbus. + * + * @param header the header + * @returns #FALSE if no memory + */ +dbus_bool_t +_dbus_header_remove_unknown_fields (DBusHeader *header) +{ + DBusTypeReader array; + DBusTypeReader fields_reader; + + _dbus_type_reader_init (&fields_reader, + _dbus_header_get_byte_order (header), + &_dbus_header_signature_str, + FIELDS_ARRAY_SIGNATURE_OFFSET, + &header->data, + FIELDS_ARRAY_LENGTH_OFFSET); + + _dbus_type_reader_recurse (&fields_reader, &array); + + while (_dbus_type_reader_get_current_type (&array) != DBUS_TYPE_INVALID) + { + DBusTypeReader sub; + unsigned char field_code; + + _dbus_type_reader_recurse (&array, &sub); + + _dbus_assert (_dbus_type_reader_get_current_type (&sub) == DBUS_TYPE_BYTE); + _dbus_type_reader_read_basic (&sub, &field_code); + + if (field_code > DBUS_HEADER_FIELD_LAST) + { + if (!reserve_header_padding (header)) + return FALSE; + + if (!_dbus_type_reader_delete (&array, &fields_reader)) + return FALSE; + + correct_header_padding (header); + _dbus_header_cache_invalidate_all (header); + } + else + { + _dbus_type_reader_next (&array); + } + } + + return TRUE; +} + /** @} */ diff --git a/dbus/dbus-marshal-header.h b/dbus/dbus-marshal-header.h index 85547efd..b838e039 100644 --- a/dbus/dbus-marshal-header.h +++ b/dbus/dbus-marshal-header.h @@ -172,7 +172,6 @@ void _dbus_header_byteswap (DBusHeader *header, int new_order); DBUS_PRIVATE_EXPORT char _dbus_header_get_byte_order (const DBusHeader *header); - - +dbus_bool_t _dbus_header_remove_unknown_fields (DBusHeader *header); #endif /* DBUS_MARSHAL_HEADER_H */ diff --git a/dbus/dbus-message-internal.h b/dbus/dbus-message-internal.h index 38c79236..3dcd5621 100644 --- a/dbus/dbus-message-internal.h +++ b/dbus/dbus-message-internal.h @@ -64,6 +64,8 @@ void _dbus_message_add_counter_link (DBusMessage *message, DBusList *link); void _dbus_message_remove_counter (DBusMessage *message, DBusCounter *counter); +DBUS_PRIVATE_EXPORT +dbus_bool_t _dbus_message_remove_unknown_fields (DBusMessage *message); DBUS_PRIVATE_EXPORT DBusMessageLoader* _dbus_message_loader_new (void); diff --git a/dbus/dbus-message.c b/dbus/dbus-message.c index 66a39747..36066848 100644 --- a/dbus/dbus-message.c +++ b/dbus/dbus-message.c @@ -262,6 +262,18 @@ void _dbus_message_get_unix_fds(DBusMessage *message, #endif } +/** + * Remove every header field not known to this version of dbus. + * + * @param message the message + * @returns #FALSE if no memory + */ +dbus_bool_t +_dbus_message_remove_unknown_fields (DBusMessage *message) +{ + return _dbus_header_remove_unknown_fields (&message->header); +} + /** * Sets the serial number of a message. * This can only be done once on a message. -- 2.15.1