diff options
author | Peter Wu <peter@lekensteyn.nl> | 2014-12-18 12:31:49 +0100 |
---|---|---|
committer | Balint Reczey <balint@balintreczey.hu> | 2015-01-11 17:45:48 +0000 |
commit | 74b20dca8c255672259d0c43004665d1e9f192dd (patch) | |
tree | 97e5562c9d076f93ff36b0adf4922a6c9cc78c67 /ui | |
parent | ae2888aeb2b418c9f627b553d0022b5250ca16d2 (diff) | |
download | wireshark-74b20dca8c255672259d0c43004665d1e9f192dd.tar.gz |
gtk: fix crash on Broadway GDK backend
The Broadway GDK backend does never sets event->string. This results in
a crash when filter_string_te_key_pressed_cb tries to read its contents.
Since the documentation marks reading the string as deprecated, try to
handle the character conversion here. It is based on
_gdk_x11_event_translate_keyboard_string (from gtk+), but without trying
to interpret Escape as '\033', and without trying to convert control
characters (example: Ctrl + 1). A buffer of 6 bytes is used to hold a
UTF-8 code point (there is no zero terminator, so 7 bytes as found in
the original implementation is unnecessary).
As g_locale_from_utf8 returns dynamically allocated memory, change the
control flow to have a single exit point where pointers are freed as
needed.
Reproduce with gtk3:
$ broadwayd :5
$ GDK_BACKEND=broadway BROADWAY_DISPLAY=:5 wireshark-gtk
(now open http://localhost:8085/ and start typing in the display filter)
Keys tested: e € (AltGr + 5) ü (AltGr + ", u)
In the X11 backend, these still get displayed correctly. In the broadway
backend however, the accents are missing due to a bug in the broadway
implementation.
Change-Id: Ic1f0ee2b87cd573023ee8e966f06489b3b744dcf
Reviewed-on: https://code.wireshark.org/review/5832
Reviewed-by: Balint Reczey <balint@balintreczey.hu>
Diffstat (limited to 'ui')
-rw-r--r-- | ui/gtk/filter_autocomplete.c | 60 |
1 files changed, 34 insertions, 26 deletions
diff --git a/ui/gtk/filter_autocomplete.c b/ui/gtk/filter_autocomplete.c index 91048aa052..cf79b4f90b 100644 --- a/ui/gtk/filter_autocomplete.c +++ b/ui/gtk/filter_autocomplete.c @@ -29,6 +29,7 @@ #include <string.h> +#include <glib.h> #include <gtk/gtk.h> #include <gdk/gdkkeysyms.h> #if GTK_CHECK_VERSION(3,0,0) @@ -342,10 +343,15 @@ filter_string_te_key_pressed_cb(GtkWidget *filter_te, GdkEventKey *event, gpoint GtkTreeSelection *selection; GtkTreeIter iter; gchar* prefix; - gchar* prefix_start; + gchar* prefix_start = NULL; gboolean stop_propagation = FALSE; guint k; - gchar ckey; + guint32 ckey = '\0'; + gint string_buf_len; + gchar string_buf[6]; /* g_unichar_to_utf8 needs 6 bytes to convert a single + char to a code point. (ISO/IEC 10646 defines this + maximum byte length, RFC 3629 changed this to 4) */ + gchar *key_string = NULL; gint pos; w_toplevel = gtk_widget_get_toplevel(filter_te); @@ -353,11 +359,18 @@ filter_string_te_key_pressed_cb(GtkWidget *filter_te, GdkEventKey *event, gpoint popup_win = (GtkWidget *)g_object_get_data(G_OBJECT(w_toplevel), E_FILT_AUTOCOMP_PTR_KEY); k = event->keyval; - ckey = event->string[0]; + if (k != GDK_KEY_VoidSymbol) { + ckey = gdk_keyval_to_unicode(k); + string_buf_len = g_unichar_to_utf8(ckey, string_buf); + key_string = + g_locale_from_utf8(string_buf, string_buf_len, NULL, NULL, NULL); + } + if (!key_string) + key_string = g_strdup(""); /* If the pressed key is SHIFT then we have nothing to do with the pressed key. */ if( k == GDK_Shift_L || k == GDK_Shift_R) - return FALSE; + goto exit; if (popup_win) gtk_widget_show(popup_win); @@ -420,14 +433,13 @@ filter_string_te_key_pressed_cb(GtkWidget *filter_te, GdkEventKey *event, gpoint gtk_widget_destroy (popup_win); } - name_with_period = g_strconcat(prefix, event->string, NULL); + name_with_period = g_strconcat(prefix, key_string, NULL); popup_win = filter_autocomplete_new(filter_te, name_with_period, FALSE, &stop_propagation); g_object_set_data(G_OBJECT(w_toplevel), E_FILT_AUTOCOMP_PTR_KEY, popup_win); g_free(name_with_period); - g_free(prefix_start); - return stop_propagation; + goto exit; } } else if(k==GDK_BackSpace && !popup_win) { @@ -443,11 +455,9 @@ filter_string_te_key_pressed_cb(GtkWidget *filter_te, GdkEventKey *event, gpoint } } - g_free(prefix_start); - - return FALSE; + goto exit; } else if(g_ascii_isalnum(ckey) && !popup_win) { - gchar *name = g_strconcat(prefix, event->string, NULL); + gchar *name = g_strconcat(prefix, key_string, NULL); if( !strchr(name, '.') && is_protocol_name_being_typed(filter_te, (int) strlen(name)) ) { popup_win = filter_autocomplete_new(filter_te, name, TRUE, &stop_propagation); @@ -455,16 +465,14 @@ filter_string_te_key_pressed_cb(GtkWidget *filter_te, GdkEventKey *event, gpoint } g_free(name); - g_free(prefix_start); - return stop_propagation; + goto exit; } /* If the popup window hasn't been constructed yet then we have nothing to do */ if( !popup_win ) { - g_free(prefix_start); - - return FALSE; + stop_propagation = FALSE; + goto exit; } @@ -507,10 +515,9 @@ filter_string_te_key_pressed_cb(GtkWidget *filter_te, GdkEventKey *event, gpoint gtk_tree_path_free(path); } - g_free(prefix_start); - /* stop event propagation */ - return TRUE; + stop_propagation = TRUE; + goto exit; case GDK_Page_Up: case GDK_Up: @@ -547,10 +554,9 @@ filter_string_te_key_pressed_cb(GtkWidget *filter_te, GdkEventKey *event, gpoint gtk_tree_path_free(path); } - g_free(prefix_start); - /* stop event propagation */ - return TRUE; + stop_propagation = TRUE; + goto exit; } @@ -571,9 +577,9 @@ filter_string_te_key_pressed_cb(GtkWidget *filter_te, GdkEventKey *event, gpoint autocomplete_protocol_string(filter_te, value); g_free(value); } - if(k != GDK_space) { - stop_propagation = TRUE; /* stop event propagation */ - } + if(k != GDK_space) { + stop_propagation = TRUE; /* stop event propagation */ + } } /* Lose popup */ @@ -588,7 +594,7 @@ filter_string_te_key_pressed_cb(GtkWidget *filter_te, GdkEventKey *event, gpoint default: { gchar* updated_str; - updated_str = g_strconcat(prefix, event->string, NULL); + updated_str = g_strconcat(prefix, key_string, NULL); if( !autocompletion_list_lookup(filter_te, popup_win, treeview, updated_str, &stop_propagation) ) { /* function returned false, ie the list is empty -> close popup */ gtk_widget_destroy(popup_win); @@ -600,7 +606,9 @@ filter_string_te_key_pressed_cb(GtkWidget *filter_te, GdkEventKey *event, gpoint } +exit: g_free(prefix_start); + g_free(key_string); return stop_propagation; } |