summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPierre Ossman <ossman@cendio.se>2015-02-25 11:27:49 +0100
committerPierre Ossman <ossman@cendio.se>2015-02-25 11:27:49 +0100
commit245c8022268ab0111cd0c1eba2d98c83e4261181 (patch)
tree298e15efdd8f8726a29b7384fe10ce37e012606c
parentb5b0ea5771f5eb1c6fef2dba998bb59c430a16b3 (diff)
downloadtigervnc-245c8022268ab0111cd0c1eba2d98c83e4261181.tar.gz
tigervnc-245c8022268ab0111cd0c1eba2d98c83e4261181.zip
Escape FLTK menu entries
We don't want it automatically creating submenus when least expected.
-rw-r--r--vncviewer/OptionsDialog.cxx4
-rw-r--r--vncviewer/Viewport.cxx45
-rw-r--r--vncviewer/fltk_layout.h48
3 files changed, 77 insertions, 20 deletions
diff --git a/vncviewer/OptionsDialog.cxx b/vncviewer/OptionsDialog.cxx
index b9752aa1..9fa9a665 100644
--- a/vncviewer/OptionsDialog.cxx
+++ b/vncviewer/OptionsDialog.cxx
@@ -724,9 +724,9 @@ void OptionsDialog::createInputPage(int tx, int ty, int tw, int th)
menuKeyChoice = new Fl_Choice(LBLLEFT(tx, ty, 150, CHOICE_HEIGHT, _("Menu key")));
- menuKeyChoice->add(_("None"), 0, NULL, (void*)0, FL_MENU_DIVIDER);
+ fltk_menu_add(menuKeyChoice, _("None"), 0, NULL, (void*)0, FL_MENU_DIVIDER);
for (int i = 0; i < getMenuKeySymbolCount(); i++)
- menuKeyChoice->add(getMenuKeySymbols()[i].name, 0, NULL, 0, 0);
+ fltk_menu_add(menuKeyChoice, getMenuKeySymbols()[i].name, 0, NULL, 0, 0);
ty += CHOICE_HEIGHT + TIGHT_MARGIN;
diff --git a/vncviewer/Viewport.cxx b/vncviewer/Viewport.cxx
index 33ba24fe..6c77e583 100644
--- a/vncviewer/Viewport.cxx
+++ b/vncviewer/Viewport.cxx
@@ -1062,39 +1062,48 @@ void Viewport::initContextMenu()
{
contextMenu->clear();
- contextMenu->add(_("E&xit viewer"), 0, NULL, (void*)ID_EXIT, FL_MENU_DIVIDER);
+ fltk_menu_add(contextMenu, _("E&xit viewer"), 0, NULL,
+ (void*)ID_EXIT, FL_MENU_DIVIDER);
#ifdef HAVE_FLTK_FULLSCREEN
- contextMenu->add(_("&Full screen"), 0, NULL, (void*)ID_FULLSCREEN,
- FL_MENU_TOGGLE | (window()->fullscreen_active()?FL_MENU_VALUE:0));
+ fltk_menu_add(contextMenu, _("&Full screen"), 0, NULL, (void*)ID_FULLSCREEN,
+ FL_MENU_TOGGLE | (window()->fullscreen_active()?FL_MENU_VALUE:0));
#endif
- contextMenu->add(_("Resize &window to session"), 0, NULL, (void*)ID_RESIZE,
+ fltk_menu_add(contextMenu, _("Resize &window to session"), 0, NULL,
+ (void*)ID_RESIZE,
#ifdef HAVE_FLTK_FULLSCREEN
- (window()->fullscreen_active()?FL_MENU_INACTIVE:0) |
+ (window()->fullscreen_active()?FL_MENU_INACTIVE:0) |
#endif
- FL_MENU_DIVIDER);
+ FL_MENU_DIVIDER);
- contextMenu->add(_("&Ctrl"), 0, NULL, (void*)ID_CTRL,
- FL_MENU_TOGGLE | (menuCtrlKey?FL_MENU_VALUE:0));
- contextMenu->add(_("&Alt"), 0, NULL, (void*)ID_ALT,
- FL_MENU_TOGGLE | (menuAltKey?FL_MENU_VALUE:0));
+ fltk_menu_add(contextMenu, _("&Ctrl"), 0, NULL, (void*)ID_CTRL,
+ FL_MENU_TOGGLE | (menuCtrlKey?FL_MENU_VALUE:0));
+ fltk_menu_add(contextMenu, _("&Alt"), 0, NULL, (void*)ID_ALT,
+ FL_MENU_TOGGLE | (menuAltKey?FL_MENU_VALUE:0));
if (menuKeySym) {
char sendMenuKey[64];
snprintf(sendMenuKey, 64, _("Send %s"), (const char *)menuKey);
- contextMenu->add(sendMenuKey, 0, NULL, (void*)ID_MENUKEY, 0);
- contextMenu->add("Secret shortcut menu key", menuKeyCode, NULL, (void*)ID_MENUKEY, FL_MENU_INVISIBLE);
+ fltk_menu_add(contextMenu, sendMenuKey, 0, NULL, (void*)ID_MENUKEY, 0);
+ fltk_menu_add(contextMenu, "Secret shortcut menu key", menuKeyCode, NULL,
+ (void*)ID_MENUKEY, FL_MENU_INVISIBLE);
}
- contextMenu->add(_("Send Ctrl-Alt-&Del"), 0, NULL, (void*)ID_CTRLALTDEL, FL_MENU_DIVIDER);
+ fltk_menu_add(contextMenu, _("Send Ctrl-Alt-&Del"), 0, NULL,
+ (void*)ID_CTRLALTDEL, FL_MENU_DIVIDER);
- contextMenu->add(_("&Refresh screen"), 0, NULL, (void*)ID_REFRESH, FL_MENU_DIVIDER);
+ fltk_menu_add(contextMenu, _("&Refresh screen"), 0, NULL,
+ (void*)ID_REFRESH, FL_MENU_DIVIDER);
- contextMenu->add(_("&Options..."), 0, NULL, (void*)ID_OPTIONS, 0);
- contextMenu->add(_("Connection &info..."), 0, NULL, (void*)ID_INFO, 0);
- contextMenu->add(_("About &TigerVNC viewer..."), 0, NULL, (void*)ID_ABOUT, FL_MENU_DIVIDER);
+ fltk_menu_add(contextMenu, _("&Options..."), 0, NULL,
+ (void*)ID_OPTIONS, 0);
+ fltk_menu_add(contextMenu, _("Connection &info..."), 0, NULL,
+ (void*)ID_INFO, 0);
+ fltk_menu_add(contextMenu, _("About &TigerVNC viewer..."), 0, NULL,
+ (void*)ID_ABOUT, FL_MENU_DIVIDER);
- contextMenu->add(_("Dismiss &menu"), 0, NULL, (void*)ID_DISMISS, 0);
+ fltk_menu_add(contextMenu, _("Dismiss &menu"), 0, NULL,
+ (void*)ID_DISMISS, 0);
}
diff --git a/vncviewer/fltk_layout.h b/vncviewer/fltk_layout.h
index c16a359f..21fb00a3 100644
--- a/vncviewer/fltk_layout.h
+++ b/vncviewer/fltk_layout.h
@@ -20,6 +20,7 @@
#define __FLTK_LAYOUT_H__
#include <FL/fl_draw.H>
+#include <FL/Fl_Menu_.H>
/* Calculates the width of a string as printed by FLTK (pixels) */
static inline int gui_str_len(const char *str)
@@ -67,6 +68,53 @@ static inline int fltk_escape(const char *in, char *out, size_t maxlen)
return len;
}
+/* Filter out unsafe characters for menu entries */
+static inline int fltk_menu_escape(const char *in, char *out, size_t maxlen)
+{
+ int len;
+
+ len = 0;
+
+ while (*in != '\0') {
+ if (*in == '/') {
+ if (maxlen >= 3) {
+ *out++ = '\\';
+ *out++ = '/';
+ maxlen -= 2;
+ }
+
+ len += 2;
+ } else {
+ if (maxlen >= 2) {
+ *out++ = *in;
+ maxlen--;
+ }
+
+ len += 1;
+ }
+
+ in++;
+ }
+
+ if (maxlen)
+ *out = '\0';
+
+ return len;
+}
+
+/* Helper to add menu entries safely */
+static inline void fltk_menu_add(Fl_Menu_ *menu, const char *text,
+ int shortcut, Fl_Callback *cb,
+ void *data = 0, int flags = 0)
+{
+ char buffer[1024];
+
+ if (fltk_menu_escape(text, buffer, sizeof(buffer)) >= sizeof(buffer))
+ return;
+
+ menu->add(buffer, shortcut, cb, data, flags);
+}
+
/**** MARGINS ****/
#define OUTER_MARGIN 10