From d356baebea8b3aeff8b20dd513c81b34f5f3826b Mon Sep 17 00:00:00 2001 From: Iain Patterson Date: Tue, 29 May 2012 13:21:23 +0000 Subject: [PATCH] Bugs with readMenu*(). MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit readMenuPipe() was calling freeline() on stuff which might be uninitialised, causing a crash if no valid input was read. readMenuPipe() was trying to snprintf() on an uninitialised pointer. We now use a fixed-length buffer like the other readMenu*() functions. Various memory leaks in readMenu*() functions have been fixed. There are still some lurking around but most have been removed. The original report from Charles Philip Chan on 22 May 2012 says that: "Window Maker crashes when I try to open a sub-menu auto-generated by using: xdg_menu --format WindowMaker --charset UTF-8" There was also a report from Amadeusz Sławiński on 24 May 2012 stating that wmaker crashes using: % cat test.sh cat << EOF Test MENU stuff EXEC true Test END EOF % grep test GNUstep/Defaults/WMRootMenu ("Generated Submenu", OPEN_MENU, "|| /home/amade/test.sh") Error is: wmaker(MonitorLoop(monitor.c:134)): warning: Window Maker exited due to a crash (signal 11) and will be restarted. --- src/rootmenu.c | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/src/rootmenu.c b/src/rootmenu.c index aec9ed16..c32411d7 100644 --- a/src/rootmenu.c +++ b/src/rootmenu.c @@ -994,8 +994,9 @@ static WMenu *parseCascade(WScreen * scr, WMenu * menu, FILE * file, char *file_ separateline(line, &title, &command, ¶ms, &shortcut); if (command == NULL || !command[0]) { - freeline(title, command, params, shortcut); wwarning(_("%s:missing command in menu config: %s"), file_name, line); + freeline(title, command, params, shortcut); + wfree(line); goto error; } @@ -1006,7 +1007,7 @@ static WMenu *parseCascade(WScreen * scr, WMenu * menu, FILE * file, char *file_ cascade = wMenuCreate(scr, M_(title), False); cascade->on_destroy = removeShortcutsForMenu; - if (parseCascade(scr, cascade, file, file_name) == NULL) { + if (!parseCascade(scr, cascade, file, file_name)) { wMenuDestroy(cascade, True); } else { wMenuEntrySetCascade(menu, wMenuAddCallback(menu, M_(title), NULL, NULL), cascade); @@ -1014,12 +1015,14 @@ static WMenu *parseCascade(WScreen * scr, WMenu * menu, FILE * file, char *file_ } else if (strcasecmp(command, "END") == 0) { /* end of menu */ freeline(title, command, params, shortcut); + wfree(line); return menu; } else { /* normal items */ addMenuEntry(menu, M_(title), shortcut, command, params, file_name); } freeline(title, command, params, shortcut); + wfree(line); } wwarning(_("%s:syntax error in menu file:END declaration missing"), file_name); @@ -1071,6 +1074,8 @@ static WMenu *readMenuFile(WScreen * scr, char *file_name) if (command == NULL || !command[0]) { wwarning(_("%s:missing command in menu config: %s"), file_name, line); + freeline(title, command, params, shortcut); + wfree(line); break; } if (strcasecmp(command, "MENU") == 0) { @@ -1078,14 +1083,20 @@ static WMenu *readMenuFile(WScreen * scr, char *file_name) menu->on_destroy = removeShortcutsForMenu; if (!parseCascade(scr, menu, file, file_name)) { wMenuDestroy(menu, True); + menu = NULL; } + freeline(title, command, params, shortcut); + wfree(line); break; } else { wwarning(_("%s:invalid menu file. MENU command is missing"), file_name); + freeline(title, command, params, shortcut); + wfree(line); break; } + freeline(title, command, params, shortcut); + wfree(line); } - freeline(title, command, params, shortcut); #ifdef USECPP if (cpp) { @@ -1112,6 +1123,7 @@ static WMenu *readMenuPipe(WScreen * scr, char **file_name) char *line; char *filename; char flat_file[MAXLINE]; + char cmd[MAXLINE]; int i; #ifdef USECPP char *args; @@ -1131,10 +1143,10 @@ static WMenu *readMenuPipe(WScreen * scr, char **file_name) if (!args) { wwarning(_("could not make arguments for menu file preprocessor")); } else { - snprintf(command, sizeof(command), "%s | %s %s", filename, CPP_PATH, args); + snprintf(cmd, sizeof(cmd), "%s | %s %s", filename, CPP_PATH, args); wfree(args); - file = popen(command, "r"); + file = popen(cmd, "r"); if (!file) { werror(_("%s:could not open/preprocess menu file"), filename); } @@ -1156,6 +1168,8 @@ static WMenu *readMenuPipe(WScreen * scr, char **file_name) if (command == NULL || !command[0]) { wwarning(_("%s:missing command in menu config: %s"), filename, line); + freeline(title, command, params, shortcut); + wfree(line); break; } if (strcasecmp(command, "MENU") == 0) { @@ -1163,14 +1177,21 @@ static WMenu *readMenuPipe(WScreen * scr, char **file_name) menu->on_destroy = removeShortcutsForMenu; if (!parseCascade(scr, menu, file, filename)) { wMenuDestroy(menu, True); + menu = NULL; } + freeline(title, command, params, shortcut); + wfree(line); break; } else { wwarning(_("%s:no title given for the root menu"), filename); + freeline(title, command, params, shortcut); + wfree(line); break; } + + freeline(title, command, params, shortcut); + wfree(line); } - freeline(title, command, params, shortcut); pclose(file);