diff --git a/gjs.spec b/gjs.spec index acd3b8f..eed01f4 100644 --- a/gjs.spec +++ b/gjs.spec @@ -1,6 +1,6 @@ Name: gjs Version: 0.7.7 -Release: 2%{?dist} +Release: 3%{?dist} Summary: Javascript Bindings for GNOME Group: System Environment/Libraries @@ -14,6 +14,14 @@ URL: http://live.gnome.org/Gjs/ Source0: ftp://ftp.gnome.org/pub/GNOME/sources/%{name}/%{version}/%{name}-%{version}.tar.bz2 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) +Patch0: js-no-string-get-ascii.patch +Patch1: js-always-utf8.patch +Patch2: js-getstringbytes-1.patch +Patch3: js-getstringbytes-2.patch +Patch4: js-getfunctionname-1.patch +Patch5: js-getfunctionname-2.patch +Patch6: js-getfunctionname-3.patch + BuildRequires: xulrunner-devel BuildRequires: gobject-introspection-devel BuildRequires: dbus-glib-devel @@ -38,6 +46,13 @@ Files for development with %{name}. %prep %setup -q +%patch0 -p1 -b .no-string-get-ascii +%patch1 -p1 -b .always-utf8 +%patch2 -p1 -b .getstringbytes-1 +%patch3 -p1 -b .getstringbytes-2 +%patch4 -p1 -b .getfunctionname-1 +%patch5 -p1 -b .getfunctionname-2 +%patch6 -p1 -b .getfunctionname-3 %build (if ! test -x configure; then NOCONFIGURE=1 ./autogen.sh; fi; @@ -82,6 +97,9 @@ rm -rf %{buildroot} %{_libdir}/*.so %changelog +* Wed Dec 29 2010 Dan Williams - 0.7.7-3 +- Work around Mozilla JS API changes + * Wed Dec 22 2010 Colin Walters - 0.7.7-2 - Remove rpath removal; we need an rpath on libmozjs, since it's in a nonstandard directory. diff --git a/js-always-utf8.patch b/js-always-utf8.patch new file mode 100644 index 0000000..b875b43 --- /dev/null +++ b/js-always-utf8.patch @@ -0,0 +1,215 @@ +commit 52593563c9e9873231f5fdae3dc1668460bee37e +Author: Colin Walters +Date: Wed Dec 1 17:11:16 2010 -0500 + + gjs_value_debug_string: Always return UTF-8 + + Returning whatever JS_GetStringBytes gave us will blow up if + the string contains non-UTF8 characters and we're trying to g_print + to a UTF-8 terminal (the standard case). Since this is just a + debugging string, import a copy of _g_utf8_make_valid which + squashes it to UTF-8 in a useful way. + +diff --git a/gjs/jsapi-util.c b/gjs/jsapi-util.c +index 11c890a..714b91e 100644 +--- a/gjs/jsapi-util.c ++++ b/gjs/jsapi-util.c +@@ -755,12 +755,20 @@ gjs_define_string_array(JSContext *context, + return array; + } + +-const char* ++/** ++ * gjs_value_debug_string: ++ * @context: ++ * @value: Any JavaScript value ++ * ++ * Returns: A UTF-8 encoded string describing @value ++ */ ++char* + gjs_value_debug_string(JSContext *context, + jsval value) + { + JSString *str; + const char *bytes; ++ char *debugstr; + + JS_BeginRequest(context); + +@@ -778,14 +786,14 @@ gjs_value_debug_string(JSContext *context, + str = JS_NewStringCopyZ(context, klass->name); + JS_ClearPendingException(context); + if (str == NULL) { +- return "[out of memory copying class name]"; ++ return g_strdup("[out of memory copying class name]"); + } + } else { + gjs_log_exception(context, NULL); +- return "[unknown object]"; ++ return g_strdup("[unknown object]"); + } + } else { +- return "[unknown non-object]"; ++ return g_strdup("[unknown non-object]"); + } + } + +@@ -795,7 +803,9 @@ gjs_value_debug_string(JSContext *context, + + JS_EndRequest(context); + +- return bytes; ++ debugstr = _gjs_g_utf8_make_valid(bytes); ++ ++ return debugstr; + } + + void +@@ -829,6 +839,7 @@ gjs_log_object_props(JSContext *context, + while (!JSID_IS_VOID(prop_id)) { + jsval propval; + const char *name; ++ char *debugstr; + + if (!gjs_get_string_id(context, prop_id, &name)) + goto next; +@@ -836,10 +847,12 @@ gjs_log_object_props(JSContext *context, + if (!gjs_object_get_property(context, obj, name, &propval)) + goto next; + ++ debugstr = gjs_value_debug_string(context, propval); + gjs_debug(topic, + "%s%s = '%s'", + prefix, name, +- gjs_value_debug_string(context, propval)); ++ debugstr); ++ g_free(debugstr); + + next: + prop_id = JSID_VOID; +@@ -859,6 +872,7 @@ gjs_explain_scope(JSContext *context, + JSObject *global; + JSObject *parent; + GString *chain; ++ char *debugstr; + + gjs_debug(GJS_DEBUG_SCOPE, + "=== %s ===", +@@ -874,14 +888,16 @@ gjs_explain_scope(JSContext *context, + ""); + + global = JS_GetGlobalObject(context); ++ debugstr = gjs_value_debug_string(context, OBJECT_TO_JSVAL(global)); + gjs_debug(GJS_DEBUG_SCOPE, + " Global: %p %s", +- global, gjs_value_debug_string(context, OBJECT_TO_JSVAL(global))); ++ global, debugstr); ++ g_free(debugstr); + + parent = JS_GetScopeChain(context); + chain = g_string_new(NULL); + while (parent != NULL) { +- const char *debug; ++ char *debug; + debug = gjs_value_debug_string(context, OBJECT_TO_JSVAL(parent)); + + if (chain->len > 0) +@@ -889,6 +905,7 @@ gjs_explain_scope(JSContext *context, + + g_string_append_printf(chain, "%p %s", + parent, debug); ++ g_free(debug); + parent = JS_GetParent(context, parent); + } + gjs_debug(GJS_DEBUG_SCOPE, +diff --git a/gjs/jsapi-util.h b/gjs/jsapi-util.h +index 424cded..b7c6a8b 100644 +--- a/gjs/jsapi-util.h ++++ b/gjs/jsapi-util.h +@@ -267,7 +267,7 @@ void gjs_log_object_props (JSContext *context, + GjsDebugTopic topic, + const char *prefix); + #endif +-const char* gjs_value_debug_string (JSContext *context, ++char* gjs_value_debug_string (JSContext *context, + jsval value); + void gjs_explain_scope (JSContext *context, + const char *title); +diff --git a/util/glib.c b/util/glib.c +index 316e6e0..b79e75f 100644 +--- a/util/glib.c ++++ b/util/glib.c +@@ -21,10 +21,12 @@ + * IN THE SOFTWARE. + */ + +-#include ++#include + + #include "glib.h" + ++#include ++ + typedef struct { + void *key; + void *value; +@@ -125,6 +127,46 @@ gjs_g_strv_concat(char ***strv_array, int len) + return (char**)g_ptr_array_free(array, FALSE); + } + ++gchar * ++_gjs_g_utf8_make_valid (const gchar *name) ++{ ++ GString *string; ++ const gchar *remainder, *invalid; ++ gint remaining_bytes, valid_bytes; ++ ++ g_return_val_if_fail (name != NULL, NULL); ++ ++ string = NULL; ++ remainder = name; ++ remaining_bytes = strlen (name); ++ ++ while (remaining_bytes != 0) ++ { ++ if (g_utf8_validate (remainder, remaining_bytes, &invalid)) ++ break; ++ valid_bytes = invalid - remainder; ++ ++ if (string == NULL) ++ string = g_string_sized_new (remaining_bytes); ++ ++ g_string_append_len (string, remainder, valid_bytes); ++ /* append U+FFFD REPLACEMENT CHARACTER */ ++ g_string_append (string, "\357\277\275"); ++ ++ remaining_bytes -= valid_bytes + 1; ++ remainder = invalid + 1; ++ } ++ ++ if (string == NULL) ++ return g_strdup (name); ++ ++ g_string_append (string, remainder); ++ ++ g_assert (g_utf8_validate (string->str, -1, NULL)); ++ ++ return g_string_free (string, FALSE); ++} ++ + #if GJS_BUILD_TESTS + + void +diff --git a/util/glib.h b/util/glib.h +index 7bdc01a..5be171f 100644 +--- a/util/glib.h ++++ b/util/glib.h +@@ -28,6 +28,8 @@ + + G_BEGIN_DECLS + ++gchar * _gjs_g_utf8_make_valid (const gchar *name); ++ + gboolean gjs_g_hash_table_remove_one (GHashTable *hash, + void **key_p, + void **value_p); diff --git a/js-getfunctionname-1.patch b/js-getfunctionname-1.patch new file mode 100644 index 0000000..525c7fa --- /dev/null +++ b/js-getfunctionname-1.patch @@ -0,0 +1,148 @@ +commit aa8e8aa60a172f13757d5f0e374c009ffdb9ccfa +Author: Marc-Antoine Perennou +Date: Tue Dec 14 18:23:29 2010 +0100 + + xulrunner2: Conditionnaly adapt to JS_GetFunctionName removal + + Upstream removed JS_GetFunctionName in commit: + http://hg.mozilla.org/mozilla-central/changeset/e35b70ffed69 + + We now have to use JS_GetFunctionId which returns a JSString* + instead of a const char* + + https://bugzilla.gnome.org/show_bug.cgi?id=637246 + +diff --git a/configure.ac b/configure.ac +index 9d3f829..13db4f5 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -147,6 +147,7 @@ else + fi + + AC_CHECK_LIB([mozjs], [JS_GetStringBytes], AC_DEFINE([HAVE_JS_GETSTRINGBYTES], [1], [Define if we still have JS_GetStringBytes]),, [$JS_LIBS]) ++AC_CHECK_LIB([mozjs], [JS_GetFunctionName], AC_DEFINE([HAVE_JS_GETFUNCTIONNAME], [1], [Define if we still have JS_GetFunctionName]),, [$JS_LIBS]) + + AC_MSG_CHECKING([for mozilla-js >= 2 ]) + if `$PKG_CONFIG --exists $JS_PACKAGE '>=' 2`; then +diff --git a/gjs/profiler.c b/gjs/profiler.c +index c579400..327a33a 100644 +--- a/gjs/profiler.c ++++ b/gjs/profiler.c +@@ -26,6 +26,7 @@ + #include "profiler.h" + #include + #include "compat.h" ++#include "jsapi-util.h" + + #include + #include +@@ -109,7 +110,8 @@ gjs_profile_function_new(GjsProfileFunctionKey *key) + self = g_slice_new0(GjsProfileFunction); + self->key.filename = g_strdup(key->filename); + self->key.lineno = key->lineno; +- self->key.function_name = g_strdup(key->function_name); ++ // Pass ownership of function_name from key to the new function ++ self->key.function_name = key->function_name; + + g_assert(self->key.filename != NULL); + g_assert(self->key.function_name != NULL); +@@ -132,6 +134,7 @@ gjs_profile_function_key_from_js(JSContext *cx, + { + JSScript *script; + JSFunction *function; ++ JSString *function_name = NULL; + + /* We're not using the JSScript or JSFunction as the key since the script + * could be unloaded and addresses reused. +@@ -151,8 +154,15 @@ gjs_profile_function_key_from_js(JSContext *cx, + * (or other object with a 'call' method) and would be good to somehow + * figure out the name of the called function. + */ +- key->function_name = (char*)(function != NULL ? JS_GetFunctionName(function) : "(unknown)"); +- ++#ifdef HAVE_JS_GETFUNCTIONNAME ++ key->function_name = g_strdup(function != NULL ? JS_GetFunctionName(function) : "(unknown)"); ++#else ++ function_name = JS_GetFunctionId(function); ++ if (function_name) ++ key->function_name = gjs_string_get_ascii(cx, STRING_TO_JSVAL(function_name)); ++ else ++ key->function_name = g_strdup("(unknown)"); ++#endif + + g_assert(key->filename != NULL); + g_assert(key->function_name != NULL); +@@ -171,16 +181,23 @@ gjs_profiler_lookup_function(GjsProfiler *self, + + function = g_hash_table_lookup(self->by_file, &key); + if (function) +- return function; ++ goto error; + + if (!create_if_missing) +- return NULL; ++ goto error; + + function = gjs_profile_function_new(&key); + + g_hash_table_insert(self->by_file, &function->key, function); + ++ /* Don't free key.function_name if we get here since we passed its ++ * ownership to the new function. ++ */ + return function; ++ ++ error: ++ g_free(key.function_name); ++ return NULL; + } + + static void +diff --git a/gjs/stack.c b/gjs/stack.c +index 6e2b987..6c852c1 100644 +--- a/gjs/stack.c ++++ b/gjs/stack.c +@@ -83,7 +83,8 @@ format_frame(JSContext* cx, JSStackFrame* fp, + JSPropertyDescArray call_props = { 0, NULL }; + JSObject* this_obj = NULL; + JSObject* call_obj = NULL; +- const char* funname = NULL; ++ JSString* funname = NULL; ++ char* funname_str = NULL; + const char* filename = NULL; + guint32 lineno = 0; + guint32 named_arg_count = 0; +@@ -115,7 +116,11 @@ format_frame(JSContext* cx, JSStackFrame* fp, + lineno = (guint32) JS_PCToLineNumber(cx, script, pc); + fun = JS_GetFrameFunction(cx, fp); + if (fun) +- funname = JS_GetFunctionName(fun); ++#ifdef HAVE_JS_GETFUNCTIONNAME ++ funname_str = JS_GetFunctionName(fun); ++#else ++ funname = JS_GetFunctionId(fun); ++#endif + + call_obj = JS_GetFrameCallObject(cx, fp); + if (call_obj) { +@@ -140,8 +145,18 @@ format_frame(JSContext* cx, JSStackFrame* fp, + + /* print the frame number and function name */ + +- if (funname) +- g_string_append_printf(buf, "%d %s(", num, funname); ++#ifndef HAVE_JS_GETFUNCTIONNAME ++ if (funname) { ++ funname_str = gjs_string_get_ascii(cx, STRING_TO_JSVAL(funname)); ++ g_string_append_printf(buf, "%d %s(", num, funname_str); ++ } ++#endif ++ if (funname_str) { ++ g_string_append_printf(buf, "%d %s(", num, funname_str); ++#ifndef HAVE_JS_GETFUNCTIONNAME ++ g_free(funname_str); ++#endif ++ } + else if (fun) + g_string_append_printf(buf, "%d anonymous(", num); + else diff --git a/js-getfunctionname-2.patch b/js-getfunctionname-2.patch new file mode 100644 index 0000000..7d97fd4 --- /dev/null +++ b/js-getfunctionname-2.patch @@ -0,0 +1,34 @@ +commit 8c9b27fdae70dfc285db12b929c66f78722b5f1a +Author: Marc-Antoine Perennou +Date: Thu Dec 16 00:36:36 2010 +0100 + + Fix previous commit + + Don"t append 2 times the frame number and the function name + +diff --git a/gjs/stack.c b/gjs/stack.c +index 6c852c1..92b589d 100644 +--- a/gjs/stack.c ++++ b/gjs/stack.c +@@ -120,6 +120,8 @@ format_frame(JSContext* cx, JSStackFrame* fp, + funname_str = JS_GetFunctionName(fun); + #else + funname = JS_GetFunctionId(fun); ++ if (funname) ++ funname_str = gjs_string_get_ascii(cx, STRING_TO_JSVAL(funname)); + #endif + + call_obj = JS_GetFrameCallObject(cx, fp); +@@ -145,12 +147,6 @@ format_frame(JSContext* cx, JSStackFrame* fp, + + /* print the frame number and function name */ + +-#ifndef HAVE_JS_GETFUNCTIONNAME +- if (funname) { +- funname_str = gjs_string_get_ascii(cx, STRING_TO_JSVAL(funname)); +- g_string_append_printf(buf, "%d %s(", num, funname_str); +- } +-#endif + if (funname_str) { + g_string_append_printf(buf, "%d %s(", num, funname_str); + #ifndef HAVE_JS_GETFUNCTIONNAME diff --git a/js-getfunctionname-3.patch b/js-getfunctionname-3.patch new file mode 100644 index 0000000..2cddb65 --- /dev/null +++ b/js-getfunctionname-3.patch @@ -0,0 +1,50 @@ +commit 08ed898f10ee888497708299f28d91fc67602699 +Author: Colin Walters +Date: Wed Dec 15 18:52:13 2010 -0500 + + More fixes for previous commit + + * Change to always malloc() to avoid compiler warnings + * Add missing brackets to fix control flow + +diff --git a/gjs/stack.c b/gjs/stack.c +index 92b589d..90d15b6 100644 +--- a/gjs/stack.c ++++ b/gjs/stack.c +@@ -83,7 +83,6 @@ format_frame(JSContext* cx, JSStackFrame* fp, + JSPropertyDescArray call_props = { 0, NULL }; + JSObject* this_obj = NULL; + JSObject* call_obj = NULL; +- JSString* funname = NULL; + char* funname_str = NULL; + const char* filename = NULL; + guint32 lineno = 0; +@@ -115,14 +114,15 @@ format_frame(JSContext* cx, JSStackFrame* fp, + filename = JS_GetScriptFilename(cx, script); + lineno = (guint32) JS_PCToLineNumber(cx, script, pc); + fun = JS_GetFrameFunction(cx, fp); +- if (fun) ++ if (fun) { + #ifdef HAVE_JS_GETFUNCTIONNAME +- funname_str = JS_GetFunctionName(fun); ++ funname_str = g_strdup(JS_GetFunctionName(fun)); + #else +- funname = JS_GetFunctionId(fun); ++ JSString* funname = JS_GetFunctionId(fun); + if (funname) + funname_str = gjs_string_get_ascii(cx, STRING_TO_JSVAL(funname)); + #endif ++ } + + call_obj = JS_GetFrameCallObject(cx, fp); + if (call_obj) { +@@ -149,9 +149,7 @@ format_frame(JSContext* cx, JSStackFrame* fp, + + if (funname_str) { + g_string_append_printf(buf, "%d %s(", num, funname_str); +-#ifndef HAVE_JS_GETFUNCTIONNAME + g_free(funname_str); +-#endif + } + else if (fun) + g_string_append_printf(buf, "%d anonymous(", num); diff --git a/js-getstringbytes-1.patch b/js-getstringbytes-1.patch new file mode 100644 index 0000000..6463ccb --- /dev/null +++ b/js-getstringbytes-1.patch @@ -0,0 +1,2090 @@ +commit 1f2cfe8773af2d6c643e1d00e9b5629451e5ff83 +Author: Marc-Antoine Perennou +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 . + + https://bugzilla.gnome.org/show_bug.cgi?id=635707 + +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, + 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; +@@ -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,7 +327,7 @@ 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); + const char* gjs_get_type_name (jsval value); + + jsval gjs_date_from_time_t (JSContext *context, time_t time); +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 + #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 ", 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, " \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 diff --git a/js-getstringbytes-2.patch b/js-getstringbytes-2.patch new file mode 100644 index 0000000..84bd293 --- /dev/null +++ b/js-getstringbytes-2.patch @@ -0,0 +1,131 @@ +commit 7222ad74d05fa226de5f236539a67e366a66ad56 +Author: Marc-Antoine Perennou +Date: Thu Dec 2 23:22:02 2010 +0100 + + Follow on to last patch to clean up goto handling + +diff --git a/modules/dbus.c b/modules/dbus.c +index 94267e8..d422e68 100644 +--- a/modules/dbus.c ++++ b/modules/dbus.c +@@ -804,10 +804,10 @@ gjs_js_dbus_unwatch_signal(JSContext *context, + { + jsval *argv = JS_ARGV(context, vp); + JSObject *obj = JS_THIS_OBJECT(context, vp); +- char *bus_name; +- char *object_path; +- char *iface; +- char *signal; ++ char *bus_name = NULL; ++ char *object_path = NULL; ++ char *iface = NULL; ++ char *signal = NULL; + SignalHandler *handler; + DBusBusType bus_type; + JSBool ret = JS_FALSE; +@@ -831,25 +831,25 @@ 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])) +- goto object_path_fail; ++ goto fail; + if (!fill_with_null_or_string(context, &iface, argv[2])) +- goto iface_fail; ++ goto fail; + if (!fill_with_null_or_string(context, &signal, argv[3])) +- goto signal_fail; ++ goto 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) { + ret = JS_TRUE; +- goto free_and_exit; ++ goto fail; + } + + handler = g_hash_table_lookup(signal_handlers_by_callable, JSVAL_TO_OBJECT(argv[4])); + + if (!handler) { + ret = JS_TRUE; +- goto free_and_exit; ++ goto fail; + } + + /* This should dispose the handler which should in turn +@@ -868,13 +868,10 @@ gjs_js_dbus_unwatch_signal(JSContext *context, + + ret = JS_TRUE; + +- free_and_exit: ++ fail: + g_free(signal); +- signal_fail: + g_free(iface); +- iface_fail: + g_free(object_path); +- object_path_fail: + g_free(bus_name); + + return ret; +@@ -892,10 +889,10 @@ gjs_js_dbus_emit_signal(JSContext *context, + DBusMessage *message; + DBusMessageIter arg_iter; + DBusSignatureIter sig_iter; +- char *object_path; +- char *iface; +- char *signal; +- char *in_signature; ++ char *object_path = NULL; ++ char *iface = NULL; ++ char *signal = NULL; ++ char *in_signature = NULL; + DBusBusType bus_type; + JSBool ret = JS_FALSE; + +@@ -917,16 +914,16 @@ gjs_js_dbus_emit_signal(JSContext *context, + return JS_FALSE; + iface = gjs_string_get_ascii(context, argv[1]); + if (!iface) +- goto iface_fail; ++ goto fail; + signal = gjs_string_get_ascii(context, argv[2]); + if (!signal) +- goto signal_fail; ++ goto fail; + in_signature = gjs_string_get_ascii(context, argv[3]); + if (!in_signature) +- goto in_signature_fail; ++ goto fail; + + if (!bus_check(context, bus_type)) +- goto free_and_exit; ++ goto fail; + + gjs_debug(GJS_DEBUG_DBUS, + "Emitting signal %s %s %s", +@@ -946,7 +943,7 @@ 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); +- goto free_and_exit; ++ goto fail; + } + + dbus_connection_send(bus_connection, message, NULL); +@@ -955,13 +952,10 @@ gjs_js_dbus_emit_signal(JSContext *context, + + ret = JS_TRUE; + +- free_and_exit: ++ fail: + g_free(in_signature); +- in_signature_fail: + g_free(signal); +- signal_fail: + g_free(iface); +- iface_fail: + g_free(object_path); + + return ret; diff --git a/js-no-string-get-ascii.patch b/js-no-string-get-ascii.patch new file mode 100644 index 0000000..1dcc7ee --- /dev/null +++ b/js-no-string-get-ascii.patch @@ -0,0 +1,348 @@ +commit 60ae0e25d58feb93f76c39aa84ffb49046a4f91e +Author: Marc-Antoine Perennou +Date: Tue Nov 30 18:29:02 2010 +0100 + + xulrunner2: Get rid of gjs_string_get_ascii + + In xulrunner2, JS_GetStringBytes has been removed, we will now always need a context. + We won't be able to use gjs_string_get_ascii anymore, port each call to it to gjs_string_get_ascii_checked + Btw, rename gjs_string_get_ascii_checked to gjs_string_get_ascii + + https://bugzilla.gnome.org/show_bug.cgi?id=635707 + +diff --git a/gi/object.c b/gi/object.c +index ffa4fa6..04c3073 100644 +--- a/gi/object.c ++++ b/gi/object.c +@@ -889,7 +889,7 @@ real_connect_func(JSContext *context, + return JS_FALSE; + } + +- signal_name = gjs_string_get_ascii_checked(context, argv[0]); ++ signal_name = gjs_string_get_ascii(context, argv[0]); + if (signal_name == NULL) { + return JS_FALSE; + } +@@ -1017,7 +1017,7 @@ emit_func(JSContext *context, + return JS_FALSE; + } + +- signal_name = gjs_string_get_ascii_checked(context, ++ signal_name = gjs_string_get_ascii(context, + argv[0]); + if (signal_name == NULL) + return JS_FALSE; +diff --git a/gi/repo.c b/gi/repo.c +index 7d3bbbc..a103c6d 100644 +--- a/gi/repo.c ++++ b/gi/repo.c +@@ -78,7 +78,7 @@ resolve_namespace_object(JSContext *context, + version = NULL; + if (JS_GetProperty(context, versions, ns_name, &version_val) && + JSVAL_IS_STRING(version_val)) { +- version = gjs_string_get_ascii(version_val); ++ version = gjs_string_get_ascii(context, version_val); + } + + repo = g_irepository_get_default(); +diff --git a/gjs/byteArray.c b/gjs/byteArray.c +index b00be17..f8b650f 100644 +--- a/gjs/byteArray.c ++++ b/gjs/byteArray.c +@@ -514,7 +514,7 @@ to_string_func(JSContext *context, + encoding_is_utf8 = TRUE; + if (argc >= 1 && + JSVAL_IS_STRING(argv[0])) { +- encoding = gjs_string_get_ascii_checked(context, argv[0]); ++ encoding = gjs_string_get_ascii(context, argv[0]); + if (encoding == NULL) + return JS_FALSE; + +@@ -634,7 +634,7 @@ from_string_func(JSContext *context, + encoding_is_utf8 = TRUE; + if (argc > 1 && + JSVAL_IS_STRING(argv[1])) { +- encoding = gjs_string_get_ascii_checked(context, argv[1]); ++ encoding = gjs_string_get_ascii(context, argv[1]); + if (encoding == NULL) + goto out; + +diff --git a/gjs/jsapi-util-string.c b/gjs/jsapi-util-string.c +index 1934097..32d7166 100644 +--- a/gjs/jsapi-util-string.c ++++ b/gjs/jsapi-util-string.c +@@ -238,25 +238,6 @@ gjs_string_from_filename(JSContext *context, + + /** + * gjs_string_get_ascii: +- * @value: a jsval +- * +- * Get the char array in the JSString contained in @value. +- * The string is expected to be encoded in ASCII, otherwise +- * you will get garbage out. See the documentation for +- * JS_GetStringBytes() for more details. +- * +- * Returns: an ASCII C string +- **/ +-const char* +-gjs_string_get_ascii(jsval value) +-{ +- g_return_val_if_fail(JSVAL_IS_STRING(value), NULL); +- +- return JS_GetStringBytes(JSVAL_TO_STRING(value)); +-} +- +-/** +- * gjs_string_get_ascii_checked: + * @context: a JSContext + * @value: a jsval + * +@@ -267,7 +248,7 @@ gjs_string_get_ascii(jsval value) + * Returns: an ASCII C string or %NULL on error + **/ + const char* +-gjs_string_get_ascii_checked(JSContext *context, ++gjs_string_get_ascii(JSContext *context, + jsval value) + { + if (!JSVAL_IS_STRING(value)) { +@@ -517,9 +498,9 @@ gjstest_test_func_gjs_jsapi_util_string_get_ascii(void) + context = fixture.context; + + js_string = JS_NewStringCopyZ(context, ascii_string); +- g_assert(g_str_equal(gjs_string_get_ascii(STRING_TO_JSVAL(js_string)), ascii_string)); ++ g_assert(g_str_equal(gjs_string_get_ascii(context, STRING_TO_JSVAL(js_string)), ascii_string)); + void_value = JSVAL_VOID; +- g_assert(gjs_string_get_ascii_checked(context, void_value) == NULL); ++ g_assert(gjs_string_get_ascii(context, void_value) == NULL); + g_assert(JS_IsExceptionPending(context)); + + _gjs_unit_test_fixture_finish(&fixture); +diff --git a/gjs/jsapi-util.c b/gjs/jsapi-util.c +index 4695ec0..11c890a 100644 +--- a/gjs/jsapi-util.c ++++ b/gjs/jsapi-util.c +@@ -1128,7 +1128,7 @@ log_prop(JSContext *context, + if (JSVAL_IS_STRING(id)) { + const char *name; + +- name = gjs_string_get_ascii(id); ++ name = gjs_string_get_ascii(context, id); + gjs_debug(GJS_DEBUG_PROPS, + "prop %s: %s", + name, what); +diff --git a/gjs/jsapi-util.h b/gjs/jsapi-util.h +index b4a07ef..424cded 100644 +--- a/gjs/jsapi-util.h ++++ b/gjs/jsapi-util.h +@@ -311,8 +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 (jsval value); +-const char* gjs_string_get_ascii_checked (JSContext *context, ++const char* gjs_string_get_ascii (JSContext *context, + jsval value); + JSBool gjs_string_get_binary_data (JSContext *context, + jsval value, +diff --git a/gjs/native.c b/gjs/native.c +index 48175e3..3d97d70 100644 +--- a/gjs/native.c ++++ b/gjs/native.c +@@ -141,7 +141,7 @@ gjs_import_native_module(JSContext *context, + if (gjs_object_get_property(context, parent, "__moduleName__", &value) && + JSVAL_IS_STRING(value)) { + const char *name; +- name = gjs_string_get_ascii(value); ++ name = gjs_string_get_ascii(context, value); + + if (module_id->len > 0) + g_string_prepend(module_id, "."); +diff --git a/modules/dbus-exports.c b/modules/dbus-exports.c +index bd86ac8..0d8d9f3 100644 +--- a/modules/dbus-exports.c ++++ b/modules/dbus-exports.c +@@ -161,7 +161,7 @@ dbus_reply_from_exception_and_sender(JSContext *context, + if (JSVAL_IS_OBJECT(exc) && + gjs_object_get_property(context, JSVAL_TO_OBJECT(exc), + "dbusErrorName", &nameval)) +- name = gjs_string_get_ascii_checked(context, nameval); ++ name = gjs_string_get_ascii(context, nameval); + + if (!gjs_log_exception(context, &s)) + return JS_FALSE; +@@ -204,7 +204,7 @@ signature_from_method(JSContext *context, + if (gjs_object_get_property(context, + method_obj, "outSignature", + &signature_value)) { +- *signature = gjs_string_get_ascii_checked(context, ++ *signature = gjs_string_get_ascii(context, + signature_value); + if (*signature == NULL) { + return JS_FALSE; +@@ -408,7 +408,7 @@ async_call_callback(JSContext *context, + gjs_log_and_keep_exception(context, NULL); + return JS_FALSE; + } +- sender = gjs_string_get_ascii_checked(context, prop_value); ++ sender = gjs_string_get_ascii(context, prop_value); + if (!sender) + return JS_FALSE; + +@@ -444,7 +444,7 @@ async_call_callback(JSContext *context, + thrown = TRUE; + goto out; + } +- signature = gjs_string_get_ascii_checked(context, prop_value); ++ signature = gjs_string_get_ascii(context, prop_value); + if (!signature) + return JS_FALSE; + +@@ -834,7 +834,7 @@ unpack_property_details(JSContext *context, + return JS_FALSE; + } + +- name = gjs_string_get_ascii_checked(context, ++ name = gjs_string_get_ascii(context, + name_val); + if (name == NULL) { + return JS_FALSE; +@@ -850,7 +850,7 @@ unpack_property_details(JSContext *context, + return JS_FALSE; + } + +- signature = gjs_string_get_ascii_checked(context, ++ signature = gjs_string_get_ascii(context, + signature_val); + if (signature == NULL) { + return JS_FALSE; +@@ -866,7 +866,7 @@ unpack_property_details(JSContext *context, + return JS_FALSE; + } + +- access = gjs_string_get_ascii_checked(context, ++ access = gjs_string_get_ascii(context, + access_val); + if (access == NULL) { + return JS_FALSE; +diff --git a/modules/dbus-values.c b/modules/dbus-values.c +index 2b23ca0..2d94c4a 100644 +--- a/modules/dbus-values.c ++++ b/modules/dbus-values.c +@@ -807,7 +807,7 @@ append_dict(JSContext *context, + JSVAL_TO_OBJECT(prop_signatures), + name, &signature_value); + if (signature_value != JSVAL_VOID) { +- value_signature = gjs_string_get_ascii_checked(context, ++ value_signature = gjs_string_get_ascii(context, + signature_value); + if (value_signature == NULL) { + return JS_FALSE; +diff --git a/modules/dbus.c b/modules/dbus.c +index 0ab3c79..f93f7ff 100644 +--- a/modules/dbus.c ++++ b/modules/dbus.c +@@ -134,31 +134,31 @@ prepare_call(JSContext *context, + if (!bus_check(context, bus_type)) + return NULL; + +- bus_name = gjs_string_get_ascii_checked(context, argv[0]); ++ bus_name = gjs_string_get_ascii(context, argv[0]); + if (bus_name == NULL) + return NULL; + +- path = gjs_string_get_ascii_checked(context, argv[1]); ++ path = gjs_string_get_ascii(context, argv[1]); + if (path == NULL) + return NULL; + + if (JSVAL_IS_NULL(argv[2])) { + interface = NULL; + } else { +- interface = gjs_string_get_ascii_checked(context, argv[2]); ++ interface = gjs_string_get_ascii(context, argv[2]); + if (interface == NULL) + return NULL; /* exception was set */ + } + +- method = gjs_string_get_ascii_checked(context, argv[3]); ++ method = gjs_string_get_ascii(context, argv[3]); + if (method == NULL) + return NULL; + +- out_signature = gjs_string_get_ascii_checked(context, argv[4]); ++ out_signature = gjs_string_get_ascii(context, argv[4]); + if (out_signature == NULL) + return NULL; + +- in_signature = gjs_string_get_ascii_checked(context, argv[5]); ++ in_signature = gjs_string_get_ascii(context, argv[5]); + if (in_signature == NULL) + return NULL; + +@@ -447,7 +447,7 @@ fill_with_null_or_string(JSContext *context, const char **string_p, jsval value) + if (JSVAL_IS_NULL(value)) + *string_p = NULL; + else { +- *string_p = gjs_string_get_ascii_checked(context, value); ++ *string_p = gjs_string_get_ascii(context, value); + if (!*string_p) + return JS_FALSE; + } +@@ -878,16 +878,16 @@ gjs_js_dbus_emit_signal(JSContext *context, + if (!get_bus_type_from_object(context, obj, &bus_type)) + return JS_FALSE; + +- object_path = gjs_string_get_ascii_checked(context, argv[0]); ++ object_path = gjs_string_get_ascii(context, argv[0]); + if (!object_path) + return JS_FALSE; +- iface = gjs_string_get_ascii_checked(context, argv[1]); ++ iface = gjs_string_get_ascii(context, argv[1]); + if (!iface) + return JS_FALSE; +- signal = gjs_string_get_ascii_checked(context, argv[2]); ++ signal = gjs_string_get_ascii(context, argv[2]); + if (!signal) + return JS_FALSE; +- in_signature = gjs_string_get_ascii_checked(context, argv[3]); ++ in_signature = gjs_string_get_ascii(context, argv[3]); + if (!in_signature) + return JS_FALSE; + +@@ -1134,7 +1134,7 @@ gjs_js_dbus_acquire_name(JSContext *context, + if (!get_bus_type_from_object(context, obj, &bus_type)) + return JS_FALSE; + +- bus_name = gjs_string_get_ascii_checked(context, argv[0]); ++ bus_name = gjs_string_get_ascii(context, argv[0]); + if (bus_name == NULL) + return JS_FALSE; + +@@ -1369,7 +1369,7 @@ gjs_js_dbus_watch_name(JSContext *context, + if (!get_bus_type_from_object(context, obj, &bus_type)) + return JS_FALSE; + +- bus_name = gjs_string_get_ascii_checked(context, argv[0]); ++ bus_name = gjs_string_get_ascii(context, argv[0]); + if (bus_name == NULL) + return JS_FALSE; + +@@ -1482,7 +1482,7 @@ gjs_js_dbus_signature_length(JSContext *context, + return JS_FALSE; + } + +- signature = gjs_string_get_ascii_checked(context, argv[0]); ++ signature = gjs_string_get_ascii(context, argv[0]); + if (signature == NULL) + return JS_FALSE; + +@@ -1523,7 +1523,7 @@ gjs_js_dbus_start_service(JSContext *context, + return JS_FALSE; + } + +- name = gjs_string_get_ascii_checked(context, argv[0]); ++ name = gjs_string_get_ascii(context, argv[0]); + if (!name) + return JS_FALSE; +