Skip to content
Commits on Source (7)
Version 1.74.2
--------------
- Various fixes ported from the development branch.
- Closed bugs and merge requests:
* build error with clang [#514, !807, Philip Chimento]
* can't compile current version with mozjs 102 [#503, !808, Philip Chimento]
* Enabling window-list extension causes gnome-shell to crash when running
"dconf update" as root [#510, !813, Philip Chimento]
* log: Fix an off-by-one buffer overflow [!817, Valentin David]
Version 1.74.1
--------------
......
......@@ -21,6 +21,7 @@
#include <js/GCVector.h>
#include <js/RootingAPI.h>
#include <js/TypeDecls.h>
#include <js/Value.h>
#include "gi/closure.h"
#include "gjs/jsapi-util.h"
......@@ -100,7 +101,7 @@ class GjsFunctionCallState {
public:
std::unordered_set<GIArgument*> ignore_release;
JS::RootedObject instance_object;
JS::RootedValueVector return_values;
JS::RootedVector<JS::Value> return_values;
GjsAutoError local_error;
GICallableInfo* info;
uint8_t gi_argc = 0;
......
......@@ -203,6 +203,12 @@ static void gjs_object_set_gproperty(GObject* object,
unsigned property_id [[maybe_unused]],
const GValue* value, GParamSpec* pspec) {
auto* priv = ObjectInstance::for_gobject(object);
if (!priv) {
g_warning("Wrapper for GObject %p was disposed, cannot set property %s",
object, g_param_spec_get_name(pspec));
return;
}
JSContext* cx = current_js_context();
JS::RootedObject js_obj(cx, priv->wrapper());
......@@ -216,6 +222,12 @@ static void gjs_object_get_gproperty(GObject* object,
unsigned property_id [[maybe_unused]],
GValue* value, GParamSpec* pspec) {
auto* priv = ObjectInstance::for_gobject(object);
if (!priv) {
g_warning("Wrapper for GObject %p was disposed, cannot get property %s",
object, g_param_spec_get_name(pspec));
return;
}
JSContext* cx = current_js_context();
JS::RootedObject js_obj(cx, priv->wrapper());
......
......@@ -140,6 +140,41 @@ describe('Garbage collection of introspected objects', function () {
System.gc();
GLib.idle_add(GLib.PRIORITY_LOW, () => done());
});
// This tests a race condition that would crash; it should warn instead
it('handles setting a property from C on an object whose JS wrapper has been collected', function (done) {
class SomeObject extends GObject.Object {
static [GObject.properties] = {
'screenfull': GObject.ParamSpec.boolean('screenfull', '', '',
GObject.ParamFlags.READWRITE,
false),
};
static {
GObject.registerClass(this);
}
}
GLib.test_expect_message('Gjs', GLib.LogLevelFlags.LEVEL_WARNING,
'*property screenfull*');
const settings = new Gio.Settings({schema: 'org.gnome.GjsTest'});
let obj = new SomeObject();
settings.bind('fullscreen', obj, 'screenfull', Gio.SettingsBindFlags.DEFAULT);
const handler = settings.connect('changed::fullscreen', () => {
obj.run_dispose();
obj = null;
settings.disconnect(handler);
GLib.idle_add(GLib.PRIORITY_LOW, () => {
GLib.test_assert_expected_messages_internal('Gjs',
'testIntrospection.js', 0,
'Warn about setting property on disposed JS object');
done();
});
});
settings.set_boolean('fullscreen', !settings.get_boolean('fullscreen'));
settings.reset('fullscreen');
});
});
describe('Gdk.Atom', function () {
......
......@@ -2,7 +2,7 @@
# SPDX-FileCopyrightText: 2019 Philip Chimento <philip.chimento@gmail.com>
# SPDX-FileCopyrightText: 2019 Chun-wei Fan <fanchunwei@src.gnome.org>
project('gjs', 'cpp', 'c', version: '1.74.1', license: ['MIT', 'LGPL2+'],
project('gjs', 'cpp', 'c', version: '1.74.2', license: ['MIT', 'LGPL2+'],
meson_version: '>= 0.54.0',
default_options: ['cpp_std=c++17', 'cpp_rtti=false', 'c_std=c99',
'warning_level=2', 'b_pch=true' ])
......
......@@ -55,12 +55,30 @@ static unsigned cpp_random_seed = 0;
using Gjs::Test::assert_equal;
template <typename T>
struct is_char_helper : public std::false_type {};
template <>
struct is_char_helper<char> : public std::true_type {};
template <>
struct is_char_helper<wchar_t> : public std::true_type {};
template <>
struct is_char_helper<char16_t> : public std::true_type {};
template <>
struct is_char_helper<char32_t> : public std::true_type {};
template <typename T>
struct is_char : public is_char_helper<std::remove_cv_t<T>>::type {};
template <typename T>
inline constexpr bool is_char_v = is_char<T>::value;
template <typename T>
T get_random_number() {
std::mt19937_64 gen(cpp_random_seed);
if constexpr (std::is_same_v<T, bool>) {
return g_random_boolean();
} else if constexpr (is_char_v<T>) {
return std::char_traits<T>::to_char_type(
get_random_number<typename std::char_traits<T>::int_type>());
} else if constexpr (std::is_integral_v<T>) {
T lowest_value = std::numeric_limits<T>::lowest();
......
......@@ -152,7 +152,8 @@ void gjs_log_init() {
GjsAutoStrv prefixes(g_strsplit(topics, ";", -1));
for (unsigned i = 0; prefixes[i] != NULL; i++) {
GjsDebugTopic topic = prefix_to_topic(prefixes[i]);
s_enabled_topics[topic] = topic != GJS_DEBUG_LAST;
if (topic != GJS_DEBUG_LAST)
s_enabled_topics[topic] = true;
}
}
}
......