[gjs] xulrunner2: Conditionally handle availability of JS_GetStringBytes
- From: Colin Walters <walters src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs] xulrunner2: Conditionally handle availability of JS_GetStringBytes
- Date: Thu, 2 Dec 2010 22:19:49 +0000 (UTC)
commit 1f2cfe8773af2d6c643e1d00e9b5629451e5ff83
Author: Marc-Antoine Perennou <Marc-Antoine Perennou com>
Date: Tue Nov 30 21:08:56 2010 +0100
xulrunner2: Conditionally handle availability of JS_GetStringBytes
This upstream mozilla commit:
http://hg.mozilla.org/mozilla-central/changeset/f7171a41a816
removed JS_GetStringBytes in favor of an API which requires
the caller to allocate. We were using this function in
a number of places, and most of those now need to malloc()
with the new API. Rather than trying to use JS_GetStringBytes
as "const", and malloc() only with the new API, wrap it
and always malloc()/free().
Based on a patch originally from Sardem FF7 <sardemff7 pub gmail com>.
https://bugzilla.gnome.org/show_bug.cgi?id=635707
configure.ac | 2 +
gi/boxed.c | 29 +++++---
gi/function.c | 3 +-
gi/ns.c | 33 +++++---
gi/object.c | 101 ++++++++++++++++---------
gi/param.c | 12 ++-
gi/repo.c | 24 ++++--
gi/union.c | 18 +++--
gjs/byteArray.c | 8 ++-
gjs/importer.c | 24 ++++---
gjs/jsapi-util-array.c | 17 ++++-
gjs/jsapi-util-error.c | 24 +++++--
gjs/jsapi-util-string.c | 70 ++++++++++++++---
gjs/jsapi-util.c | 21 ++++-
gjs/jsapi-util.h | 6 +-
gjs/native.c | 3 +-
gjs/stack.c | 26 ++++--
modules/console.c | 10 ++-
modules/dbus-exports.c | 78 ++++++++++++-------
modules/dbus-values.c | 19 ++++-
modules/dbus.c | 191 +++++++++++++++++++++++++++++++----------------
21 files changed, 491 insertions(+), 228 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 70efee1..8950b57 100644
--- a/configure.ac
+++ b/configure.ac
@@ -146,6 +146,8 @@ else
AC_MSG_ERROR([$JS_PACKAGE >= 1.9.2 is required])
fi
+AC_CHECK_LIB([mozjs], [JS_GetStringBytes], AC_DEFINE([HAVE_JS_GETSTRINGBYTES], [1], [Define if we still have JS_GetStringBytes]),, [$JS_LIBS])
+
AC_MSG_CHECKING([for mozilla-js >= 2 ])
if `$PKG_CONFIG --exists $JS_PACKAGE '>=' 2`; then
AC_MSG_RESULT([yes])
diff --git a/gi/boxed.c b/gi/boxed.c
index 6559ad0..bd554f0 100644
--- a/gi/boxed.c
+++ b/gi/boxed.c
@@ -89,7 +89,8 @@ boxed_new_resolve(JSContext *context,
JSObject **objp)
{
Boxed *priv;
- const char *name;
+ char *name;
+ JSBool ret = JS_FALSE;
*objp = NULL;
@@ -100,7 +101,8 @@ boxed_new_resolve(JSContext *context,
gjs_debug_jsprop(GJS_DEBUG_GBOXED, "Resolve prop '%s' hook obj %p priv %p", name, obj, priv);
if (priv == NULL)
- return JS_FALSE; /* wrong class */
+ goto out; /* wrong class */
+
if (priv->gboxed == NULL) {
/* We are the prototype, so look for methods and other class properties */
@@ -127,7 +129,8 @@ boxed_new_resolve(JSContext *context,
g_base_info_get_namespace( (GIBaseInfo*) priv->info),
g_base_info_get_name( (GIBaseInfo*) priv->info));
g_base_info_unref( (GIBaseInfo*) method_info);
- return JS_TRUE;
+ ret = JS_TRUE;
+ goto out;
}
gjs_debug(GJS_DEBUG_GBOXED,
@@ -140,7 +143,7 @@ boxed_new_resolve(JSContext *context,
if (gjs_define_function(context, boxed_proto, method_info) == NULL) {
g_base_info_unref( (GIBaseInfo*) method_info);
- return JS_FALSE;
+ goto out;
}
*objp = boxed_proto; /* we defined the prop in object_proto */
@@ -156,8 +159,11 @@ boxed_new_resolve(JSContext *context,
* hooks, not this resolve hook.
*/
}
+ ret = JS_TRUE;
- return JS_TRUE;
+ out:
+ g_free(name);
+ return ret;
}
/* Check to see if jsval passed in is another Boxed object of the same,
@@ -329,7 +335,7 @@ boxed_init_from_props(JSContext *context,
while (!JSID_IS_VOID(prop_id)) {
GIFieldInfo *field_info;
- const char *name;
+ char *name;
jsval value;
if (!gjs_get_string_id(context, prop_id, &name))
@@ -339,15 +345,18 @@ boxed_init_from_props(JSContext *context,
if (field_info == NULL) {
gjs_throw(context, "No field %s on boxed type %s",
name, g_base_info_get_name((GIBaseInfo *)priv->info));
+ g_free(name);
goto out;
}
- if (!gjs_object_require_property(context, props, "property list", name, &value))
+ if (!gjs_object_require_property(context, props, "property list", name, &value)) {
+ g_free(name);
goto out;
+ }
+ g_free(name);
- if (!boxed_set_field_from_value(context, priv, field_info, value)) {
+ if (!boxed_set_field_from_value(context, priv, field_info, value))
goto out;
- }
prop_id = JSID_VOID;
if (!JS_NextProperty(context, iter, &prop_id))
@@ -356,7 +365,7 @@ boxed_init_from_props(JSContext *context,
success = TRUE;
-out:
+ out:
g_hash_table_destroy(field_map);
return success;
diff --git a/gi/function.c b/gi/function.c
index ebd634c..56fc5f5 100644
--- a/gi/function.c
+++ b/gi/function.c
@@ -108,7 +108,7 @@ function_new_resolve(JSContext *context,
JSObject **objp)
{
Function *priv;
- const char *name;
+ char *name;
*objp = NULL;
@@ -118,6 +118,7 @@ function_new_resolve(JSContext *context,
priv = priv_from_js(context, obj);
gjs_debug_jsprop(GJS_DEBUG_GFUNCTION, "Resolve prop '%s' hook obj %p priv %p", name, obj, priv);
+ g_free(name);
if (priv == NULL)
return JS_TRUE; /* we are the prototype, or have the wrong class */
diff --git a/gi/ns.c b/gi/ns.c
index 0eb474a..b6591ff 100644
--- a/gi/ns.c
+++ b/gi/ns.c
@@ -68,9 +68,10 @@ ns_new_resolve(JSContext *context,
JSObject **objp)
{
Ns *priv;
- const char *name;
+ char *name;
GIRepository *repo;
GIBaseInfo *info;
+ JSBool ret = JS_FALSE;
*objp = NULL;
@@ -79,14 +80,18 @@ ns_new_resolve(JSContext *context,
/* let Object.prototype resolve these */
if (strcmp(name, "valueOf") == 0 ||
- strcmp(name, "toString") == 0)
- return JS_TRUE;
+ strcmp(name, "toString") == 0) {
+ ret = JS_TRUE;
+ goto out;
+ }
priv = priv_from_js(context, obj);
gjs_debug_jsprop(GJS_DEBUG_GNAMESPACE, "Resolve prop '%s' hook obj %p priv %p", name, obj, priv);
- if (priv == NULL)
- return JS_TRUE; /* we are the prototype, or have the wrong class */
+ if (priv == NULL) {
+ ret = JS_TRUE; /* we are the prototype, or have the wrong class */
+ goto out;
+ }
JS_BeginRequest(context);
@@ -101,18 +106,19 @@ ns_new_resolve(JSContext *context,
obj,
NULL)) {
JS_EndRequest(context);
- return JS_FALSE;
+ goto out;
} else {
*objp = obj; /* we defined the property in this object */
JS_EndRequest(context);
- return JS_TRUE;
+ ret = JS_TRUE;
+ goto out;
}
} else {
gjs_throw(context,
"No symbol '%s' in namespace '%s'",
name, priv->namespace);
JS_EndRequest(context);
- return JS_FALSE;
+ goto out;
}
}
@@ -125,18 +131,19 @@ ns_new_resolve(JSContext *context,
if (gjs_define_info(context, obj, info)) {
g_base_info_unref(info);
*objp = obj; /* we defined the property in this object */
- JS_EndRequest(context);
- return JS_TRUE;
+ ret = JS_TRUE;
} else {
gjs_debug(GJS_DEBUG_GNAMESPACE,
"Failed to define info '%s'",
g_base_info_get_name(info));
g_base_info_unref(info);
-
- JS_EndRequest(context);
- return JS_FALSE;
}
+ JS_EndRequest(context);
+
+ out:
+ g_free(name);
+ return ret;
}
/* If we set JSCLASS_CONSTRUCT_PROTOTYPE flag, then this is called on
diff --git a/gi/object.c b/gi/object.c
index 04c3073..559b44c 100644
--- a/gi/object.c
+++ b/gi/object.c
@@ -125,10 +125,11 @@ object_instance_get_prop(JSContext *context,
jsval *value_p)
{
ObjectInstance *priv;
- const char *name;
+ char *name;
char *gname;
GParamSpec *param;
GValue gvalue = { 0, };
+ JSBool ret = JS_TRUE;
if (!gjs_get_string_id(context, id, &name))
return JS_TRUE; /* not resolved, but no error */
@@ -137,10 +138,12 @@ object_instance_get_prop(JSContext *context,
gjs_debug_jsprop(GJS_DEBUG_GOBJECT,
"Get prop '%s' hook obj %p priv %p", name, obj, priv);
- if (priv == NULL)
- return JS_FALSE; /* wrong class passed in */
- if (priv->gobj == NULL)
- return JS_TRUE; /* prototype, not an instance. */
+ if (priv == NULL) {
+ ret = JS_FALSE; /* wrong class passed in */
+ goto out;
+ }
+ if (priv->gobj == NULL) /* prototype, not an instance. */
+ goto out;
gname = gjs_hyphen_from_camel(name);
param = g_object_class_find_property(G_OBJECT_GET_CLASS(priv->gobj),
@@ -149,12 +152,11 @@ object_instance_get_prop(JSContext *context,
if (param == NULL) {
/* leave value_p as it was */
- return JS_TRUE;
+ goto out;
}
- if ((param->flags & G_PARAM_READABLE) == 0) {
- return JS_TRUE;
- }
+ if ((param->flags & G_PARAM_READABLE) == 0)
+ goto out;
gjs_debug_jsprop(GJS_DEBUG_GOBJECT,
"Overriding %s with GObject prop %s",
@@ -165,11 +167,14 @@ object_instance_get_prop(JSContext *context,
&gvalue);
if (!gjs_value_from_g_value(context, value_p, &gvalue)) {
g_value_unset(&gvalue);
- return JS_FALSE;
+ ret = JS_FALSE;
+ goto out;
}
g_value_unset(&gvalue);
- return JS_TRUE;
+ out:
+ g_free(name);
+ return ret;
}
/* a hook on setting a property; set value_p to override property value to
@@ -182,8 +187,9 @@ object_instance_set_prop(JSContext *context,
jsval *value_p)
{
ObjectInstance *priv;
- const char *name;
+ char *name;
GParameter param = { NULL, { 0, }};
+ JSBool ret = JS_TRUE;
if (!gjs_get_string_id(context, id, &name))
return JS_TRUE; /* not resolved, but no error */
@@ -192,19 +198,21 @@ object_instance_set_prop(JSContext *context,
gjs_debug_jsprop(GJS_DEBUG_GOBJECT,
"Set prop '%s' hook obj %p priv %p", name, obj, priv);
- if (priv == NULL)
- return JS_FALSE; /* wrong class passed in */
- if (priv->gobj == NULL)
- return JS_TRUE; /* prototype, not an instance. */
+ if (priv == NULL) {
+ ret = JS_FALSE; /* wrong class passed in */
+ goto out;
+ }
+ if (priv->gobj == NULL) /* prototype, not an instance. */
+ goto out;
switch (init_g_param_from_property(context, name,
*value_p,
G_TYPE_FROM_INSTANCE(priv->gobj),
¶m)) {
case SOME_ERROR_OCCURRED:
- return JS_FALSE;
+ ret = JS_FALSE;
case NO_SUCH_G_PROPERTY:
- return JS_TRUE;
+ goto out;
case VALUE_WAS_SET:
break;
}
@@ -220,7 +228,9 @@ object_instance_set_prop(JSContext *context,
* getter/setter maybe, don't know if that is better.
*/
- return JS_TRUE;
+ out:
+ g_free(name);
+ return ret;
}
/*
@@ -244,7 +254,8 @@ object_instance_new_resolve(JSContext *context,
JSObject **objp)
{
ObjectInstance *priv;
- const char *name;
+ char *name;
+ JSBool ret = JS_FALSE;
*objp = NULL;
@@ -264,7 +275,7 @@ object_instance_new_resolve(JSContext *context,
(priv && priv->gobj) ? g_type_name_from_instance((GTypeInstance*) priv->gobj) : "(type unknown)");
if (priv == NULL)
- return JS_FALSE; /* we are the wrong class */
+ goto out; /* we are the wrong class */
if (priv->gobj == NULL) {
/* We are the prototype, so look for methods and other class properties */
@@ -367,7 +378,8 @@ object_instance_new_resolve(JSContext *context,
g_base_info_get_namespace( (GIBaseInfo*) priv->info),
g_base_info_get_name( (GIBaseInfo*) priv->info));
g_base_info_unref( (GIBaseInfo*) method_info);
- return JS_TRUE;
+ ret = JS_TRUE;
+ goto out;
}
gjs_debug(GJS_DEBUG_GOBJECT,
@@ -379,7 +391,7 @@ object_instance_new_resolve(JSContext *context,
if (gjs_define_function(context, obj, method_info) == NULL) {
g_base_info_unref( (GIBaseInfo*) method_info);
- return JS_FALSE;
+ goto out;
}
*objp = obj; /* we defined the prop in obj */
@@ -415,7 +427,10 @@ object_instance_new_resolve(JSContext *context,
}
}
- return JS_TRUE;
+ ret = JS_TRUE;
+ out:
+ g_free(name);
+ return ret;
}
static void
@@ -480,30 +495,34 @@ object_instance_props_to_g_parameters(JSContext *context,
}
while (!JSID_IS_VOID(prop_id)) {
- const char *name;
+ char *name;
jsval value;
GParameter gparam = { NULL, { 0, }};
if (!gjs_get_string_id(context, prop_id, &name))
goto free_array_and_fail;
- if (!gjs_object_require_property(context, props, "property list", name, &value))
+ if (!gjs_object_require_property(context, props, "property list", name, &value)) {
+ g_free(name);
goto free_array_and_fail;
+ }
switch (init_g_param_from_property(context, name,
value,
gtype,
&gparam)) {
- case SOME_ERROR_OCCURRED:
- goto free_array_and_fail;
case NO_SUCH_G_PROPERTY:
gjs_throw(context, "No property %s on this GObject %s",
name, g_type_name(gtype));
+ case SOME_ERROR_OCCURRED:
+ g_free(name);
goto free_array_and_fail;
case VALUE_WAS_SET:
break;
}
+ g_free(name);
+
g_array_append_val(gparams, gparam);
prop_id = JSID_VOID;
@@ -860,9 +879,10 @@ real_connect_func(JSContext *context,
GClosure *closure;
gulong id;
guint signal_id;
- const char *signal_name;
+ char *signal_name;
GQuark signal_detail;
jsval retval;
+ JSBool ret = JS_FALSE;
priv = priv_from_js(context, obj);
gjs_debug_gsignal("connect obj %p priv %p argc %d", obj, priv, argc);
@@ -902,12 +922,12 @@ real_connect_func(JSContext *context,
gjs_throw(context, "No signal '%s' on object '%s'",
signal_name,
g_type_name(G_OBJECT_TYPE(priv->gobj)));
- return JS_FALSE;
+ goto out;
}
closure = gjs_closure_new_for_signal(context, JSVAL_TO_OBJECT(argv[1]), "signal callback", signal_id);
if (closure == NULL)
- return JS_FALSE;
+ goto out;
id = g_signal_connect_closure(priv->gobj,
signal_name,
@@ -916,12 +936,15 @@ real_connect_func(JSContext *context,
if (!JS_NewNumberValue(context, id, &retval)) {
g_signal_handler_disconnect(priv->gobj, id);
- return JS_FALSE;
+ goto out;
}
JS_SET_RVAL(context, vp, retval);
- return JS_TRUE;
+ ret = JS_TRUE;
+ out:
+ g_free(signal_name);
+ return ret;
}
static JSBool
@@ -990,12 +1013,13 @@ emit_func(JSContext *context,
guint signal_id;
GQuark signal_detail;
GSignalQuery signal_query;
- const char *signal_name;
+ char *signal_name;
GValue *instance_and_args;
GValue rvalue;
unsigned int i;
gboolean failed;
jsval retval;
+ JSBool ret = JS_FALSE;
priv = priv_from_js(context, obj);
gjs_debug_gsignal("emit obj %p priv %p argc %d", obj, priv, argc);
@@ -1030,7 +1054,7 @@ emit_func(JSContext *context,
gjs_throw(context, "No signal '%s' on object '%s'",
signal_name,
g_type_name(G_OBJECT_TYPE(priv->gobj)));
- return JS_FALSE;
+ goto out;
}
g_signal_query(signal_id, &signal_query);
@@ -1041,7 +1065,7 @@ emit_func(JSContext *context,
g_type_name(G_OBJECT_TYPE(priv->gobj)),
signal_query.n_params,
argc - 1);
- return JS_FALSE;
+ goto out;
}
if (signal_query.return_type != G_TYPE_NONE) {
@@ -1090,7 +1114,10 @@ emit_func(JSContext *context,
if (!failed)
JS_SET_RVAL(context, vp, retval);
- return !failed;
+ ret = !failed;
+ out:
+ g_free(signal_name);
+ return ret;
}
/* Default spidermonkey toString is worthless. Replace it
diff --git a/gi/param.c b/gi/param.c
index 5c4c669..1b03ad2 100644
--- a/gi/param.c
+++ b/gi/param.c
@@ -54,7 +54,7 @@ param_get_prop(JSContext *context,
jsval *value_p)
{
Param *priv;
- const char *name;
+ char *name;
const char *value_str;
if (!gjs_get_string_id(context, id, &name))
@@ -65,8 +65,10 @@ param_get_prop(JSContext *context,
gjs_debug_jsprop(GJS_DEBUG_GPARAM,
"Get prop '%s' hook obj %p priv %p", name, obj, priv);
- if (priv == NULL)
+ if (priv == NULL) {
+ g_free(name);
return JS_FALSE; /* wrong class */
+ }
value_str = NULL;
if (strcmp(name, "name") == 0)
@@ -76,6 +78,8 @@ param_get_prop(JSContext *context,
else if (strcmp(name, "blurb") == 0)
value_str = g_param_spec_get_blurb(priv->gparam);
+ g_free(name);
+
if (value_str != NULL) {
*value_p = STRING_TO_JSVAL(JS_NewStringCopyZ(context, value_str));
}
@@ -104,7 +108,7 @@ param_new_resolve(JSContext *context,
JSObject **objp)
{
Param *priv;
- const char *name;
+ char *name;
*objp = NULL;
@@ -115,6 +119,8 @@ param_new_resolve(JSContext *context,
gjs_debug_jsprop(GJS_DEBUG_GPARAM, "Resolve prop '%s' hook obj %p priv %p", name, obj, priv);
+ g_free(name);
+
if (priv == NULL)
return JS_FALSE; /* wrong class */
diff --git a/gi/repo.c b/gi/repo.c
index a103c6d..3381da1 100644
--- a/gi/repo.c
+++ b/gi/repo.c
@@ -60,7 +60,7 @@ resolve_namespace_object(JSContext *context,
jsval versions_val;
JSObject *versions;
jsval version_val;
- const char *version;
+ char *version;
JSObject *result;
JS_BeginRequest(context);
@@ -90,10 +90,13 @@ resolve_namespace_object(JSContext *context,
"Requiring %s, version %s: %s",
ns_name, version?version:"none", error->message);
g_error_free(error);
+ g_free(version);
JS_EndRequest(context);
return NULL;
}
+ g_free(version);
+
/* Defines a property on "obj" (the javascript repo object)
* with the given namespace name, pointing to that namespace
* in the repo.
@@ -124,7 +127,8 @@ repo_new_resolve(JSContext *context,
JSObject **objp)
{
Repo *priv;
- const char *name;
+ char *name;
+ JSBool ret = JS_TRUE;
*objp = NULL;
@@ -134,23 +138,25 @@ repo_new_resolve(JSContext *context,
/* let Object.prototype resolve these */
if (strcmp(name, "valueOf") == 0 ||
strcmp(name, "toString") == 0)
- return JS_TRUE;
+ goto out;
priv = priv_from_js(context, obj);
gjs_debug_jsprop(GJS_DEBUG_GREPO, "Resolve prop '%s' hook obj %p priv %p", name, obj, priv);
- if (priv == NULL)
- return JS_TRUE; /* we are the prototype, or have the wrong class */
+ if (priv == NULL) /* we are the prototype, or have the wrong class */
+ goto out;
JS_BeginRequest(context);
if (resolve_namespace_object(context, obj, name) == NULL) {
- JS_EndRequest(context);
- return JS_FALSE;
+ ret = JS_FALSE;
} else {
*objp = obj; /* store the object we defined the prop in */
- JS_EndRequest(context);
- return JS_TRUE;
}
+ JS_EndRequest(context);
+
+ out:
+ g_free(name);
+ return ret;
}
/* If we set JSCLASS_CONSTRUCT_PROTOTYPE flag, then this is called on
diff --git a/gi/union.c b/gi/union.c
index 118cc88..b2978af 100644
--- a/gi/union.c
+++ b/gi/union.c
@@ -73,7 +73,8 @@ union_new_resolve(JSContext *context,
JSObject **objp)
{
Union *priv;
- const char *name;
+ char *name;
+ JSBool ret = JS_TRUE;
*objp = NULL;
@@ -83,8 +84,10 @@ union_new_resolve(JSContext *context,
priv = priv_from_js(context, obj);
gjs_debug_jsprop(GJS_DEBUG_GBOXED, "Resolve prop '%s' hook obj %p priv %p", name, obj, priv);
- if (priv == NULL)
- return JS_FALSE; /* wrong class */
+ if (priv == NULL) {
+ ret = JS_FALSE; /* wrong class */
+ goto out;
+ }
if (priv->gboxed == NULL) {
/* We are the prototype, so look for methods and other class properties */
@@ -111,7 +114,7 @@ union_new_resolve(JSContext *context,
g_base_info_get_namespace( (GIBaseInfo*) priv->info),
g_base_info_get_name( (GIBaseInfo*) priv->info));
g_base_info_unref( (GIBaseInfo*) method_info);
- return JS_TRUE;
+ goto out;
}
gjs_debug(GJS_DEBUG_GBOXED,
@@ -124,7 +127,8 @@ union_new_resolve(JSContext *context,
if (gjs_define_function(context, union_proto, method_info) == NULL) {
g_base_info_unref( (GIBaseInfo*) method_info);
- return JS_FALSE;
+ ret = JS_FALSE;
+ goto out;
}
*objp = union_proto; /* we defined the prop in object_proto */
@@ -141,7 +145,9 @@ union_new_resolve(JSContext *context,
*/
}
- return JS_TRUE;
+ out:
+ g_free(name);
+ return ret;
}
static void*
diff --git a/gjs/byteArray.c b/gjs/byteArray.c
index f8b650f..ea09cc4 100644
--- a/gjs/byteArray.c
+++ b/gjs/byteArray.c
@@ -503,7 +503,7 @@ to_string_func(JSContext *context,
jsval *argv = JS_ARGV(context, vp);
JSObject *object = JS_THIS_OBJECT(context, vp);
ByteArrayInstance *priv;
- const char *encoding;
+ char *encoding;
gboolean encoding_is_utf8;
priv = priv_from_js(context, object);
@@ -523,6 +523,7 @@ to_string_func(JSContext *context,
* just an optimization anyway.
*/
if (strcmp(encoding, "UTF-8") == 0) {
+ g_free(encoding);
encoding_is_utf8 = TRUE;
} else {
encoding_is_utf8 = FALSE;
@@ -560,6 +561,7 @@ to_string_func(JSContext *context,
NULL, /* bytes read */
&bytes_written,
&error);
+ g_free(encoding);
if (u16_str == NULL) {
/* frees the GError */
gjs_throw_g_error(context, error);
@@ -609,7 +611,7 @@ from_string_func(JSContext *context,
{
jsval *argv = JS_ARGV(context, vp);
ByteArrayInstance *priv;
- const char *encoding;
+ char *encoding;
gboolean encoding_is_utf8;
JSObject *obj;
JSBool retval = JS_FALSE;
@@ -643,6 +645,7 @@ from_string_func(JSContext *context,
* just an optimization anyway.
*/
if (strcmp(encoding, "UTF-8") == 0) {
+ g_free(encoding);
encoding_is_utf8 = TRUE;
} else {
encoding_is_utf8 = FALSE;
@@ -686,6 +689,7 @@ from_string_func(JSContext *context,
NULL, /* bytes read */
&bytes_written,
&error);
+ g_free(encoding);
if (encoded == NULL) {
/* frees the GError */
gjs_throw_g_error(context, error);
diff --git a/gjs/importer.c b/gjs/importer.c
index 9986b9b..b0a921f 100644
--- a/gjs/importer.c
+++ b/gjs/importer.c
@@ -366,13 +366,14 @@ load_module_elements(JSContext *context,
}
while (!JSID_IS_VOID(idp)) {
- const char *name;
+ char *name;
if (!gjs_get_string_id(context, idp, &name)) {
continue;
}
- g_ptr_array_add(iter->elements, g_strdup(name));
+ /* Pass ownership of name */
+ g_ptr_array_add(iter->elements, name);
if (!JS_NextProperty(context, jsiter, &idp)) {
break;
@@ -918,7 +919,8 @@ importer_new_resolve(JSContext *context,
JSObject **objp)
{
Importer *priv;
- const char *name;
+ char *name;
+ JSBool ret = JS_TRUE;
*objp = NULL;
@@ -929,23 +931,25 @@ importer_new_resolve(JSContext *context,
if (strcmp(name, "valueOf") == 0 ||
strcmp(name, "toString") == 0 ||
strcmp(name, "__iterator__") == 0)
- return JS_TRUE;
+ goto out;
priv = priv_from_js(context, obj);
gjs_debug_jsprop(GJS_DEBUG_IMPORTER, "Resolve prop '%s' hook obj %p priv %p", name, obj, priv);
- if (priv == NULL)
- return JS_TRUE; /* we are the prototype, or have the wrong class */
+ if (priv == NULL) /* we are the prototype, or have the wrong class */
+ goto out;
JS_BeginRequest(context);
if (do_import(context, obj, priv, name)) {
*objp = obj;
- JS_EndRequest(context);
- return JS_TRUE;
} else {
- JS_EndRequest(context);
- return JS_FALSE;
+ ret = JS_FALSE;
}
+ JS_EndRequest(context);
+
+ out:
+ g_free(name);
+ return ret;
}
/* If we set JSCLASS_CONSTRUCT_PROTOTYPE flag, then this is called on
diff --git a/gjs/jsapi-util-array.c b/gjs/jsapi-util-array.c
index ce72810..dbbd96e 100644
--- a/gjs/jsapi-util-array.c
+++ b/gjs/jsapi-util-array.c
@@ -315,15 +315,28 @@ gjstest_test_func_gjs_jsapi_util_array(void)
JS_GC(context);
for (i = 0; i < N_ELEMS; i++) {
- const char *ascii;
+ char *ascii;
+ JSString *str;
value = gjs_rooted_array_get(context, array, i);
g_assert(JSVAL_IS_STRING(value));
- ascii = JS_GetStringBytes(JSVAL_TO_STRING(value));
+ str = JSVAL_TO_STRING(value);
+#ifdef HAVE_JS_GETSTRINGBYTES
+ ascii = g_strdup(JS_GetStringBytes(str));
+#else
+ size_t len = JS_GetStringEncodingLength(context, str);
+ if (len == (size_t)(-1))
+ continue;
+
+ ascii = g_malloc((len + 1) * sizeof(char));
+ JS_EncodeStringToBuffer(str, ascii, len);
+ ascii[len] = '\0';
+#endif
/* if the string was freed, hopefully this will fail
* even if we didn't crash yet
*/
g_assert(strcmp(ascii, "abcdefghijk") == 0);
+ g_free(ascii);
}
gjs_rooted_array_free(context, array, TRUE);
diff --git a/gjs/jsapi-util-error.c b/gjs/jsapi-util-error.c
index cb0d507..2dcdc73 100644
--- a/gjs/jsapi-util-error.c
+++ b/gjs/jsapi-util-error.c
@@ -204,7 +204,9 @@ gjstest_test_func_gjs_jsapi_util_error_throw(void)
GjsUnitTestFixture fixture;
JSContext *context;
jsval exc, value, previous;
- const char *s;
+ char *s = NULL;
+ JSString *str;
+ int strcmp_result;
_gjs_unit_test_fixture_begin(&fixture);
context = fixture.context;
@@ -224,14 +226,24 @@ gjstest_test_func_gjs_jsapi_util_error_throw(void)
&value);
g_assert(JSVAL_IS_STRING(value));
+ str = JSVAL_TO_STRING(value);
+#ifdef HAVE_JS_GETSTRINGBYTES
/* JS_GetStringBytes() is broken for non-ASCII but that's OK here */
- s = JS_GetStringBytes(JSVAL_TO_STRING(value));
- g_assert(s != NULL);
- if (strcmp(s, "This is an exception 42") != 0) {
- g_error("Exception has wrong message '%s'",
- s);
+ s = g_strdup(JS_GetStringBytes(str));
+#else
+ size_t len = JS_GetStringEncodingLength(context, str);
+ if (len != (size_t)(-1)) {
+ s = g_malloc((len + 1) * sizeof(char));
+ JS_EncodeStringToBuffer(str, s, len);
+ s[len] = '\0';
}
+#endif
+ g_assert(s != NULL);
+ strcmp_result = strcmp(s, "This is an exception 42");
+ free(s);
+ if (strcmp_result != 0)
+ g_error("Exception has wrong message '%s'", s);
/* keep this around before we clear it */
previous = exc;
diff --git a/gjs/jsapi-util-string.c b/gjs/jsapi-util-string.c
index 32d7166..c1af3bc 100644
--- a/gjs/jsapi-util-string.c
+++ b/gjs/jsapi-util-string.c
@@ -247,16 +247,32 @@ gjs_string_from_filename(JSContext *context,
*
* Returns: an ASCII C string or %NULL on error
**/
-const char*
+char*
gjs_string_get_ascii(JSContext *context,
- jsval value)
+ jsval value)
{
+ JSString *str;
+
if (!JSVAL_IS_STRING(value)) {
gjs_throw(context, "A string was expected, but value was not a string");
return NULL;
}
- return JS_GetStringBytes(JSVAL_TO_STRING(value));
+ str = JSVAL_TO_STRING(value);
+
+#ifdef HAVE_JS_GETSTRINGBYTES
+ return g_strdup(JS_GetStringBytes(str));
+#else
+ char *ascii;
+ size_t len = JS_GetStringEncodingLength(context, str);
+ if (len == (size_t)(-1))
+ return NULL;
+
+ ascii = g_malloc((len + 1) * sizeof(char));
+ JS_EncodeStringToBuffer(str, ascii, len);
+ ascii[len] = '\0';
+ return ascii;
+#endif
}
static JSBool
@@ -291,7 +307,7 @@ gjs_string_get_binary_data(JSContext *context,
char **data_p,
gsize *len_p)
{
- char *js_data;
+ JSString *str;
JS_BeginRequest(context);
@@ -307,12 +323,25 @@ gjs_string_get_binary_data(JSContext *context,
return JS_FALSE;
}
- js_data = JS_GetStringBytes(JSVAL_TO_STRING(value));
+ str = JSVAL_TO_STRING(value);
+
+#ifdef HAVE_JS_GETSTRINGBYTES
+ const char *js_data = JS_GetStringBytes(str);
+
/* GetStringLength returns number of 16-bit jschar;
* we stored binary data as 1 byte per jschar
*/
- *len_p = JS_GetStringLength(JSVAL_TO_STRING(value));
+ *len_p = JS_GetStringLength(str);
*data_p = g_memdup(js_data, *len_p);
+#else
+ *len_p = JS_GetStringEncodingLength(context, str);
+ if (*len_p == (gsize)(-1))
+ return JS_FALSE;
+
+ *data_p = g_malloc((*len_p + 1) * sizeof(char));
+ JS_EncodeStringToBuffer(str, *data_p, *len_p);
+ (*data_p)[*len_p] = '\0';
+#endif
JS_EndRequest(context);
@@ -414,15 +443,27 @@ gjs_string_get_uint16_data(JSContext *context,
JSBool
gjs_get_string_id (JSContext *context,
jsid id,
- const char **name_p)
+ char **name_p)
{
jsval id_val;
+ JSString *str;
if (!JS_IdToValue(context, id, &id_val))
return JS_FALSE;
if (JSVAL_IS_STRING(id_val)) {
- *name_p = JS_GetStringBytes(JSVAL_TO_STRING(id_val));
+ str = JSVAL_TO_STRING(id_val);
+#ifdef HAVE_JS_GETSTRINGBYTES
+ *name_p = g_strdup(JS_GetStringBytes(str));
+#else
+ size_t len = JS_GetStringEncodingLength(context, str);
+ if (len == (size_t)(-1))
+ return JS_FALSE;
+
+ *name_p = g_malloc((len + 1) * sizeof(char));
+ JS_EncodeStringToBuffer(str, *name_p, len);
+ (*name_p)[len] = '\0';
+#endif
return JS_TRUE;
} else {
*name_p = NULL;
@@ -444,11 +485,11 @@ gjs_get_string_id (JSContext *context,
*/
gboolean
gjs_unichar_from_string (JSContext *context,
- JSString *string,
+ jsval value,
gunichar *result)
{
char *utf8_str;
- if (gjs_string_to_utf8(context, STRING_TO_JSVAL(string), &utf8_str)) {
+ if (gjs_string_to_utf8(context, value, &utf8_str)) {
*result = g_utf8_get_char(utf8_str);
g_free(utf8_str);
return TRUE;
@@ -493,14 +534,19 @@ gjstest_test_func_gjs_jsapi_util_string_get_ascii(void)
const char *ascii_string = "Hello, world";
JSString *js_string;
jsval void_value;
+ char *test;
_gjs_unit_test_fixture_begin(&fixture);
context = fixture.context;
js_string = JS_NewStringCopyZ(context, ascii_string);
- g_assert(g_str_equal(gjs_string_get_ascii(context, STRING_TO_JSVAL(js_string)), ascii_string));
+ test = gjs_string_get_ascii(context, STRING_TO_JSVAL(js_string));
+ g_assert(g_str_equal(test, ascii_string));
+ g_free(test);
void_value = JSVAL_VOID;
- g_assert(gjs_string_get_ascii(context, void_value) == NULL);
+ test = gjs_string_get_ascii(context, void_value);
+ g_assert(test == NULL);
+ g_free(test);
g_assert(JS_IsExceptionPending(context));
_gjs_unit_test_fixture_finish(&fixture);
diff --git a/gjs/jsapi-util.c b/gjs/jsapi-util.c
index 714b91e..56e3a3f 100644
--- a/gjs/jsapi-util.c
+++ b/gjs/jsapi-util.c
@@ -767,7 +767,7 @@ gjs_value_debug_string(JSContext *context,
jsval value)
{
JSString *str;
- const char *bytes;
+ char *bytes;
char *debugstr;
JS_BeginRequest(context);
@@ -799,11 +799,20 @@ gjs_value_debug_string(JSContext *context,
g_assert(str != NULL);
- bytes = JS_GetStringBytes(str);
-
+#ifdef HAVE_JS_GETSTRINGBYTES
+ bytes = g_strdup(JS_GetStringBytes(str));
+#else
+ size_t len = JS_GetStringEncodingLength(context, str);
+ if (len != (size_t)(-1)) {
+ bytes = g_malloc((len + 1) * sizeof(char));
+ JS_EncodeStringToBuffer(str, bytes, len);
+ bytes[len] = '\0';
+ }
+#endif
JS_EndRequest(context);
debugstr = _gjs_g_utf8_make_valid(bytes);
+ g_free(bytes);
return debugstr;
}
@@ -838,7 +847,7 @@ gjs_log_object_props(JSContext *context,
while (!JSID_IS_VOID(prop_id)) {
jsval propval;
- const char *name;
+ char *name;
char *debugstr;
if (!gjs_get_string_id(context, prop_id, &name))
@@ -855,6 +864,7 @@ gjs_log_object_props(JSContext *context,
g_free(debugstr);
next:
+ g_free(name);
prop_id = JSID_VOID;
if (!JS_NextProperty(context, props_iter, &prop_id))
break;
@@ -1143,12 +1153,13 @@ log_prop(JSContext *context,
const char *what)
{
if (JSVAL_IS_STRING(id)) {
- const char *name;
+ char *name;
name = gjs_string_get_ascii(context, id);
gjs_debug(GJS_DEBUG_PROPS,
"prop %s: %s",
name, what);
+ g_free(name);
} else if (JSVAL_IS_INT(id)) {
gjs_debug(GJS_DEBUG_PROPS,
"prop %d: %s",
diff --git a/gjs/jsapi-util.h b/gjs/jsapi-util.h
index b7c6a8b..e75561e 100644
--- a/gjs/jsapi-util.h
+++ b/gjs/jsapi-util.h
@@ -311,7 +311,7 @@ JSBool gjs_string_from_filename (JSContext *context,
const char *filename_string,
gssize n_bytes,
jsval *value_p);
-const char* gjs_string_get_ascii (JSContext *context,
+char* gjs_string_get_ascii (JSContext *context,
jsval value);
JSBool gjs_string_get_binary_data (JSContext *context,
jsval value,
@@ -327,11 +327,11 @@ JSBool gjs_string_get_uint16_data (JSContext *context,
gsize *len_p);
JSBool gjs_get_string_id (JSContext *context,
jsid id,
- const char **name_p);
+ char **name_p);
gboolean gjs_unichar_from_string (JSContext *context,
- JSString *string,
+ jsval string,
gunichar *result);
const char* gjs_get_type_name (jsval value);
diff --git a/gjs/native.c b/gjs/native.c
index 3d97d70..822fd6a 100644
--- a/gjs/native.c
+++ b/gjs/native.c
@@ -140,13 +140,14 @@ gjs_import_native_module(JSContext *context,
if (gjs_object_get_property(context, parent, "__moduleName__", &value) &&
JSVAL_IS_STRING(value)) {
- const char *name;
+ char *name;
name = gjs_string_get_ascii(context, value);
if (module_id->len > 0)
g_string_prepend(module_id, ".");
g_string_prepend(module_id, name);
+ g_free(name);
}
/* Move up to parent */
diff --git a/gjs/stack.c b/gjs/stack.c
index b542aa9..6e2b987 100644
--- a/gjs/stack.c
+++ b/gjs/stack.c
@@ -46,22 +46,25 @@
#include <jsdbgapi.h>
#include "context.h"
#include "compat.h"
+#include "jsapi-util.h"
-static const char*
+static char*
jsvalue_to_string(JSContext* cx, jsval val, gboolean* is_string)
{
- const char* value = NULL;
+ char* value = NULL;
JSString* value_str;
(void)JS_EnterLocalRootScope(cx);
value_str = JS_ValueToString(cx, val);
if (value_str)
- value = JS_GetStringBytes(value_str);
+ value = gjs_value_debug_string(cx, val);
if (value) {
const char* found = strstr(value, "function ");
- if(found && (value == found || value+1 == found || value+2 == found))
- value = "[function]";
+ if(found && (value == found || value+1 == found || value+2 == found)) {
+ g_free(value);
+ value = g_strdup("[function]");
+ }
}
if (is_string)
@@ -145,13 +148,15 @@ format_frame(JSContext* cx, JSStackFrame* fp,
g_string_append_printf(buf, "%d <TOP LEVEL>", num);
for (i = 0; i < call_props.length; i++) {
- const char *name;
- const char *value;
+ char *name;
+ char *value;
JSPropertyDesc* desc = &call_props.array[i];
if(desc->flags & JSPD_ARGUMENT) {
name = jsvalue_to_string(cx, desc->id, &is_string);
- if(!is_string)
+ if(!is_string) {
+ g_free(name);
name = NULL;
+ }
value = jsvalue_to_string(cx, desc->value, &is_string);
g_string_append_printf(buf, "%s%s%s%s%s%s",
@@ -163,6 +168,8 @@ format_frame(JSContext* cx, JSStackFrame* fp,
is_string ? "\"" : "");
named_arg_count++;
}
+ g_free(name);
+ g_free(value);
}
/* print any unnamed trailing args (found in 'arguments' object) */
@@ -181,12 +188,13 @@ format_frame(JSContext* cx, JSStackFrame* fp,
g_snprintf(number, 8, "%d", (int) k);
if (JS_GetProperty(cx, args_obj, number, &val)) {
- const char *value = jsvalue_to_string(cx, val, &is_string);
+ char *value = jsvalue_to_string(cx, val, &is_string);
g_string_append_printf(buf, "%s%s%s%s",
k ? ", " : "",
is_string ? "\"" : "",
value ? value : "?unknown?",
is_string ? "\"" : "");
+ g_free(value);
}
}
}
diff --git a/modules/console.c b/modules/console.c
index bb930a7..4e4f82b 100644
--- a/modules/console.c
+++ b/modules/console.c
@@ -212,8 +212,14 @@ gjs_console_interact(JSContext *context,
str = JS_ValueToString(context, result);
}
- if (str)
- g_fprintf(stdout, "%s\n", JS_GetStringBytes(str));
+ if (str) {
+ char *display_str;
+ display_str = gjs_value_debug_string(context, result);
+ if (display_str != NULL) {
+ g_fprintf(stdout, "%s\n", display_str);
+ g_free(display_str);
+ }
+ }
if (script)
JS_DestroyScript(context, script);
diff --git a/modules/dbus-exports.c b/modules/dbus-exports.c
index 0d8d9f3..8a685d3 100644
--- a/modules/dbus-exports.c
+++ b/modules/dbus-exports.c
@@ -150,7 +150,7 @@ dbus_reply_from_exception_and_sender(JSContext *context,
{
char *s;
jsval exc;
- const char *name = NULL;
+ char *name = NULL;
jsval nameval;
*reply_p = NULL;
@@ -163,8 +163,10 @@ dbus_reply_from_exception_and_sender(JSContext *context,
"dbusErrorName", &nameval))
name = gjs_string_get_ascii(context, nameval);
- if (!gjs_log_exception(context, &s))
+ if (!gjs_log_exception(context, &s)) {
+ g_free(name);
return JS_FALSE;
+ }
gjs_debug(GJS_DEBUG_DBUS,
"JS exception we will send as dbus reply to %s: %s",
@@ -176,6 +178,7 @@ dbus_reply_from_exception_and_sender(JSContext *context,
dbus_message_set_reply_serial(*reply_p, serial);
dbus_message_set_no_reply(*reply_p, TRUE);
dbus_message_set_error_name(*reply_p, name ? name : DBUS_ERROR_FAILED);
+ g_free(name);
if (s != NULL) {
DBusMessageIter iter;
@@ -197,7 +200,7 @@ dbus_reply_from_exception_and_sender(JSContext *context,
static JSBool
signature_from_method(JSContext *context,
JSObject *method_obj,
- const char **signature)
+ char **signature)
{
jsval signature_value;
@@ -211,7 +214,7 @@ signature_from_method(JSContext *context,
}
} else {
/* We default to a{sv} */
- *signature = "a{sv}";
+ *signature = g_strdup("a{sv}");
}
return JS_TRUE;
@@ -292,7 +295,7 @@ invoke_js_from_dbus(JSContext *context,
jsval rval;
DBusMessageIter arg_iter;
GjsRootedArray *values;
- const char *signature;
+ char *signature;
if (JS_IsExceptionPending(context)) {
gjs_debug(GJS_DEBUG_DBUS,
@@ -359,6 +362,8 @@ invoke_js_from_dbus(JSContext *context,
dbus_message_get_serial(method_call),
rval);
+ g_free(signature);
+
out:
gjs_rooted_array_free(context, values, TRUE);
JS_RemoveValueRoot(context, &rval);
@@ -388,10 +393,10 @@ async_call_callback(JSContext *context,
DBusBusType which_bus;
DBusMessage *reply;
JSObject *callback_object;
- const char *sender;
+ char *sender;
dbus_uint32_t serial;
jsval prop_value;
- const char *signature;
+ char *signature = NULL;
gboolean thrown;
callback_object = JSVAL_TO_OBJECT(JS_CALLEE(context, vp));
@@ -418,10 +423,10 @@ async_call_callback(JSContext *context,
"_dbusSerial",
&prop_value)) {
gjs_log_and_keep_exception(context, NULL);
- return JS_FALSE;
+ goto fail;
}
if (!JS_ValueToECMAUint32(context, prop_value, &serial))
- return JS_FALSE;
+ goto fail;
if (!gjs_object_require_property(context,
callback_object,
@@ -429,7 +434,7 @@ async_call_callback(JSContext *context,
"_dbusBusType",
&prop_value)) {
gjs_log_and_keep_exception(context, NULL);
- return JS_FALSE;
+ goto fail;
}
which_bus = JSVAL_TO_INT(prop_value);
@@ -446,7 +451,7 @@ async_call_callback(JSContext *context,
}
signature = gjs_string_get_ascii(context, prop_value);
if (!signature)
- return JS_FALSE;
+ goto fail;
if (argc != 1) {
gjs_throw(context, "The callback to async DBus calls takes one argument, "
@@ -468,6 +473,9 @@ async_call_callback(JSContext *context,
"dbus method invocation failed but no exception was set?");
}
+ g_free(sender);
+ g_free(signature);
+
if (reply) {
gjs_dbus_add_bus_weakref(which_bus, &connection);
if (!connection) {
@@ -485,6 +493,10 @@ async_call_callback(JSContext *context,
JS_SET_RVAL(context, vp, JSVAL_VOID);
return (thrown == FALSE);
+
+ fail:
+ g_free(sender);
+ return JS_FALSE;
}
/* returns an error message or NULL */
@@ -506,7 +518,7 @@ invoke_js_async_from_dbus(JSContext *context,
jsval serial_value;
gboolean thrown;
jsval ignored;
- const char *signature;
+ char *signature;
JSString *signature_string;
reply = NULL;
@@ -600,6 +612,7 @@ invoke_js_async_from_dbus(JSContext *context,
}
signature_string = JS_NewStringCopyZ(context, signature);
+ g_free(signature);
if (!signature_string) {
thrown = TRUE;
goto out;
@@ -821,9 +834,9 @@ unpack_property_details(JSContext *context,
jsval name_val;
jsval signature_val;
jsval access_val;
- const char *name;
- const char *signature;
- const char *access;
+ char *name = NULL;
+ char *signature = NULL;
+ char *access = NULL;
if (!gjs_object_get_property(context,
prop_description,
@@ -847,14 +860,13 @@ unpack_property_details(JSContext *context,
gjs_throw(context,
"Property %s has no signature",
name);
- return JS_FALSE;
+ goto fail;
}
signature = gjs_string_get_ascii(context,
signature_val);
- if (signature == NULL) {
- return JS_FALSE;
- }
+ if (signature == NULL)
+ goto fail;
if (!gjs_object_get_property(context,
prop_description,
@@ -863,14 +875,13 @@ unpack_property_details(JSContext *context,
gjs_throw(context,
"Property %s has no access",
name);
- return JS_FALSE;
+ goto fail;
}
access = gjs_string_get_ascii(context,
access_val);
- if (access == NULL) {
- return JS_FALSE;
- }
+ if (access == NULL)
+ goto fail;
g_assert(name && signature && access);
@@ -883,13 +894,20 @@ unpack_property_details(JSContext *context,
details->writable = TRUE;
} else {
gjs_throw(context, "Unknown access on property, should be readwrite read or write");
- return JS_FALSE;
+ goto fail;
}
- details->name = g_strdup(name);
- details->signature = g_strdup(signature);
+ details->name = name;
+ details->signature = signature;
+ g_free(access);
return JS_TRUE;
+
+ fail:
+ g_free(access);
+ g_free(signature);
+ g_free(name);
+ return JS_FALSE;
}
/* FALSE on exception, NULL property name in details if no such
@@ -1432,13 +1450,15 @@ handle_introspect(JSContext *context,
goto out;
}
- key = JS_GetStringBytes(key_str);
+ if (!gjs_string_to_utf8(context, keyval, &key))
+ goto out;
if (!gjs_object_require_property(context, dir_obj,
"dbus directory",
key, &valueval)) {
gjs_debug(GJS_DEBUG_DBUS,
"Somehow failed to get property of dbus object");
+ g_free(key);
goto out;
}
@@ -1447,6 +1467,7 @@ handle_introspect(JSContext *context,
g_string_append_printf(doc, " <node name=\"%s\"/>\n",
key);
}
+ g_free(key);
prop_id = JSID_VOID;
if (!JS_NextProperty(context, props_iter, &prop_id)) {
@@ -1661,7 +1682,7 @@ exports_new_resolve(JSContext *context,
JSObject **objp)
{
Exports *priv;
- const char *name;
+ char *name;
*objp = NULL;
@@ -1670,6 +1691,7 @@ exports_new_resolve(JSContext *context,
priv = priv_from_js(context, obj);
gjs_debug_jsprop(GJS_DEBUG_DBUS, "Resolve prop '%s' hook obj %p priv %p", name, obj, priv);
+ g_free(name);
if (priv == NULL)
return JS_TRUE; /* we are the prototype, or have the wrong class */
diff --git a/modules/dbus-values.c b/modules/dbus-values.c
index 2d94c4a..f41a03b 100644
--- a/modules/dbus-values.c
+++ b/modules/dbus-values.c
@@ -101,7 +101,7 @@ gjs_js_one_value_from_dbus(JSContext *context,
DBusMessageIter entry_iter;
jsval key_value, entry_value;
JSString *key_str;
- const char *key;
+ char *key;
dbus_message_iter_recurse(&array_iter, &entry_iter);
@@ -121,7 +121,11 @@ gjs_js_one_value_from_dbus(JSContext *context,
key_str = JS_ValueToString(context, key_value);
JS_AddStringRoot(context, &key_str);
- key = JS_GetStringBytes(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);
@@ -130,6 +134,7 @@ gjs_js_one_value_from_dbus(JSContext *context,
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);
@@ -140,6 +145,7 @@ gjs_js_one_value_from_dbus(JSContext *context,
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);
@@ -147,6 +153,7 @@ gjs_js_one_value_from_dbus(JSContext *context,
return JS_FALSE;
}
+ g_free(key);
JS_RemoveValueRoot(context, &key_value);
JS_RemoveStringRoot(context, &key_str);
JS_RemoveValueRoot(context, &entry_value);
@@ -785,7 +792,7 @@ append_dict(JSContext *context,
char *name;
jsval propval;
DBusMessageIter entry_iter;
- const char *value_signature;
+ char *value_signature;
if (!JS_IdToValue(context, prop_id, &nameval))
return JS_FALSE;
@@ -815,8 +822,10 @@ append_dict(JSContext *context,
}
}
- if (!gjs_object_require_property(context, props, "DBus append_dict", name, &propval))
+ if (!gjs_object_require_property(context, props, "DBus append_dict", name, &propval)) {
+ g_free(value_signature);
return JS_FALSE;
+ }
gjs_debug_dbus_marshal(" Adding property %s",
name);
@@ -827,6 +836,7 @@ append_dict(JSContext *context,
if (JSVAL_IS_NULL(propval)) {
gjs_throw(context, "Property '%s' has a null value, can't send over dbus",
name);
+ g_free(value_signature);
return JS_FALSE;
}
@@ -855,6 +865,7 @@ append_dict(JSContext *context,
return JS_FALSE;
dbus_message_iter_close_container(&entry_iter, &variant_iter);
+ g_free(value_signature);
} else {
if (!gjs_js_one_value_to_dbus(context, propval, &entry_iter,
&dict_value_sig_iter))
diff --git a/modules/dbus.c b/modules/dbus.c
index f93f7ff..94267e8 100644
--- a/modules/dbus.c
+++ b/modules/dbus.c
@@ -120,14 +120,14 @@ prepare_call(JSContext *context,
jsval *argv,
DBusBusType bus_type)
{
- DBusMessage *message;
- const char *bus_name;
- const char *path;
- const char *interface;
- const char *method;
+ DBusMessage *message = NULL;
+ char *bus_name = NULL;
+ char *path = NULL;
+ char *interface = NULL;
+ char *method = NULL;
gboolean auto_start;
- const char *out_signature;
- const char *in_signature;
+ char *out_signature = NULL;
+ char *in_signature = NULL;
DBusMessageIter arg_iter;
DBusSignatureIter sig_iter;
@@ -140,33 +140,33 @@ prepare_call(JSContext *context,
path = gjs_string_get_ascii(context, argv[1]);
if (path == NULL)
- return NULL;
+ goto fail;
if (JSVAL_IS_NULL(argv[2])) {
interface = NULL;
} else {
interface = gjs_string_get_ascii(context, argv[2]);
if (interface == NULL)
- return NULL; /* exception was set */
+ goto fail; /* exception was set */
}
method = gjs_string_get_ascii(context, argv[3]);
if (method == NULL)
- return NULL;
+ goto fail;
out_signature = gjs_string_get_ascii(context, argv[4]);
if (out_signature == NULL)
- return NULL;
+ goto fail;
in_signature = gjs_string_get_ascii(context, argv[5]);
if (in_signature == NULL)
- return NULL;
+ goto fail;
g_assert(bus_name && path && method && in_signature && out_signature);
if (!JSVAL_IS_BOOLEAN(argv[6])) {
gjs_throw(context, "arg 7 must be boolean");
- return NULL;
+ goto fail;
}
auto_start = JSVAL_TO_BOOLEAN(argv[6]);
@@ -180,7 +180,7 @@ prepare_call(JSContext *context,
method);
if (message == NULL) {
gjs_throw(context, "Out of memory (or invalid args to dbus_message_new_method_call)");
- return NULL;
+ goto fail;
}
dbus_message_set_auto_start(message, auto_start);
@@ -195,9 +195,17 @@ prepare_call(JSContext *context,
if (!gjs_js_values_to_dbus(context, 0, argv[8], &arg_iter, &sig_iter)) {
gjs_debug(GJS_DEBUG_DBUS, "Failed to marshal call from JS to dbus");
dbus_message_unref(message);
- return NULL;
+ message = NULL;
}
+ fail:
+ g_free(in_signature);
+ g_free(out_signature);
+ g_free(method);
+ g_free(interface);
+ g_free(path);
+ g_free(bus_name);
+
return message;
}
@@ -442,7 +450,7 @@ gjs_js_dbus_call_async(JSContext *context,
}
static JSBool
-fill_with_null_or_string(JSContext *context, const char **string_p, jsval value)
+fill_with_null_or_string(JSContext *context, char **string_p, jsval value)
{
if (JSVAL_IS_NULL(value))
*string_p = NULL;
@@ -696,13 +704,14 @@ gjs_js_dbus_watch_signal(JSContext *context,
{
jsval *argv = JS_ARGV(context, vp);
JSObject *obj = JS_THIS_OBJECT(context, vp);
- const char *bus_name;
- const char *object_path;
- const char *iface;
- const char *signal;
+ char *bus_name = NULL;
+ char *object_path = NULL;
+ char *iface = NULL;
+ char *signal = NULL;
SignalHandler *handler;
int id;
DBusBusType bus_type;
+ JSBool ret = JS_FALSE;
if (argc < 5) {
gjs_throw(context, "Not enough args, need bus name, object path, interface, signal and callback");
@@ -720,18 +729,18 @@ gjs_js_dbus_watch_signal(JSContext *context,
if (!fill_with_null_or_string(context, &bus_name, argv[0]))
return JS_FALSE;
if (!fill_with_null_or_string(context, &object_path, argv[1]))
- return JS_FALSE;
+ goto fail;
if (!fill_with_null_or_string(context, &iface, argv[2]))
- return JS_FALSE;
+ goto fail;
if (!fill_with_null_or_string(context, &signal, argv[3]))
- return JS_FALSE;
+ goto fail;
if (!get_bus_type_from_object(context, obj, &bus_type))
- return JS_FALSE;
+ goto fail;
handler = signal_handler_new(context, argv[4]);
if (handler == NULL)
- return JS_FALSE;
+ goto fail;
id = gjs_dbus_watch_signal(bus_type,
bus_name,
@@ -750,7 +759,15 @@ gjs_js_dbus_watch_signal(JSContext *context,
JS_SET_RVAL(context, vp, INT_TO_JSVAL(id));
- return JS_TRUE;
+ ret = JS_TRUE;
+
+ fail:
+ g_free(signal);
+ g_free(iface);
+ g_free(object_path);
+ g_free(bus_name);
+
+ return ret;
}
/* Args are handler id */
@@ -787,12 +804,13 @@ gjs_js_dbus_unwatch_signal(JSContext *context,
{
jsval *argv = JS_ARGV(context, vp);
JSObject *obj = JS_THIS_OBJECT(context, vp);
- const char *bus_name;
- const char *object_path;
- const char *iface;
- const char *signal;
+ char *bus_name;
+ char *object_path;
+ char *iface;
+ char *signal;
SignalHandler *handler;
DBusBusType bus_type;
+ JSBool ret = JS_FALSE;
if (argc < 5) {
gjs_throw(context, "Not enough args, need bus name, object path, interface, signal and callback");
@@ -813,22 +831,26 @@ gjs_js_dbus_unwatch_signal(JSContext *context,
if (!fill_with_null_or_string(context, &bus_name, argv[0]))
return JS_FALSE;
if (!fill_with_null_or_string(context, &object_path, argv[1]))
- return JS_FALSE;
+ goto object_path_fail;
if (!fill_with_null_or_string(context, &iface, argv[2]))
- return JS_FALSE;
+ goto iface_fail;
if (!fill_with_null_or_string(context, &signal, argv[3]))
- return JS_FALSE;
+ goto signal_fail;
/* we don't complain if the signal seems to have been already removed
* or to never have been watched, to match g_signal_handler_disconnect
*/
- if (!signal_handlers_by_callable)
- return JS_TRUE;
+ if (!signal_handlers_by_callable) {
+ ret = JS_TRUE;
+ goto free_and_exit;
+ }
handler = g_hash_table_lookup(signal_handlers_by_callable, JSVAL_TO_OBJECT(argv[4]));
- if (!handler)
- return JS_TRUE;
+ if (!handler) {
+ ret = JS_TRUE;
+ goto free_and_exit;
+ }
/* This should dispose the handler which should in turn
* remove it from the handler table
@@ -844,7 +866,18 @@ gjs_js_dbus_unwatch_signal(JSContext *context,
g_assert(g_hash_table_lookup(signal_handlers_by_callable,
JSVAL_TO_OBJECT(argv[4])) == NULL);
- return JS_TRUE;
+ ret = JS_TRUE;
+
+ free_and_exit:
+ g_free(signal);
+ signal_fail:
+ g_free(iface);
+ iface_fail:
+ g_free(object_path);
+ object_path_fail:
+ g_free(bus_name);
+
+ return ret;
}
/* Args are object_path, iface, signal, arguments signature, arguments */
@@ -859,11 +892,12 @@ gjs_js_dbus_emit_signal(JSContext *context,
DBusMessage *message;
DBusMessageIter arg_iter;
DBusSignatureIter sig_iter;
- const char *object_path;
- const char *iface;
- const char *signal;
- const char *in_signature;
+ char *object_path;
+ char *iface;
+ char *signal;
+ char *in_signature;
DBusBusType bus_type;
+ JSBool ret = JS_FALSE;
if (argc < 4) {
gjs_throw(context, "Not enough args, need object path, interface and signal and the arguments");
@@ -883,16 +917,16 @@ gjs_js_dbus_emit_signal(JSContext *context,
return JS_FALSE;
iface = gjs_string_get_ascii(context, argv[1]);
if (!iface)
- return JS_FALSE;
+ goto iface_fail;
signal = gjs_string_get_ascii(context, argv[2]);
if (!signal)
- return JS_FALSE;
+ goto signal_fail;
in_signature = gjs_string_get_ascii(context, argv[3]);
if (!in_signature)
- return JS_FALSE;
+ goto in_signature_fail;
if (!bus_check(context, bus_type))
- return JS_FALSE;
+ goto free_and_exit;
gjs_debug(GJS_DEBUG_DBUS,
"Emitting signal %s %s %s",
@@ -912,14 +946,25 @@ gjs_js_dbus_emit_signal(JSContext *context,
if (!gjs_js_values_to_dbus(context, 0, argv[4], &arg_iter, &sig_iter)) {
dbus_message_unref(message);
- return JS_FALSE;
+ goto free_and_exit;
}
dbus_connection_send(bus_connection, message, NULL);
dbus_message_unref(message);
- return JS_TRUE;
+ ret = JS_TRUE;
+
+ free_and_exit:
+ g_free(in_signature);
+ in_signature_fail:
+ g_free(signal);
+ signal_fail:
+ g_free(iface);
+ iface_fail:
+ g_free(object_path);
+
+ return ret;
}
/* Blocks until dbus outgoing message queue is empty. This is the only way
@@ -1117,7 +1162,7 @@ gjs_js_dbus_acquire_name(JSContext *context,
{
jsval *argv = JS_ARGV(context, vp);
JSObject *obj = JS_THIS_OBJECT(context, vp);
- const char *bus_name;
+ char *bus_name;
JSObject *acquire_func;
JSObject *lost_func;
GjsJSDBusNameOwner *owner;
@@ -1141,28 +1186,28 @@ gjs_js_dbus_acquire_name(JSContext *context,
if (!JSVAL_IS_INT(argv[1])) {
gjs_throw(context, "Second arg is an integer representing the name type (single or multiple instances)\n"
"Use the constants DBus.SINGLE_INSTANCE and DBus.MANY_INSTANCES, defined in the DBus module");
- return JS_FALSE;
+ goto fail;
}
name_type = (GjsDBusNameType)JSVAL_TO_INT(argv[1]);
if (!JSVAL_IS_OBJECT(argv[2])) {
gjs_throw(context, "Third arg is a callback to invoke on acquiring the name");
- return JS_FALSE;
+ goto fail;
}
acquire_func = JSVAL_TO_OBJECT(argv[2]);
if (!JSVAL_IS_OBJECT(argv[3])) {
gjs_throw(context, "Fourth arg is a callback to invoke on losing the name");
- return JS_FALSE;
+ goto fail;
}
lost_func = JSVAL_TO_OBJECT(argv[3]);
owner = g_slice_new0(GjsJSDBusNameOwner);
- owner->funcs.name = g_strdup(bus_name);
+ owner->funcs.name = bus_name;
owner->funcs.type = name_type;
owner->funcs.acquired = on_name_acquired;
owner->funcs.lost = on_name_lost;
@@ -1191,11 +1236,15 @@ gjs_js_dbus_acquire_name(JSContext *context,
if (!JS_NewNumberValue(context, (jsdouble)id, &retval)) {
gjs_throw(context, "Could not convert name owner id to jsval");
- return JS_FALSE;
+ goto fail;
}
JS_SET_RVAL(context, vp, retval);
return JS_TRUE;
+
+ fail:
+ g_free(bus_name);
+ return JS_FALSE;
}
/* Args are name owner monitor id */
@@ -1354,7 +1403,7 @@ gjs_js_dbus_watch_name(JSContext *context,
{
jsval *argv = JS_ARGV(context, vp);
JSObject *obj = JS_THIS_OBJECT(context, vp);
- const char *bus_name;
+ char *bus_name;
JSBool start_if_not_found;
JSObject *appeared_func;
JSObject *vanished_func;
@@ -1377,19 +1426,19 @@ gjs_js_dbus_watch_name(JSContext *context,
if (!JS_ValueToBoolean(context, argv[1], &start_if_not_found)) {
if (!JS_IsExceptionPending(context))
gjs_throw(context, "Second arg is a bool for whether to start the name if not found");
- return JS_FALSE;
+ goto fail;
}
if (!JSVAL_IS_OBJECT(argv[2])) {
gjs_throw(context, "Third arg is a callback to invoke on seeing the name");
- return JS_FALSE;
+ goto fail;
}
appeared_func = JSVAL_TO_OBJECT(argv[2]);
if (!JSVAL_IS_OBJECT(argv[3])) {
gjs_throw(context, "Fourth arg is a callback to invoke when the name vanishes");
- return JS_FALSE;
+ goto fail;
}
vanished_func = JSVAL_TO_OBJECT(argv[3]);
@@ -1409,7 +1458,7 @@ gjs_js_dbus_watch_name(JSContext *context,
g_closure_sink(watcher->vanished_closure);
watcher->bus_type = bus_type;
- watcher->bus_name = g_strdup(bus_name);
+ watcher->bus_name = bus_name;
/* Only add the invalidate notifier to one of the closures, should
* be enough */
@@ -1425,6 +1474,10 @@ gjs_js_dbus_watch_name(JSContext *context,
JS_SET_RVAL(context, vp, JSVAL_VOID);
return JS_TRUE;
+
+ fail:
+ g_free(bus_name);
+ return JS_FALSE;
}
/* a hook on getting a property; set value_p to override property's value.
@@ -1436,7 +1489,7 @@ unique_name_getter(JSContext *context,
jsid id,
jsval *value_p)
{
- const char *name;
+ char *name;
DBusConnection *bus_connection;
DBusBusType bus_type;
@@ -1447,6 +1500,7 @@ unique_name_getter(JSContext *context,
return JS_FALSE;
gjs_debug_jsprop(GJS_DEBUG_DBUS, "Get prop '%s' on dbus object", name);
+ g_free(name);
bus_check(context, bus_type);
@@ -1473,7 +1527,7 @@ gjs_js_dbus_signature_length(JSContext *context,
jsval *vp)
{
jsval *argv = JS_ARGV(context, vp);
- const char *signature;
+ char *signature;
DBusSignatureIter iter;
int length = 0;
@@ -1488,6 +1542,7 @@ gjs_js_dbus_signature_length(JSContext *context,
if (!dbus_signature_validate(signature, NULL)) {
gjs_throw(context, "Invalid signature");
+ g_free(signature);
return JS_FALSE;
}
@@ -1502,6 +1557,7 @@ gjs_js_dbus_signature_length(JSContext *context,
} while (dbus_signature_iter_next(&iter));
out:
+ g_free(signature);
JS_SET_RVAL(context, vp, INT_TO_JSVAL(length));
return JS_TRUE;
@@ -1514,9 +1570,10 @@ gjs_js_dbus_start_service(JSContext *context,
{
jsval *argv = JS_ARGV(context, vp);
JSObject *obj = JS_THIS_OBJECT(context, vp);
- const char *name;
+ char *name;
DBusBusType bus_type;
DBusConnection *bus_connection;
+ JSBool ret = JS_FALSE;
if (argc != 1) {
gjs_throw(context, "Wrong number of arguments, expected service name");
@@ -1528,16 +1585,20 @@ gjs_js_dbus_start_service(JSContext *context,
return JS_FALSE;
if (!get_bus_type_from_object(context, obj, &bus_type))
- return JS_FALSE;
+ goto out;
if (!bus_check(context, bus_type))
- return JS_FALSE;
+ goto out;
bus_connection = DBUS_CONNECTION_FROM_TYPE(bus_type);
gjs_dbus_start_service(bus_connection, name);
- return JS_TRUE;
+ ret = JS_TRUE;
+
+ out:
+ g_free(name);
+ return ret;
}
static JSBool
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]