From a77a3b990e3a59b0e993f86836a92cc3ff9bc8ff Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Mon, 14 Nov 2022 21:15:48 -0800 Subject: function: Do not allow returning a transfer-none string from JS callback In order to marshal a string from JS into C, we have to create a temporary UTF-8 string. That string cannot be returned as transfer-none, because there is no obvious place to keep it alive so that it can live as long as the C code needs it to. See #519 for more explanation. This is currently "supported" but causes a memory leak. Instead, throw when creating a callback or vfunc in JS that would otherwise have this memory leak. --- gi/function.cpp | 13 +++++++++++++ installed-tests/js/testGIMarshalling.js | 7 ++++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/gi/function.cpp b/gi/function.cpp index c9f8b1f3..e6672e05 100644 --- a/gi/function.cpp +++ b/gi/function.cpp @@ -679,6 +679,19 @@ bool GjsCallbackTrampoline::initialize() { g_assert(is_valid()); g_assert(!m_closure); + GITypeInfo return_type; + g_callable_info_load_return_type(m_info, &return_type); + GITypeTag return_tag = g_type_info_get_tag(&return_type); + if (g_callable_info_get_caller_owns(m_info) == GI_TRANSFER_NOTHING && + (return_tag == GI_TYPE_TAG_FILENAME || + return_tag == GI_TYPE_TAG_UTF8)) { + gjs_throw(context(), + "%s %s returns a transfer-none string. This is not supported " + "(https://gitlab.gnome.org/GNOME/gjs/-/issues/519)", + m_is_vfunc ? "VFunc" : "Callback", m_info.name()); + return false; + } + /* Analyze param types and directions, similarly to * init_cached_function_data */ int n_param_types = g_callable_info_get_n_args(m_info); diff --git a/installed-tests/js/testGIMarshalling.js b/installed-tests/js/testGIMarshalling.js index 97f8d542..2140f67b 100644 --- a/installed-tests/js/testGIMarshalling.js +++ b/installed-tests/js/testGIMarshalling.js @@ -1258,9 +1258,10 @@ let VFuncTester = GObject.registerClass(class VFuncTester extends GIMarshallingT return i + 4; } - vfunc_method_str_arg_out_ret(s) { - return [`Called with ${s}`, 41]; - } + // https://gitlab.gnome.org/GNOME/gjs/-/issues/519 + // vfunc_method_str_arg_out_ret(s) { + // return [`Called with ${s}`, 41]; + // } vfunc_method_with_default_implementation(i) { this.int = i + 2; -- cgit v1.2.1