From 214b60a3af67b6e8dafdb8edba666a369f18be12 Mon Sep 17 00:00:00 2001 From: fujiwarat Date: Fri, 26 Mar 2021 22:48:08 +0900 Subject: [PATCH] src/tests: Run gnome-session with no-overview mode gnome-shell 40 now shows the overview mode by login and gnome-desktop-testing-runner cannot get the input focus. Running gnome-session with no-overview shell extension can get the input focus or mutter is another option. The default may be changed to twm if mutter also will be changed not to accept the application focus in the future. Disable Tour dialog which prevent test application from getting the input focus. Don't output FAIL if the actual failure is 0 for Fedora CI. BUG=https://discourse.gnome.org/t/focus-on-autostart-application-by-login/5863 --- src/tests/ibus-desktop-testing-runner.in | 69 ++++++++++++++++++++---- 1 file changed, 60 insertions(+), 9 deletions(-) diff --git a/src/tests/ibus-desktop-testing-runner.in b/src/tests/ibus-desktop-testing-runner.in index 4232c549..15b2369d 100755 --- a/src/tests/ibus-desktop-testing-runner.in +++ b/src/tests/ibus-desktop-testing-runner.in @@ -4,7 +4,7 @@ # # ibus - The Input Bus # -# Copyright (c) 2018-2020 Takao Fujiwara +# Copyright (c) 2018-2021 Takao Fujiwara # Copyright (c) 2018 Red Hat, Inc. # # This program is free software; you can redistribute it and/or modify @@ -36,7 +36,7 @@ PROGNAME=`basename $0` -VERSION=0.1 +VERSION=0.2 DISPLAY=:99.0 BUILDDIR="." SRCDIR="." @@ -80,7 +80,9 @@ usage() "-b, --builddir=BUILDDIR Set the BUILDDIR\n" \ "-s, --srcdir=SOURCEDIR Set the SOURCEDIR\n" \ "-c, --no-graphics Use Xvfb instead of Xorg\n" \ -"-d, --desktop=DESKTOP Run DESTKTOP. The default is gnome-session\n" \ +"-d, --desktop=DESKTOP Run DESTKTOP. The default is gnome-session.\n" \ +" Suffix '-with-dbus' can run DESKTOP with dbus session." \ +" E.g. --desktop=mutter-with-dbus" \ "-t, --tests=\"TESTS...\" Run TESTS programs which is separated by space\n" \ "-r, --runner=RUNNER Run TESTS programs with a test RUNNER.\n" \ " RUNNDER = gnome or default.\n" \ @@ -115,6 +117,13 @@ parse_args() * ) usage; exit 1;; esac done + DL='$' + echo "$DESKTOP_COMMAND" | grep "\-with\-dbus$DL" > /dev/null + HAS_DBUS_SUFFIX=$? + if [ $HAS_DBUS_SUFFIX -eq 0 ] ; then + DESKTOP_COMMAND=`echo "$DESKTOP_COMMAND" | sed -e 's/-with-dbus$//'` + DESKTOP_COMMAND="dbus-launch --exit-with-session $DESKTOP_COMMAND" + fi } init_desktop() @@ -124,8 +133,9 @@ init_desktop() rm $RESULT_LOG fi fi - HAS_STDOUT=`echo "$TEST_LOG" | grep ':stdout'` - if [ x"$HAS_STDOUT" != x ] ; then + echo "$TEST_LOG" | grep ':stdout' > /dev/null + HAS_STDOUT=$? + if [ $HAS_STDOUT -eq 0 ] ; then TEST_LOG=`echo "$TEST_LOG" | sed -e 's|:stdout||'` TEST_LOG_STDOUT=1 fi @@ -203,6 +213,39 @@ run_dbus_daemon() export DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/$UID/bus" } +init_gnome() +{ + # Disable Tour dialog to get focus + V=`gsettings get org.gnome.shell welcome-dialog-last-shown-version` + if [ x"$V" = x ] ; then + gsettings set org.gnome.shell welcome-dialog-last-shown-version '100' + fi + # gnome-shell now starts overview mode by login. + # https://extensions.gnome.org/extension/4099/no-overview/ + NO_SYS_DIR=/usr/share/gnome-shell/extensions/no-overview@fthx + NO_USER_DIR=$HOME/.local/share/gnome-shell/extensions/no-overview@fthx + if [ ! -d $NO_SYS_DIR ] && [ ! -d $NO_USER_DIR ] ; then + mkdir -p `dirname $NO_USER_DIR` + cp -R no-overview@fthx `dirname $NO_USER_DIR` + fi + V=`gsettings get org.gnome.shell disable-user-extensions` + if [ x"$V" = x"true" ] ; then + gsettings set org.gnome.shell disable-user-extensions false + fi + V=`gsettings get org.gnome.shell enabled-extensions` + echo "$V" | grep "no-overview" > /dev/null + V2=$? + if [ $V2 -ne 0 ] ; then + V3=`echo "$V" | sed -e 's/\[//' -e 's/\]//'` + if [ x"$V3" = x ] ; then + V4="['no-overview@fthx']" + else + V4="[$V3, 'no-overview@fthx']" + fi + gsettings set org.gnome.shell enabled-extensions "$V4" + fi +} + run_desktop() { if test $HAVE_GRAPHICS -eq 1 ; then @@ -217,8 +260,11 @@ run_desktop() $DESKTOP_COMMAND & PID_GNOME_SESSION=$! sleep 30 - HAS_GNOME=`echo $DESKTOP_COMMAND | grep gnome-session` - if [ x"$HAS_GNOME" = x ] ; then + echo "$DESKTOP_COMMAND" | grep gnome-session > /dev/null + HAS_GNOME=$? + if [ $HAS_GNOME -eq 0 ] ; then + init_gnome + else ibus-daemon --daemonize --verbose sleep 3 fi @@ -360,8 +406,13 @@ EOF_RUNNER ;; esac echo "" - print_log -e "${GREEN}PASS${NC}: $pass" - print_log -e "${RED}FAIL${NC}: $fail" + # Fedora CI assumes the test is failed even if $fail is 0. + if [ $pass -ne 0 ] ; then + print_log -e "${GREEN}PASS${NC}: $pass" + fi + if [ $fail -ne 0 ] ; then + print_log -e "${RED}FAIL${NC}: $fail" + fi echo "" if [ $TEST_LOG_STDOUT -eq 1 ] ; then cat $TEST_LOG -- 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 e9e1642870994abfdbd06b0138524ac231c159b8 Mon Sep 17 00:00:00 2001 From: fujiwarat Date: Wed, 16 Jun 2021 18:00:31 +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 | 148 ++++++++++++++++++++++++++++------ util/IMdkit/i18nUtil.c | 20 +++++ util/IMdkit/i18nX.c | 29 ++++--- 29 files changed, 524 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..c8250f68 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", strerror (errno)); context = g_option_context_new ("- ibus dconf component"); diff --git a/portal/portal.c b/portal/portal.c index e78bc92f..c2e4fc7f 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", strerror (errno)); 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..8dc52714 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_finit2; + } /*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,18 @@ 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: + FrameMgrFree (fm); +GetIMValuesMessageProc_finit2: + 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); + } } static void CreateICMessageProc (XIMS ims, @@ -1435,6 +1496,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 +1512,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 +1538,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 +1619,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 From bc7811c6247b7bb8eba2f9f80c4f9f1510cd6b65 Mon Sep 17 00:00:00 2001 From: fujiwarat Date: Wed, 16 Jun 2021 20:39:35 +0900 Subject: [PATCH] src/tests: Fix ibus-desktop-testing-runner to get gsettings result gsettings null string is '' and the quote mark needs to be parsed. Also no-overview gsetting should be changed before run gnome-session. --- src/tests/ibus-desktop-testing-runner.in | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/tests/ibus-desktop-testing-runner.in b/src/tests/ibus-desktop-testing-runner.in index 15b2369d..54b7e0d7 100755 --- a/src/tests/ibus-desktop-testing-runner.in +++ b/src/tests/ibus-desktop-testing-runner.in @@ -215,9 +215,11 @@ run_dbus_daemon() init_gnome() { + # gsettings set command needs dconf-service with the same $DISPLAY + pkill dconf-service # Disable Tour dialog to get focus V=`gsettings get org.gnome.shell welcome-dialog-last-shown-version` - if [ x"$V" = x ] ; then + if [ x"$V" = x"''" ] ; then gsettings set org.gnome.shell welcome-dialog-last-shown-version '100' fi # gnome-shell now starts overview mode by login. @@ -237,7 +239,7 @@ init_gnome() V2=$? if [ $V2 -ne 0 ] ; then V3=`echo "$V" | sed -e 's/\[//' -e 's/\]//'` - if [ x"$V3" = x ] ; then + if [ x"$V3" = x"''" ] ; then V4="['no-overview@fthx']" else V4="[$V3, 'no-overview@fthx']" @@ -248,6 +250,8 @@ init_gnome() run_desktop() { + echo "$DESKTOP_COMMAND" | grep gnome-session > /dev/null + HAS_GNOME=$? if test $HAVE_GRAPHICS -eq 1 ; then /usr/libexec/Xorg.wrap -noreset +extension GLX +extension RANDR +extension RENDER -logfile ./xorg.log -config ./xorg.conf -configdir . $DISPLAY & else @@ -256,15 +260,15 @@ run_desktop() PID_XORG=$! sleep 1 export DISPLAY=$DISPLAY + # init_gnome need to be called with $DISPLAY before gnome-session is called + if [ $HAS_GNOME -eq 0 ] ; then + init_gnome + fi echo "Running $DESKTOP_COMMAND with $USER in `tty`" $DESKTOP_COMMAND & PID_GNOME_SESSION=$! sleep 30 - echo "$DESKTOP_COMMAND" | grep gnome-session > /dev/null - HAS_GNOME=$? - if [ $HAS_GNOME -eq 0 ] ; then - init_gnome - else + if [ $HAS_GNOME -ne 0 ] ; then ibus-daemon --daemonize --verbose sleep 3 fi -- 2.28.0 From 9f9c88be46436b0a7aa8e09e044a2223356b46dc Mon Sep 17 00:00:00 2001 From: lf- Date: Fri, 18 Jun 2021 15:39:19 +0900 Subject: [PATCH] src/ibuscomposetable: Add support for the include directive We also fix an issue with excess space at the start of lines stopping comments being recognized. BUG=https://github.com/ibus/ibus/pull/2296 --- src/ibuscomposetable.c | 100 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 95 insertions(+), 5 deletions(-) diff --git a/src/ibuscomposetable.c b/src/ibuscomposetable.c index 685ac717..66a5dfa7 100644 --- a/src/ibuscomposetable.c +++ b/src/ibuscomposetable.c @@ -21,7 +21,6 @@ #include #include -#include #include #include @@ -36,6 +35,7 @@ #define IBUS_COMPOSE_TABLE_MAGIC "IBusComposeTable" #define IBUS_COMPOSE_TABLE_VERSION (3) +#define PATHLEN_MAX 256 typedef struct { gunichar *sequence; @@ -181,7 +181,8 @@ parse_compose_sequence (IBusComposeData *compose_data, int n = 0; if (g_strv_length (words) < 2) { - g_warning ("key sequence format is ...: %s", line); + g_warning ("too few words; key sequence format is ...: %s", + line); goto fail; } @@ -244,10 +245,68 @@ fail: } +static gchar * +expand_include_path (const gchar *include_path) { + gchar *out = g_malloc0 (PATHLEN_MAX); + gchar *out_lastchar = out + PATHLEN_MAX - 2; + const gchar *i = include_path; + gchar *o = out; + + while (*i && o < out_lastchar) { + // expand sequence + if (*i == '%') { + switch (*(i+1)) { + // $HOME + case 'H': { + const gchar *home = getenv ("HOME"); + if (!home) { + g_warning ("while parsing XCompose include target %s, " + "%%H replacement failed because HOME is not " + "defined; the include has been ignored", + include_path); + goto fail; + } + o = out + g_strlcat (out, home, PATHLEN_MAX); + break; + } + // locale compose file + case 'L': + g_warning ("while handling XCompose include target %s, found " + "redundant %%L include; the include has been " + "ignored", include_path); + goto fail; + // system compose dir + case 'S': + o = out + g_strlcat (out, "/usr/share/X11/locale", + PATHLEN_MAX); + break; + // escaped % + case '%': + *o++ = '%'; + break; + default: + g_warning ("while parsing XCompose include target %s, found " + "unknown substitution character '%c'; the include " + "has been ignored", include_path, *(i+1)); + goto fail; + } + i += 2; + } else { + *o++ = *i++; + } + } + return out; +fail: + g_free (out); + return NULL; +} + + static void parse_compose_line (GList **compose_list, const gchar *line, - int *compose_len) + int *compose_len, + gchar **include) { gchar **components = NULL; IBusComposeData *compose_data = NULL; @@ -256,11 +315,32 @@ parse_compose_line (GList **compose_list, g_assert (compose_len); *compose_len = 0; + // eat spaces at the start of the line + while (*line && (*line == ' ' || *line == '\t')) line++; + if (line[0] == '\0' || line[0] == '#') return; - if (g_str_has_prefix (line, "include ")) + if (g_str_has_prefix (line, "include ")) { + const char *rest = line + sizeof ("include ") - 1; + while (*rest && *rest == ' ') rest++; + + // grabbed the path part of the line + char *rest2; + if (*rest == '"') { + rest++; + rest2 = g_strdup (rest); + // eat the closing quote + char *i = rest2; + while (*i && *i != '"') i++; + *i = '\0'; + } else { + rest2 = g_strdup (rest); + } + *include = expand_include_path (rest2); + g_free (rest2); return; + } components = g_strsplit (line, ":", 2); @@ -316,8 +396,18 @@ ibus_compose_list_parse_file (const gchar *compose_file, lines = g_strsplit (contents, "\n", -1); g_free (contents); + gchar *include = NULL; for (i = 0; lines[i] != NULL; i++) { - parse_compose_line (&compose_list, lines[i], &compose_len); + parse_compose_line (&compose_list, lines[i], &compose_len, &include); + if (include && *include) { + GList *rest = ibus_compose_list_parse_file (include, + max_compose_len); + if (rest) { + compose_list = g_list_concat (compose_list, rest); + } + } + + g_clear_pointer (&include, g_free); if (*max_compose_len < compose_len) *max_compose_len = compose_len; } -- 2.28.0 From a755d1601a730b5fa0d463e7820311c12b1f1661 Mon Sep 17 00:00:00 2001 From: fujiwarat Date: Fri, 18 Jun 2021 15:39:50 +0900 Subject: [PATCH] src/ibuscomposetable: Do not include the same compose file BUG=https://github.com/ibus/ibus/pull/2296 --- src/ibuscomposetable.c | 130 +++++++++++++++++++++++++++++++---------- 1 file changed, 100 insertions(+), 30 deletions(-) diff --git a/src/ibuscomposetable.c b/src/ibuscomposetable.c index 66a5dfa7..916fcae3 100644 --- a/src/ibuscomposetable.c +++ b/src/ibuscomposetable.c @@ -34,8 +34,8 @@ #include "ibusenginesimpleprivate.h" #define IBUS_COMPOSE_TABLE_MAGIC "IBusComposeTable" -#define IBUS_COMPOSE_TABLE_VERSION (3) -#define PATHLEN_MAX 256 +#define IBUS_COMPOSE_TABLE_VERSION (4) +#define X11_DATADIR X11_DATA_PREFIX "/share/X11/locale" typedef struct { gunichar *sequence; @@ -247,17 +247,15 @@ fail: static gchar * expand_include_path (const gchar *include_path) { - gchar *out = g_malloc0 (PATHLEN_MAX); - gchar *out_lastchar = out + PATHLEN_MAX - 2; - const gchar *i = include_path; - gchar *o = out; + gchar *out = strdup (""); + const gchar *head, *i; + gchar *former, *o; - while (*i && o < out_lastchar) { - // expand sequence + for (head = i = include_path; *i; ++i) { + /* expand sequence */ if (*i == '%') { - switch (*(i+1)) { - // $HOME - case 'H': { + switch (*(i + 1)) { + case 'H': { /* $HOME */ const gchar *home = getenv ("HOME"); if (!home) { g_warning ("while parsing XCompose include target %s, " @@ -266,23 +264,34 @@ expand_include_path (const gchar *include_path) { include_path); goto fail; } - o = out + g_strlcat (out, home, PATHLEN_MAX); + o = out; + former = g_strndup (head, i - head); + out = g_strdup_printf ("%s%s%s", o, former, home); + head = i + 2; + g_free (o); + g_free (former); break; } - // locale compose file - case 'L': + case 'L': /* locale compose file */ g_warning ("while handling XCompose include target %s, found " "redundant %%L include; the include has been " "ignored", include_path); goto fail; - // system compose dir - case 'S': - o = out + g_strlcat (out, "/usr/share/X11/locale", - PATHLEN_MAX); + case 'S': /* system compose dir */ + o = out; + former = g_strndup (head, i - head); + out = g_strdup_printf ("%s%s%s", o, former, X11_DATADIR); + head = i + 2; + g_free (o); + g_free (former); break; - // escaped % - case '%': - *o++ = '%'; + case '%': /* escaped % */ + o = out; + former = g_strndup (head, i - head); + out = g_strdup_printf ("%s%s%s", o, former, "%"); + head = i + 2; + g_free (o); + g_free (former); break; default: g_warning ("while parsing XCompose include target %s, found " @@ -290,11 +299,12 @@ expand_include_path (const gchar *include_path) { "has been ignored", include_path, *(i+1)); goto fail; } - i += 2; - } else { - *o++ = *i++; + ++i; } } + o = out; + out = g_strdup_printf ("%s%s", o, head); + g_free (o); return out; fail: g_free (out); @@ -315,7 +325,7 @@ parse_compose_line (GList **compose_list, g_assert (compose_len); *compose_len = 0; - // eat spaces at the start of the line + /* eat spaces at the start of the line */ while (*line && (*line == ' ' || *line == '\t')) line++; if (line[0] == '\0' || line[0] == '#') @@ -325,12 +335,12 @@ parse_compose_line (GList **compose_list, const char *rest = line + sizeof ("include ") - 1; while (*rest && *rest == ' ') rest++; - // grabbed the path part of the line + /* grabbed the path part of the line */ char *rest2; if (*rest == '"') { rest++; rest2 = g_strdup (rest); - // eat the closing quote + /* eat the closing quote */ char *i = rest2; while (*i && *i != '"') i++; *i = '\0'; @@ -374,6 +384,23 @@ fail: } +static gchar * +get_en_compose_file (void) +{ + gchar * const sys_langs[] = { "en_US.UTF-8", "en_US", "en.UTF-8", + "en", NULL }; + gchar * const *sys_lang = NULL; + gchar *path = NULL; + for (sys_lang = sys_langs; *sys_lang; sys_lang++) { + path = g_build_filename (X11_DATADIR, *sys_lang, "Compose", NULL); + if (g_file_test (path, G_FILE_TEST_EXISTS)) + break; + g_free (path); + } + return path; +} + + static GList * ibus_compose_list_parse_file (const gchar *compose_file, int *max_compose_len) @@ -399,6 +426,52 @@ ibus_compose_list_parse_file (const gchar *compose_file, gchar *include = NULL; for (i = 0; lines[i] != NULL; i++) { parse_compose_line (&compose_list, lines[i], &compose_len, &include); + if (*max_compose_len < compose_len) + *max_compose_len = compose_len; + if (include && *include) { + GStatBuf buf_include = { 0, }; + GStatBuf buf_parent = { 0, }; + gchar *en_compose; + errno = 0; + if (g_stat (include, &buf_include)) { + g_warning ("Cannot access %s: %s", + include, + g_strerror (errno)); + g_clear_pointer (&include, g_free); + continue; + } + errno = 0; + if (g_stat (compose_file, &buf_parent)) { + g_warning ("Cannot access %s: %s", + compose_file, + g_strerror (errno)); + g_clear_pointer (&include, g_free); + continue; + } + if (buf_include.st_ino == buf_parent.st_ino) { + g_warning ("Found recursive nest same file %s", include); + g_clear_pointer (&include, g_free); + continue; + } + en_compose = get_en_compose_file (); + if (en_compose) { + errno = 0; + if (g_stat (en_compose, &buf_parent)) { + g_warning ("Cannot access %s: %s", + compose_file, + g_strerror (errno)); + g_clear_pointer (&include, g_free); + g_free (en_compose); + continue; + } + } + g_free (en_compose); + if (buf_include.st_ino == buf_parent.st_ino) { + g_log ("System en_US Compose is already loaded %s\n", include); + g_clear_pointer (&include, g_free); + continue; + } + } if (include && *include) { GList *rest = ibus_compose_list_parse_file (include, max_compose_len); @@ -406,10 +479,7 @@ ibus_compose_list_parse_file (const gchar *compose_file, compose_list = g_list_concat (compose_list, rest); } } - g_clear_pointer (&include, g_free); - if (*max_compose_len < compose_len) - *max_compose_len = compose_len; } g_strfreev (lines); -- 2.28.0 From 7f09379b3cb69c7de6d8d667ce398dcfc0000433 Mon Sep 17 00:00:00 2001 From: lf- Date: Thu, 24 Jun 2021 16:10:12 +0900 Subject: [PATCH] src/ibuscomposetable: Fix a buffer overflow in compose handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I believe this has no security impact but it is making my Valgrind sad. Thanks to Omni for the help in finding the root cause of this. ~/.XCompose is: ``` : "η" : "ϑ" : "ɣ" ``` BUG=https://github.com/ibus/ibus/pull/2297 --- src/ibuscomposetable.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/ibuscomposetable.c b/src/ibuscomposetable.c index 916fcae3..dd7cbf83 100644 --- a/src/ibuscomposetable.c +++ b/src/ibuscomposetable.c @@ -410,7 +410,6 @@ ibus_compose_list_parse_file (const gchar *compose_file, gsize length = 0; GError *error = NULL; GList *compose_list = NULL; - int compose_len = 0; int i; g_assert (max_compose_len); @@ -423,8 +422,9 @@ ibus_compose_list_parse_file (const gchar *compose_file, lines = g_strsplit (contents, "\n", -1); g_free (contents); - gchar *include = NULL; for (i = 0; lines[i] != NULL; i++) { + int compose_len = 0; + gchar *include = NULL; parse_compose_line (&compose_list, lines[i], &compose_len, &include); if (*max_compose_len < compose_len) *max_compose_len = compose_len; @@ -467,7 +467,8 @@ ibus_compose_list_parse_file (const gchar *compose_file, } g_free (en_compose); if (buf_include.st_ino == buf_parent.st_ino) { - g_log ("System en_US Compose is already loaded %s\n", include); + g_message ("System en_US Compose is already loaded %s\n", + include); g_clear_pointer (&include, g_free); continue; } @@ -583,12 +584,20 @@ ibus_compose_data_compare (gpointer a, IBusComposeData *compose_data_b = b; int max_compose_len = GPOINTER_TO_INT (data); int i; + /* The allocation length of compose_data_a->sequence[] is different from + * one of compose_data_b->sequence[] and max_compose_len indicates + * the sequence length only but not include the compose value length. + * So max_compose_len is greater than any allocation lengths of sequence[] + * and this API should return if code_a or code_b is 0. + */ for (i = 0; i < max_compose_len; i++) { gunichar code_a = compose_data_a->sequence[i]; gunichar code_b = compose_data_b->sequence[i]; if (code_a != code_b) return code_a - code_b; + if (code_a == 0 && code_b == 0) + return 0; } return 0; } -- 2.28.0 From ab6b9587a497e9662a2936df3dabed4582eeabdb Mon Sep 17 00:00:00 2001 From: fujiwarat Date: Tue, 29 Jun 2021 12:40:20 +0900 Subject: [PATCH] src/tests: Delete G_MESSAGES_DEBUG in desktop-testing for gsettings G_MESSAGES_DEBUG message could be appended to the output of gsettings command and it's not useful to check the output. --- src/tests/ibus-desktop-testing-runner.in | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/tests/ibus-desktop-testing-runner.in b/src/tests/ibus-desktop-testing-runner.in index 54b7e0d7..0ef72c03 100755 --- a/src/tests/ibus-desktop-testing-runner.in +++ b/src/tests/ibus-desktop-testing-runner.in @@ -217,6 +217,10 @@ init_gnome() { # gsettings set command needs dconf-service with the same $DISPLAY pkill dconf-service + # G_MESSAGES_DEBUG=all or G_MESSAGES_DEBUG=GLib-GIO-DEBUG would append + # debug messages to gsettings output and could not get the result correctly. + backup_G_MESSAGES_DEBUG="$G_MESSAGES_DEBUG" + export -n G_MESSAGES_DEBUG='' # Disable Tour dialog to get focus V=`gsettings get org.gnome.shell welcome-dialog-last-shown-version` if [ x"$V" = x"''" ] ; then @@ -238,14 +242,17 @@ init_gnome() echo "$V" | grep "no-overview" > /dev/null V2=$? if [ $V2 -ne 0 ] ; then - V3=`echo "$V" | sed -e 's/\[//' -e 's/\]//'` - if [ x"$V3" = x"''" ] ; then + V3=`echo "$V" | sed -e 's/@as //' -e 's/\[//' -e 's/\]//'` + if [ x"$V3" = x"''" ] || [ x"$V3" = x"" ]; then V4="['no-overview@fthx']" else V4="[$V3, 'no-overview@fthx']" fi gsettings set org.gnome.shell enabled-extensions "$V4" fi + if [ x"$backup_G_MESSAGES_DEBUG" != x ] ; then + export G_MESSAGES_DEBUG="$backup_G_MESSAGES_DEBUG" + fi } run_desktop() -- 2.28.0 From b952d30a1b7c741052c168fe1081ecb4d4b1c034 Mon Sep 17 00:00:00 2001 From: fujiwarat Date: Wed, 14 Jul 2021 22:31:47 +0900 Subject: [PATCH] Change default Emoji shortcut key The shortcut key was Ctrl-Shit-e to follow Unicode code point shortcut key but now the shorcut key is changed to Ctrl-period to follow GTK. BUG=https://github.com/ibus/ibus/issues/2325 --- data/dconf/org.freedesktop.ibus.gschema.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/dconf/org.freedesktop.ibus.gschema.xml b/data/dconf/org.freedesktop.ibus.gschema.xml index a79e9296..099b9c60 100644 --- a/data/dconf/org.freedesktop.ibus.gschema.xml +++ b/data/dconf/org.freedesktop.ibus.gschema.xml @@ -183,7 +183,7 @@ The shortcut keys for turning Unicode typing on or off - [ '<Control><Shift>e' ] + [ '<Control>period' ] Emoji shortcut keys for gtk_accelerator_parse The shortcut keys for turning emoji typing on or off -- 2.28.0