summaryrefslogtreecommitdiff
path: root/_dbus_bindings/message-append.c
diff options
context:
space:
mode:
authorSimon McVittie <simon.mcvittie@collabora.co.uk>2007-01-16 17:00:00 +0000
committerSimon McVittie <simon.mcvittie@collabora.co.uk>2007-01-16 17:00:00 +0000
commite8d766e1b2d5013e3f2c0a95d43b1dcb5eb00044 (patch)
treedf3fdef2f0cf0afac3621461e7f8350413ea6fe7 /_dbus_bindings/message-append.c
parentbd2baf2aad6a7f5ecf0bf7e867e74077cf733cd6 (diff)
downloaddbus-python-e8d766e1b2d5013e3f2c0a95d43b1dcb5eb00044.tar.gz
Ensure we put the right number of items in a struct or message and add test cases.
This avoids us getting kicked off the bus when trying to put the wrong number of things in a struct - this used to happen, but was masked by the fact that the tests ran with service activation, so the service was just killed and reactivated. Forthcoming changes to get_object make this automatic reactivation not happen (messages will be directed to the unique name by default, so stateful communication can work).
Diffstat (limited to '_dbus_bindings/message-append.c')
-rw-r--r--_dbus_bindings/message-append.c55
1 files changed, 36 insertions, 19 deletions
diff --git a/_dbus_bindings/message-append.c b/_dbus_bindings/message-append.c
index 74faf9f..f629c57 100644
--- a/_dbus_bindings/message-append.c
+++ b/_dbus_bindings/message-append.c
@@ -410,7 +410,8 @@ dbus_py_Message_guess_signature(PyObject *unused UNUSED, PyObject *args)
static int _message_iter_append_pyobject(DBusMessageIter *appender,
DBusSignatureIter *sig_iter,
- PyObject *obj);
+ PyObject *obj,
+ dbus_bool_t *more);
static int _message_iter_append_variant(DBusMessageIter *appender,
PyObject *obj);
@@ -522,6 +523,7 @@ _message_iter_append_dictentry(DBusMessageIter *appender,
DBusMessageIter sub;
int ret = -1;
PyObject *value = PyObject_GetItem(dict, key);
+ dbus_bool_t more;
if (!value) return -1;
@@ -553,9 +555,9 @@ _message_iter_append_dictentry(DBusMessageIter *appender,
PyErr_NoMemory();
goto out;
}
- ret = _message_iter_append_pyobject(&sub, &sub_sig_iter, key);
+ ret = _message_iter_append_pyobject(&sub, &sub_sig_iter, key, &more);
if (ret == 0) {
- ret = _message_iter_append_pyobject(&sub, &sub_sig_iter, value);
+ ret = _message_iter_append_pyobject(&sub, &sub_sig_iter, value, &more);
}
DBG("%s", "Closing DICT_ENTRY container");
if (!dbus_message_iter_close_container(appender, &sub)) {
@@ -581,6 +583,7 @@ _message_iter_append_multi(DBusMessageIter *appender,
int container = mode;
dbus_bool_t is_byte_array = DBusPyByteArray_Check(obj);
int inner_type;
+ dbus_bool_t more;
#ifdef USING_DBG
fprintf(stderr, "Appending multiple: ");
@@ -666,15 +669,27 @@ _message_iter_append_multi(DBusMessageIter *appender,
Py_DECREF(byte);
}
else {
+ /* advances sub_sig_iter and sets more on success - for array
+ * this doesn't matter, for struct it's essential */
ret = _message_iter_append_pyobject(&sub_appender, &sub_sig_iter,
- contents);
+ contents, &more);
}
+
Py_DECREF(contents);
if (ret < 0) {
break;
}
}
- if (PyErr_Occurred()) ret = -1;
+
+ if (PyErr_Occurred()) {
+ ret = -1;
+ }
+ else if (mode == DBUS_TYPE_STRUCT && more) {
+ PyErr_Format(PyExc_TypeError, "More items found in struct's D-Bus "
+ "signature than in Python arguments ");
+ ret = -1;
+ }
+
/* This must be run as cleanup, even on failure. */
DBG("Closing %c container", container);
if (!dbus_message_iter_close_container(appender, &sub_appender)) {
@@ -730,6 +745,7 @@ _message_iter_append_variant(DBusMessageIter *appender, PyObject *obj)
PyObject *obj_sig;
int ret;
long variant_level;
+ dbus_bool_t dummy;
/* Separate the object into the contained object, and the number of
* variants it's wrapped in. */
@@ -777,7 +793,7 @@ _message_iter_append_variant(DBusMessageIter *appender, PyObject *obj)
/* Put the object itself into the innermost variant */
ret = _message_iter_append_pyobject(&variant_iters[variant_level-1],
- &obj_sig_iter, obj);
+ &obj_sig_iter, obj, &dummy);
/* here we rely on i (and variant_level) being a signed long */
for (i = variant_level - 1; i >= 0; i--) {
@@ -804,10 +820,12 @@ out:
return ret;
}
+/* On success, *more is set to whether there's more in the signature. */
static int
_message_iter_append_pyobject(DBusMessageIter *appender,
DBusSignatureIter *sig_iter,
- PyObject *obj)
+ PyObject *obj,
+ dbus_bool_t *more)
{
int sig_type = dbus_signature_iter_get_current_type(sig_iter);
union {
@@ -983,16 +1001,11 @@ _message_iter_append_pyobject(DBusMessageIter *appender,
if (ret < 0) return -1;
DBG("Advancing signature iter at %p", sig_iter);
+ *more = dbus_signature_iter_next(sig_iter);
#ifdef USING_DBG
- {
- dbus_bool_t b =
-#endif
- dbus_signature_iter_next(sig_iter);
-#ifdef USING_DBG
- DBG("- result: %ld, type %02x '%c'", (long)b,
- (int)dbus_signature_iter_get_current_type(sig_iter),
- (int)dbus_signature_iter_get_current_type(sig_iter));
- }
+ DBG("- result: %ld, type %02x '%c'", (long)(*more),
+ (int)dbus_signature_iter_get_current_type(sig_iter),
+ (int)dbus_signature_iter_get_current_type(sig_iter));
#endif
return 0;
}
@@ -1007,6 +1020,9 @@ dbus_py_Message_append(Message *self, PyObject *args, PyObject *kwargs)
DBusMessageIter appender;
int i;
static char *argnames[] = {"signature", NULL};
+ /* must start FALSE for the case where there's nothing there and we
+ * never iterate at all */
+ dbus_bool_t more;
if (!self->msg) return DBusPy_RaiseUnusableMessage();
@@ -1040,14 +1056,15 @@ dbus_py_Message_append(Message *self, PyObject *args, PyObject *kwargs)
}
dbus_signature_iter_init(&sig_iter, signature);
dbus_message_iter_init_append(self->msg, &appender);
+ more = (signature[0] != '\0');
for (i = 0; i < PyTuple_GET_SIZE(args); i++) {
if (_message_iter_append_pyobject(&appender, &sig_iter,
- PyTuple_GET_ITEM(args, i)) < 0) {
+ PyTuple_GET_ITEM(args, i),
+ &more) < 0) {
goto hosed;
}
}
- if (dbus_signature_iter_get_current_type(&sig_iter)
- != DBUS_TYPE_INVALID) {
+ if (more) {
PyErr_SetString(PyExc_TypeError, "More items found in D-Bus "
"signature than in Python arguments");
goto hosed;