summaryrefslogtreecommitdiff
path: root/ui
diff options
context:
space:
mode:
authorPeter Wu <peter@lekensteyn.nl>2014-12-18 12:31:49 +0100
committerBalint Reczey <balint@balintreczey.hu>2015-01-11 17:45:48 +0000
commit74b20dca8c255672259d0c43004665d1e9f192dd (patch)
tree97e5562c9d076f93ff36b0adf4922a6c9cc78c67 /ui
parentae2888aeb2b418c9f627b553d0022b5250ca16d2 (diff)
downloadwireshark-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.c60
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;
}