Commit e57a368c authored by Scott James Remnant's avatar Scott James Remnant

bfo22316 - add dbus_message_iter_abandon_container()

It's not currently possible to abandon creation of a container without
either hitting asserts or leaking memory.  This new function allows
that.
Signed-off-by: default avatarScott James Remnant <scott@ubuntu.com>
parent 4bea3ca2
......@@ -1296,8 +1296,8 @@ _dbus_message_test (const char *test_data_dir)
/* uh-oh, error, try and unwind */
_dbus_assert (dbus_message_iter_close_container (&array_iter, &struct_iter));
_dbus_assert (dbus_message_iter_close_container (&array_iter, &iter));
dbus_message_iter_abandon_container (&array_iter, &struct_iter);
dbus_message_iter_abandon_container (&array_iter, &iter);
dbus_message_unref (message);
......
......@@ -2200,6 +2200,35 @@ _dbus_message_iter_close_signature (DBusMessageRealIter *real)
return retval;
}
/**
* Frees the signature string and marks the iterator as not having a
* type_str anymore. Since the new signature is not set, the message
* will generally be hosed after this is called.
*
* @param real an iterator without a type_str
*/
static void
_dbus_message_iter_abandon_signature (DBusMessageRealIter *real)
{
DBusString *str;
_dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
_dbus_assert (real->u.writer.type_str != NULL);
_dbus_assert (real->sig_refcount > 0);
real->sig_refcount -= 1;
if (real->sig_refcount > 0)
return;
_dbus_assert (real->sig_refcount == 0);
str = real->u.writer.type_str;
_dbus_type_writer_remove_types (&real->u.writer);
_dbus_string_free (str);
dbus_free (str);
}
#ifndef DBUS_DISABLE_CHECKS
static dbus_bool_t
_dbus_message_iter_append_check (DBusMessageRealIter *iter)
......@@ -2427,6 +2456,32 @@ dbus_message_iter_close_container (DBusMessageIter *iter,
return ret;
}
/**
* Abandons creation of a contained-typed value and frees resources created
* by dbus_message_iter_open_container(). Once this returns, the message
* is hosed and you have to start over building the whole message.
*
* This should only be used to abandon creation of a message when you have
* open containers.
*
* @param iter the append iterator
* @param sub sub-iterator to close
*/
void
dbus_message_iter_abandon_container (DBusMessageIter *iter,
DBusMessageIter *sub)
{
DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
_dbus_return_if_fail (_dbus_message_iter_append_check (real));
_dbus_return_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
_dbus_return_if_fail (_dbus_message_iter_append_check (real_sub));
_dbus_return_if_fail (real_sub->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
_dbus_message_iter_abandon_signature (real);
}
/**
* Sets a flag indicating that the message does not want a reply; if
* this flag is set, the other end of the connection may (but is not
......
......@@ -197,6 +197,8 @@ dbus_bool_t dbus_message_iter_open_container (DBusMessageIter *iter,
DBusMessageIter *sub);
dbus_bool_t dbus_message_iter_close_container (DBusMessageIter *iter,
DBusMessageIter *sub);
void dbus_message_iter_abandon_container (DBusMessageIter *iter,
DBusMessageIter *sub);
void dbus_message_lock (DBusMessage *message);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment