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;