From e58334995691797db5e5942785817ba5341babb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Fri, 10 Apr 2020 09:54:02 +0200 Subject: [PATCH] accelgroup: Restructure gtk_accelerator_name To fix invalid reads and make the function a bit shorter while we're at it. Fixes #2602 --- gtk/gtkaccelgroup.c | 89 +++++++++++++++++++-------------------------- 1 file changed, 37 insertions(+), 52 deletions(-) diff --git a/gtk/gtkaccelgroup.c b/gtk/gtkaccelgroup.c index 964974abb4..a941b6055c 100644 --- a/gtk/gtkaccelgroup.c +++ b/gtk/gtkaccelgroup.c @@ -570,20 +570,28 @@ gtk_accelerator_name_with_keycode (GdkDisplay *display, * * Returns: a newly-allocated accelerator name */ -gchar* +char * gtk_accelerator_name (guint accelerator_key, GdkModifierType accelerator_mods) { - static const gchar text_shift[] = ""; - static const gchar text_control[] = ""; - static const gchar text_alt[] = ""; - static const gchar text_meta[] = ""; - static const gchar text_super[] = ""; - static const gchar text_hyper[] = ""; + static const struct { + guint mask; + const char *text; + gsize text_len; + } mask_text[] = { + { GDK_SHIFT_MASK, "", strlen ("") }, + { GDK_CONTROL_MASK, "", strlen ("") }, + { GDK_ALT_MASK, "", strlen ("") }, + { GDK_META_MASK, "", strlen ("") }, + { GDK_SUPER_MASK, "", strlen ("") }, + { GDK_HYPER_MASK, "", strlen ("") } + }; GdkModifierType saved_mods; guint l; + guint name_len; const char *keyval_name; - gchar *accelerator; + char *accelerator; + int i; accelerator_mods &= GDK_MODIFIER_MASK; @@ -591,57 +599,34 @@ gtk_accelerator_name (guint accelerator_key, if (!keyval_name) keyval_name = ""; - saved_mods = accelerator_mods; - l = strlen (keyval_name); - if (accelerator_mods & GDK_SHIFT_MASK) - l += sizeof (text_shift) - 1; - if (accelerator_mods & GDK_CONTROL_MASK) - l += sizeof (text_control) - 1; - if (accelerator_mods & GDK_ALT_MASK) - l += sizeof (text_alt) - 1; - if (accelerator_mods & GDK_META_MASK) - l += sizeof (text_meta) - 1; - if (accelerator_mods & GDK_HYPER_MASK) - l += sizeof (text_hyper) - 1; - if (accelerator_mods & GDK_SUPER_MASK) - l += sizeof (text_super) - 1; + name_len = strlen (keyval_name); - accelerator = g_new (gchar, l + 1); + saved_mods = accelerator_mods; + for (i = 0; i < G_N_ELEMENTS (mask_text); i++) + { + if (accelerator_mods & mask_text[i].mask) + name_len += mask_text[i].text_len; + } + + if (name_len == 0) + return g_strdup (keyval_name); + + name_len += 1; /* NUL byte */ + accelerator = g_new (char, name_len); accelerator_mods = saved_mods; l = 0; - accelerator[l] = 0; - if (accelerator_mods & GDK_SHIFT_MASK) + for (i = 0; i < G_N_ELEMENTS (mask_text); i++) { - strcpy (accelerator + l, text_shift); - l += sizeof (text_shift) - 1; - } - if (accelerator_mods & GDK_CONTROL_MASK) - { - strcpy (accelerator + l, text_control); - l += sizeof (text_control) - 1; - } - if (accelerator_mods & GDK_ALT_MASK) - { - strcpy (accelerator + l, text_alt); - l += sizeof (text_alt) - 1; - } - if (accelerator_mods & GDK_META_MASK) - { - strcpy (accelerator + l, text_meta); - l += sizeof (text_meta) - 1; - } - if (accelerator_mods & GDK_HYPER_MASK) - { - strcpy (accelerator + l, text_hyper); - l += sizeof (text_hyper) - 1; - } - if (accelerator_mods & GDK_SUPER_MASK) - { - strcpy (accelerator + l, text_super); - l += sizeof (text_super) - 1; + if (accelerator_mods & mask_text[i].mask) + { + strcpy (accelerator + l, mask_text[i].text); + l += mask_text[i].text_len; + } } + strcpy (accelerator + l, keyval_name); + accelerator[name_len - 1] = '\0'; return accelerator; }