public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
* [rpms/ibus] autotool: Resolves: #2237664 Fix mouse position in Emojier category list
@ 2026-05-31 2:09 Takao Fujiwara
0 siblings, 0 replies; only message in thread
From: Takao Fujiwara @ 2026-05-31 2:09 UTC (permalink / raw)
To: git-commits
A new commit has been pushed.
Repo : rpms/ibus
Branch : autotool
Commit : 990903b4ad15a7089c2b45047f00853bb7310553
Author : Takao Fujiwara <tfujiwar@redhat.com>
Date : 2025-11-27T09:43:49+09:00
Stats : +2052/-54 in 3 file(s)
URL : https://src.fedoraproject.org/rpms/ibus/c/990903b4ad15a7089c2b45047f00853bb7310553?branch=autotool
Log:
Resolves: #2237664 Fix mouse position in Emojier category list
- Resolves: #2326455 Free IBusInputContext in input_method_activate()
- Resolves: #2346033 Fix SEGV with allocation fail in _Xi18nChangeIC()
- Resolves: #2392358 Refer QT_IM_MODULES to check Wayland
- don't build in parallel in ui/gtk3
- Fix GCC `-Wunused-but-set-variable` flag
- '--enable-wayland-im' option without daemon
- Fix memory leaks with fail safe
- Fix memory leaks #2
- Set MessageDialog at input cursor
- Move group name detection to ibus_get_group_name()
---
diff --git a/ibus-1385349-segv-bus-proxy.patch b/ibus-1385349-segv-bus-proxy.patch
index 612b654..2d919b2 100644
--- a/ibus-1385349-segv-bus-proxy.patch
+++ b/ibus-1385349-segv-bus-proxy.patch
@@ -1,4 +1,4 @@
-From 1286ce92a5ccf68b5dcf1b4a7c0884ce29d5c51b Mon Sep 17 00:00:00 2001
+From 656390df46ba963afe51420ecb9399b6dde9a2bd Mon Sep 17 00:00:00 2001
From: fujiwarat <takao.fujiwara1@gmail.com>
Date: Fri, 12 Jul 2024 23:30:25 +0900
Subject: [PATCH] Fix SEGV in bus_panel_proxy_focus_in()
@@ -21,9 +21,6 @@ WIP: Add a GError to get the error message to check why the SEGV happened.
rhbz#1663528 SEGV in g_mutex_clear() in bus_dbus_impl_destroy()
If the mutex is not unlocked, g_mutex_clear() causes assert.
-rhbz#1767691 SEGV in client/x11/main.c:_sighandler().
-Do not call atexit functions in _sighandler().
-
rhbz#2195895 SEGV in client/x11/main.c:_xim_set_cursor_location()
check if IBusInputContext was disconnected.
@@ -48,7 +45,6 @@ Connect "handle-destroy" signal after g_list_prepend().
BUG=rhbz#1350291
BUG=rhbz#1601577
BUG=rhbz#1663528
-BUG=rhbz#1767691
BUG=rhbz#1795499
BUG=rhbz#1771238
BUG=rhbz#1767976
@@ -57,21 +53,21 @@ BUG=rhbz#2151344
BUG=rhbz#2195895
BUG=rhbz#2239633
---
- bus/dbusimpl.c | 47 ++++++++++++++++++++++++---
- bus/engineproxy.c | 44 +++++++++++++++++++------
- bus/panelproxy.c | 9 +++++-
- client/x11/main.c | 56 ++++++++++++++++++++++++++++----
- portal/portal.c | 25 ++++++++++++---
- src/ibusbus.c | 6 ++++
- ui/gtk3/extension.vala | 4 +++
- ui/gtk3/switcher.vala | 73 +++++++++++++++++++++++++-----------------
- 8 files changed, 208 insertions(+), 56 deletions(-)
+ bus/dbusimpl.c | 47 ++++++++++++++++++++++++++++++++++++----
+ bus/engineproxy.c | 44 ++++++++++++++++++++++++++++---------
+ bus/panelproxy.c | 9 +++++++-
+ client/x11/main.c | 49 +++++++++++++++++++++++++++++++++++++-----
+ portal/portal.c | 25 ++++++++++++++++-----
+ src/ibusbus.c | 6 ++++++
+ ui/gtk3/extension.vala | 4 ++++
+ ui/gtk3/switcher.vala | 48 +++++++++++++++++++++++++----------------
+ 8 files changed, 188 insertions(+), 44 deletions(-)
diff --git a/bus/dbusimpl.c b/bus/dbusimpl.c
-index 110d864a..391d576a 100644
+index 70792be8..9c535bf2 100644
--- a/bus/dbusimpl.c
+++ b/bus/dbusimpl.c
-@@ -621,6 +621,7 @@ static void
+@@ -634,6 +634,7 @@ static void
bus_dbus_impl_destroy (BusDBusImpl *dbus)
{
GList *p;
@@ -79,7 +75,7 @@ index 110d864a..391d576a 100644
for (p = dbus->objects; p != NULL; p = p->next) {
IBusService *object = (IBusService *) p->data;
-@@ -644,6 +645,10 @@ bus_dbus_impl_destroy (BusDBusImpl *dbus)
+@@ -657,6 +658,10 @@ bus_dbus_impl_destroy (BusDBusImpl *dbus)
for (p = dbus->connections; p != NULL; p = p->next) {
BusConnection *connection = BUS_CONNECTION (p->data);
@@ -90,7 +86,7 @@ index 110d864a..391d576a 100644
g_signal_handlers_disconnect_by_func (connection,
bus_dbus_impl_connection_destroy_cb, dbus);
ibus_object_destroy (IBUS_OBJECT (connection));
-@@ -658,12 +663,39 @@ bus_dbus_impl_destroy (BusDBusImpl *dbus)
+@@ -675,12 +680,39 @@ bus_dbus_impl_destroy (BusDBusImpl *dbus)
dbus->unique_names = NULL;
dbus->names = NULL;
@@ -132,7 +128,7 @@ index 110d864a..391d576a 100644
/* FIXME destruct _lock and _queue members. */
IBUS_OBJECT_CLASS(bus_dbus_impl_parent_class)->destroy ((IBusObject *)dbus);
-@@ -1539,13 +1571,20 @@ bus_dbus_impl_connection_filter_cb (GDBusConnection *dbus_connection,
+@@ -1556,13 +1588,20 @@ bus_dbus_impl_connection_filter_cb (GDBusConnection *dbus_connection,
gboolean incoming,
gpointer user_data)
{
@@ -156,10 +152,10 @@ index 110d864a..391d576a 100644
if (incoming) {
/* is incoming message */
diff --git a/bus/engineproxy.c b/bus/engineproxy.c
-index b3e16066..ba479b59 100644
+index 37736b69..7f34604c 100644
--- a/bus/engineproxy.c
+++ b/bus/engineproxy.c
-@@ -693,10 +693,12 @@ bus_engine_proxy_g_signal (GDBusProxy *proxy,
+@@ -775,10 +775,12 @@ bus_engine_proxy_g_signal (GDBusProxy *proxy,
g_return_if_reached ();
}
@@ -173,7 +169,7 @@ index b3e16066..ba479b59 100644
{
GDBusProxyFlags flags;
BusEngineProxy *engine;
-@@ -706,12 +708,20 @@ bus_engine_proxy_new_internal (const gchar *path,
+@@ -788,12 +790,20 @@ bus_engine_proxy_new_internal (const gchar *path,
g_assert (path);
g_assert (IBUS_IS_ENGINE_DESC (desc));
g_assert (G_IS_DBUS_CONNECTION (connection));
@@ -195,7 +191,7 @@ index b3e16066..ba479b59 100644
"desc", desc,
"g-connection", connection,
"g-interface-name", IBUS_INTERFACE_ENGINE,
-@@ -719,6 +729,12 @@ bus_engine_proxy_new_internal (const gchar *path,
+@@ -801,6 +811,12 @@ bus_engine_proxy_new_internal (const gchar *path,
"g-default-timeout", g_gdbus_timeout,
"g-flags", flags,
NULL);
@@ -208,7 +204,7 @@ index b3e16066..ba479b59 100644
const gchar *layout = ibus_engine_desc_get_layout (desc);
if (layout != NULL && layout[0] != '\0') {
engine->keymap = ibus_keymap_get (layout);
-@@ -756,6 +772,7 @@ bus_engine_proxy_new_internal (const gchar *path,
+@@ -838,6 +854,7 @@ bus_engine_proxy_new_internal (const gchar *path,
return engine;
}
@@ -216,7 +212,7 @@ index b3e16066..ba479b59 100644
typedef struct {
GTask *task;
-@@ -818,23 +835,30 @@ create_engine_ready_cb (BusFactoryProxy *factory,
+@@ -900,23 +917,30 @@ create_engine_ready_cb (BusFactoryProxy *factory,
GAsyncResult *res,
EngineProxyNewData *data)
{
@@ -256,10 +252,10 @@ index b3e16066..ba479b59 100644
/* FIXME: set destroy callback ? */
g_task_return_pointer (data->task, engine, NULL);
diff --git a/bus/panelproxy.c b/bus/panelproxy.c
-index e6001ebf..00828fbc 100644
+index 4c2c8885..a7bec193 100644
--- a/bus/panelproxy.c
+++ b/bus/panelproxy.c
-@@ -122,6 +122,8 @@ bus_panel_proxy_new (BusConnection *connection,
+@@ -124,6 +124,8 @@ bus_panel_proxy_new (BusConnection *connection,
const gchar *path = NULL;
GObject *obj;
BusPanelProxy *panel;
@@ -268,7 +264,7 @@ index e6001ebf..00828fbc 100644
g_assert (BUS_IS_CONNECTION (connection));
-@@ -138,7 +140,7 @@ bus_panel_proxy_new (BusConnection *connection,
+@@ -140,7 +142,7 @@ bus_panel_proxy_new (BusConnection *connection,
obj = g_initable_new (BUS_TYPE_PANEL_PROXY,
NULL,
@@ -277,7 +273,7 @@ index e6001ebf..00828fbc 100644
"g-object-path", path,
"g-interface-name", IBUS_INTERFACE_PANEL,
"g-connection", bus_connection_get_dbus_connection (connection),
-@@ -146,6 +148,11 @@ bus_panel_proxy_new (BusConnection *connection,
+@@ -148,6 +150,11 @@ bus_panel_proxy_new (BusConnection *connection,
"g-flags", G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START | G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
NULL);
@@ -290,7 +286,7 @@ index e6001ebf..00828fbc 100644
panel->panel_type = panel_type;
return panel;
diff --git a/client/x11/main.c b/client/x11/main.c
-index b7eb5961..3075d5d0 100644
+index 5fadd43d..26d4a7f1 100644
--- a/client/x11/main.c
+++ b/client/x11/main.c
@@ -45,6 +45,7 @@
@@ -436,20 +432,6 @@ index b7eb5961..3075d5d0 100644
ibus_input_context_reset (x11ic->context);
-@@ -1309,7 +1348,12 @@ _atexit_cb ()
- static void
- _sighandler (int sig)
- {
-- exit(EXIT_FAILURE);
-+ /* rhbz#1767691 _sighandler() is called with SIGTERM
-+ * and exit() causes SEGV during calling atexit functions.
-+ * _atexit_cb() might be broken. _exit() does not call
-+ * atexit functions.
-+ */
-+ _exit(EXIT_FAILURE);
- }
-
- static void
diff --git a/portal/portal.c b/portal/portal.c
index 5cd38779..5110baad 100644
--- a/portal/portal.c
@@ -510,10 +492,10 @@ index 5cd38779..5110baad 100644
g_object_unref (portal_context);
}
diff --git a/src/ibusbus.c b/src/ibusbus.c
-index 0e6d67f1..fcc742b6 100644
+index 540d1da3..defdb73b 100644
--- a/src/ibusbus.c
+++ b/src/ibusbus.c
-@@ -742,6 +742,12 @@ ibus_bus_destroy (IBusObject *object)
+@@ -750,6 +750,12 @@ ibus_bus_destroy (IBusObject *object)
_bus = NULL;
if (bus->priv->monitor) {
@@ -527,7 +509,7 @@ index 0e6d67f1..fcc742b6 100644
bus->priv->monitor = NULL;
}
diff --git a/ui/gtk3/extension.vala b/ui/gtk3/extension.vala
-index a6f2e8e6..b7a04081 100644
+index 5cd1a6ad..3acd76ea 100644
--- a/ui/gtk3/extension.vala
+++ b/ui/gtk3/extension.vala
@@ -73,6 +73,10 @@ class ExtensionGtk : Gtk.Application {
@@ -542,7 +524,7 @@ index a6f2e8e6..b7a04081 100644
m_panel.load_settings();
}
diff --git a/ui/gtk3/switcher.vala b/ui/gtk3/switcher.vala
-index 26bded99..21ede7be 100644
+index d4a5fa11..788eea06 100644
--- a/ui/gtk3/switcher.vala
+++ b/ui/gtk3/switcher.vala
@@ -251,27 +251,37 @@ class Switcher : Gtk.Window {
@@ -566,6 +548,7 @@ index 26bded99..21ede7be 100644
- out m_mouse_init_x,
- out m_mouse_init_y);
- m_mouse_moved = false;
+-
+ } else {
+ status = seat.grab(get_window(),
+ Gdk.SeatCapabilities.POINTER,
@@ -577,6 +560,9 @@ index 26bded99..21ede7be 100644
+ warning("Grab pointer failed! status = %d", status);
+ }
+- m_loop = new GLib.MainLoop();
+- m_loop.run();
+- m_loop = null;
+ /* Fix RHBZ #1771238 assert(m_loop == null)
+ * Grabbing keyboard can be failed when the second Super-e is typed
+ * before Switcher dialog is focused. And m_loop could not be released
@@ -590,10 +576,7 @@ index 26bded99..21ede7be 100644
+ out m_mouse_init_x,
+ out m_mouse_init_y);
+ m_mouse_moved = false;
-
-- m_loop = new GLib.MainLoop();
-- m_loop.run();
-- m_loop = null;
++
+ m_loop = new GLib.MainLoop();
+ m_loop.run();
+ m_loop = null;
@@ -602,5 +585,5 @@ index 26bded99..21ede7be 100644
seat.ungrab();
--
-2.45.0
+2.51.0
diff --git a/ibus-HEAD.patch b/ibus-HEAD.patch
index e69de29..d0f51e5 100644
--- a/ibus-HEAD.patch
+++ b/ibus-HEAD.patch
@@ -0,0 +1,2001 @@
+From 563b433d721201e76b4e8ac6ea593e873fd72a13 Mon Sep 17 00:00:00 2001
+From: Arnout Engelen <arnout@bzzt.net>
+Date: Mon, 3 Nov 2025 09:49:46 +0100
+Subject: [PATCH] ui/gtk3: don't build in parallel
+
+As that led to nondeterministic generated method names. This
+only seems to have a small effect on performance (~10s on a
+whole fresh build).
+
+While I appreciate the ibus project doesn't consider such
+nondeterminisms as particularly problematic (#2272), having
+bitwise reproducible builds is increasingly desirable in Linux
+distributions, so hopefully you could consider applying this
+change nonetheless.
+
+BUG=https://github.com/ibus/ibus/pull/2821
+---
+ ui/gtk3/Makefile.am | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/ui/gtk3/Makefile.am b/ui/gtk3/Makefile.am
+index d99d8e82..4df6c5eb 100644
+--- a/ui/gtk3/Makefile.am
++++ b/ui/gtk3/Makefile.am
+@@ -317,6 +317,8 @@ panelbinding.o: $(srcdir)/panelbinding.c
+ $(AM_V_CC_no)$(COMPILE) -c -o $@ $<
+ $(NULL)
+
++.NOTPARALLEL:
++
+ MAINTAINERCLEANFILES += extension.c panelbinding.c
+
+ man_seven_DATA = ibus-emoji.7
+--
+2.51.0
+
+From 02032bc5f0fc89c7d18774758ae052dd3606408b Mon Sep 17 00:00:00 2001
+From: fujiwarat <takao.fujiwara1@gmail.com>
+Date: Mon, 6 Oct 2025 20:40:17 +0900
+Subject: [PATCH 1/4] src: Fix GCC `-Wunused-but-set-variable` flag
+
+Add `G_GNUC_UNUSED` flag for the GCC warnings.
+
+BUG=https://github.com/ibus/ibus/pull/2805
+---
+ src/ibuscomponent.c | 4 ++--
+ src/ibusmessage.c | 2 +-
+ src/ibusserializable.c | 4 ++--
+ 3 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/src/ibuscomponent.c b/src/ibuscomponent.c
+index 80ace332..c453a2f5 100644
+--- a/src/ibuscomponent.c
++++ b/src/ibuscomponent.c
+@@ -2,7 +2,7 @@
+ /* vim:set et sts=4: */
+ /* bus - The Input Bus
+ * Copyright (C) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
+- * Copyright (C) 2020 Takao Fujiwara <takao.fujiwara1@gmail.com>
++ * Copyright (C) 2020-2025 Takao Fujiwara <takao.fujiwara1@gmail.com>
+ * Copyright (C) 2008-2020 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+@@ -729,7 +729,7 @@ ibus_component_new_varargs (const gchar *first_property_name, ...)
+ {
+ va_list var_args;
+ IBusComponent *component;
+- IBusComponentPrivate *priv;
++ G_GNUC_UNUSED IBusComponentPrivate *priv;
+
+ g_assert (first_property_name);
+
+diff --git a/src/ibusmessage.c b/src/ibusmessage.c
+index 89e31771..12fbb48e 100644
+--- a/src/ibusmessage.c
++++ b/src/ibusmessage.c
+@@ -459,7 +459,7 @@ ibus_message_new (guint domain,
+ GValue *values, *values_tmp;
+ guint n_properties = 4, i;
+ IBusMessage *msg;
+- IBusMessagePrivate *priv;
++ G_GNUC_UNUSED IBusMessagePrivate *priv;
+
+ g_return_val_if_fail (domain > 0 && domain <= G_MAXUINT8, NULL);
+ g_return_val_if_fail (code <= G_MAXUINT8, NULL);
+diff --git a/src/ibusserializable.c b/src/ibusserializable.c
+index 231020b7..501841b3 100644
+--- a/src/ibusserializable.c
++++ b/src/ibusserializable.c
+@@ -2,7 +2,7 @@
+ /* vim:set et sts=4: */
+ /* ibus - The Input Bus
+ * Copyright (C) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
+- * Copyright (C) 2018-2019 Takao Fujiwara <takao.fujiwara1@gmail.com>
++ * Copyright (C) 2018-2025 Takao Fujiwara <takao.fujiwara1@gmail.com>
+ * Copyright (C) 2008-2019 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+@@ -269,7 +269,7 @@ GVariant *
+ ibus_serializable_serialize_object (IBusSerializable *object)
+ {
+ g_return_val_if_fail (IBUS_IS_SERIALIZABLE (object), FALSE);
+- gboolean retval;
++ G_GNUC_UNUSED gboolean retval;
+
+ GVariantBuilder builder;
+ g_variant_builder_init (&builder, G_VARIANT_TYPE_TUPLE);
+--
+2.51.1
+
+From c9d5d0f521de9f02a876c319c02978235a7453cc Mon Sep 17 00:00:00 2001
+From: fujiwarat <takao.fujiwara1@gmail.com>
+Date: Mon, 6 Oct 2025 20:40:25 +0900
+Subject: [PATCH 2/4] ui/gtk3/application: --enable-wayland-im option without daemon
+
+Wish to run ibus-daemon after run ibus-ui-gtk3 for the debug purpose.
+
+BUG=https://github.com/ibus/ibus/pull/2805
+---
+ ui/gtk3/application.vala | 33 ++++++++++++++++++++++++---------
+ 1 file changed, 24 insertions(+), 9 deletions(-)
+
+diff --git a/ui/gtk3/application.vala b/ui/gtk3/application.vala
+index 82cc5397..65ab43cf 100644
+--- a/ui/gtk3/application.vala
++++ b/ui/gtk3/application.vala
+@@ -37,6 +37,7 @@ class Application {
+ private static bool m_verbose;
+ private static bool m_enable_wayland_im;
+ #if USE_GDK_WAYLAND
++ private static ulong m_bus_connected_id;
+ private static ulong m_realize_surface_id;
+ private static ulong m_ibus_focus_in_id;
+ private static ulong m_ibus_focus_out_id;
+@@ -285,7 +286,7 @@ class Application {
+ bus = new IBus.Bus();
+ GLib.MainLoop? loop = null;
+ if (!bus.is_connected() && m_exec_daemon) {
+- ulong handler_id = bus.connected.connect((bus) => {
++ m_bus_connected_id = bus.connected.connect((bus) => {
+ if (loop != null)
+ loop.quit();
+ });
+@@ -295,17 +296,31 @@ class Application {
+ loop.run();
+ }
+ }
+- bus.disconnect(handler_id);
++ bus.disconnect(m_bus_connected_id);
++ m_bus_connected_id = 0;
+ }
+ if (!bus.is_connected()) {
+- m_log.printf("Failed to connect to ibus-daemon\n");
+- m_log.flush();
+- assert_not_reached();
++ if (m_exec_daemon) {
++ m_log.printf("Failed to connect to ibus-daemon\n");
++ m_log.flush();
++ assert_not_reached();
++ } else {
++ m_bus_connected_id = bus.connected.connect((bus) => {
++ m_wayland_im = new IBus.WaylandIM("bus", bus,
++ "wl_display", wl_display,
++ "log", m_log,
++ "verbose", m_verbose);
++ bus.disconnect(m_bus_connected_id);
++ m_bus_connected_id = 0;
++ });
++ }
++ }
++ if (bus.is_connected()) {
++ m_wayland_im = new IBus.WaylandIM("bus", bus,
++ "wl_display", wl_display,
++ "log", m_log,
++ "verbose", m_verbose);
+ }
+- m_wayland_im = new IBus.WaylandIM("bus", bus,
+- "wl_display", wl_display,
+- "log", m_log,
+- "verbose", m_verbose);
+ }
+
+ private void set_wayland_surface(void *surface) {
+--
+2.51.1
+
+From 1a9ea16b12d4e90e4caf74c4569a596660da6e9c Mon Sep 17 00:00:00 2001
+From: fujiwarat <takao.fujiwara1@gmail.com>
+Date: Wed, 26 Nov 2025 14:55:28 +0900
+Subject: [PATCH 3/4] util/IMdkit: Fix memory leaks with fail safe
+
+- When malloc() is failed, the pointer should not be deallocated
+ and also other allocated memory pointers should be freed in FrameMgr.c.
+- The `XIM_STRFUNC` macro implemented in XimProto.h.
+- GCC `-Wanalyzer-malloc-leak` flag does not have to warn the reallocation
+ since the `address` pointer is not changed and `address->imvalue_mask`
+ should work in i18nMethod.c
+- Seems GCC does not understand `if (!p->value)` and replace it with a
+ wrapper variable in i18nMethod.c
+- Fix exit() from within signal handler by CWE-479 and
+ `-Wanalyzer-unsafe-call-within-signal-handler` in client/x11/main.c
+
+BUG=https://github.com/ibus/ibus/pull/2805
+---
+ client/x11/main.c | 7 +-
+ util/IMdkit/FrameMgr.c | 316 ++++++++++++++++++++++++++++++++++-----
+ util/IMdkit/XimProto.h | 7 +-
+ util/IMdkit/i18nMethod.c | 104 +++++++------
+ 4 files changed, 352 insertions(+), 82 deletions(-)
+
+diff --git a/client/x11/main.c b/client/x11/main.c
+index ab9679dd..5fadd43d 100644
+--- a/client/x11/main.c
++++ b/client/x11/main.c
+@@ -1309,7 +1309,12 @@ _atexit_cb ()
+ static void
+ _sighandler (int sig)
+ {
+- exit(EXIT_FAILURE);
++ /* rhbz#1767691 _sighandler() is called with SIGTERM
++ * and exit() causes SEGV during calling atexit functions.
++ * _atexit_cb() might be broken. _exit() does not call
++ * atexit functions.
++ */
++ _exit (EXIT_FAILURE);
+ }
+
+ static void
+diff --git a/util/IMdkit/FrameMgr.c b/util/IMdkit/FrameMgr.c
+index 80d019a0..976db94e 100644
+--- a/util/IMdkit/FrameMgr.c
++++ b/util/IMdkit/FrameMgr.c
+@@ -23,6 +23,7 @@ SOFTWARE.
+ miyamoto@jrd.dec.com
+
+ This version tidied and debugged by Steve Underwood May 1999
++ This version tidied and debugged by Takao Fujiwara Nov 2025
+
+ ******************************************************************/
+
+@@ -30,6 +31,7 @@ SOFTWARE.
+ #include <assert.h>
+ #include <stdlib.h>
+ #include "FrameMgr.h"
++#include "XimProto.h"
+
+ /* Convenient macro */
+
+@@ -218,7 +220,11 @@ FrameMgr FrameMgrInit (XimFrame frame, char* area, Bool byte_swap)
+ {
+ FrameMgr fm;
+
+- fm = (FrameMgr) Xmalloc (sizeof (FrameMgrRec));
++ if ((fm = (FrameMgr) Xmalloc (sizeof (FrameMgrRec))) == NULL) {
++ fprintf (stderr, "(XIM-IMdkit) WARNING: malloc failed in %s:%s.\n",
++ __FILE__, XIM_STRFUNC);
++ return NULL;
++ }
+
+ fm->frame = frame;
+ fm->fi = FrameInstInit (frame);
+@@ -259,7 +265,8 @@ void FrameMgrFree (FrameMgr fm)
+ }
+ /*endwhile*/
+
+- FrameInstFree (fm->fi);
++ if (fm->fi)
++ FrameInstFree (fm->fi);
+ Xfree (fm);
+ }
+
+@@ -868,7 +875,11 @@ static FrameInst FrameInstInit (XimFrame frame)
+ {
+ FrameInst fi;
+
+- fi = (FrameInst) Xmalloc (sizeof (FrameInstRec));
++ if ((fi = (FrameInst) Xmalloc (sizeof (FrameInstRec))) == NULL) {
++ fprintf (stderr, "(XIM-IMdkit) WARNING: malloc failed in %s:%s.\n",
++ __FILE__, XIM_STRFUNC);
++ return NULL;
++ }
+
+ fi->template = frame;
+ fi->cur_no = 0;
+@@ -884,7 +895,7 @@ static void FrameInstFree (FrameInst fi)
+
+ ChainIterInit (&ci, &fi->cm);
+
+- while (ChainIterGetNext (&ci, &frame_no, &d))
++ while (ChainIterGetNext (&ci, &frame_no, &d) && fi->template)
+ {
+ register XimFrameType type;
+ type = fi->template[frame_no].type;
+@@ -912,6 +923,11 @@ static XimFrameType FrameInstGetNextType(FrameInst fi, XimFrameTypeInfo info)
+ {
+ XimFrameType ret_type;
+
++ if (!fi) {
++ fprintf (stderr, "(XIM-IMdkit) WARNING: fi != NULL in %s:%s.\n",
++ __FILE__, XIM_STRFUNC);
++ return -1;
++ }
+ ret_type = fi->template[fi->cur_no].type;
+
+ switch (ret_type)
+@@ -944,7 +960,13 @@ static XimFrameType FrameInstGetNextType(FrameInst fi, XimFrameTypeInfo info)
+ if ((d = ChainMgrGetExtraData (&fi->cm, iter_idx)) == NULL)
+ {
+ dr.iter = IterInit (&fi->template[iter_idx + 1], NO_VALUE);
++ if (!dr.iter)
++ return -1;
+ d = ChainMgrSetData (&fi->cm, iter_idx, dr);
++ if (!d) {
++ IterFree (dr.iter);
++ return -1;
++ }
+ }
+ /*endif*/
+ info->counter.iter = d->iter;
+@@ -980,6 +1002,7 @@ static XimFrameType FrameInstGetNextType(FrameInst fi, XimFrameTypeInfo info)
+ register int unit;
+ register int number;
+ register int size;
++ register int s;
+ register int i;
+
+ unit = _UNIT ((long) fi->template[fi->cur_no].data);
+@@ -991,11 +1014,21 @@ static XimFrameType FrameInstGetNextType(FrameInst fi, XimFrameTypeInfo info)
+ {
+ i = _FrameInstDecrement (fi->template, i);
+ assert (i >= 0);
+- size += _FrameInstGetItemSize (fi, i);
++ s = _FrameInstGetItemSize (fi, i);
++ if (s == NO_VALUE) {
++ size = NO_VALUE;
++ number = 0;
++ break;
++ } else {
++ size += s;
++ }
+ number--;
+ }
+ /*endwhile*/
+- info->num = (unit - (size%unit))%unit;
++ if (size == NO_VALUE)
++ info->num = NO_VALUE;
++ else
++ info->num = (unit - (size%unit))%unit;
+ }
+ /*endif*/
+ fi->cur_no = _FrameInstIncrement (fi->template, fi->cur_no);
+@@ -1011,7 +1044,13 @@ static XimFrameType FrameInstGetNextType(FrameInst fi, XimFrameTypeInfo info)
+ if ((d = ChainMgrGetExtraData (&fi->cm, fi->cur_no)) == NULL)
+ {
+ dr.iter = IterInit (&fi->template[fi->cur_no + 1], NO_VALUE);
++ if (!dr.iter)
++ return -1;
+ d = ChainMgrSetData (&fi->cm, fi->cur_no, dr);
++ if (!d) {
++ IterFree (dr.iter);
++ return -1;
++ }
+ }
+ /*endif*/
+ sub_type = IterGetNextType (d->iter, info);
+@@ -1037,7 +1076,13 @@ static XimFrameType FrameInstGetNextType(FrameInst fi, XimFrameTypeInfo info)
+ if ((d = ChainMgrGetExtraData (&fi->cm, fi->cur_no)) == NULL)
+ {
+ dr.fi = FrameInstInit (fi->template[fi->cur_no + 1].data);
++ if (!dr.fi)
++ return -1;
+ d = ChainMgrSetData (&fi->cm, fi->cur_no, dr);
++ if (!d) {
++ FrameInstFree (dr.fi);
++ return -1;
++ }
+ }
+ /*endif*/
+ sub_type = FrameInstGetNextType (d->fi, info);
+@@ -1064,6 +1109,11 @@ static XimFrameType FrameInstPeekNextType (FrameInst fi, XimFrameTypeInfo info)
+ {
+ XimFrameType ret_type;
+
++ if (!fi) {
++ fprintf (stderr, "(XIM-IMdkit) WARNING: fi != NULL in %s:%s.\n",
++ __FILE__, XIM_STRFUNC);
++ return -1;
++ }
+ ret_type = fi->template[fi->cur_no].type;
+
+ switch (ret_type)
+@@ -1096,7 +1146,13 @@ static XimFrameType FrameInstPeekNextType (FrameInst fi, XimFrameTypeInfo info)
+ if ((d = ChainMgrGetExtraData (&fi->cm, iter_idx)) == NULL)
+ {
+ dr.iter = IterInit (&fi->template[iter_idx + 1], NO_VALUE);
++ if (!dr.iter)
++ return -1;
+ d = ChainMgrSetData (&fi->cm, iter_idx, dr);
++ if (!d) {
++ IterFree (dr.iter);
++ return -1;
++ }
+ }
+ /*endif*/
+ info->counter.iter = d->iter;
+@@ -1130,6 +1186,7 @@ static XimFrameType FrameInstPeekNextType (FrameInst fi, XimFrameTypeInfo info)
+ register int unit;
+ register int number;
+ register int size;
++ register int s;
+ register int i;
+
+ unit = _UNIT ((long) fi->template[fi->cur_no].data);
+@@ -1141,11 +1198,21 @@ static XimFrameType FrameInstPeekNextType (FrameInst fi, XimFrameTypeInfo info)
+ {
+ i = _FrameInstDecrement (fi->template, i);
+ assert (i >= 0);
+- size += _FrameInstGetItemSize (fi, i);
++ s = _FrameInstGetItemSize (fi, i);
++ if (s == NO_VALUE) {
++ size = NO_VALUE;
++ number = 0;
++ break;
++ } else {
++ size += s;
++ }
+ number--;
+ }
+ /*endwhile*/
+- info->num = (unit - (size%unit))%unit;
++ if (size == NO_VALUE)
++ info->num = NO_VALUE;
++ else
++ info->num = (unit - (size%unit))%unit;
+ }
+ /*endif*/
+ break;
+@@ -1159,7 +1226,13 @@ static XimFrameType FrameInstPeekNextType (FrameInst fi, XimFrameTypeInfo info)
+ if ((d = ChainMgrGetExtraData (&fi->cm, fi->cur_no)) == NULL)
+ {
+ dr.iter = IterInit (&fi->template[fi->cur_no + 1], NO_VALUE);
++ if (!dr.iter)
++ return -1;
+ d = ChainMgrSetData (&fi->cm, fi->cur_no, dr);
++ if (!d) {
++ IterFree (dr.iter);
++ return -1;
++ }
+ }
+ /*endif*/
+ sub_type = IterPeekNextType (d->iter, info);
+@@ -1180,7 +1253,13 @@ static XimFrameType FrameInstPeekNextType (FrameInst fi, XimFrameTypeInfo info)
+ if ((d = ChainMgrGetExtraData (&fi->cm, fi->cur_no)) == NULL)
+ {
+ dr.fi = FrameInstInit (fi->template[fi->cur_no + 1].data);
++ if (!dr.fi)
++ return -1;
+ d = ChainMgrSetData (&fi->cm, fi->cur_no, dr);
++ if (!d) {
++ FrameInstFree (dr.fi);
++ return -1;
++ }
+ }
+ /*endif*/
+ sub_type = FrameInstPeekNextType (d->fi, info);
+@@ -1202,6 +1281,11 @@ static Bool FrameInstIsIterLoopEnd (FrameInst fi)
+ {
+ Bool ret = False;
+
++ if (!fi) {
++ fprintf (stderr, "(XIM-IMdkit) WARNING: fi != NULL in %s:%s.\n",
++ __FILE__, XIM_STRFUNC);
++ return True;
++ }
+ if (fi->template[fi->cur_no].type == ITER)
+ {
+ ExtraData d = ChainMgrGetExtraData (&fi->cm, fi->cur_no);
+@@ -1313,6 +1397,11 @@ static FmStatus FrameInstSetSize (FrameInst fi, int num)
+ XimFrameType type;
+ register int i;
+
++ if (!fi) {
++ fprintf (stderr, "(XIM-IMdkit) WARNING: fi != NULL in %s:%s.\n",
++ __FILE__, XIM_STRFUNC);
++ return FmNoMoreData;
++ }
+ i = 0;
+ while ((type = fi->template[i].type) != EOL)
+ {
+@@ -1323,6 +1412,8 @@ static FmStatus FrameInstSetSize (FrameInst fi, int num)
+ {
+ dr.num = -1;
+ d = ChainMgrSetData (&fi->cm, i, dr);
++ if (!d)
++ return FmNoMoreData;
+ }
+ /*endif*/
+ if (d->num == NO_VALUE)
+@@ -1336,7 +1427,13 @@ static FmStatus FrameInstSetSize (FrameInst fi, int num)
+ if ((d = ChainMgrGetExtraData (&fi->cm, i)) == NULL)
+ {
+ dr.iter = IterInit (&fi->template[i + 1], NO_VALUE);
++ if (!dr.iter)
++ return FmNoMoreData;
+ d = ChainMgrSetData (&fi->cm, i, dr);
++ if (!d) {
++ IterFree (dr.iter);
++ return FmNoMoreData;
++ }
+ }
+ /*endif*/
+ if (IterSetSize (d->iter, num) == FmSuccess)
+@@ -1348,7 +1445,13 @@ static FmStatus FrameInstSetSize (FrameInst fi, int num)
+ if ((d = ChainMgrGetExtraData(&fi->cm, i)) == NULL)
+ {
+ dr.fi = FrameInstInit(fi->template[i + 1].data);
+- d = ChainMgrSetData(&fi->cm, i, dr);
++ if (!dr.fi)
++ return FmNoMoreData;
++ d = ChainMgrSetData (&fi->cm, i, dr);
++ if (!d) {
++ FrameInstFree (dr.fi);
++ return FmNoMoreData;
++ }
+ }
+ /*endif*/
+ if (FrameInstSetSize(d->fi, num) == FmSuccess)
+@@ -1374,6 +1477,11 @@ static int FrameInstGetSize (FrameInst fi)
+ ExtraDataRec dr;
+ int ret_size;
+
++ if (!fi) {
++ fprintf (stderr, "(XIM-IMdkit) WARNING: fi != NULL in %s:%s.\n",
++ __FILE__, XIM_STRFUNC);
++ return NO_VALID_FIELD;
++ }
+ i = fi->cur_no;
+ while ((type = fi->template[i].type) != EOL)
+ {
+@@ -1389,7 +1497,13 @@ static int FrameInstGetSize (FrameInst fi)
+ if ((d = ChainMgrGetExtraData (&fi->cm, i)) == NULL)
+ {
+ dr.iter = IterInit (&fi->template[i + 1], NO_VALUE);
++ if (!dr.iter)
++ return NO_VALID_FIELD;
+ d = ChainMgrSetData (&fi->cm, i, dr);
++ if (!d) {
++ IterFree (dr.iter);
++ return NO_VALID_FIELD;
++ }
+ }
+ /*endif*/
+ ret_size = IterGetSize(d->iter);
+@@ -1402,7 +1516,13 @@ static int FrameInstGetSize (FrameInst fi)
+ if ((d = ChainMgrGetExtraData (&fi->cm, i)) == NULL)
+ {
+ dr.fi = FrameInstInit (fi->template[i + 1].data);
++ if (!dr.fi)
++ return NO_VALID_FIELD;
+ d = ChainMgrSetData (&fi->cm, i, dr);
++ if (!d) {
++ FrameInstFree (dr.fi);
++ return NO_VALID_FIELD;
++ }
+ }
+ /*endif*/
+ ret_size = FrameInstGetSize (d->fi);
+@@ -1428,6 +1548,11 @@ static FmStatus FrameInstSetIterCount (FrameInst fi, int num)
+ register int i;
+ XimFrameType type;
+
++ if (!fi) {
++ fprintf (stderr, "(XIM-IMdkit) WARNING: fi != NULL in %s:%s.\n",
++ __FILE__, XIM_STRFUNC);
++ return FmNoMoreData;
++ }
+ i = 0;
+ while ((type = fi->template[i].type) != EOL)
+ {
+@@ -1437,7 +1562,12 @@ static FmStatus FrameInstSetIterCount (FrameInst fi, int num)
+ if ((d = ChainMgrGetExtraData (&fi->cm, i)) == NULL)
+ {
+ dr.iter = IterInit (&fi->template[i + 1], num);
+- (void)ChainMgrSetData (&fi->cm, i, dr);
++ if (!dr.iter)
++ return FmNoMoreData;
++ if (!ChainMgrSetData (&fi->cm, i, dr)) {
++ IterFree (dr.iter);
++ return FmNoMoreData;
++ }
+ return FmSuccess;
+ }
+ /*endif*/
+@@ -1450,7 +1580,13 @@ static FmStatus FrameInstSetIterCount (FrameInst fi, int num)
+ if ((d = ChainMgrGetExtraData (&fi->cm, i)) == NULL)
+ {
+ dr.fi = FrameInstInit (fi->template[i + 1].data);
++ if (!dr.fi)
++ return FmNoMoreData;
+ d = ChainMgrSetData (&fi->cm, i, dr);
++ if (!d) {
++ FrameInstFree (dr.fi);
++ return FmNoMoreData;
++ }
+ }
+ /*endif*/
+ if (FrameInstSetIterCount (d->fi, num) == FmSuccess)
+@@ -1472,14 +1608,26 @@ static FmStatus FrameInstSetIterCount (FrameInst fi, int num)
+ static int FrameInstGetTotalSize (FrameInst fi)
+ {
+ register int size;
++ register int s;
+ register int i;
+
+ size = 0;
+ i = 0;
+
++ if (!fi) {
++ fprintf (stderr, "(XIM-IMdkit) WARNING: fi != NULL in %s:%s.\n",
++ __FILE__, XIM_STRFUNC);
++ return 0;
++ }
+ while (fi->template[i].type != EOL)
+ {
+- size += _FrameInstGetItemSize (fi, i);
++ s = _FrameInstGetItemSize (fi, i);
++ if (s == NO_VALUE) {
++ size = NO_VALUE;
++ break;
++ } else {
++ size += s;
++ }
+ assert (i >= 0);
+ i = _FrameInstIncrement (fi->template, i);
+ }
+@@ -1526,8 +1674,8 @@ static Iter IterInit (XimFrame frame, int count)
+
+ it = (Iter) Xmalloc (sizeof (IterRec));
+ if (!it) {
+- fprintf (stderr, "(XIM-IMdkit) WARNING: malloc failed in %s:%d.\n",
+- __FILE__, __LINE__);
++ fprintf (stderr, "(XIM-IMdkit) WARNING: malloc failed in %s:%s.\n",
++ __FILE__, XIM_STRFUNC);
+ return NULL;
+ }
+ it->template = frame;
+@@ -1600,7 +1748,7 @@ static void IterFree (Iter it)
+ ExtraDataRec dr;
+
+ ChainIterInit (&ci, &it->cm);
+- while (ChainIterGetNext (&ci, &count, &dr))
++ while (ChainIterGetNext (&ci, &count, &dr) && dr.fi)
+ FrameInstFree (dr.fi);
+ /*endwhile*/
+ ChainIterFree (&ci);
+@@ -1638,8 +1786,12 @@ static Bool IterIsLoopEnd (Iter it, Bool *myself)
+ }
+ else
+ {
+- if (FrameInstIsEnd (d->fi))
+- {
++ if (!d->fi) {
++ fprintf (stderr, "(XIM-IMdkit) WARNING: d->fi != NULL " \
++ "in %s:%s.\n",
++ __FILE__, XIM_STRFUNC);
++ ret = True;
++ } else if (FrameInstIsEnd (d->fi)) {
+ it->cur_no++;
+ if (!it->allow_expansion && it->cur_no == it->max_count)
+ {
+@@ -1677,9 +1829,9 @@ static XimFrameType IterGetNextType (Iter it, XimFrameTypeInfo info)
+ XimFrameType type;
+
+ if (!it || !it->template) {
+- fprintf (stderr, "(XIM-IMdkit) WARNING: malloc failed in %s:%d.\n",
+- __FILE__, __LINE__);
+- return (XimFrameType) NULL;
++ fprintf (stderr, "(XIM-IMdkit) WARNING: malloc failed in %s:%s.\n",
++ __FILE__, XIM_STRFUNC);
++ return (XimFrameType)NULL;
+ }
+
+ type = it->template->type;
+@@ -1732,7 +1884,13 @@ static XimFrameType IterGetNextType (Iter it, XimFrameTypeInfo info)
+ if ((d = ChainMgrGetExtraData (&it->cm, it->cur_no)) == NULL)
+ {
+ dr.iter = IterInit (it->template + 1, NO_VALUE);
++ if (!dr.iter)
++ return (XimFrameType)NULL;
+ d = ChainMgrSetData (&it->cm, it->cur_no, dr);
++ if (!d) {
++ IterFree (dr.iter);
++ return (XimFrameType)NULL;
++ }
+ }
+ /*endif*/
+
+@@ -1755,7 +1913,13 @@ static XimFrameType IterGetNextType (Iter it, XimFrameTypeInfo info)
+ if ((d = ChainMgrGetExtraData (&it->cm, it->cur_no)) == NULL)
+ {
+ dr.fi = FrameInstInit (it->template[1].data);
++ if (!dr.fi)
++ return (XimFrameType)NULL;
+ d = ChainMgrSetData (&it->cm, it->cur_no, dr);
++ if (!d) {
++ FrameInstFree (dr.fi);
++ return (XimFrameType)NULL;
++ }
+ }
+ /*endif*/
+
+@@ -1781,9 +1945,9 @@ static XimFrameType IterPeekNextType (Iter it, XimFrameTypeInfo info)
+ XimFrameType type;
+
+ if (!it->template) {
+- fprintf (stderr, "(XIM-IMdkit) WARNING: dereference pointer %s:%d.\n",
+- __FILE__, __LINE__);
+- return (XimFrameType) NULL;
++ fprintf (stderr, "(XIM-IMdkit) WARNING: dereference pointer %s:%s.\n",
++ __FILE__, XIM_STRFUNC);
++ return (XimFrameType)NULL;
+ }
+
+ type = it->template->type;
+@@ -1823,7 +1987,13 @@ static XimFrameType IterPeekNextType (Iter it, XimFrameTypeInfo info)
+ if ((d = ChainMgrGetExtraData (&it->cm, it->cur_no)) == NULL)
+ {
+ dr.iter = IterInit (it->template + 1, NO_VALUE);
++ if (!dr.iter)
++ return (XimFrameType)NULL;
+ d = ChainMgrSetData (&it->cm, it->cur_no, dr);
++ if (!d) {
++ IterFree (dr.iter);
++ return (XimFrameType)NULL;
++ }
+ }
+ /*endif*/
+
+@@ -1843,7 +2013,13 @@ static XimFrameType IterPeekNextType (Iter it, XimFrameTypeInfo info)
+ if ((d = ChainMgrGetExtraData (&it->cm, it->cur_no)) == NULL)
+ {
+ dr.fi = FrameInstInit (it->template[1].data);
++ if (!dr.fi)
++ return (XimFrameType)NULL;
+ d = ChainMgrSetData (&it->cm, it->cur_no, dr);
++ if (!d) {
++ FrameInstFree (dr.fi);
++ return (XimFrameType)NULL;
++ }
+ }
+ /*endif*/
+
+@@ -1885,9 +2061,8 @@ static FmStatus IterSetSize (Iter it, int num)
+ {
+ dr.num = NO_VALUE;
+ d = ChainMgrSetData (&it->cm, i, dr);
+- }
+- if (!d) {
+- return FmNoMoreData;
++ if (!d)
++ return FmNoMoreData;
+ }
+ /*endif*/
+ if (d->num == NO_VALUE)
+@@ -1903,7 +2078,8 @@ static FmStatus IterSetSize (Iter it, int num)
+ ExtraDataRec dr;
+
+ dr.num = num;
+- ChainMgrSetData (&it->cm, it->max_count, dr);
++ if (!ChainMgrSetData (&it->cm, it->max_count, dr))
++ return FmNoMoreData;
+ it->max_count++;
+
+ return FmSuccess;
+@@ -1922,7 +2098,13 @@ static FmStatus IterSetSize (Iter it, int num)
+ if ((d = ChainMgrGetExtraData (&it->cm, i)) == NULL)
+ {
+ dr.iter = IterInit (it->template + 1, NO_VALUE);
++ if (!dr.iter)
++ return FmNoMoreData;
+ d = ChainMgrSetData (&it->cm, i, dr);
++ if (!d) {
++ IterFree (dr.iter);
++ return FmNoMoreData;
++ }
+ }
+ /*endif*/
+ if (IterSetSize (d->iter, num) == FmSuccess)
+@@ -1935,7 +2117,12 @@ static FmStatus IterSetSize (Iter it, int num)
+ ExtraDataRec dr;
+
+ dr.iter = IterInit (it->template + 1, NO_VALUE);
+- ChainMgrSetData (&it->cm, it->max_count, dr);
++ if (!dr.iter)
++ return FmNoMoreData;
++ if (!ChainMgrSetData (&it->cm, it->max_count, dr)) {
++ IterFree (dr.iter);
++ return FmNoMoreData;
++ }
+ it->max_count++;
+
+ if (IterSetSize(dr.iter, num) == FmSuccess)
+@@ -1956,7 +2143,13 @@ static FmStatus IterSetSize (Iter it, int num)
+ if ((d = ChainMgrGetExtraData (&it->cm, i)) == NULL)
+ {
+ dr.fi = FrameInstInit (it->template[1].data);
++ if (!dr.fi)
++ return FmNoMoreData;
+ d = ChainMgrSetData (&it->cm, i, dr);
++ if (!d) {
++ FrameInstFree (dr.fi);
++ return FmNoMoreData;
++ }
+ }
+ /*endif*/
+ if (FrameInstSetSize (d->fi, num) == FmSuccess)
+@@ -1969,7 +2162,12 @@ static FmStatus IterSetSize (Iter it, int num)
+ ExtraDataRec dr;
+
+ dr.fi = FrameInstInit (it->template[1].data);
+- ChainMgrSetData (&it->cm, it->max_count, dr);
++ if (!dr.fi)
++ return FmNoMoreData;
++ if (!ChainMgrSetData (&it->cm, it->max_count, dr)) {
++ FrameInstFree (dr.fi);
++ return FmNoMoreData;
++ }
+ it->max_count++;
+
+ if (FrameInstSetSize (dr.fi, num) == FmSuccess)
+@@ -2013,7 +2211,13 @@ static int IterGetSize (Iter it)
+ if ((d = ChainMgrGetExtraData (&it->cm, i)) == NULL)
+ {
+ dr.iter = IterInit (it->template + 1, NO_VALUE);
++ if (!dr.iter)
++ return NO_VALID_FIELD;
+ d = ChainMgrSetData (&it->cm, i, dr);
++ if (!d) {
++ IterFree (dr.iter);
++ return NO_VALID_FIELD;
++ }
+ }
+ /*endif*/
+ ret_size = IterGetSize (d->iter);
+@@ -2032,7 +2236,13 @@ static int IterGetSize (Iter it)
+ if ((d = ChainMgrGetExtraData (&it->cm, i)) == NULL)
+ {
+ dr.fi = FrameInstInit (it->template[1].data);
++ if (!dr.fi)
++ return NO_VALID_FIELD;
+ d = ChainMgrSetData (&it->cm, i, dr);
++ if (!d) {
++ FrameInstFree (dr.fi);
++ return NO_VALID_FIELD;
++ }
+ }
+ /*endif*/
+ ret_size = FrameInstGetSize (d->fi);
+@@ -2077,7 +2287,12 @@ static FmStatus IterSetIterCount (Iter it, int num)
+ if ((d = ChainMgrGetExtraData(&it->cm, i)) == NULL)
+ {
+ dr.iter = IterInit(it->template + 1, num);
+- (void)ChainMgrSetData(&it->cm, i, dr);
++ if (!dr.iter)
++ return FmNoMoreData;
++ if (!ChainMgrSetData(&it->cm, i, dr)) {
++ IterFree (dr.iter);
++ return FmNoMoreData;
++ }
+ return FmSuccess;
+ }
+ /*endif*/
+@@ -2091,7 +2306,12 @@ static FmStatus IterSetIterCount (Iter it, int num)
+ ExtraDataRec dr;
+
+ dr.iter = IterInit (it->template + 1, num);
+- ChainMgrSetData (&it->cm, it->max_count, dr);
++ if (!dr.iter)
++ return FmNoMoreData;
++ if (!ChainMgrSetData (&it->cm, it->max_count, dr)) {
++ IterFree (dr.iter);
++ return FmNoMoreData;
++ }
+ it->max_count++;
+
+ return FmSuccess;
+@@ -2108,7 +2328,13 @@ static FmStatus IterSetIterCount (Iter it, int num)
+ if ((d = ChainMgrGetExtraData (&it->cm, i)) == NULL)
+ {
+ dr.fi = FrameInstInit (it->template[1].data);
++ if (!dr.fi)
++ return FmNoMoreData;
+ d = ChainMgrSetData (&it->cm, i, dr);
++ if (!d) {
++ FrameInstFree (dr.fi);
++ return FmNoMoreData;
++ }
+ }
+ /*endif*/
+ if (FrameInstSetIterCount (d->fi, num) == FmSuccess)
+@@ -2121,7 +2347,12 @@ static FmStatus IterSetIterCount (Iter it, int num)
+ ExtraDataRec dr;
+
+ dr.fi = FrameInstInit (it->template[1].data);
+- ChainMgrSetData (&it->cm, it->max_count, dr);
++ if (!dr.fi)
++ return FmNoMoreData;
++ if (!ChainMgrSetData (&it->cm, it->max_count, dr)) {
++ FrameInstFree (dr.fi);
++ return FmNoMoreData;
++ }
+ it->max_count++;
+
+ if (FrameInstSetIterCount (dr.fi, num) == FmSuccess)
+@@ -2215,7 +2446,13 @@ static int IterGetTotalSize (Iter it)
+ if ((d = ChainMgrGetExtraData (&it->cm, i)) == NULL)
+ {
+ dr.fi = FrameInstInit (it->template[1].data);
++ if (!dr.fi)
++ return NO_VALUE;
+ d = ChainMgrSetData (&it->cm, i, dr);
++ if (!d) {
++ FrameInstFree (dr.fi);
++ return NO_VALUE;
++ }
+ }
+ /*endif*/
+ if ((num = FrameInstGetTotalSize (d->fi)) == NO_VALUE)
+@@ -2278,8 +2515,8 @@ static ExtraData ChainMgrSetData (ChainMgr cm,
+ {
+ Chain cur = (Chain) Xmalloc (sizeof (ChainRec));
+ if (!cur) {
+- fprintf (stderr, "(XIM-IMdkit) WARNING: malloc failed in %s:%d.\n",
+- __FILE__, __LINE__);
++ fprintf (stderr, "(XIM-IMdkit) WARNING: malloc failed in %s:%s.\n",
++ __FILE__, XIM_STRFUNC);
+ return NULL;
+ }
+
+@@ -2445,6 +2682,7 @@ static int _FrameInstGetItemSize (FrameInst fi, int cur_no)
+ register int unit;
+ register int number;
+ register int size;
++ register int s;
+ register int i;
+
+ unit = _UNIT ((long) fi->template[cur_no].data);
+@@ -2456,11 +2694,19 @@ static int _FrameInstGetItemSize (FrameInst fi, int cur_no)
+ {
+ assert (i >= 0);
+ i = _FrameInstDecrement (fi->template, i);
+- size += _FrameInstGetItemSize (fi, i);
++ s = _FrameInstGetItemSize (fi, i);
++ if (s == NO_VALUE) {
++ size = NO_VALUE;
++ number = 0;
++ break;
++ } else {
++ size += s;
++ }
+ number--;
+ }
+ /*endwhile*/
+- size = (unit - (size%unit))%unit;
++ if (size != NO_VALUE)
++ size = (unit - (size%unit))%unit;
+ return size;
+ }
+
+diff --git a/util/IMdkit/XimProto.h b/util/IMdkit/XimProto.h
+index e3ed168c..a25213f5 100644
+--- a/util/IMdkit/XimProto.h
++++ b/util/IMdkit/XimProto.h
+@@ -1,4 +1,4 @@
+-/* $XConsortium: XimProto.h,v 1.2 94/01/20 18:02:24 rws Exp $ */
++/* $XConsortium: XimProto.h,v 1.3 25/09/24 00:00:00 rws Exp $ */
+ /******************************************************************
+
+ Copyright 1992, 1993, 1994 by FUJITSU LIMITED
+@@ -226,5 +226,10 @@ typedef CARD16 XICID; /* Input Context ID */
+ } \
+ }
+
++#if (defined(_MSC_VER) && (_MSC_VER > 1300))
++#define XIM_STRFUNC ((const char*) (__FUNCTION__))
++#else
++#define XIM_STRFUNC ((const char*) (__func__))
+ #endif
+
++#endif
+diff --git a/util/IMdkit/i18nMethod.c b/util/IMdkit/i18nMethod.c
+index 7f343d87..f7a53f40 100644
+--- a/util/IMdkit/i18nMethod.c
++++ b/util/IMdkit/i18nMethod.c
+@@ -2,7 +2,8 @@
+
+ Copyright 1994, 1995 by Sun Microsystems, Inc.
+ Copyright 1993, 1994 by Hewlett-Packard Company
+- Copyright (C) 2014-2025 Red Hat, Inc.
++ Copyright (C) 2008-2025 Red Hat, Inc.
++ Copyright (C) 2018-2025 Takao Fujiwara
+
+ Permission to use, copy, modify, distribute, and sell this software
+ and its documentation for any purpose is hereby granted without fee,
+@@ -37,6 +38,8 @@ IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ #endif
+ #include <X11/Xproto.h>
+ #undef NEED_EVENTS
++#include <assert.h>
++
+ #include "FrameMgr.h"
+ #include "IMdkit.h"
+ #include "Xi18n.h"
+@@ -194,17 +197,18 @@ static char *ParseArgs (Xi18n i18n_core, int mode, XIMArg *args)
+ if (address->imvalue_mask & I18N_IM_LOCALE)
+ return IMLocale;
+ /*endif*/
+- /* address->im_locale will be released later and don't need
+- * -Wanalyzer-malloc-leak flag in gcc 11.0.1.
++ /* xi18n_setup() initialize the `address` structure with 0 and
++ * the pointer of the `address` is not changed and
++ * `address->imvalue_mask` should avoid the reallocation so
++ * the `-Wanalyzer-malloc-leak` flag in GCC 11.0.1 should not
++ * warn about leaks of CWE-401.
+ */
+-#pragma GCC diagnostic push
+-#pragma GCC diagnostic ignored "-Wanalyzer-malloc-leak"
+- address->im_locale = (char *) malloc (strlen (p->value) + 1);
++ assert (!address->im_locale);
++ address->im_locale = (char *)malloc (strlen (p->value) + 1);
+ if (!address->im_locale)
+ return IMLocale;
+ /*endif*/
+ strcpy (address->im_locale, p->value);
+-#pragma GCC diagnostic pop
+ address->imvalue_mask |= I18N_IM_LOCALE;
+ }
+ else if (strcmp (p->name, IMServerTransport) == 0)
+@@ -212,14 +216,12 @@ static char *ParseArgs (Xi18n i18n_core, int mode, XIMArg *args)
+ if (address->imvalue_mask & I18N_IM_ADDRESS)
+ return IMServerTransport;
+ /*endif*/
+-#pragma GCC diagnostic push
+-#pragma GCC diagnostic ignored "-Wanalyzer-malloc-leak"
+- address->im_addr = (char *) malloc (strlen (p->value) + 1);
++ assert (!address->im_addr);
++ address->im_addr = (char *)malloc (strlen (p->value) + 1);
+ if (!address->im_addr)
+ return IMServerTransport;
+ /*endif*/
+ strcpy(address->im_addr, p->value);
+-#pragma GCC diagnostic pop
+ address->imvalue_mask |= I18N_IM_ADDRESS;
+ }
+ else if (strcmp (p->name, IMServerName) == 0)
+@@ -227,14 +229,12 @@ static char *ParseArgs (Xi18n i18n_core, int mode, XIMArg *args)
+ if (address->imvalue_mask & I18N_IM_NAME)
+ return IMServerName;
+ /*endif*/
+-#pragma GCC diagnostic push
+-#pragma GCC diagnostic ignored "-Wanalyzer-malloc-leak"
+- address->im_name = (char *) malloc (strlen (p->value) + 1);
++ assert (!address->im_name);
++ address->im_name = (char *)malloc (strlen (p->value) + 1);
+ if (!address->im_name)
+ return IMServerName;
+ /*endif*/
+ strcpy (address->im_name, p->value);
+-#pragma GCC diagnostic pop
+ address->imvalue_mask |= I18N_IM_NAME;
+ }
+ else if (strcmp (p->name, IMServerWindow) == 0)
+@@ -242,7 +242,7 @@ static char *ParseArgs (Xi18n i18n_core, int mode, XIMArg *args)
+ if (address->imvalue_mask & I18N_IMSERVER_WIN)
+ return IMServerWindow;
+ /*endif*/
+- address->im_window = (Window) p->value;
++ address->im_window = (Window)p->value;
+ address->imvalue_mask |= I18N_IMSERVER_WIN;
+ }
+ else if (strcmp (p->name, IMInputStyles) == 0)
+@@ -252,19 +252,21 @@ static char *ParseArgs (Xi18n i18n_core, int mode, XIMArg *args)
+ /*endif*/
+ address->input_styles.count_styles =
+ ((XIMStyles*)p->value)->count_styles;
+- address->input_styles.supported_styles =
+- (XIMStyle *) malloc (sizeof (XIMStyle)*address->input_styles.count_styles);
+- if (address->input_styles.supported_styles == (XIMStyle *) NULL)
++ assert (!address->input_styles.supported_styles);
++ address->input_styles.supported_styles = (XIMStyle *)malloc (
++ sizeof (XIMStyle) * address->input_styles.count_styles);
++ if (address->input_styles.supported_styles == (XIMStyle *)NULL)
+ return IMInputStyles;
+ /*endif*/
+ memmove (address->input_styles.supported_styles,
+- ((XIMStyles *) p->value)->supported_styles,
+- sizeof (XIMStyle)*address->input_styles.count_styles);
++ ((XIMStyles *)p->value)->supported_styles,
++ sizeof (XIMStyle) *
++ address->input_styles.count_styles);
+ address->imvalue_mask |= I18N_INPUT_STYLES;
+ }
+ else if (strcmp (p->name, IMProtocolHandler) == 0)
+ {
+- address->improto = (IMProtoHandler) p->value;
++ address->improto = (IMProtoHandler)p->value;
+ address->imvalue_mask |= I18N_IM_HANDLER;
+ }
+ else if (strcmp (p->name, IMOnKeysList) == 0)
+@@ -273,15 +275,16 @@ static char *ParseArgs (Xi18n i18n_core, int mode, XIMArg *args)
+ return IMOnKeysList;
+ /*endif*/
+ address->on_keys.count_keys =
+- ((XIMTriggerKeys *) p->value)->count_keys;
+- address->on_keys.keylist =
+- (XIMTriggerKey *) malloc (sizeof (XIMTriggerKey)*address->on_keys.count_keys);
+- if (address->on_keys.keylist == (XIMTriggerKey *) NULL)
++ ((XIMTriggerKeys *)p->value)->count_keys;
++ assert (!address->on_keys.keylist);
++ address->on_keys.keylist = (XIMTriggerKey *)malloc (
++ sizeof (XIMTriggerKey) * address->on_keys.count_keys);
++ if (address->on_keys.keylist == (XIMTriggerKey *)NULL)
+ return IMOnKeysList;
+ /*endif*/
+ memmove (address->on_keys.keylist,
+- ((XIMTriggerKeys *) p->value)->keylist,
+- sizeof (XIMTriggerKey)*address->on_keys.count_keys);
++ ((XIMTriggerKeys *)p->value)->keylist,
++ sizeof (XIMTriggerKey) * address->on_keys.count_keys);
+ address->imvalue_mask |= I18N_ON_KEYS;
+ }
+ else if (strcmp (p->name, IMOffKeysList) == 0)
+@@ -290,15 +293,16 @@ static char *ParseArgs (Xi18n i18n_core, int mode, XIMArg *args)
+ return IMOffKeysList;
+ /*endif*/
+ address->off_keys.count_keys =
+- ((XIMTriggerKeys *) p->value)->count_keys;
+- address->off_keys.keylist =
+- (XIMTriggerKey *) malloc (sizeof (XIMTriggerKey)*address->off_keys.count_keys);
+- if (address->off_keys.keylist == (XIMTriggerKey *) NULL)
++ ((XIMTriggerKeys *)p->value)->count_keys;
++ assert (!address->off_keys.keylist);
++ address->off_keys.keylist = (XIMTriggerKey *)malloc (
++ sizeof (XIMTriggerKey) * address->off_keys.count_keys);
++ if (address->off_keys.keylist == (XIMTriggerKey *)NULL)
+ return IMOffKeysList;
+ /*endif*/
+ memmove (address->off_keys.keylist,
+- ((XIMTriggerKeys *) p->value)->keylist,
+- sizeof (XIMTriggerKey)*address->off_keys.count_keys);
++ ((XIMTriggerKeys *)p->value)->keylist,
++ sizeof (XIMTriggerKey) * address->off_keys.count_keys);
+ address->imvalue_mask |= I18N_OFF_KEYS;
+ }
+ else if (strcmp (p->name, IMEncodingList) == 0)
+@@ -308,17 +312,19 @@ static char *ParseArgs (Xi18n i18n_core, int mode, XIMArg *args)
+ /*endif*/
+ address->encoding_list.count_encodings =
+ ((XIMEncodings *) p->value)->count_encodings;
++ assert (!address->encoding_list.supported_encodings);
+ address->encoding_list.supported_encodings =
+- (XIMEncoding *) malloc (sizeof (XIMEncoding)*address->encoding_list.count_encodings);
++ (XIMEncoding *)malloc (sizeof (XIMEncoding) *
++ address->encoding_list.count_encodings);
+ if (address->encoding_list.supported_encodings
+- == (XIMEncoding *) NULL)
+- {
++ == (XIMEncoding *)NULL) {
+ return IMEncodingList;
+ }
+ /*endif*/
+ memmove (address->encoding_list.supported_encodings,
+- ((XIMEncodings *) p->value)->supported_encodings,
+- sizeof (XIMEncoding)*address->encoding_list.count_encodings);
++ ((XIMEncodings *)p->value)->supported_encodings,
++ sizeof (XIMEncoding) *
++ address->encoding_list.count_encodings);
+ address->imvalue_mask |= I18N_ENCODINGS;
+ }
+ else if (strcmp (p->name, IMFilterEventMask) == 0)
+@@ -354,30 +360,38 @@ static char *ParseArgs (Xi18n i18n_core, int mode, XIMArg *args)
+ {
+ for (p = args; p->name != NULL; p++)
+ {
++ register char *_p = NULL;
+ if (strcmp (p->name, IMLocale) == 0)
+ {
+- p->value = (char *) malloc (strlen (address->im_locale) + 1);
+- if (!p->value)
++ _p = (char *)malloc (strlen (address->im_locale) + 1);
++ /* Workaround to avoid the warning of the leak of '*p.value'
++ * CWE-401 and -Wanalyzer-malloc-leak. Seems GCC does not
++ * understand the `if (!p->value)` sentence.
++ */
++ if (!_p)
+ return IMLocale;
+ /*endif*/
++ p->value = _p;
+ strcpy (p->value, address->im_locale);
+ }
+ else if (strcmp (p->name, IMServerTransport) == 0)
+ {
+- p->value = (char *) malloc (strlen (address->im_addr) + 1);
+- if (!p->value)
++ _p = (char *)malloc (strlen (address->im_addr) + 1);
++ if (!_p)
+ return IMServerTransport;
+ /*endif*/
++ p->value = _p;
+ strcpy (p->value, address->im_addr);
+ }
+ else if (strcmp (p->name, IMServerName) == 0)
+ {
+ if (address->imvalue_mask & I18N_IM_NAME)
+ {
+- p->value = (char *) malloc (strlen (address->im_name) + 1);
+- if (!p->value)
++ _p = (char *)malloc (strlen (address->im_name) + 1);
++ if (!_p)
+ return IMServerName;
+ /*endif*/
++ p->value = _p;
+ strcpy (p->value, address->im_name);
+ }
+ else
+--
+2.51.1
+
+From 59bdaf6169f34a3353d6bf597fef0e84e2ca73c8 Mon Sep 17 00:00:00 2001
+From: fujiwarat <takao.fujiwara1@gmail.com>
+Date: Tue, 14 Oct 2025 09:00:24 +0900
+Subject: [PATCH 4/4] Fix memory leaks #2
+
+- Fix leaks of GOptionContext in bus/main.c
+- Fix leaks of IBusEngineDesc when IME is switched in
+ client/wayland/ibuswaylandim.c
+- Fix leaks of IBusTextClass:copy(), which is used in
+ Emojier:get_one_dimension_lookup_table(), in src/ibustext.c
+- Fix leak of IBusExtensionEvent with commit-text signal and clicking close
+ button since it's not floating in ui/gtk3/panelbinding.vala
+
+Fixes: https://github.com/ibus/ibus/commit/a800957
+BUG=https://github.com/ibus/ibus/pull/2805
+---
+ bus/main.c | 35 +++++++++++++++++++++-------------
+ client/wayland/ibuswaylandim.c | 1 +
+ src/ibustext.c | 11 ++++++++---
+ ui/gtk3/panelbinding.vala | 6 ++++++
+ 4 files changed, 37 insertions(+), 16 deletions(-)
+
+diff --git a/bus/main.c b/bus/main.c
+index e0db15b3..ff9941ec 100644
+--- a/bus/main.c
++++ b/bus/main.c
+@@ -182,6 +182,14 @@ _on_sigusr1 (void)
+ }
+ #endif
+
++static inline void
++exit_and_free_context (int status,
++ GOptionContext *context)
++{
++ g_option_context_free (context);
++ exit (status);
++}
++
+ gint
+ main (gint argc, gchar **argv)
+ {
+@@ -203,11 +211,11 @@ main (gint argc, gchar **argv)
+ if (!g_option_context_parse (context, &argc, &argv, &error)) {
+ g_printerr ("Option parsing failed: %s\n", error->message);
+ g_error_free (error);
+- exit (-1);
++ exit_and_free_context (EXIT_FAILURE, context);
+ }
+ if (g_gdbus_timeout < -1) {
+ g_printerr ("Bad timeout (must be >= -1): %d\n", g_gdbus_timeout);
+- exit (-1);
++ exit_and_free_context (EXIT_FAILURE, context);
+ }
+
+ if (g_mempro) {
+@@ -220,7 +228,7 @@ main (gint argc, gchar **argv)
+
+ if (pwd == NULL || g_strcmp0 (pwd->pw_name, username) != 0) {
+ g_printerr ("Please run ibus-daemon with login user! Do not run ibus-daemon with sudo or su.\n");
+- exit (-1);
++ exit_and_free_context (EXIT_FAILURE, context);
+ }
+ }
+
+@@ -245,7 +253,7 @@ main (gint argc, gchar **argv)
+ if (daemonize) {
+ if (daemon (1, 0) != 0) {
+ g_printerr ("Cannot daemonize ibus.\n");
+- exit (-1);
++ exit_and_free_context (EXIT_FAILURE, context);
+ }
+ }
+
+@@ -267,7 +275,7 @@ main (gint argc, gchar **argv)
+ if (ibus_bus_is_connected (bus)) {
+ if (!replace) {
+ g_printerr ("current session already has an ibus-daemon.\n");
+- exit (-1);
++ exit_and_free_context (EXIT_FAILURE, context);
+ }
+ ibus_bus_exit (bus, FALSE);
+ while (ibus_bus_is_connected (bus)) {
+@@ -301,11 +309,11 @@ main (gint argc, gchar **argv)
+ }
+ if (component == NULL || !bus_component_start (component, g_verbose)) {
+ g_printerr ("Can not execute default config program\n");
+- exit (-1);
++ exit_and_free_context (EXIT_FAILURE, context);
+ }
+ } else if (g_strcmp0 (config, "disable") != 0 && g_strcmp0 (config, "") != 0) {
+ if (!execute_cmdline (config))
+- exit (-1);
++ exit_and_free_context (EXIT_FAILURE, context);
+ }
+
+ /* execute panel component */
+@@ -318,11 +326,11 @@ main (gint argc, gchar **argv)
+ }
+ if (component == NULL || !bus_component_start (component, g_verbose)) {
+ g_printerr ("Can not execute default panel program\n");
+- exit (-1);
++ exit_and_free_context (EXIT_FAILURE, context);
+ }
+ } else if (g_strcmp0 (panel, "disable") != 0 && g_strcmp0 (panel, "") != 0) {
+ if (!execute_cmdline (panel))
+- exit (-1);
++ exit_and_free_context (EXIT_FAILURE, context);
+ }
+ }
+
+@@ -337,25 +345,25 @@ main (gint argc, gchar **argv)
+ if (component != NULL &&
+ !bus_component_start (component, g_verbose)) {
+ g_printerr ("Can not execute default panel program\n");
+- exit (-1);
++ exit_and_free_context (EXIT_FAILURE, context);
+ }
+ } else if (g_strcmp0 (emoji_extension, "disable") != 0 &&
+ g_strcmp0 (emoji_extension, "") != 0) {
+ if (!execute_cmdline (emoji_extension))
+- exit (-1);
++ exit_and_free_context (EXIT_FAILURE, context);
+ }
+ #endif
+
+ /* execute ibus xim server */
+ if (xim) {
+ if (!execute_cmdline (LIBEXECDIR "/ibus-x11 --kill-daemon"))
+- exit (-1);
++ exit_and_free_context (EXIT_FAILURE, context);
+ }
+
+ if (!daemonize) {
+ if (getppid () == 1) {
+ g_warning ("The parent process died.");
+- exit (0);
++ exit_and_free_context (EXIT_SUCCESS, context);
+ }
+ #ifdef HAVE_SYS_PRCTL_H
+ #ifdef G_OS_UNIX
+@@ -396,5 +404,6 @@ main (gint argc, gchar **argv)
+ #endif
+ }
+ bus_server_run ();
++ g_option_context_free (context);
+ return 0;
+ }
+diff --git a/client/wayland/ibuswaylandim.c b/client/wayland/ibuswaylandim.c
+index e058044f..60257779 100644
+--- a/client/wayland/ibuswaylandim.c
++++ b/client/wayland/ibuswaylandim.c
+@@ -924,6 +924,7 @@ _bus_global_engine_changed_cb (IBusBus *bus,
+ keymap = create_user_xkb_keymap (priv->xkb_context, desc);
+ if (keymap && !ibus_wayland_im_update_xkb_state (wlim, keymap))
+ xkb_keymap_unref (keymap);
++ g_object_unref (desc);
+ }
+
+
+diff --git a/src/ibustext.c b/src/ibustext.c
+index 73d3d10c..0576f6c8 100644
+--- a/src/ibustext.c
++++ b/src/ibustext.c
+@@ -2,7 +2,7 @@
+ /* vim:set et sts=4: */
+ /* IBus - The Input Bus
+ * Copyright (C) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
+- * Copyright (C) 2011-2021 Takao Fujiwara <takao.fujiwara1@gmail.com>
++ * Copyright (C) 2011-2025 Takao Fujiwara <takao.fujiwara1@gmail.com>
+ * Copyright (C) 2008-2021 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+@@ -109,7 +109,7 @@ ibus_text_deserialize (IBusText *text,
+ retval = IBUS_SERIALIZABLE_CLASS (ibus_text_parent_class)->deserialize (
+ (IBusSerializable *)text, variant);
+
+- if (text->is_static == FALSE)
++ if (!text->is_static)
+ g_free (text->text);
+ g_variant_get_child (variant, retval++, "s", &text->text);
+ text->is_static = FALSE;
+@@ -139,10 +139,15 @@ ibus_text_copy (IBusText *dest,
+ g_return_val_if_fail (IBUS_IS_TEXT (dest), FALSE);
+ g_return_val_if_fail (IBUS_IS_TEXT (src), FALSE);
+
++ if (!dest->is_static)
++ g_free (dest->text);
+ dest->text = g_strdup (src->text);
+ dest->is_static = FALSE;
++ if (dest->attrs)
++ g_clear_object (&dest->attrs);
+ if (src->attrs) {
+- dest->attrs = (IBusAttrList *)ibus_serializable_copy ((IBusSerializable *)src->attrs);
++ dest->attrs = (IBusAttrList *)ibus_serializable_copy (
++ (IBusSerializable *)src->attrs);
+ g_object_ref_sink (dest->attrs);
+ }
+
+diff --git a/ui/gtk3/panelbinding.vala b/ui/gtk3/panelbinding.vala
+index 49c91575..507b3dac 100644
+--- a/ui/gtk3/panelbinding.vala
++++ b/ui/gtk3/panelbinding.vala
+@@ -910,6 +910,9 @@ class PanelBinding : IBus.PanelService {
+ "is-enabled", false,
+ "is-extension", true);
+ panel_extension(close_event);
++ // Vala calls event.ref_sink() and panel_extension() does not
++ // unref the event and need to call event.unref() here.
++ close_event.unref();
+ });
+ m_emojier.send_message.connect((m) => {
+ send_message(m);
+@@ -1175,6 +1178,9 @@ class PanelBinding : IBus.PanelService {
+ "is-enabled", false,
+ "is-extension", true);
+ panel_extension(event);
++ // Vala calls event.ref_sink() and panel_extension() does not unref
++ // the event and need to call event.unref() here.
++ event.unref();
+ return;
+ }
+ if (m_emojier == null)
+--
+2.51.1
+
+From 296192bd69448e5d782a33162de25534db0a79e7 Mon Sep 17 00:00:00 2001
+From: fujiwarat <takao.fujiwara1@gmail.com>
+Date: Fri, 17 Oct 2025 13:14:32 +0900
+Subject: [PATCH 1/5] ui/gtk3: Fix mouse position in Emojier category list
+
+BUG=rhbz#2237664
+---
+ ui/gtk3/emojier.vala | 17 +++++++++++------
+ 1 file changed, 11 insertions(+), 6 deletions(-)
+
+diff --git a/ui/gtk3/emojier.vala b/ui/gtk3/emojier.vala
+index ffa8cdaa..71422266 100644
+--- a/ui/gtk3/emojier.vala
++++ b/ui/gtk3/emojier.vala
+@@ -29,6 +29,8 @@ public class IBusEmojier : Gtk.ApplicationWindow {
+ valign : Gtk.Align.FILL
+ );
+ this.motion_notify_event.connect((e) => {
++ if (!m_enter_notify_enable)
++ return false;
+ Gdk.EventMotion pe = e;
+ if (m_mouse_x == pe.x_root && m_mouse_y == pe.y_root)
+ return false;
+@@ -37,6 +39,7 @@ public class IBusEmojier : Gtk.ApplicationWindow {
+ var row = this.get_row_at_y((int)e.y);
+ if (row != null)
+ this.select_row(row);
++ m_category_active_index = row.get_index();
+ return false;
+ });
+ this.enter_notify_event.connect((e) => {
+@@ -279,6 +282,12 @@ public class IBusEmojier : Gtk.ApplicationWindow {
+ private const unichar[] EMOJI_VARIANT_LIST = {
+ 0x1f3fb, 0x1f3fc, 0x1f3fd, 0x1f3fe, 0x1f3ff, 0x200d };
+
++ // Access both class methods and instances.
++ protected static int m_category_active_index = -1;
++ protected static bool m_enter_notify_enable = true;
++ protected static double m_mouse_x;
++ protected static double m_mouse_y;
++
+ // Set the actual default values in the constructor
+ // because these fields are used for class_init() and static functions,
+ // e.g. set_emoji_font(), can be called before class_init() is called.
+@@ -348,14 +357,10 @@ public class IBusEmojier : Gtk.ApplicationWindow {
+ * Unicode category list.
+ */
+ private bool m_candidate_panel_mode;
+- private int m_category_active_index = -1;
+ private IBus.LookupTable m_lookup_table;
+ private Gtk.Label[] m_candidates;
+- private bool m_enter_notify_enable = true;
+ private uint m_entry_notify_show_id;
+ private uint m_entry_notify_disable_id;
+- protected static double m_mouse_x;
+- protected static double m_mouse_y;
+ private Gtk.ProgressBar m_unicode_progress_bar;
+ private uint m_unicode_progress_id;
+ private Gtk.Label m_unicode_percent_label;
+@@ -988,7 +993,7 @@ public class IBusEmojier : Gtk.ApplicationWindow {
+ EPaddedLabelBox widget =
+ new EPaddedLabelBox(_(category), Gtk.Align.CENTER);
+ row.add(widget);
+- m_list_box.add(row);
++ m_list_box.insert(row, -1);
+ if (i == m_category_active_index)
+ m_list_box.select_row(row);
+ }
+@@ -1113,7 +1118,7 @@ public class IBusEmojier : Gtk.ApplicationWindow {
+ TravelDirection.NONE,
+ caption);
+ row.add(widget);
+- m_list_box.add(row);
++ m_list_box.insert(row, -1);
+ if (n++ == m_category_active_index) {
+ m_list_box.select_row(row);
+ }
+--
+2.51.1
+
+From b00d9464e1a54630098fe7b5bbdf372a5f9b832b Mon Sep 17 00:00:00 2001
+From: fujiwarat <takao.fujiwara1@gmail.com>
+Date: Fri, 17 Oct 2025 13:14:34 +0900
+Subject: [PATCH 2/5] ui/gtk3: Set MessageDialog at input cursor
+
+---
+ ui/gtk3/candidatepanel.vala | 4 ++++
+ ui/gtk3/message.vala | 6 ++++++
+ ui/gtk3/panel.vala | 4 ++++
+ 3 files changed, 14 insertions(+)
+
+diff --git a/ui/gtk3/candidatepanel.vala b/ui/gtk3/candidatepanel.vala
+index 3cc2c086..74de6f74 100644
+--- a/ui/gtk3/candidatepanel.vala
++++ b/ui/gtk3/candidatepanel.vala
+@@ -161,6 +161,10 @@ public class CandidatePanel : Gtk.Box{
+ }
+ }
+
++ public Gdk.Rectangle? get_cursor_rect() {
++ return m_cursor_location;
++ }
++
+ public void set_cursor_location(int x, int y, int width, int height) {
+ Gdk.Rectangle location = Gdk.Rectangle(){
+ x = x, y = y, width = width, height = height };
+diff --git a/ui/gtk3/message.vala b/ui/gtk3/message.vala
+index 0c7dd478..b6366557 100644
+--- a/ui/gtk3/message.vala
++++ b/ui/gtk3/message.vala
+@@ -91,6 +91,12 @@ public class MessageDialog : Gtk.Box{
+ create_ui(message);
+ }
+
++ public void set_cursor_rect(Gdk.Rectangle location) {
++ if (m_cursor_location == location)
++ return;
++ m_cursor_location = location;
++ }
++
+ public void set_cursor_location(int x, int y, int width, int height) {
+ Gdk.Rectangle location = Gdk.Rectangle(){
+ x = x, y = y, width = width, height = height };
+diff --git a/ui/gtk3/panel.vala b/ui/gtk3/panel.vala
+index fcb30220..90194529 100644
+--- a/ui/gtk3/panel.vala
++++ b/ui/gtk3/panel.vala
+@@ -930,6 +930,10 @@ class Panel : IBus.PanelService {
+ (w, s) => this.realize_surface(s));
+ #endif
+ m_popup_dialogs.insert(serial, popup);
++ if (m_candidate_panel_active != null) {
++ popup.set_cursor_rect(
++ m_candidate_panel_active.get_cursor_rect());
++ }
+ popup.show();
+ }
+ }
+--
+2.51.1
+
+From 0314cf5bf5bb3a46ff96cfb4f93ac937c129b7fb Mon Sep 17 00:00:00 2001
+From: fujiwarat <takao.fujiwara1@gmail.com>
+Date: Fri, 17 Oct 2025 23:38:00 +0900
+Subject: [PATCH 3/5] client/wayland: Free IBusInputContext in input_method_activate()
+
+Call input_method_deactivate() when input_method_activate() is
+called twice and zwp_input_method_context_v1 is null but
+IBusInputContext is not null.
+This enhances not to cause a SEGV in _context_hide_preedit_text_cb()
+
+BUG=rhbz#2326455
+---
+ client/wayland/ibuswaylandim.c | 10 +++-------
+ 1 file changed, 3 insertions(+), 7 deletions(-)
+
+diff --git a/client/wayland/ibuswaylandim.c b/client/wayland/ibuswaylandim.c
+index e058044f..631bea93 100644
+--- a/client/wayland/ibuswaylandim.c
++++ b/client/wayland/ibuswaylandim.c
+@@ -1796,7 +1796,7 @@ input_method_activate (void *data,
+
+ g_return_if_fail (IBUS_IS_WAYLAND_IM (wlim));
+ priv = ibus_wayland_im_get_instance_private (wlim);
+- if (priv->context)
++ if (priv->context || priv->ibuscontext)
+ input_method_deactivate (data, input_method, context);
+
+ priv->context = context;
+@@ -1828,10 +1828,7 @@ input_method_activate (void *data,
+ g_assert_not_reached ();
+ }
+
+- if (priv->ibuscontext) {
+- g_object_unref (priv->ibuscontext);
+- priv->ibuscontext = NULL;
+- }
++ g_assert (!priv->ibuscontext);
+
+ priv->cancellable = g_cancellable_new ();
+ ibus_bus_create_input_context_async (priv->ibusbus,
+@@ -1884,8 +1881,7 @@ input_method_deactivate (void *data,
+ priv->ibuscontext,
+ G_CALLBACK (_context_hide_preedit_text_cb),
+ wlim);
+- g_object_unref (priv->ibuscontext);
+- priv->ibuscontext = NULL;
++ g_clear_object (&priv->ibuscontext);
+ g_signal_emit (wlim,
+ wayland_im_signals[IBUS_FOCUS_OUT],
+ 0,
+--
+2.51.1
+
+From f6c52ce0baf0ad11705a0f9af160076a97104bf2 Mon Sep 17 00:00:00 2001
+From: fujiwarat <takao.fujiwara1@gmail.com>
+Date: Wed, 26 Nov 2025 15:16:03 +0900
+Subject: [PATCH 4/5] util/IMdkit: Fix SEGV with allocation fail in _Xi18nChangeIC()
+
+When malloc() is failed, it should break the for loop to set
+attrib_num value correctly to free attrib_list array.
+
+BUG=rhbz#2346033
+---
+ util/IMdkit/i18nIc.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/util/IMdkit/i18nIc.c b/util/IMdkit/i18nIc.c
+index 14a3dc51..e82ffbcf 100644
+--- a/util/IMdkit/i18nIc.c
++++ b/util/IMdkit/i18nIc.c
+@@ -2,6 +2,8 @@
+
+ Copyright 1994, 1995 by Sun Microsystems, Inc.
+ Copyright 1993, 1994 by Hewlett-Packard Company
++ Copyright (C) 2008-2025 Red Hat, Inc.
++ Copyright (C) 2017-2025 Takao Fujiwara
+
+ Permission to use, copy, modify, distribute, and sell this software
+ and its documentation for any purpose is hereby granted without fee,
+@@ -714,10 +716,11 @@ void _Xi18nChangeIC (XIMS ims,
+ FrameMgrSetSize (fm, value_length);
+ attrib_list[attrib_num].value_length = value_length;
+ FrameMgrGetToken (fm, value);
+- attrib_list[attrib_num].value = (void *) malloc (value_length + 1);
++ attrib_list[attrib_num].value = (void *)malloc (value_length + 1);
+ if (!attrib_list[attrib_num].value) {
+ fprintf (stderr, "(XIM-IMdkit) WARNING: malloc failed in %s:%d.\n",
+ __FILE__, __LINE__);
++ break;
+ } else {
+ memmove (attrib_list[attrib_num].value, value, value_length);
+ ((char *)attrib_list[attrib_num].value)[value_length] = '\0';
+--
+2.51.1
+
+From ca0193f5b1c17f5c8a456e09421d2a8688c5d667 Mon Sep 17 00:00:00 2001
+From: fujiwarat <takao.fujiwara1@gmail.com>
+Date: Thu, 23 Oct 2025 22:45:11 +0900
+Subject: [PATCH 5/5] ui/gtk3: Refer QT_IM_MODULES to check Wayland configuration
+
+QT_IM_MODULES and QT_IM_MODULE is available. The warning message
+is not changed at the moment.
+ibus-setup also runs `ibus start` instead ibus-daemon.
+
+BUG=rhbz#2392358
+---
+ setup/main.py | 19 ++++++++++++++-----
+ ui/gtk3/panel.vala | 6 +++++-
+ 2 files changed, 19 insertions(+), 6 deletions(-)
+
+diff --git a/setup/main.py b/setup/main.py
+index d0e05666..31b44037 100644
+--- a/setup/main.py
++++ b/setup/main.py
+@@ -4,8 +4,8 @@
+ # ibus - The Input Bus
+ #
+ # Copyright (c) 2007-2016 Peng Huang <shawn.p.huang@gmail.com>
+-# Copyright (c) 2010-2020 Takao Fujiwara <takao.fujiwara1@gmail.com>
+-# Copyright (c) 2007-2020 Red Hat, Inc.
++# Copyright (c) 2010-2025 Takao Fujiwara <takao.fujiwara1@gmail.com>
++# Copyright (c) 2007-2025 Red Hat, Inc.
+ #
+ # This library is free software; you can redistribute it and/or
+ # modify it under the terms of the GNU Lesser General Public
+@@ -602,13 +602,22 @@ class Setup(object):
+ GLib.timeout_add_seconds(timeout, lambda *args: main_loop.quit())
+ self.__bus.connect("connected", lambda *args: main_loop.quit())
+
+- os.spawnlp(os.P_NOWAIT, "ibus-daemon", "ibus-daemon", "--xim", "--daemonize")
++ os.spawnlp(os.P_NOWAIT, "ibus", "ibus", "start", "--xim", "--daemonize")
+
+ main_loop.run()
+
+ if self.__bus.is_connected():
+- message = _("IBus has been started! "
+- "If you cannot use IBus, add the following lines to your $HOME/.bashrc; then relog into your desktop.\n"
++ message = _("IBus has been started. "
++ "If you cannot use IBus, add the following lines to your "
++ "$HOME/.bashrc; then relog into your desktop.\n"
++ "\n"
++ " # For Wayland sessions ($XDG_SESSION_TYPE is \"wayland\")\n"
++ " export GTK_IM_MODULE=wayland\n"
++ " export XMODIFIERS=@im=ibus\n"
++ " export QT_IM_MODULES=wayland;ibus\n"
++ " export QT_IM_MODULE=ibus\n"
++ "\n"
++ " # For X11 sessions ($XDG_SESSION_TYPE is \"x11\")\n"
+ " export GTK_IM_MODULE=ibus\n"
+ " export XMODIFIERS=@im=ibus\n"
+ " export QT_IM_MODULE=ibus"
+diff --git a/ui/gtk3/panel.vala b/ui/gtk3/panel.vala
+index 90194529..cfa6e50d 100644
+--- a/ui/gtk3/panel.vala
++++ b/ui/gtk3/panel.vala
+@@ -1027,7 +1027,11 @@ class Panel : IBus.PanelService {
+ "Wayland",
+ "ibus start");
+ } else if (m_is_wayland && m_is_wayland_im && !is_gnome()) {
+- if (Environment.get_variable("QT_IM_MODULE") == "ibus") {
++ var qt_im_module = Environment.get_variable("QT_IM_MODULE");
++ var qt_im_modules = Environment.get_variable("QT_IM_MODULES");
++ if ((qt_im_module != null && qt_im_module != "wayland") &&
++ (qt_im_modules == null ||
++ !qt_im_modules.has_prefix("wayland"))) {
+ var format =
+ _("Please unset QT_IM_MODULE and GTK_IM_MODULE " +
+ "environment variables and 'ibus-daemon --panel " +
+--
+2.51.1
+
+From 69eb4c6de1dc7f6137780139510b5a1598dc7183 Mon Sep 17 00:00:00 2001
+From: Joan Torres Lopez <joantolo@redhat.com>
+Date: Wed, 26 Nov 2025 16:02:18 +0900
+Subject: [PATCH] src: Move group name detection to ibus_get_group_name()
+
+Resolves: https://github.com/ibus/ibus/commit/c158800
+BUG=https://github.com/ibus/ibus/pull/2806
+---
+ bus/main.c | 47 ++++++++++++++++-------------------------------
+ src/ibusshare.c | 34 +++++++++++++++++++++++++++++++++-
+ src/ibusshare.h | 18 +++++++++++++++---
+ 3 files changed, 64 insertions(+), 35 deletions(-)
+
+diff --git a/bus/main.c b/bus/main.c
+index e0db15b3..8695b065 100644
+--- a/bus/main.c
++++ b/bus/main.c
+@@ -39,7 +39,6 @@
+
+ #ifdef G_OS_UNIX
+ #include <glib-unix.h>
+-#include <grp.h>
+ #endif
+
+ #include "global.h"
+@@ -195,11 +194,7 @@ main (gint argc, gchar **argv)
+ {
+ int i;
+ const gchar *username = ibus_get_user_name ();
+- const gchar *groupname = NULL;
+-#ifdef HAVE_GETGRGID_R
+- char buffer[4096];
+- struct group gbuf;
+-#endif
++ const gchar *groupname = ibus_get_group_name ();
+
+ setlocale (LC_ALL, "");
+
+@@ -227,28 +222,12 @@ main (gint argc, gchar **argv)
+ struct passwd *pwd = getpwuid (getuid ());
+
+ if (pwd == NULL || g_strcmp0 (pwd->pw_name, username) != 0) {
+- g_printerr ("Please run ibus-daemon with login user! Do not run ibus-daemon with sudo or su.\n");
++ g_printerr ("Please run ibus-daemon with login user! Do not run "
++ "ibus-daemon with sudo or su.\n");
+ exit_and_free_context (EXIT_FAILURE, context);
+ }
+ }
+
+- /* get group name */
+- {
+- struct group *grp = NULL;
+-#ifdef HAVE_GETGRGID_R
+- /* MT-Safe locale */
+- getgrgid_r (getgid (), &gbuf, buffer, sizeof(buffer), &grp);
+-#else
+- /* MT-Unsafe race:grgid locale */
+- grp = getgrgid (getgid ());
+-#endif
+-
+- if (grp && grp->gr_name && grp->gr_name[0])
+- groupname = grp->gr_name;
+- else
+- g_warning ("Couldn't get group name");
+- }
+-
+ /* daemonize process */
+ if (daemonize) {
+ if (daemon (1, 0) != 0) {
+@@ -257,7 +236,9 @@ main (gint argc, gchar **argv)
+ }
+ }
+
+- /* create a new process group. this is important to kill all of its children by SIGTERM at a time in bus_ibus_impl_destroy. */
++ /* create a new process group. this is important to kill all of its
++ * children by SIGTERM at a time in bus_ibus_impl_destroy.
++ */
+ setpgid (0, 0);
+
+ ibus_init ();
+@@ -286,13 +267,13 @@ main (gint argc, gchar **argv)
+ }
+
+ bus_server_init ();
+- for (i = 0; i < G_N_ELEMENTS(panel_extension_disable_users); i++) {
++ for (i = 0; i < G_N_ELEMENTS (panel_extension_disable_users); i++) {
+ if (!g_strcmp0 (username, panel_extension_disable_users[i]) != 0) {
+ emoji_extension = "disable";
+ break;
+ }
+ }
+- for (i = 0; i < G_N_ELEMENTS(panel_extension_disable_groups); i++) {
++ for (i = 0; i < G_N_ELEMENTS (panel_extension_disable_groups); i++) {
+ if (g_strcmp0 (groupname, panel_extension_disable_groups[i]) == 0) {
+ emoji_extension = "disable";
+ break;
+@@ -307,11 +288,13 @@ main (gint argc, gchar **argv)
+ if (component) {
+ bus_component_set_restart (component, restart);
+ }
+- if (component == NULL || !bus_component_start (component, g_verbose)) {
++ if (component == NULL ||
++ !bus_component_start (component, g_verbose)) {
+ g_printerr ("Can not execute default config program\n");
+ exit_and_free_context (EXIT_FAILURE, context);
+ }
+- } else if (g_strcmp0 (config, "disable") != 0 && g_strcmp0 (config, "") != 0) {
++ } else if (g_strcmp0 (config, "disable") != 0 &&
++ g_strcmp0 (config, "") != 0) {
+ if (!execute_cmdline (config))
+ exit_and_free_context (EXIT_FAILURE, context);
+ }
+@@ -324,11 +307,13 @@ main (gint argc, gchar **argv)
+ if (component) {
+ bus_component_set_restart (component, restart);
+ }
+- if (component == NULL || !bus_component_start (component, g_verbose)) {
++ if (component == NULL ||
++ !bus_component_start (component, g_verbose)) {
+ g_printerr ("Can not execute default panel program\n");
+ exit_and_free_context (EXIT_FAILURE, context);
+ }
+- } else if (g_strcmp0 (panel, "disable") != 0 && g_strcmp0 (panel, "") != 0) {
++ } else if (g_strcmp0 (panel, "disable") != 0 &&
++ g_strcmp0 (panel, "") != 0) {
+ if (!execute_cmdline (panel))
+ exit_and_free_context (EXIT_FAILURE, context);
+ }
+diff --git a/src/ibusshare.c b/src/ibusshare.c
+index 57e3ef14..9d66a60c 100644
+--- a/src/ibusshare.c
++++ b/src/ibusshare.c
+@@ -2,7 +2,7 @@
+ /* vim:set et sts=4: */
+ /* ibus - The Input Bus
+ * Copyright (C) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
+- * Copyright (C) 2015-2024 Takao Fujiwara <takao.fujiwara1@gmail.com>
++ * Copyright (C) 2015-2025 Takao Fujiwara <takao.fujiwara1@gmail.com>
+ * Copyright (C) 2008-2018 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+@@ -37,6 +37,10 @@
+ #include <string.h>
+ #include <ibus.h>
+
++#ifdef G_OS_UNIX
++#include <grp.h>
++#endif
++
+ static gchar *_display = NULL;
+
+ const gchar *
+@@ -82,6 +86,34 @@ ibus_get_user_name (void)
+ return g_get_user_name ();
+ }
+
++const gchar *
++ibus_get_group_name (void)
++{
++ static gchar *groupname = NULL;
++ struct group *grp = NULL;
++#ifdef HAVE_GETGRGID_R
++ char buffer[4096];
++ struct group gbuf;
++#endif
++
++ if (groupname)
++ return groupname;
++
++#ifdef HAVE_GETGRGID_R
++ /* MT-Safe locale */
++ getgrgid_r (getgid (), &gbuf, buffer, sizeof(buffer), &grp);
++#else
++ /* MT-Unsafe race:grgid locale */
++ grp = getgrgid (getgid ());
++#endif
++
++ g_return_val_if_fail (grp && grp->gr_name && grp->gr_name[0], NULL);
++
++ /* buffer will be erased out of this function. */
++ groupname = g_strdup (grp->gr_name);
++ return groupname;
++}
++
+ glong
+ ibus_get_daemon_uid (void)
+ {
+diff --git a/src/ibusshare.h b/src/ibusshare.h
+index 6379c51d..7e9274e4 100644
+--- a/src/ibusshare.h
++++ b/src/ibusshare.h
+@@ -205,7 +205,7 @@ G_BEGIN_DECLS
+ *
+ * Obtains the machine UUID of the machine this process is running on.
+ *
+- * Returns: A newly allocated string that shows the UUID of the machine.
++ * Returns: A const string that shows the UUID of the machine.
+ */
+ const gchar *ibus_get_local_machine_id
+ (void);
+@@ -259,10 +259,22 @@ void ibus_write_address (const gchar *address);
+ * <listitem><para>Environment variable LNAME</para></listitem>
+ * </orderedlist>
+ *
+- * Returns: A newly allocated string that stores current user name.
++ * Returns: A const string that stores current user name.
+ */
+ const gchar *ibus_get_user_name (void);
+
++/**
++ * ibus_get_group_name:
++ *
++ * Get the current user group name.
++ *
++ * Returns: A const string that stores current user group name.
++ *
++ * Since: 1.5.34
++ * Stability: Unstable
++ */
++const gchar *ibus_get_group_name (void);
++
+ /**
+ * ibus_get_daemon_uid:
+ *
+@@ -280,7 +292,7 @@ glong ibus_get_daemon_uid (void) G_GNUC_DEPRECATED;
+ *
+ * Get the path of socket file.
+ *
+- * Returns: A newly allocated string that stores the path of socket file.
++ * Returns: A const string that stores the path of socket file.
+ */
+ const gchar *ibus_get_socket_path (void);
+
+--
+2.51.1
+
diff --git a/ibus.spec b/ibus.spec
index 098e2d0..f78a304 100644
--- a/ibus.spec
+++ b/ibus.spec
@@ -63,7 +63,7 @@
Name: ibus
Version: 1.5.34~alpha1
# https://github.com/fedora-infra/rpmautospec/issues/101
-Release: 1%{?dist}
+Release: 2%{?dist}
Summary: Intelligent Input Bus for Linux OS
License: LGPL-2.1-or-later
URL: https://github.com/ibus/%name/wiki
@@ -72,6 +72,7 @@ Source1: https://github.com/ibus/%name/releases/download/%{source_version
Source2: %{name}-xinput
Source3: %{name}.conf.5
# Patch0: %%{name}-HEAD.patch
+Patch0: %{name}-HEAD.patch
# Under testing #1349148 #1385349 #1350291 #1406699 #1432252 #1601577
Patch1: %{name}-1385349-segv-bus-proxy.patch
@@ -638,6 +639,19 @@ dconf update || :
%{_datadir}/installed-tests/ibus
%changelog
+* Wed Nov 26 2025 Takao Fujiwara <tfujiwar@redhat.com> - 1.5.34~alpha1-2
+- Resolves: #2237664 Fix mouse position in Emojier category list
+- Resolves: #2326455 Free IBusInputContext in input_method_activate()
+- Resolves: #2346033 Fix SEGV with allocation fail in _Xi18nChangeIC()
+- Resolves: #2392358 Refer QT_IM_MODULES to check Wayland
+- don't build in parallel in ui/gtk3
+- Fix GCC `-Wunused-but-set-variable` flag
+- '--enable-wayland-im' option without daemon
+- Fix memory leaks with fail safe
+- Fix memory leaks #2
+- Set MessageDialog at input cursor
+- Move group name detection to ibus_get_group_name()
+
* Sat Nov 22 2025 Takao Fujiwara <tfujiwar@redhat.com> - 1.5.34~alpha1-1
- Bump to 1.5.34-alpha1
- Delete gnome-themes-extra from Fedora CI
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2026-05-31 2:09 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-05-31 2:09 [rpms/ibus] autotool: Resolves: #2237664 Fix mouse position in Emojier category list Takao Fujiwara
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox