diff --git a/ibus-HEAD.patch b/ibus-HEAD.patch index 021f84a..aae3e21 100644 --- a/ibus-HEAD.patch +++ b/ibus-HEAD.patch @@ -106,3 +106,1944 @@ index 4232c549..23e3411e 100755 -- 2.28.0 +From d105a3941aad53b0c7470a1e9c1033987b029fb8 Mon Sep 17 00:00:00 2001 +From: fujiwarat +Date: Wed, 12 May 2021 18:54:30 +0900 +Subject: [PATCH] client/gtk2: Implement + ibus_im_context_set_surrounding_with_selection() + +Selection bounds need to be re-calculated when pre-edit text is +inserted and the selection position is changed. +GTK4 has a new API GtkIMContext.set_surrounding_with_selection() +to fix this issue and now IBus GTK module inherits the API. + +BUG=https://github.com/ibus/ibus/issues/2013 +--- + client/gtk2/ibusimcontext.c | 53 ++++++++++++++++++++++++++++++------- + 1 file changed, 44 insertions(+), 9 deletions(-) + +diff --git a/client/gtk2/ibusimcontext.c b/client/gtk2/ibusimcontext.c +index e153081d..61194816 100644 +--- a/client/gtk2/ibusimcontext.c ++++ b/client/gtk2/ibusimcontext.c +@@ -2,8 +2,8 @@ + /* vim:set et sts=4: */ + /* ibus - The Input Bus + * Copyright (C) 2008-2013 Peng Huang +- * Copyright (C) 2015-2020 Takao Fujiwara +- * Copyright (C) 2008-2020 Red Hat, Inc. ++ * Copyright (C) 2015-2021 Takao Fujiwara ++ * Copyright (C) 2008-2021 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 +@@ -165,11 +165,19 @@ static void ibus_im_context_set_cursor_location + static void ibus_im_context_set_use_preedit + (GtkIMContext *context, + gboolean use_preedit); ++#if !GTK_CHECK_VERSION (4, 1, 2) + static void ibus_im_context_set_surrounding + (GtkIMContext *slave, + const gchar *text, +- gint len, +- gint cursor_index); ++ int len, ++ int cursor_index); ++#endif ++static void ibus_im_context_set_surrounding_with_selection ++ (GtkIMContext *slave, ++ const gchar *text, ++ int len, ++ int cursor_index, ++ int anchor_index); + + /* static methods*/ + static void _ibus_context_update_preedit_text_cb +@@ -724,7 +732,12 @@ ibus_im_context_class_init (IBusIMContextClass *class) + #endif + im_context_class->set_cursor_location = ibus_im_context_set_cursor_location; + im_context_class->set_use_preedit = ibus_im_context_set_use_preedit; ++#if GTK_CHECK_VERSION (4, 1, 2) ++ im_context_class->set_surrounding_with_selection ++ = ibus_im_context_set_surrounding_with_selection; ++#else + im_context_class->set_surrounding = ibus_im_context_set_surrounding; ++#endif + gobject_class->notify = ibus_im_context_notify; + gobject_class->finalize = ibus_im_context_finalize; + +@@ -1624,8 +1637,22 @@ get_selection_anchor_point (IBusIMContext *ibusimcontext, + static void + ibus_im_context_set_surrounding (GtkIMContext *context, + const gchar *text, +- gint len, +- gint cursor_index) ++ int len, ++ int cursor_index) ++{ ++ ibus_im_context_set_surrounding_with_selection (context, ++ text, ++ len, ++ cursor_index, ++ cursor_index); ++} ++ ++static void ++ibus_im_context_set_surrounding_with_selection (GtkIMContext *context, ++ const gchar *text, ++ int len, ++ int cursor_index, ++ int anchor_index) + { + g_return_if_fail (context != NULL); + g_return_if_fail (IBUS_IS_IM_CONTEXT (context)); +@@ -1647,18 +1674,26 @@ ibus_im_context_set_surrounding (GtkIMContext *context, + ibustext = ibus_text_new_from_string (p); + g_free (p); + +- guint anchor_pos = get_selection_anchor_point (ibusimcontext, +- cursor_pos, +- utf8_len); ++ gint anchor_pos = get_selection_anchor_point (ibusimcontext, ++ cursor_pos, ++ utf8_len); + ibus_input_context_set_surrounding_text (ibusimcontext->ibuscontext, + ibustext, + cursor_pos, + anchor_pos); + } ++#if GTK_CHECK_VERSION (4, 1, 2) ++ gtk_im_context_set_surrounding_with_selection (ibusimcontext->slave, ++ text, ++ len, ++ cursor_index, ++ anchor_index); ++#else + gtk_im_context_set_surrounding (ibusimcontext->slave, + text, + len, + cursor_index); ++#endif + } + + static void +-- +2.28.0 + +From 65f709bb3a094a031ad7a7a802a12bd9ab7c27e2 Mon Sep 17 00:00:00 2001 +From: fujiwarat +Date: Sun, 23 May 2021 23:09:26 +0900 +Subject: [PATCH] Fix code reviews + +--- + bus/ibusimpl.c | 23 ++++-- + bus/server.c | 10 +-- + client/gtk2/ibusimcontext.c | 8 ++ + client/wayland/main.c | 9 ++- + client/x11/main.c | 22 +++-- + conf/dconf/main.c | 7 +- + portal/portal.c | 7 +- + setup/ibus-setup.in | 2 +- + src/emoji-parser.c | 46 ++++++----- + src/ibusaccelgroup.c | 2 +- + src/ibusbus.c | 10 ++- + src/ibuscomposetable.c | 91 ++++++++++++++++++--- + src/ibusemoji.c | 8 +- + src/ibusenginesimple.c | 21 +++-- + src/ibushotkey.c | 4 +- + src/ibusregistry.c | 9 ++- + src/ibusshare.c | 36 +++++---- + src/ibustext.c | 5 +- + src/ibusunicode.c | 17 +++- + src/tests/ibus-compose.c | 6 +- + src/tests/ibus-keypress.c | 3 +- + src/unicode-parser.c | 52 ++++++------ + util/IMdkit/FrameMgr.c | 34 +++++++- + util/IMdkit/i18nIc.c | 41 ++++++++-- + util/IMdkit/i18nMethod.c | 24 +++++- + util/IMdkit/i18nOffsetCache.c | 2 +- + util/IMdkit/i18nPtHdr.c | 147 ++++++++++++++++++++++++++++------ + util/IMdkit/i18nUtil.c | 20 +++++ + util/IMdkit/i18nX.c | 29 ++++--- + 29 files changed, 523 insertions(+), 172 deletions(-) + +diff --git a/bus/ibusimpl.c b/bus/ibusimpl.c +index e432e849..49a138fe 100644 +--- a/bus/ibusimpl.c ++++ b/bus/ibusimpl.c +@@ -2,8 +2,8 @@ + /* vim:set et sts=4: */ + /* ibus - The Input Bus + * Copyright (C) 2008-2013 Peng Huang +- * Copyright (C) 2011-2020 Takao Fujiwara +- * Copyright (C) 2008-2020 Red Hat, Inc. ++ * Copyright (C) 2011-2021 Takao Fujiwara ++ * Copyright (C) 2008-2021 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 +@@ -624,7 +624,6 @@ bus_ibus_impl_destroy (BusIBusImpl *ibus) + + g_list_foreach (ibus->components, (GFunc) bus_component_stop, NULL); + +- pid = 0; + timeout = 0; + flag = FALSE; + while (1) { +@@ -1190,6 +1189,7 @@ _ibus_get_current_input_context (BusIBusImpl *ibus, + GDBusConnection *connection, + GError **error) + { ++ GVariant *retval = NULL; + if (error) { + *error = NULL; + } +@@ -1204,8 +1204,14 @@ _ibus_get_current_input_context (BusIBusImpl *ibus, + const gchar *path = ibus_service_get_object_path ( + (IBusService *) ibus->focused_context); + /* the format-string 'o' is for a D-Bus object path. */ +- return g_variant_new_object_path (path); ++ retval = g_variant_new_object_path (path); ++ if (!retval) { ++ g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, ++ "Could not get object path from %s", ++ path ? path : "(null)"); ++ } + } ++ return retval; + } + + static void +@@ -1572,6 +1578,7 @@ _ibus_get_global_engine (BusIBusImpl *ibus, + GError **error) + { + IBusEngineDesc *desc = NULL; ++ GVariant *retval = NULL; + + if (error) { + *error = NULL; +@@ -1592,7 +1599,13 @@ _ibus_get_global_engine (BusIBusImpl *ibus, + GVariant *variant = ibus_serializable_serialize ( + (IBusSerializable *) desc); + // Set type "v" for introspection_xml. +- return g_variant_new_variant (variant); ++ retval = g_variant_new_variant (variant); ++ if (!retval) { ++ g_set_error (error, ++ G_DBUS_ERROR, G_DBUS_ERROR_FAILED, ++ "Failed to serialize engine desc."); ++ } ++ return retval; + } while (0); + + g_set_error (error, +diff --git a/bus/server.c b/bus/server.c +index 6c9e2c02..e8d0ce2b 100644 +--- a/bus/server.c ++++ b/bus/server.c +@@ -2,8 +2,8 @@ + /* vim:set et sts=4: */ + /* bus - The Input Bus + * Copyright (C) 2008-2010 Peng Huang +- * Copyright (C) 2011-2019 Takao Fujiwara +- * Copyright (C) 2008-2019 Red Hat, Inc. ++ * Copyright (C) 2011-2021 Takao Fujiwara ++ * Copyright (C) 2008-2021 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 +@@ -22,12 +22,11 @@ + */ + #include "server.h" + +-#include + #include + #include +-#include +-#include + #include ++#include ++#include + #include + + #include "dbusimpl.h" +@@ -282,6 +281,7 @@ bus_server_init (void) + * `chmod` runs for the last directory only not to change the modes + * of the parent directories. E.g. "/tmp/ibus". + */ ++ errno = 0; + if (g_mkdir_with_parents (unix_dir, 0700) != 0) { + g_error ("mkdir is failed in: %s: %s", + unix_dir, g_strerror (errno)); +diff --git a/client/gtk2/ibusimcontext.c b/client/gtk2/ibusimcontext.c +index 61194816..e7ce5363 100644 +--- a/client/gtk2/ibusimcontext.c ++++ b/client/gtk2/ibusimcontext.c +@@ -385,7 +385,9 @@ _process_key_event_done (GObject *object, + + ProcessKeyEventData *data = (ProcessKeyEventData *)user_data; + GdkEvent *event = data->event; ++#if GTK_CHECK_VERSION (3, 98, 4) + IBusIMContext *ibusimcontext = data->ibusimcontext; ++#endif + GError *error = NULL; + + g_slice_free (ProcessKeyEventData, data); +@@ -1634,6 +1636,7 @@ get_selection_anchor_point (IBusIMContext *ibusimcontext, + return anchor; + } + ++#if !GTK_CHECK_VERSION (4, 1, 2) + static void + ibus_im_context_set_surrounding (GtkIMContext *context, + const gchar *text, +@@ -1646,6 +1649,7 @@ ibus_im_context_set_surrounding (GtkIMContext *context, + cursor_index, + cursor_index); + } ++#endif + + static void + ibus_im_context_set_surrounding_with_selection (GtkIMContext *context, +@@ -1851,7 +1855,11 @@ _create_gdk_event (IBusIMContext *ibusimcontext, + if (event->state & GDK_CONTROL_MASK) { + if ((c >= '@' && c < '\177') || c == ' ') c &= 0x1F; + else if (c == '2') { ++#if GLIB_CHECK_VERSION (2, 68, 0) ++ event->string = g_memdup2 ("\0\0", 2); ++#else + event->string = g_memdup ("\0\0", 2); ++#endif + event->length = 1; + buf[0] = '\0'; + goto out; +diff --git a/client/wayland/main.c b/client/wayland/main.c +index d86bab9e..1f99c804 100644 +--- a/client/wayland/main.c ++++ b/client/wayland/main.c +@@ -1,7 +1,7 @@ + /* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */ + /* vim:set et sts=4: */ + /* ibus - The Input Bus +- * Copyright (C) 2019 Takao Fujiwara ++ * Copyright (C) 2019-2021 Takao Fujiwara + * Copyright (C) 2013 Intel Corporation + * Copyright (C) 2013-2019 Red Hat, Inc. + * +@@ -339,16 +339,19 @@ input_method_keyboard_keymap (void *data, + { + IBusWaylandIM *wlim = data; + GMappedFile *map; +- GError *error; ++ GError *error = NULL; + + if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) { + close(fd); + return; + } + +- error = NULL; + map = g_mapped_file_new_from_fd (fd, FALSE, &error); + if (map == NULL) { ++ if (error) { ++ g_warning ("Failed to map file fd %s", error->message); ++ g_error_free (error); ++ } + close (fd); + return; + } +diff --git a/client/x11/main.c b/client/x11/main.c +index c9ee174d..ffd776fd 100644 +--- a/client/x11/main.c ++++ b/client/x11/main.c +@@ -2,7 +2,7 @@ + /* vim:set et sts=4: */ + /* ibus + * Copyright (C) 2007-2015 Peng Huang +- * Copyright (C) 2015-2019 Takao Fujiwara ++ * Copyright (C) 2015-2021 Takao Fujiwara + * Copyright (C) 2007-2015 Red Hat, Inc. + * + * main.c: +@@ -229,12 +229,13 @@ _xim_preedit_callback_draw (XIMS xims, X11IC *x11ic, const gchar *preedit_string + } + } + +- for (i = 0; i < len; i++) { ++ for (i = 0; feedback && i < len; i++) { + if (feedback[i] == 0) { + feedback[i] = XIMUnderline; + } + } +- feedback[len] = 0; ++ if (feedback) ++ feedback[len] = 0; + + pcb.major_code = XIM_PREEDIT_DRAW; + pcb.connect_id = x11ic->connect_id; +@@ -736,9 +737,20 @@ xim_get_ic_values (XIMS xims, IMChangeICStruct *call_data) + + for (i = 0; i < (int) call_data->ic_attr_num; ++i, ++ic_attr) { + if (g_strcmp0 (XNFilterEvents, ic_attr->name) == 0) { ++ /* ic_attr->value will be freed in server side and ignore ++ * leak of malloc with -Wanalyzer-malloc-leak flags in gcc 11.0.1 ++ */ ++#pragma GCC diagnostic push ++#pragma GCC diagnostic ignored "-Wanalyzer-malloc-leak" + ic_attr->value = (void *) malloc (sizeof (CARD32)); +- *(CARD32 *) ic_attr->value = KeyPressMask | KeyReleaseMask; +- ic_attr->value_length = sizeof (CARD32); ++ if (ic_attr->value) { ++ *(CARD32 *) ic_attr->value = KeyPressMask | KeyReleaseMask; ++ ic_attr->value_length = sizeof (CARD32); ++ } else { ++ g_warning ("Failed to malloc"); ++ ic_attr->value_length = 0; ++ } ++#pragma GCC diagnostic pop + } + } + +diff --git a/conf/dconf/main.c b/conf/dconf/main.c +index e6878424..0d78b97d 100644 +--- a/conf/dconf/main.c ++++ b/conf/dconf/main.c +@@ -2,7 +2,8 @@ + /* vim:set et sts=4: */ + /* ibus - The Input Bus + * Copyright (C) 2008-2010 Peng Huang +- * Copyright (C) 2008-2010 Red Hat, Inc. ++ * Copyright (C) 2012-2021 Takao Fujiwara ++ * Copyright (C) 2008-2021 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 +@@ -70,7 +71,9 @@ main (gint argc, gchar **argv) + GOptionContext *context; + + setlocale (LC_ALL, ""); +- g_setenv ("DCONF_PROFILE", "ibus", FALSE); ++ errno = 0; ++ if (!g_setenv ("DCONF_PROFILE", "ibus", FALSE)) ++ g_warning ("Failed setenv %s", errno ? strerror (errno) : "(null)"); + + context = g_option_context_new ("- ibus dconf component"); + +diff --git a/portal/portal.c b/portal/portal.c +index e78bc92f..213e2ba6 100644 +--- a/portal/portal.c ++++ b/portal/portal.c +@@ -1,7 +1,7 @@ + /* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */ + /* vim:set et sts=4: */ + /* ibus - The Input Bus +- * Copyright (C) 2017-2019 Red Hat, Inc. ++ * Copyright (C) 2017-2021 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 +@@ -508,7 +508,6 @@ create_input_context_done (IBusBus *bus, + if (portal_context == NULL) { + g_dbus_method_invocation_return_gerror (invocation, error); + g_error_free (error); +- g_object_unref (portal_context); + return; + } + +@@ -656,8 +655,10 @@ main (gint argc, gchar **argv) + exit (-1); + } + ++ errno = 0; + /* Avoid even loading gvfs to avoid accidental confusion */ +- g_setenv ("GIO_USE_VFS", "local", TRUE); ++ if (!g_setenv ("GIO_USE_VFS", "local", TRUE)) ++ g_warning ("Failed setenv %s", errno ? strerror (errno) : "(null)"); + + ibus_init (); + +diff --git a/setup/ibus-setup.in b/setup/ibus-setup.in +index 4a6830af..474ce8a8 100644 +--- a/setup/ibus-setup.in ++++ b/setup/ibus-setup.in +@@ -27,5 +27,5 @@ export IBUS_PREFIX=@prefix@ + export IBUS_DATAROOTDIR=@datarootdir@ + export IBUS_LOCALEDIR=@localedir@ + export IBUS_LIBEXECDIR=${libexecdir} +-exec ${PYTHON:-@PYTHON@} @prefix@/share/ibus/setup/main.py $@ ++exec ${PYTHON:-@PYTHON@} @prefix@/share/ibus/setup/main.py "$@" + +diff --git a/src/emoji-parser.c b/src/emoji-parser.c +index b117b1b4..36d36e05 100644 +--- a/src/emoji-parser.c ++++ b/src/emoji-parser.c +@@ -1,7 +1,7 @@ + /* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */ + /* vim:set et sts=4: */ + /* ibus - The Input Bus +- * Copyright (C) 2016-2020 Takao Fujiwara ++ * Copyright (C) 2016-2021 Takao Fujiwara + * Copyright (C) 2016 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or +@@ -291,11 +291,9 @@ emoji_data_new_object (EmojiData *data) + "annotations", + data->annotations, + "description", +- data->description ? data->description +- : g_strdup (""), ++ data->description ? data->description : "", + "category", +- data->category ? data->category +- : g_strdup (""), ++ data->category ? data->category : "", + NULL); + data->list = g_slist_append (data->list, emoji); + } +@@ -608,7 +606,7 @@ unicode_emoji_test_parse_line (const gchar *line, + return FALSE; + } + unicode_emoji_test_parse_description (segments[1], data); +- g_strfreev (segments); ++ g_clear_pointer (&segments, g_strfreev); + if (data->annotations == NULL) { + if (data->subcategory) { + int i; +@@ -631,7 +629,7 @@ unicode_emoji_test_parse_line (const gchar *line, + data->annotations = g_slist_append (data->annotations, + g_strdup (segments[i])); + } +- g_strfreev (segments); ++ g_clear_pointer (&segments, g_strfreev); + } else { + g_warning ("No subcategory line\n"); + goto failed_to_parse_unicode_emoji_test_line; +@@ -672,7 +670,7 @@ unicode_emoji_test_parse_file (const gchar *filename, + filename, error ? error->message : ""); + goto failed_to_parse_unicode_emoji_test; + } +- head = end = content; ++ end = content; + while (*end == '\n' && end - content < length) { + end++; + n++; +@@ -1100,10 +1098,12 @@ static void + category_list_dump (const gchar *category, + GString *buff) + { ++ gchar *line; + g_return_if_fail (buff != NULL); + +- const gchar *line = g_strdup_printf (" N_(\"%s\"),\n", category); ++ line = g_strdup_printf (" N_(\"%s\"),\n", category); + g_string_append (buff, line); ++ g_free (line); + } + + static void +@@ -1113,7 +1113,7 @@ category_file_save (const gchar *filename, + gchar *content = NULL; + gsize length = 0; + GError *error = NULL; +- gchar *p; ++ gchar *p, *substr; + GString *buff = NULL; + int i; + GSList *list_categories = NULL; +@@ -1139,24 +1139,28 @@ category_file_save (const gchar *filename, + break; + } + if (p != NULL) { +- g_string_append (buff, g_strndup (content, p - content)); ++ substr = g_strndup (content, p - content); ++ g_string_append (buff, substr); ++ g_free (substr); + g_string_append_c (buff, '\n'); + } + g_clear_pointer (&content, g_free); + +- g_string_append (buff, g_strdup ("\n")); +- g_string_append (buff, g_strdup_printf ("/* This file is generated by %s. */", __FILE__)); +- g_string_append (buff, g_strdup ("\n")); +- g_string_append (buff, g_strdup ("include \n")); +- g_string_append (buff, g_strdup ("\n")); +- g_string_append (buff, g_strdup ("#ifndef __IBUS_EMOJI_GEN_H_\n")); +- g_string_append (buff, g_strdup ("#define __IBUS_EMOJI_GEN_H_\n")); +- g_string_append (buff, g_strdup ("const static char *unicode_emoji_categories[] = {\n")); ++ g_string_append (buff, "\n"); ++ substr = g_strdup_printf ("/* This file is generated by %s. */", __FILE__); ++ g_string_append (buff, substr); ++ g_free (substr); ++ g_string_append (buff, "\n"); ++ g_string_append (buff, "include \n"); ++ g_string_append (buff, "\n"); ++ g_string_append (buff, "#ifndef __IBUS_EMOJI_GEN_H_\n"); ++ g_string_append (buff, "#define __IBUS_EMOJI_GEN_H_\n"); ++ g_string_append (buff, "const static char *unicode_emoji_categories[] = {\n"); + list_categories = g_slist_sort (list_categories, (GCompareFunc)g_strcmp0); + g_slist_foreach (list_categories, (GFunc)category_list_dump, buff); + g_slist_free (list_categories); +- g_string_append (buff, g_strdup ("};\n")); +- g_string_append (buff, g_strdup ("#endif\n")); ++ g_string_append (buff, "};\n"); ++ g_string_append (buff, "#endif\n"); + + if (!g_file_set_contents (filename, buff->str, -1, &error)) { + g_warning ("Failed to save emoji category file %s: %s", filename, error->message); +diff --git a/src/ibusaccelgroup.c b/src/ibusaccelgroup.c +index 8a81597e..ef2d3976 100644 +--- a/src/ibusaccelgroup.c ++++ b/src/ibusaccelgroup.c +@@ -468,7 +468,7 @@ ibus_accelerator_name (guint accelerator_key, + if (accelerator_mods & IBUS_SUPER_MASK) + l += sizeof (text_super) - 1; + +- accelerator = g_new (gchar, l + 1); ++ g_return_val_if_fail ((accelerator = g_new (gchar, l + 1)), NULL); + + accelerator_mods = saved_mods; + l = 0; +diff --git a/src/ibusbus.c b/src/ibusbus.c +index b7ffbb47..e9b0bcbb 100644 +--- a/src/ibusbus.c ++++ b/src/ibusbus.c +@@ -2,7 +2,7 @@ + /* vim:set et sts=4: */ + /* ibus - The Input Bus + * Copyright (C) 2008-2015 Peng Huang +- * Copyright (C) 2015-2019 Takao Fujiwara ++ * Copyright (C) 2015-2021 Takao Fujiwara + * Copyright (C) 2008-2016 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or +@@ -555,12 +555,18 @@ ibus_bus_init (IBusBus *bus) + + path = g_path_get_dirname (ibus_get_socket_path ()); + +- g_mkdir_with_parents (path, 0700); ++ errno = 0; ++ if (g_mkdir_with_parents (path, 0700)) { ++ g_warning ("Failed to mkdir %s: %s", path, g_strerror (errno)); ++ g_free (path); ++ return; ++ } + + if (stat (path, &buf) == 0) { + if (buf.st_uid != getuid ()) { + g_warning ("The owner of %s is not %s!", + path, ibus_get_user_name ()); ++ g_free (path); + return; + } + if (buf.st_mode != (S_IFDIR | S_IRWXU)) { +diff --git a/src/ibuscomposetable.c b/src/ibuscomposetable.c +index ef20469c..685ac717 100644 +--- a/src/ibuscomposetable.c ++++ b/src/ibuscomposetable.c +@@ -1,7 +1,7 @@ + /* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */ + /* ibus - The Input Bus + * Copyright (C) 2013-2014 Peng Huang +- * Copyright (C) 2013-2019 Takao Fujiwara ++ * Copyright (C) 2013-2021 Takao Fujiwara + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public +@@ -108,6 +108,7 @@ parse_compose_value (IBusComposeData *compose_data, + } + ++head; + p = head; ++ end = NULL; + while ((*p != '\0') && (end = strchr (p, '\"'))) { + if (*(end - 1) == '\\' && *(end - 2) == '\\') + break; +@@ -516,10 +517,10 @@ ibus_compose_hash_get_cache_path (guint32 hash) + "ibus", "compose", NULL); + } + path = g_build_filename (dir, basename, NULL); +- if (g_mkdir_with_parents (dir, 0755) != 0) { +- g_warning ("Failed to mkdir %s", dir); +- g_free (path); +- path = NULL; ++ errno = 0; ++ if (g_mkdir_with_parents (dir, 0755)) { ++ g_warning ("Failed to mkdir %s: %s", dir, g_strerror (errno)); ++ g_clear_pointer (&path, g_free); + } + + g_free (dir); +@@ -812,10 +813,14 @@ ibus_compose_table_deserialize (const gchar *contents, + } + } + if (data_length) { +- retval->priv->data_second = g_new (guint32, data_length); +- memcpy (retval->priv->data_second, +- data_32bit_second, data_length * sizeof (guint32)); +- retval->priv->second_size = second_size; ++ if ((retval->priv->data_second = g_new (guint32, data_length))) { ++ memcpy (retval->priv->data_second, ++ data_32bit_second, data_length * sizeof (guint32)); ++ retval->priv->second_size = second_size; ++ } else { ++ g_warning ("Failed g_new"); ++ retval->priv->second_size = 0; ++ } + } + + +@@ -910,6 +915,43 @@ ibus_compose_table_new_with_list (GList *compose_list, + int n_index_stride, + guint32 hash) + { ++ /* @ibus_compose_seqs: Include both compose sequence and the value(compose ++ * output) as the tradition GTK. The value is one character only ++ * and within 16bit. I.e. All compose sequences and the values ++ * are 16bit. ++ * @ibus_compose_seqs_32bit_second: Include the compose values only. ++ * The length of values by compose sequence is more than one characster ++ * or one of the values is outside 16bit but within 32bit. ++ * Some values could be more than one character and Emoji character ++ * could be outside 16bit. ++ * See also ibus/src/tests/ibus-compose.emoji file for e.g. ++ * @ibus_compose_seqs_32bit_first: Include the compose sequence only in ++ * case the value is included in @ibus_compose_seqs_32bit_second. ++ * @s_size_total: The number of compose sequences. ++ * @s_size_16bit: The number of compose sequences whose value is one ++ * character only and within 16bit. I.e. the number of the compose ++ * sequence in @ibus_compose_seqs is @@s_size_16bit. And ++ * @s_size_total - @s_size_16bit is the number of the compose sequence ++ * in @ibus_compose_seqs_32bit_first. ++ * @v_size_32bit: The total number of compose values. Each length of the ++ * values is more than one character or one of the value is ++ * outside 16bit but within 32bit. I.e. The size of ++ * @ibus_compose_seqs_32bit_second is @v_size_32bit. ++ * @v_index_32bit: Each index of the compose values in ++ * @ibus_compose_seqs_32bit_second and this is not a fixed value in ++ * this API. If a compose sequence is found in ++ * @ibus_compose_seqs_32bit_first and the next value is 0, 0 is lined ++ * in @ibus_compose_seqs_32bit_first until @max_compose_len after ++ * the found compose sequence. And the next value is the length of ++ * the compose values and the next value is the @v_index_32bit, i.e. ++ * the index of @ibus_compose_seqs_32bit_second. ++ * E.g. the following line could be found in ++ * @ibus_compose_seqs_32bit_first: ++ * ..., "U17ff", "0", "0", "0", "0", 2, 100, ... ++ * @ibus_compose_seqs_32bit_second[100] is "ាំ" and the character ++ * length is 2. ++ * @max_compose_len is 5 and @n_index_stride is 7. ++ */ + gsize s_size_total, s_size_16bit, v_size_32bit, v_index_32bit; + guint n = 0, m = 0; + int i, j; +@@ -935,13 +977,25 @@ ibus_compose_table_new_with_list (GList *compose_list, + } + } + +- if (s_size_16bit) ++ if (s_size_16bit) { + ibus_compose_seqs = g_new (guint16, s_size_16bit * n_index_stride); ++ if (!ibus_compose_seqs) { ++ g_warning ("Failed g_new"); ++ return NULL; ++ } ++ } + if (s_size_total > s_size_16bit) { + ibus_compose_seqs_32bit_first = + g_new (guint16, + (s_size_total - s_size_16bit) * n_index_stride); + ibus_compose_seqs_32bit_second = g_new (guint32, v_size_32bit); ++ if (!ibus_compose_seqs_32bit_first || !ibus_compose_seqs_32bit_second) { ++ g_warning ("Failed g_new"); ++ g_free (ibus_compose_seqs); ++ g_free (ibus_compose_seqs_32bit_first); ++ g_free (ibus_compose_seqs_32bit_second); ++ return NULL; ++ } + } + + v_index_32bit = 0; +@@ -951,32 +1005,45 @@ ibus_compose_table_new_with_list (GList *compose_list, + + is_32bit = unichar_length (compose_data->values) > 1 ? TRUE : + compose_data->values[0] >= 0xFFFF ? TRUE : FALSE; ++ if (is_32bit) { ++ g_assert (ibus_compose_seqs_32bit_first); ++ g_assert (ibus_compose_seqs_32bit_second); ++ } + for (i = 0; i < max_compose_len; i++) { + if (compose_data->sequence[i] == 0) { + for (j = i; j < max_compose_len; j++) { +- if (is_32bit) ++ if (is_32bit) { ++ g_assert (m < (s_size_total - s_size_16bit) ++ * n_index_stride); + ibus_compose_seqs_32bit_first[m++] = 0; +- else ++ } else { ++ g_assert (n < s_size_16bit * n_index_stride); + ibus_compose_seqs[n++] = 0; ++ } + } + break; + } + if (is_32bit) { ++ g_assert (m < (s_size_total - s_size_16bit) * n_index_stride); + ibus_compose_seqs_32bit_first[m++] = + (guint16) compose_data->sequence[i]; + } else { ++ g_assert (n < s_size_16bit * n_index_stride); + ibus_compose_seqs[n++] = (guint16) compose_data->sequence[i]; + } + } + if (is_32bit) { + for (j = 0; compose_data->values[j]; j++) { ++ g_assert (v_index_32bit + j < v_size_32bit); + ibus_compose_seqs_32bit_second[v_index_32bit + j] = + compose_data->values[j]; + } ++ g_assert (m + 1 < (s_size_total - s_size_16bit) * n_index_stride); + ibus_compose_seqs_32bit_first[m++] = j; + ibus_compose_seqs_32bit_first[m++] = v_index_32bit; + v_index_32bit += j; + } else { ++ g_assert (n + 1 < s_size_16bit * n_index_stride); + ibus_compose_seqs[n++] = (guint16) compose_data->values[0]; + ibus_compose_seqs[n++] = 0; + } +diff --git a/src/ibusemoji.c b/src/ibusemoji.c +index ae8907a2..df97264b 100644 +--- a/src/ibusemoji.c ++++ b/src/ibusemoji.c +@@ -1,7 +1,7 @@ + /* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */ + /* vim:set et sts=4: */ + /* bus - The Input Bus +- * Copyright (C) 2017-2019 Takao Fujiwara ++ * Copyright (C) 2017-2021 Takao Fujiwara + * Copyright (C) 2017-2019 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or +@@ -497,7 +497,11 @@ ibus_emoji_data_save (const gchar *path, + + dir = g_path_get_dirname (path); + if (g_strcmp0 (dir, ".") != 0 && g_stat (dir, &buf) != 0) { +- g_mkdir_with_parents (dir, 0777); ++ errno = 0; ++ if (g_mkdir_with_parents (dir, 0777)) { ++ g_warning ("Failed mkdir %s: %s", dir, g_strerror (errno)); ++ return; ++ } + } + g_free (dir); + if (!g_file_set_contents (path, contents, length, &error)) { +diff --git a/src/ibusenginesimple.c b/src/ibusenginesimple.c +index 43bd5283..6dbc39c7 100644 +--- a/src/ibusenginesimple.c ++++ b/src/ibusenginesimple.c +@@ -2,7 +2,7 @@ + /* vim:set et sts=4: */ + /* ibus - The Input Bus + * Copyright (C) 2014 Peng Huang +- * Copyright (C) 2015-2019 Takao Fujiwara ++ * Copyright (C) 2015-2021 Takao Fujiwara + * Copyright (C) 2014-2017 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or +@@ -466,11 +466,15 @@ check_hex (IBusEngineSimple *simple, + + ch = ibus_keyval_to_unicode (priv->compose_buffer[i]); + +- if (ch == 0) ++ if (ch == 0) { ++ g_string_free (str, TRUE); + return FALSE; ++ } + +- if (!g_unichar_isxdigit (ch)) ++ if (!g_unichar_isxdigit (ch)) { ++ g_string_free (str, TRUE); + return FALSE; ++ } + + buf[g_unichar_to_utf8 (ch, buf)] = '\0'; + +@@ -487,8 +491,9 @@ check_hex (IBusEngineSimple *simple, + if (nptr - str->str < str->len) { + g_string_free (str, TRUE); + return FALSE; +- } else ++ } else { + g_string_free (str, TRUE); ++ } + + if (g_unichar_validate (n)) { + priv->tentative_match = n; +@@ -559,11 +564,15 @@ check_emoji_table (IBusEngineSimple *simple, + + ch = ibus_keyval_to_unicode (priv->compose_buffer[i]); + +- if (ch == 0) ++ if (ch == 0) { ++ g_string_free (str, TRUE); + return FALSE; ++ } + +- if (!g_unichar_isprint (ch)) ++ if (!g_unichar_isprint (ch)) { ++ g_string_free (str, TRUE); + return FALSE; ++ } + + buf[g_unichar_to_utf8 (ch, buf)] = '\0'; + +diff --git a/src/ibushotkey.c b/src/ibushotkey.c +index d4ab7c23..e72b8305 100644 +--- a/src/ibushotkey.c ++++ b/src/ibushotkey.c +@@ -2,7 +2,7 @@ + /* vim:set et sts=4: */ + /* IBus - The Input Bus + * Copyright (C) 2008-2010 Peng Huang +- * Copyright (C) 2018-2019 Takao Fujiwara ++ * Copyright (C) 2018-2021 Takao Fujiwara + * Copyright (C) 2008-2019 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or +@@ -373,6 +373,8 @@ ibus_hotkey_profile_add_hotkey (IBusHotkeyProfile *profile, + p->event = event; + } + ++ if (!p) ++ return FALSE; + p->hotkeys = g_list_append (p->hotkeys, hotkey); + + return TRUE; +diff --git a/src/ibusregistry.c b/src/ibusregistry.c +index 3386a5d1..23c5ca1b 100644 +--- a/src/ibusregistry.c ++++ b/src/ibusregistry.c +@@ -2,7 +2,7 @@ + /* vim:set et sts=4: */ + /* bus - The Input Bus + * Copyright (C) 2015 Peng Huang +- * Copyright (C) 2015-2020 Takao Fujiwara ++ * Copyright (C) 2015-2021 Takao Fujiwara + * Copyright (C) 2015-2020 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or +@@ -438,7 +438,12 @@ ibus_registry_save_cache_file (IBusRegistry *registry, + g_assert (filename != NULL); + + cachedir = g_path_get_dirname (filename); +- g_mkdir_with_parents (cachedir, 0775); ++ errno = 0; ++ if (g_mkdir_with_parents (cachedir, 0775)) { ++ g_warning ("Failed to mkdir %s: %s", cachedir, g_strerror (errno)); ++ g_free (cachedir); ++ return FALSE; ++ } + g_free (cachedir); + + variant = ibus_serializable_serialize (IBUS_SERIALIZABLE (registry)); +diff --git a/src/ibusshare.c b/src/ibusshare.c +index e0ef2ce0..8974511a 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 +- * Copyright (C) 2015-2018 Takao Fujiwara ++ * Copyright (C) 2015-2021 Takao Fujiwara + * Copyright (C) 2008-2018 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or +@@ -197,22 +197,17 @@ ibus_get_address (void) + FILE *pf; + + /* free address */ +- if (address != NULL) { +- g_free (address); +- address = NULL; +- } ++ g_clear_pointer (&address, g_free); + + /* get address from env variable */ + address = g_strdup (g_getenv ("IBUS_ADDRESS")); +- if (address) { ++ if (address) + return address; +- } + + /* read address from ~/.config/ibus/bus/soketfile */ + pf = fopen (ibus_get_socket_path (), "r"); +- if (pf == NULL) { ++ if (pf == NULL) + return NULL; +- } + + while (!feof (pf)) { + gchar *p = buffer; +@@ -224,11 +219,12 @@ ibus_get_address (void) + continue; + /* parse IBUS_ADDRESS */ + if (strncmp (p, "IBUS_ADDRESS=", sizeof ("IBUS_ADDRESS=") - 1) == 0) { +- address = p + sizeof ("IBUS_ADDRESS=") - 1; +- for (p = (gchar *)address; *p != '\n' && *p != '\0'; p++); ++ gchar *head = p + sizeof ("IBUS_ADDRESS=") - 1; ++ for (p = head; *p != '\n' && *p != '\0'; p++); + if (*p == '\n') + *p = '\0'; +- address = g_strdup (address); ++ g_free (address); ++ address = g_strdup (head); + continue; + } + +@@ -241,9 +237,8 @@ ibus_get_address (void) + } + fclose (pf); + +- if (pid == -1 || kill (pid, 0) != 0) { ++ if (pid == -1 || kill (pid, 0) != 0) + return NULL; +- } + + return address; + } +@@ -256,10 +251,19 @@ ibus_write_address (const gchar *address) + g_return_if_fail (address != NULL); + + path = g_path_get_dirname (ibus_get_socket_path ()); +- g_mkdir_with_parents (path, 0700); ++ errno = 0; ++ if (g_mkdir_with_parents (path, 0700)) { ++ g_warning ("Failed to mkdir %s: %s", path, g_strerror (errno)); ++ g_free (path); ++ return; ++ } + g_free (path); + +- g_unlink (ibus_get_socket_path ()); ++ errno = 0; ++ if (g_unlink (ibus_get_socket_path ())) { ++ g_warning ("Failed to unlink %s: %s", ++ ibus_get_socket_path (), g_strerror (errno)); ++ } + pf = fopen (ibus_get_socket_path (), "w"); + g_return_if_fail (pf != NULL); + +diff --git a/src/ibustext.c b/src/ibustext.c +index a5e3c43b..ed0fe666 100644 +--- a/src/ibustext.c ++++ b/src/ibustext.c +@@ -2,7 +2,8 @@ + /* vim:set et sts=4: */ + /* IBus - The Input Bus + * Copyright (C) 2008-2010 Peng Huang +- * Copyright (C) 2008-2010 Red Hat, Inc. ++ * Copyright (C) 2011-2021 Takao Fujiwara ++ * Copyright (C) 2008-2021 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 +@@ -220,7 +221,7 @@ ibus_text_new_from_unichar (gunichar c) + text= g_object_new (IBUS_TYPE_TEXT, NULL); + + text->is_static = FALSE; +- text->text = (gchar *)g_malloc (12); ++ g_return_val_if_fail ((text->text = (gchar *)g_malloc (12)), NULL); + len = g_unichar_to_utf8 (c, text->text); + text->text[len] = 0; + +diff --git a/src/ibusunicode.c b/src/ibusunicode.c +index 9e6f6b2b..f7a897d1 100644 +--- a/src/ibusunicode.c ++++ b/src/ibusunicode.c +@@ -1,8 +1,8 @@ + /* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */ + /* vim:set et sts=4: */ + /* bus - The Input Bus +- * Copyright (C) 2018-2019 Takao Fujiwara +- * Copyright (C) 2018-2019 Red Hat, Inc. ++ * Copyright (C) 2018-2021 Takao Fujiwara ++ * Copyright (C) 2018-2021 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 +@@ -472,7 +472,12 @@ ibus_unicode_data_save (const gchar *path, + + dir = g_path_get_dirname (path); + if (g_strcmp0 (dir, ".") != 0 && g_stat (dir, &buf) != 0) { +- g_mkdir_with_parents (dir, 0777); ++ errno = 0; ++ if (g_mkdir_with_parents (dir, 0777)) { ++ g_warning ("Failed to mkdir %s: %s", dir, g_strerror (errno)); ++ return; ++ } ++ + } + g_free (dir); + if (!g_file_set_contents (path, contents, length, &error)) { +@@ -967,7 +972,11 @@ ibus_unicode_block_save (const gchar *path, + + dir = g_path_get_dirname (path); + if (g_strcmp0 (dir, ".") != 0 && g_stat (dir, &buf) != 0) { +- g_mkdir_with_parents (dir, 0777); ++ errno = 0; ++ if (g_mkdir_with_parents (dir, 0777)) { ++ g_warning ("Failed to mkdir %s: %s", dir, g_strerror (errno)); ++ return; ++ } + } + g_free (dir); + if (!g_file_set_contents (path, contents, length, &error)) { +diff --git a/src/tests/ibus-compose.c b/src/tests/ibus-compose.c +index 4b4c56e7..81bfc69b 100644 +--- a/src/tests/ibus-compose.c ++++ b/src/tests/ibus-compose.c +@@ -360,11 +360,13 @@ main (int argc, char *argv[]) + /* Avoid a warning of "AT-SPI: Could not obtain desktop path or name" + * with gtk_main(). + */ +- g_setenv ("NO_AT_BRIDGE", "1", TRUE); ++ if (!g_setenv ("NO_AT_BRIDGE", "1", TRUE)) ++ g_message ("Failed setenv NO_AT_BRIDGE\n"); + g_test_init (&argc, &argv, NULL); + gtk_init (&argc, &argv); + +- m_srcdir = argc > 1 ? g_strdup (argv[1]) : g_strdup ("."); ++ m_srcdir = (argc > 1 && strlen (argv[1]) < FILENAME_MAX) ++ ? g_strdup (argv[1]) : g_strdup ("."); + m_compose_file = g_strdup (g_getenv ("COMPOSE_FILE")); + #if GLIB_CHECK_VERSION (2, 58, 0) + test_name = g_get_language_names_with_category ("LC_CTYPE")[0]; +diff --git a/src/tests/ibus-keypress.c b/src/tests/ibus-keypress.c +index dd1b0042..bab05398 100644 +--- a/src/tests/ibus-keypress.c ++++ b/src/tests/ibus-keypress.c +@@ -291,7 +291,8 @@ main (int argc, char *argv[]) + /* Avoid a warning of "AT-SPI: Could not obtain desktop path or name" + * with gtk_main(). + */ +- g_setenv ("NO_AT_BRIDGE", "1", TRUE); ++ if (!g_setenv ("NO_AT_BRIDGE", "1", TRUE)) ++ g_message ("Failed setenv NO_AT_BRIDGE\n"); + g_test_init (&argc, &argv, NULL); + gtk_init (&argc, &argv); + +diff --git a/src/unicode-parser.c b/src/unicode-parser.c +index b4303ea8..2c4eb677 100644 +--- a/src/unicode-parser.c ++++ b/src/unicode-parser.c +@@ -1,8 +1,8 @@ + /* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */ + /* vim:set et sts=4: */ + /* ibus - The Input Bus +- * Copyright (C) 2018 Takao Fujiwara +- * Copyright (C) 2018 Red Hat, Inc. ++ * Copyright (C) 2018-2021 Takao Fujiwara ++ * Copyright (C) 2018-2021 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 +@@ -76,11 +76,9 @@ unicode_data_new_object (UnicodeData *data) + ibus_unicode_data_new ("code", + data->code, + "name", +- data->name ? g_strdup (data->name) +- : g_strdup (""), ++ data->name ? data->name : "", + "alias", +- data->alias ? g_strdup (data->alias) +- : g_strdup (""), ++ data->alias ? data->alias : "", + NULL); + data->list = g_slist_append (data->list, unicode); + } +@@ -98,8 +96,7 @@ unicode_block_new_object (UnicodeData *data) + "end", + data->end, + "name", +- data->name ? g_strdup (data->name) +- : g_strdup (""), ++ data->name ? data->name : "", + NULL); + data->list = g_slist_append (data->list, block); + } +@@ -285,7 +282,7 @@ ucd_parse_file (const gchar *filename, + filename, error ? error->message : ""); + goto failed_to_parse_ucd_names_list; + } +- head = end = content; ++ end = content; + while (*end == '\n' && end - content < length) { + end++; + n++; +@@ -352,6 +349,7 @@ static void + block_list_dump (IBusUnicodeBlock *block, + GString *buff) + { ++ gchar *line; + g_return_if_fail (buff != NULL); + + g_string_append (buff, " /* TRANSLATORS: You might refer the " \ +@@ -359,9 +357,10 @@ block_list_dump (IBusUnicodeBlock *block, + " the following command:\n" \ + " msgmerge -C gucharmap.po ibus.po " \ + "ibus.pot */\n"); +- gchar *line = g_strdup_printf (" N_(\"%s\"),\n", +- ibus_unicode_block_get_name (block)); ++ line = g_strdup_printf (" N_(\"%s\"),\n", ++ ibus_unicode_block_get_name (block)); + g_string_append (buff, line); ++ g_free (line); + } + + static void +@@ -371,7 +370,7 @@ ucd_block_translatable_save (const gchar *filename, + gchar *content = NULL; + gsize length = 0; + GError *error = NULL; +- gchar *p; ++ gchar *p, *substr; + GString *buff = NULL; + int i; + GSList *list = blocks_list; +@@ -392,25 +391,30 @@ ucd_block_translatable_save (const gchar *filename, + break; + } + if (p != NULL) { +- g_string_append (buff, g_strndup (content, p - content)); ++ substr = g_strndup (content, p - content); ++ g_string_append (buff, substr); ++ g_free (substr); + g_string_append_c (buff, '\n'); + } + g_clear_pointer (&content, g_free); + +- g_string_append (buff, g_strdup ("\n")); +- g_string_append (buff, g_strdup_printf ("/* This file is generated by %s. */", __FILE__)); +- g_string_append (buff, g_strdup ("\n")); +- g_string_append (buff, g_strdup ("include \n")); +- g_string_append (buff, g_strdup ("\n")); +- g_string_append (buff, g_strdup ("#ifndef __IBUS_UNICODE_GEN_H_\n")); +- g_string_append (buff, g_strdup ("#define __IBUS_UNICODE_GEN_H_\n")); +- g_string_append (buff, g_strdup ("const static char *unicode_blocks[] = {\n")); ++ g_string_append (buff, "\n"); ++ substr = g_strdup_printf ("/* This file is generated by %s. */", __FILE__); ++ g_string_append (buff, substr); ++ g_free (substr); ++ g_string_append (buff, "\n"); ++ g_string_append (buff, "include \n"); ++ g_string_append (buff, "\n"); ++ g_string_append (buff, "#ifndef __IBUS_UNICODE_GEN_H_\n"); ++ g_string_append (buff, "#define __IBUS_UNICODE_GEN_H_\n"); ++ g_string_append (buff, "const static char *unicode_blocks[] = {\n"); + g_slist_foreach (list, (GFunc)block_list_dump, buff); +- g_string_append (buff, g_strdup ("};\n")); +- g_string_append (buff, g_strdup ("#endif\n")); ++ g_string_append (buff, "};\n"); ++ g_string_append (buff, "#endif\n"); + + if (!g_file_set_contents (filename, buff->str, -1, &error)) { +- g_warning ("Failed to save emoji category file %s: %s", filename, error->message); ++ g_warning ("Failed to save emoji category file %s: %s", ++ filename, error->message); + g_error_free (error); + } + +diff --git a/util/IMdkit/FrameMgr.c b/util/IMdkit/FrameMgr.c +index 0e91b78e..80d019a0 100644 +--- a/util/IMdkit/FrameMgr.c ++++ b/util/IMdkit/FrameMgr.c +@@ -851,7 +851,7 @@ static Bool _FrameMgrProcessPadding (FrameMgr fm, FmStatus* status) + return True; + } + /*endif*/ +- next_type = FrameInstGetNextType (fm->fi, &info); ++ FrameInstGetNextType (fm->fi, &info); + fm->idx += info.num; + if ((fitr = _FrameIterCounterIncr (fm->iters, info.num))) + _FrameMgrRemoveIter (fm, fitr); +@@ -1525,6 +1525,11 @@ static Iter IterInit (XimFrame frame, int count) + register XimFrameType type; + + it = (Iter) Xmalloc (sizeof (IterRec)); ++ if (!it) { ++ fprintf (stderr, "(XIM-IMdkit) WARNING: malloc failed in %s:%d.\n", ++ __FILE__, __LINE__); ++ return NULL; ++ } + it->template = frame; + it->max_count = (count == NO_VALUE) ? 0 : count; + it->allow_expansion = (count == NO_VALUE); +@@ -1669,8 +1674,15 @@ static Bool IterIsLoopEnd (Iter it, Bool *myself) + + static XimFrameType IterGetNextType (Iter it, XimFrameTypeInfo info) + { +- XimFrameType type = it->template->type; ++ XimFrameType type; ++ ++ if (!it || !it->template) { ++ fprintf (stderr, "(XIM-IMdkit) WARNING: malloc failed in %s:%d.\n", ++ __FILE__, __LINE__); ++ return (XimFrameType) NULL; ++ } + ++ type = it->template->type; + if (it->start_counter) + { + (*it->start_watch_proc) (it, it->client_data); +@@ -1766,7 +1778,15 @@ static XimFrameType IterGetNextType (Iter it, XimFrameTypeInfo info) + + static XimFrameType IterPeekNextType (Iter it, XimFrameTypeInfo info) + { +- XimFrameType type = it->template->type; ++ XimFrameType type; ++ ++ if (!it->template) { ++ fprintf (stderr, "(XIM-IMdkit) WARNING: dereference pointer %s:%d.\n", ++ __FILE__, __LINE__); ++ return (XimFrameType) NULL; ++ } ++ ++ type = it->template->type; + + if (!it->allow_expansion && it->cur_no >= it->max_count) + return (EOL); +@@ -1866,6 +1886,9 @@ static FmStatus IterSetSize (Iter it, int num) + dr.num = NO_VALUE; + d = ChainMgrSetData (&it->cm, i, dr); + } ++ if (!d) { ++ return FmNoMoreData; ++ } + /*endif*/ + if (d->num == NO_VALUE) + { +@@ -2254,6 +2277,11 @@ static ExtraData ChainMgrSetData (ChainMgr cm, + ExtraDataRec data) + { + Chain cur = (Chain) Xmalloc (sizeof (ChainRec)); ++ if (!cur) { ++ fprintf (stderr, "(XIM-IMdkit) WARNING: malloc failed in %s:%d.\n", ++ __FILE__, __LINE__); ++ return NULL; ++ } + + cur->frame_no = frame_no; + cur->d = data; +diff --git a/util/IMdkit/i18nIc.c b/util/IMdkit/i18nIc.c +index 289837a6..14a3dc51 100644 +--- a/util/IMdkit/i18nIc.c ++++ b/util/IMdkit/i18nIc.c +@@ -470,13 +470,16 @@ static XICAttribute *CreateNestedList (CARD16 attr_id, + /*endfor*/ + + nest_list = (XICAttribute *) malloc (sizeof (XICAttribute)); +- if (nest_list == NULL) ++ if (nest_list == NULL) { ++ XFree (values); + return NULL; ++ } + /*endif*/ + memset (nest_list, 0, sizeof (XICAttribute)); + nest_list->value = (void *) malloc (value_length); + if (nest_list->value == NULL) { + XFree (nest_list); ++ XFree (values); + return NULL; + } + /*endif*/ +@@ -539,7 +542,13 @@ static int GetICValue (Xi18n i18n_core, + attr_ret[n].attribute_id = xic_attr[j].attribute_id; + attr_ret[n].name_length = xic_attr[j].length; + attr_ret[n].name = malloc (xic_attr[j].length + 1); +- strcpy(attr_ret[n].name, xic_attr[j].name); ++ if (!attr_ret[n].name) { ++ fprintf (stderr, ++ "(XIM-IMdkit) WARNING: malloc failed in %s:%d.\n", ++ __FILE__, __LINE__); ++ } else { ++ strcpy(attr_ret[n].name, xic_attr[j].name); ++ } + attr_ret[n].type = xic_attr[j].type; + n++; + i++; +@@ -560,7 +569,13 @@ static int GetICValue (Xi18n i18n_core, + attr_ret[n].attribute_id = xic_attr[j].attribute_id; + attr_ret[n].name_length = xic_attr[j].length; + attr_ret[n].name = malloc (xic_attr[j].length + 1); +- strcpy(attr_ret[n].name, xic_attr[j].name); ++ if (!attr_ret[n].name) { ++ fprintf (stderr, ++ "(XIM-IMdkit) WARNING: malloc failed in %s:%d.\n", ++ __FILE__, __LINE__); ++ } else { ++ strcpy(attr_ret[n].name, xic_attr[j].name); ++ } + attr_ret[n].type = xic_attr[j].type; + n++; + break; +@@ -700,10 +715,15 @@ void _Xi18nChangeIC (XIMS ims, + attrib_list[attrib_num].value_length = value_length; + FrameMgrGetToken (fm, value); + attrib_list[attrib_num].value = (void *) malloc (value_length + 1); +- memmove (attrib_list[attrib_num].value, value, value_length); +- ((char *)attrib_list[attrib_num].value)[value_length] = '\0'; ++ if (!attrib_list[attrib_num].value) { ++ fprintf (stderr, "(XIM-IMdkit) WARNING: malloc failed in %s:%d.\n", ++ __FILE__, __LINE__); ++ } else { ++ memmove (attrib_list[attrib_num].value, value, value_length); ++ ((char *)attrib_list[attrib_num].value)[value_length] = '\0'; ++ total_value_length += (value_length + 1); ++ } + attrib_num++; +- total_value_length += (value_length + 1); + } + /*endwhile*/ + +@@ -917,6 +937,12 @@ void _Xi18nGetIC (XIMS ims, IMProtocol *call_data, unsigned char *p) + FrameMgrGetToken (fm, byte_length); + + attrID_list = (CARD16 *) malloc (sizeof (CARD16)*IC_SIZE); /* bogus */ ++ if (!attrID_list) { ++ fprintf (stderr, "(XIM-IMdkit) WARNING: malloc failed in %s:%d.\n", ++ __FILE__, __LINE__); ++ FrameMgrFree (fm); ++ return; ++ } + memset (attrID_list, 0, sizeof (CARD16)*IC_SIZE); + + number = 0; +@@ -1026,7 +1052,7 @@ void _Xi18nGetIC (XIMS ims, IMProtocol *call_data, unsigned char *p) + { + _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0); + XFree (attrID_list); +- FrameMgrFree (fm); ++ goto _Xi18nGetIC_finit; + return; + } + /*endif*/ +@@ -1097,6 +1123,7 @@ void _Xi18nGetIC (XIMS ims, IMProtocol *call_data, unsigned char *p) + } + /*endfor*/ + ++_Xi18nGetIC_finit: + if (preedit_ret) + { + XFree (preedit_ret->value); +diff --git a/util/IMdkit/i18nMethod.c b/util/IMdkit/i18nMethod.c +index 36dd28ac..9c44e7fe 100644 +--- a/util/IMdkit/i18nMethod.c ++++ b/util/IMdkit/i18nMethod.c +@@ -166,8 +166,14 @@ static Bool GetEncodings(Xi18n i18n_core, XIMEncodings **p_encoding) + { + (*p_encoding)->supported_encodings[i] + = (char *) malloc (strlen (p->supported_encodings[i]) + 1); +- strcpy ((*p_encoding)->supported_encodings[i], +- p->supported_encodings[i]); ++ if (!((*p_encoding)->supported_encodings[i])) { ++ fprintf (stderr, "(XIM-IMdkit) WARNING: malloc failed in %s:%d.\n", ++ __FILE__, __LINE__); ++ ++ } else { ++ strcpy ((*p_encoding)->supported_encodings[i], ++ p->supported_encodings[i]); ++ } + } + /*endif*/ + return True; +@@ -187,11 +193,17 @@ 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. ++ */ ++#pragma GCC diagnostic push ++#pragma GCC diagnostic ignored "-Wanalyzer-malloc-leak" + 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) +@@ -199,11 +211,14 @@ 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); + 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) +@@ -211,11 +226,14 @@ 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); + 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) +@@ -698,7 +716,7 @@ static void ReturnSelectionNotify (Xi18n i18n_core, XSelectionRequestEvent *ev) + { + XEvent event; + Display *dpy = i18n_core->address.dpy; +- char buf[4096]; ++ char buf[4096] = { '\0', }; + + event.type = SelectionNotify; + event.xselection.requestor = ev->requestor; +diff --git a/util/IMdkit/i18nOffsetCache.c b/util/IMdkit/i18nOffsetCache.c +index d5379051..e2fe8c6b 100644 +--- a/util/IMdkit/i18nOffsetCache.c ++++ b/util/IMdkit/i18nOffsetCache.c +@@ -94,7 +94,7 @@ void _Xi18nSetPropertyOffset (Xi18nOffsetCache *offset_cache, Atom key, + } + + assert (data != NULL); +- if (offset_cache->size > 0) { ++ if (offset_cache->size > 0 && i < offset_cache->capacity) { + data[i].key = key; + data[i].offset = offset; + } +diff --git a/util/IMdkit/i18nPtHdr.c b/util/IMdkit/i18nPtHdr.c +index eaeeee1c..367cc1e7 100644 +--- a/util/IMdkit/i18nPtHdr.c ++++ b/util/IMdkit/i18nPtHdr.c +@@ -181,8 +181,13 @@ static void OpenMessageProc(XIMS ims, IMProtocol *call_data, unsigned char *p) + FrameMgrGetToken (fm, name); + imopen->lang.length = str_length; + imopen->lang.name = malloc (str_length + 1); +- strncpy (imopen->lang.name, name, str_length); +- imopen->lang.name[str_length] = (char) 0; ++ if (!imopen->lang.name) { ++ fprintf (stderr, "(XIM-IMdkit) WARNING: malloc failed in %s:%d.\n", ++ __FILE__, __LINE__); ++ } else { ++ strncpy (imopen->lang.name, name, str_length); ++ imopen->lang.name[str_length] = (char) 0; ++ } + + FrameMgrFree (fm); + +@@ -339,7 +344,7 @@ static XIMExt *MakeExtensionList (Xi18n i18n_core, + int number, + int *reply_number) + { +- XIMExt *ext_list; ++ XIMExt *ext_list = NULL; + XIMExt *im_ext = (XIMExt *) i18n_core->address.extension; + int im_ext_len = i18n_core->address.ext_num; + int i; +@@ -358,7 +363,8 @@ static XIMExt *MakeExtensionList (Xi18n i18n_core, + { + for (j = 0; j < (int) number; j++) + { +- if (strcmp (lib_extension[j].name, im_ext[i].name) == 0) ++ if (lib_extension[j].name ++ && strcmp (lib_extension[j].name, im_ext[i].name) == 0) + { + (*reply_number)++; + break; +@@ -389,7 +395,13 @@ static XIMExt *MakeExtensionList (Xi18n i18n_core, + ext_list[i].minor_opcode = im_ext[i].minor_opcode; + ext_list[i].length = im_ext[i].length; + ext_list[i].name = malloc (im_ext[i].length + 1); +- strcpy (ext_list[i].name, im_ext[i].name); ++ if (!ext_list[i].name) { ++ fprintf (stderr, ++ "(XIM-IMdkit) WARNING: malloc failed in %s:%d.\n", ++ __FILE__, __LINE__); ++ } else { ++ strcpy (ext_list[i].name, im_ext[i].name); ++ } + } + /*endfor*/ + } +@@ -401,13 +413,20 @@ static XIMExt *MakeExtensionList (Xi18n i18n_core, + { + for (j = 0; j < (int)number; j++) + { +- if (strcmp (lib_extension[j].name, im_ext[i].name) == 0) ++ if (lib_extension[j].name ++ && strcmp (lib_extension[j].name, im_ext[i].name) == 0) + { + ext_list[n].major_opcode = im_ext[i].major_opcode; + ext_list[n].minor_opcode = im_ext[i].minor_opcode; + ext_list[n].length = im_ext[i].length; + ext_list[n].name = malloc (im_ext[i].length + 1); +- strcpy (ext_list[n].name, im_ext[i].name); ++ if (!ext_list[n].name) { ++ fprintf (stderr, ++ "(XIM-IMdkit) WARNING: malloc failed in %s:%d.\n", ++ __FILE__, __LINE__); ++ } else { ++ strcpy (ext_list[n].name, im_ext[i].name); ++ } + n++; + break; + } +@@ -450,6 +469,11 @@ static void QueryExtensionMessageProc (XIMS ims, + FrameMgrGetToken (fm, input_method_ID); + FrameMgrGetToken (fm, byte_length); + query_ext->extension = (XIMStr *) malloc (sizeof (XIMStr)*10); ++ if (!query_ext->extension) { ++ fprintf (stderr, "(XIM-IMdkit) WARNING: malloc failed in %s:%d.\n", ++ __FILE__, __LINE__); ++ return; ++ } + memset (query_ext->extension, 0, sizeof (XIMStr)*10); + number = 0; + while (FrameMgrIsIterLoopEnd (fm, &status) == False) +@@ -461,9 +485,20 @@ static void QueryExtensionMessageProc (XIMS ims, + FrameMgrSetSize (fm, str_length); + query_ext->extension[number].length = str_length; + FrameMgrGetToken (fm, name); ++ /* I don't know why extension[number].name is detected as leak ++ * with -Wanalyzer-malloc-leak option in gcc 11.0.1. ++ */ ++#pragma GCC diagnostic push ++#pragma GCC diagnostic ignored "-Wanalyzer-malloc-leak" + query_ext->extension[number].name = malloc (str_length + 1); +- strncpy (query_ext->extension[number].name, name, str_length); +- query_ext->extension[number].name[str_length] = (char) 0; ++ if (!query_ext->extension[number].name) { ++ fprintf (stderr, "(XIM-IMdkit) WARNING: malloc failed in %s:%d.\n", ++ __FILE__, __LINE__); ++ } else { ++ strncpy (query_ext->extension[number].name, name, str_length); ++ query_ext->extension[number].name[str_length] = (char) 0; ++ } ++#pragma GCC diagnostic pop + number++; + } + /*endwhile*/ +@@ -490,6 +525,8 @@ static void QueryExtensionMessageProc (XIMS ims, + XFree (query_ext->extension[i].name); + /*endfor*/ + XFree (query_ext->extension); ++ if (!ext_list) ++ return; + + fm = FrameMgrInit (query_extension_reply_fr, + NULL, +@@ -501,7 +538,10 @@ static void QueryExtensionMessageProc (XIMS ims, + /* set length of BARRAY item in ext_fr */ + for (i = 0; i < reply_number; i++) + { +- str_size = strlen (ext_list[i].name); ++ if (ext_list[i].name) ++ str_size = strlen (ext_list[i].name); ++ else ++ str_size = 0; + FrameMgrSetSize (fm, str_size); + } + /*endfor*/ +@@ -700,7 +740,13 @@ static XIMAttribute *MakeIMAttributeList (Xi18n i18n_core, + &value_length); + attrib_list[list_num].value_length = value_length; + attrib_list[list_num].value = (void *) malloc (value_length); +- memset(attrib_list[list_num].value, 0, value_length); ++ if (attrib_list[list_num].value) { ++ memset(attrib_list[list_num].value, 0, value_length); ++ } else { ++ fprintf (stderr, ++ "(XIM-IMdkit) WARNING: malloc failed in %s:%d.\n", ++ __FILE__, __LINE__); ++ } + GetIMValueFromName (i18n_core, + connect_id, + attrib_list[list_num].value, +@@ -737,10 +783,10 @@ static void GetIMValuesMessageProc (XIMS ims, + register int i; + register int j; + int number; +- CARD16 *im_attrID_list; +- char **name_list; ++ CARD16 *im_attrID_list = NULL; ++ char **name_list = NULL; + CARD16 name_number; +- XIMAttribute *im_attribute_list; ++ XIMAttribute *im_attribute_list = NULL; + IMGetIMValuesStruct *getim = (IMGetIMValuesStruct *)&call_data->getim; + CARD16 connect_id = call_data->any.connect_id; + CARD16 input_method_ID; +@@ -753,8 +799,18 @@ static void GetIMValuesMessageProc (XIMS ims, + FrameMgrGetToken (fm, input_method_ID); + FrameMgrGetToken (fm, byte_length); + im_attrID_list = (CARD16 *) malloc (sizeof (CARD16)*20); ++ if (!im_attrID_list) { ++ fprintf (stderr, "(XIM-IMdkit) WARNING: malloc failed in %s:%d.\n", ++ __FILE__, __LINE__); ++ goto GetIMValuesMessageProc_finit; ++ } + memset (im_attrID_list, 0, sizeof (CARD16)*20); + name_list = (char **)malloc(sizeof(char *) * 20); ++ if (!name_list) { ++ fprintf (stderr, "(XIM-IMdkit) WARNING: malloc failed in %s:%d.\n", ++ __FILE__, __LINE__); ++ goto GetIMValuesMessageProc_finit; ++ } + memset(name_list, 0, sizeof(char *) * 20); + number = 0; + while (FrameMgrIsIterLoopEnd (fm, &status) == False) +@@ -792,8 +848,11 @@ static void GetIMValuesMessageProc (XIMS ims, + im_attrID_list, + &number, + &list_len); +- if (im_attrID_list) +- XFree (im_attrID_list); ++ if (!im_attribute_list) { ++ fprintf (stderr, "(XIM-IMdkit) WARNING: malloc failed in %s:%d.\n", ++ __FILE__, __LINE__); ++ goto GetIMValuesMessageProc_finit; ++ } + /*endif*/ + + fm = FrameMgrInit (get_im_values_reply_fr, +@@ -815,11 +874,7 @@ static void GetIMValuesMessageProc (XIMS ims, + if (!reply) + { + _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0); +- FrameMgrFree (fm); +- for (i = 0; i < iter_count; i++) +- XFree(im_attribute_list[i].value); +- XFree (im_attribute_list); +- return; ++ goto GetIMValuesMessageProc_finit; + } + /*endif*/ + memset (reply, 0, total_size); +@@ -840,12 +895,17 @@ static void GetIMValuesMessageProc (XIMS ims, + 0, + reply, + total_size); +- FrameMgrFree (fm); + XFree (reply); + +- for (i = 0; i < iter_count; i++) +- XFree(im_attribute_list[i].value); +- XFree (im_attribute_list); ++GetIMValuesMessageProc_finit: ++ if (im_attrID_list) ++ XFree (im_attrID_list); ++ if (im_attribute_list) { ++ for (i = 0; i < iter_count; i++) ++ XFree(im_attribute_list[i].value); ++ XFree (im_attribute_list); ++ } ++ FrameMgrFree (fm); + } + + static void CreateICMessageProc (XIMS ims, +@@ -1435,6 +1495,11 @@ static void EncodingNegotiatonMessageProc (XIMS ims, + if (byte_length > 0) + { + enc_nego->encoding = (XIMStr *) malloc (sizeof (XIMStr)*10); ++ if (!enc_nego->encoding) { ++ fprintf (stderr, "(XIM-IMdkit) WARNING: malloc failed in %s:%d.\n", ++ __FILE__, __LINE__); ++ goto EncodingNegotiatonMessageProc_finit; ++ } + memset (enc_nego->encoding, 0, sizeof (XIMStr)*10); + i = 0; + while (FrameMgrIsIterLoopEnd (fm, &status) == False) +@@ -1446,9 +1511,21 @@ static void EncodingNegotiatonMessageProc (XIMS ims, + FrameMgrSetSize (fm, str_length); + enc_nego->encoding[i].length = str_length; + FrameMgrGetToken (fm, name); ++ /* I don't know why encoding[i].name is detected as leak ++ * with -Wanalyzer-malloc-leak option in gcc 11.0.1. ++ */ ++#pragma GCC diagnostic push ++#pragma GCC diagnostic ignored "-Wanalyzer-malloc-leak" + enc_nego->encoding[i].name = malloc (str_length + 1); ++ if (!(enc_nego->encoding[i].name)) { ++ fprintf (stderr, ++ "(XIM-IMdkit) WARNING: malloc failed in %s:%d.\n", ++ __FILE__, __LINE__); ++ goto EncodingNegotiatonMessageProc_finit; ++ } + strncpy (enc_nego->encoding[i].name, name, str_length); + enc_nego->encoding[i].name[str_length] = '\0'; ++#pragma GCC diagnostic pop + i++; + } + /*endwhile*/ +@@ -1460,20 +1537,37 @@ static void EncodingNegotiatonMessageProc (XIMS ims, + if (byte_length > 0) + { + enc_nego->encodinginfo = (XIMStr *) malloc (sizeof (XIMStr)*10); ++ if (!enc_nego->encodinginfo) { ++ fprintf (stderr, "(XIM-IMdkit) WARNING: malloc failed in %s:%d.\n", ++ __FILE__, __LINE__); ++ goto EncodingNegotiatonMessageProc_finit; ++ } + memset (enc_nego->encodinginfo, 0, sizeof (XIMStr)*10); + i = 0; + while (FrameMgrIsIterLoopEnd (fm, &status) == False) + { + char *name; + int str_length; +- ++ + FrameMgrGetToken (fm, str_length); + FrameMgrSetSize (fm, str_length); + enc_nego->encodinginfo[i].length = str_length; + FrameMgrGetToken (fm, name); ++ /* I don't know why encodinginfo[i].name is detected as leak ++ * with -Wanalyzer-malloc-leak option in gcc 11.0.1. ++ */ ++#pragma GCC diagnostic push ++#pragma GCC diagnostic ignored "-Wanalyzer-malloc-leak" + enc_nego->encodinginfo[i].name = malloc (str_length + 1); ++ if (!enc_nego->encodinginfo[i].name) { ++ fprintf (stderr, ++ "(XIM-IMdkit) WARNING: malloc failed in %s:%d.\n", ++ __FILE__, __LINE__); ++ goto EncodingNegotiatonMessageProc_finit; ++ } + strncpy (enc_nego->encodinginfo[i].name, name, str_length); + enc_nego->encodinginfo[i].name[str_length] = '\0'; ++#pragma GCC diagnostic pop + i++; + } + /*endwhile*/ +@@ -1524,6 +1618,7 @@ static void EncodingNegotiatonMessageProc (XIMS ims, + total_size); + XFree (reply); + ++EncodingNegotiatonMessageProc_finit: + /* free data for encoding list */ + if (enc_nego->encoding) + { +diff --git a/util/IMdkit/i18nUtil.c b/util/IMdkit/i18nUtil.c +index 109dcdf9..c62154e7 100644 +--- a/util/IMdkit/i18nUtil.c ++++ b/util/IMdkit/i18nUtil.c +@@ -46,6 +46,8 @@ _Xi18nNeedSwap (Xi18n i18n_core, CARD16 connect_id) + CARD8 im_byteOrder = i18n_core->address.im_byteOrder; + Xi18nClient *client = _Xi18nFindClient (i18n_core, connect_id); + ++ if (!client) ++ return True; + return (client->byte_order != im_byteOrder); + } + +@@ -67,6 +69,11 @@ Xi18nClient *_Xi18nNewClient(Xi18n i18n_core) + new_connect_id = ++connect_id; + } + /*endif*/ ++ if (!client) { ++ fprintf (stderr, "(XIM-IMdkit) WARNING: malloc failed in %s:%d.\n", ++ __FILE__, __LINE__); ++ return NULL; ++ } + memset (client, 0, sizeof (Xi18nClient)); + client->connect_id = new_connect_id; + client->pending = (XIMPending *) NULL; +@@ -113,7 +120,14 @@ void _Xi18nDeleteClient (Xi18n i18n_core, CARD16 connect_id) + ccp0->next = ccp->next; + /*endif*/ + /* put it back to free list */ ++ /* gcc 11.0.1 warns dereference of NULL with ++ * -Wanalyzer-null-dereference option ++ * but target should not be NULL. ++ */ ++#pragma GCC diagnostic push ++#pragma GCC diagnostic ignored "-Wanalyzer-null-dereference" + target->next = i18n_core->address.free_clients; ++#pragma GCC diagnostic pop + i18n_core->address.free_clients = target; + return; + } +@@ -161,6 +175,12 @@ void _Xi18nSendMessage (XIMS ims, + + reply_length = header_size + length; + reply = (unsigned char *) malloc (reply_length); ++ if (!reply) { ++ _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0); ++ XFree (reply_hdr); ++ FrameMgrFree (fm); ++ return; ++ } + replyp = reply; + memmove (reply, reply_hdr, header_size); + replyp += header_size; +diff --git a/util/IMdkit/i18nX.c b/util/IMdkit/i18nX.c +index 5e5c15fa..152fc4e8 100644 +--- a/util/IMdkit/i18nX.c ++++ b/util/IMdkit/i18nX.c +@@ -58,16 +58,21 @@ static XClient *NewXClient (Xi18n i18n_core, Window new_client) + XClient *x_client; + + x_client = (XClient *) malloc (sizeof (XClient)); +- x_client->client_win = new_client; +- x_client->accept_win = XCreateSimpleWindow (dpy, +- DefaultRootWindow(dpy), +- 0, +- 0, +- 1, +- 1, +- 1, +- 0, +- 0); ++ if (!x_client) { ++ fprintf (stderr, "(XIM-IMdkit) WARNING: malloc failed in %s:%d.\n", ++ __FILE__, __LINE__); ++ } else { ++ x_client->client_win = new_client; ++ x_client->accept_win = XCreateSimpleWindow (dpy, ++ DefaultRootWindow(dpy), ++ 0, ++ 0, ++ 1, ++ 1, ++ 1, ++ 0, ++ 0); ++ } + client->trans_rec = x_client; + return ((XClient *) x_client); + } +@@ -219,7 +224,7 @@ static void ReadXConnectMessage (XIMS ims, XClientMessageEvent *ev) + } + /*endif*/ + _XRegisterFilterByType (dpy, +- x_client->accept_win, ++ x_client ? x_client->accept_win : 0, + ClientMessage, + ClientMessage, + WaitXIMProtocol, +@@ -229,7 +234,7 @@ static void ReadXConnectMessage (XIMS ims, XClientMessageEvent *ev) + event.xclient.window = new_client; + event.xclient.message_type = spec->connect_request; + event.xclient.format = 32; +- event.xclient.data.l[0] = x_client->accept_win; ++ event.xclient.data.l[0] = x_client ? x_client->accept_win : 0; + event.xclient.data.l[1] = major_version; + event.xclient.data.l[2] = minor_version; + event.xclient.data.l[3] = XCM_DATA_LIMIT; +-- +2.28.0 + diff --git a/ibus.spec b/ibus.spec index 01eae44..25493a0 100644 --- a/ibus.spec +++ b/ibus.spec @@ -38,7 +38,7 @@ Name: ibus Version: 1.5.24 -Release: 4%{?dist} +Release: 5%{?dist} Summary: Intelligent Input Bus for Linux OS License: LGPLv2+ URL: https://github.com/ibus/%name/wiki @@ -266,6 +266,8 @@ the functionality of the installed %{name} package. # cp client/gtk2/ibusimcontext.c client/gtk3/ibusimcontext.c || : # cp client/gtk2/ibusim.c client/gtk3/ibusim.c || : # cp client/gtk2/ibusimcontext.c client/gtk4/ibusimcontext.c || : +cp client/gtk2/ibusimcontext.c client/gtk3/ibusimcontext.c || : +cp client/gtk2/ibusimcontext.c client/gtk4/ibusimcontext.c || : # prep test @@ -340,6 +342,10 @@ echo "NoDisplay=true" >> $RPM_BUILD_ROOT%{_datadir}/applications/org.freedesktop %endif #echo "X-GNOME-Autostart-enabled=false" >> $RPM_BUILD_ROOT%%{_sysconfdir}/xdg/autostart/ibus.desktop +HAS_PREFIX=$(grep prefix $RPM_BUILD_ROOT%{_bindir}/ibus-setup | wc -l) +[ x"$HAS_PREFIX" == x1 ] && \ + sed -i -e '/prefix/d' $RPM_BUILD_ROOT%{_bindir}/ibus-setup + desktop-file-install --delete-original \ --dir $RPM_BUILD_ROOT%{_datadir}/applications \ $RPM_BUILD_ROOT%{_datadir}/applications/* @@ -488,6 +494,10 @@ dconf update || : %{_datadir}/installed-tests/ibus %changelog +* Fri May 21 2021 Takao Fujiwara - 1.5.24-5 +- Fix covscan reviews +- Implement ibus_im_context_set_surrounding_with_selection() + * Fri Apr 16 2021 Mohan Boddu - 1.5.24-4 - Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937