[gjs] dbus: Fix dict entry conversion path
- From: Colin Walters <walters src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs] dbus: Fix dict entry conversion path
- Date: Fri, 10 Dec 2010 15:03:57 +0000 (UTC)
commit bbdd4848b4426a98a03e7ed9516b8aee18e55b67
Author: Colin Walters <walters verbum org>
Date: Thu Dec 9 17:58:44 2010 -0500
dbus: Fix dict entry conversion path
Multiple issues:
* We need to handle JS_ValueToString possibly returning NULL, a
look at the SpiderMonkey sources shows it can happen in unusual
circumstances.
* The JS_Add/RemoveRoot pairing was utterly fucked. Fix it by
rooting everything at the top.
* Move it to a separate function for sanity.
https://bugzilla.gnome.org/show_bug.cgi?id=636927
modules/dbus-values.c | 157 +++++++++++++++++++++++++-----------------------
1 files changed, 82 insertions(+), 75 deletions(-)
---
diff --git a/modules/dbus-values.c b/modules/dbus-values.c
index f41a03b..98f25b0 100644
--- a/modules/dbus-values.c
+++ b/modules/dbus-values.c
@@ -31,6 +31,87 @@
#include <string.h>
+static JSBool
+_gjs_js_one_value_from_dbus_dict_entry(JSContext *context,
+ DBusMessageIter *iter,
+ jsval *value_p)
+{
+ /* Create a dictionary object */
+ JSObject *obj;
+ DBusMessageIter array_iter;
+ jsval key_value, entry_value;
+ JSString *key_str;
+ char *key;
+ JSBool retval = JS_FALSE;
+
+ obj = JS_ConstructObject(context, NULL, NULL, NULL);
+ if (obj == NULL)
+ return JS_FALSE;
+
+ key = NULL;
+ key_value = JSVAL_VOID;
+ entry_value = JSVAL_VOID;
+ key_str = NULL;
+
+ JS_AddObjectRoot(context, &obj);
+ JS_AddValueRoot(context, &key_value);
+ JS_AddValueRoot(context, &entry_value);
+ JS_AddStringRoot(context, &key_str);
+
+ dbus_message_iter_recurse(iter, &array_iter);
+
+ while (dbus_message_iter_get_arg_type(&array_iter) != DBUS_TYPE_INVALID) {
+ DBusMessageIter entry_iter;
+
+ /* Cleanup from previous loop */
+ g_free(key);
+ key = NULL;
+
+ dbus_message_iter_recurse(&array_iter, &entry_iter);
+
+ if (!dbus_type_is_basic(dbus_message_iter_get_arg_type(&entry_iter))) {
+ gjs_throw(context, "Dictionary keys are not a basic type, can't convert to JavaScript");
+ goto out;
+ }
+
+ if (!gjs_js_one_value_from_dbus(context, &entry_iter, &key_value))
+ goto out;
+
+ key_str = JS_ValueToString(context, key_value);
+ if (key_str == NULL) {
+ gjs_throw(context, "Couldn't convert value to string");
+ goto out;
+ }
+ if (!gjs_string_to_utf8(context, key_value, &key))
+ goto out;
+
+ dbus_message_iter_next(&entry_iter);
+
+ gjs_debug_dbus_marshal("Defining dict entry %s in jsval dict", key);
+
+ if (!gjs_js_one_value_from_dbus(context, &entry_iter, &entry_value))
+ goto out;
+
+ if (!JS_DefineProperty(context, obj,
+ key, entry_value,
+ NULL, NULL, JSPROP_ENUMERATE))
+ goto out;
+
+ dbus_message_iter_next(&array_iter);
+ }
+
+ *value_p = OBJECT_TO_JSVAL(obj);
+ retval = JS_TRUE;
+ out:
+ g_free(key);
+ JS_RemoveObjectRoot(context, &obj);
+ JS_RemoveValueRoot(context, &key_value);
+ JS_RemoveValueRoot(context, &entry_value);
+ JS_RemoveStringRoot(context, &key_str);
+ return retval;
+}
+
+
JSBool
gjs_js_one_value_from_dbus(JSContext *context,
DBusMessageIter *iter,
@@ -87,81 +168,7 @@ gjs_js_one_value_from_dbus(JSContext *context,
int elem_type = dbus_message_iter_get_element_type(iter);
if (elem_type == DBUS_TYPE_DICT_ENTRY) {
- /* Create a dictionary object */
- JSObject *obj;
- DBusMessageIter array_iter;
-
- obj = JS_ConstructObject(context, NULL, NULL, NULL);
- if (obj == NULL)
- return JS_FALSE;
-
- JS_AddObjectRoot(context, &obj);
- dbus_message_iter_recurse(iter, &array_iter);
- while (dbus_message_iter_get_arg_type(&array_iter) != DBUS_TYPE_INVALID) {
- DBusMessageIter entry_iter;
- jsval key_value, entry_value;
- JSString *key_str;
- char *key;
-
- dbus_message_iter_recurse(&array_iter, &entry_iter);
-
- if (!dbus_type_is_basic(dbus_message_iter_get_arg_type(&entry_iter))) {
- gjs_throw(context, "Dictionary keys are not a basic type, can't convert to JavaScript");
- JS_RemoveObjectRoot(context, &obj);
- return JS_FALSE;
- }
-
- entry_value = JSVAL_VOID;
- JS_AddValueRoot(context, &entry_value);
- if (!gjs_js_one_value_from_dbus(context, &entry_iter, &key_value)) {
- JS_RemoveValueRoot(context, &key_value);
- JS_RemoveObjectRoot(context, &obj);
- return JS_FALSE;
- }
-
- key_str = JS_ValueToString(context, key_value);
- JS_AddStringRoot(context, &key_str);
- if (!gjs_string_to_utf8(context, key_value, &key)) {
- JS_RemoveValueRoot(context, &key_value);
- JS_RemoveObjectRoot(context, &obj);
- return JS_FALSE;
- }
-
- dbus_message_iter_next(&entry_iter);
-
- gjs_debug_dbus_marshal("Defining dict entry %s in jsval dict", key);
-
- entry_value = JSVAL_VOID;
- JS_AddValueRoot(context, &entry_value);
- if (!gjs_js_one_value_from_dbus(context, &entry_iter, &entry_value)) {
- g_free(key);
- JS_RemoveValueRoot(context, &key_value);
- JS_RemoveStringRoot(context, &key_str);
- JS_RemoveValueRoot(context, &entry_value);
- JS_RemoveObjectRoot(context, &obj);
- return JS_FALSE;
- }
-
- if (!JS_DefineProperty(context, obj,
- key, entry_value,
- NULL, NULL, JSPROP_ENUMERATE)) {
- g_free(key);
- JS_RemoveValueRoot(context, &key_value);
- JS_RemoveStringRoot(context, &key_str);
- JS_RemoveValueRoot(context, &entry_value);
- JS_RemoveObjectRoot(context, &obj);
- return JS_FALSE;
- }
-
- g_free(key);
- JS_RemoveValueRoot(context, &key_value);
- JS_RemoveStringRoot(context, &key_str);
- JS_RemoveValueRoot(context, &entry_value);
- dbus_message_iter_next(&array_iter);
- }
-
- *value_p = OBJECT_TO_JSVAL(obj);
- JS_RemoveObjectRoot(context, &obj);
+ return _gjs_js_one_value_from_dbus_dict_entry(context, iter, value_p);
} else if (elem_type == DBUS_TYPE_BYTE) {
/* byte arrays go to a string */
const char *v_BYTES;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]