hw/xwin: Fix a crash trying to reload window icons when not in multiwindow mode

ReloadEnumWindowsProc() accesses window privates, which are only valid in
multiwindow mode, but is called in all modes.

Fix this potential crash by not doing this unless in multiwindow mode.

Reproduction steps:
1/ XWin -mwextwm
2/ Run a client which creates an X window e.g. xterm
3/ Right click on notification area icon, and choose 'Reload .XWinrc' from the menu

Signed-off-by: Jon Turney <jon.turney@dronecode.org.uk>
Reviewed-by: Colin Harrison <colin.harrison@virgin.net>
This commit is contained in:
Jon Turney 2016-02-26 18:03:04 +00:00
parent 91ae257145
commit 0a0c1bd932
4 changed files with 26 additions and 16 deletions

View File

@ -428,7 +428,7 @@ winTopLevelWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
/*
* Any window menu items go through here
*/
if (HandleCustomWM_COMMAND(hwnd, LOWORD(wParam))) {
if (HandleCustomWM_COMMAND(hwnd, LOWORD(wParam), s_pScreenPriv)) {
/* Don't pass customized menus to DefWindowProc */
return 0;
}

View File

@ -206,18 +206,21 @@ ReloadEnumWindowsProc(HWND hwnd, LPARAM lParam)
* Set custom icons and menus again.
*/
static void
ReloadPrefs(void)
ReloadPrefs(winPrivScreenPtr pScreenPriv)
{
int i;
#ifdef XWIN_MULTIWINDOW
winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
/* First, iterate over all windows, deleting their icons and custom menus.
* This is really only needed because winDestroyIcon() will try to
* destroy the old global icons, which will have changed.
* It is probably better to set a windows USER_DATA to flag locally defined
* icons, and use that to accurately know when to destroy old icons.
*/
EnumThreadWindows(g_dwCurrentThreadID, ReloadEnumWindowsProc, FALSE);
if (pScreenInfo->fMultiWindow)
EnumThreadWindows(g_dwCurrentThreadID, ReloadEnumWindowsProc, FALSE);
#endif
/* Now, free/clear all info from our prefs structure */
@ -262,12 +265,12 @@ ReloadPrefs(void)
g_hSmallIconX = NULL;
#ifdef XWIN_MULTIWINDOW
winInitGlobalIcons();
#endif
if (pScreenInfo->fMultiWindow) {
winInitGlobalIcons();
#ifdef XWIN_MULTIWINDOW
/* Rebuild the icons and menus */
EnumThreadWindows(g_dwCurrentThreadID, ReloadEnumWindowsProc, TRUE);
/* Rebuild the icons and menus */
EnumThreadWindows(g_dwCurrentThreadID, ReloadEnumWindowsProc, TRUE);
}
#endif
/* Whew, done */
@ -303,7 +306,7 @@ HandleCustomWM_INITMENU(HWND hwnd, HMENU hmenu)
* Return TRUE if command is proccessed, FALSE otherwise.
*/
Bool
HandleCustomWM_COMMAND(HWND hwnd, int command)
HandleCustomWM_COMMAND(HWND hwnd, WORD command, winPrivScreenPtr pScreenPriv)
{
int i, j;
MENUPARSED *m;
@ -383,13 +386,17 @@ HandleCustomWM_COMMAND(HWND hwnd, int command)
HWND_TOPMOST,
0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
#if XWIN_MULTIWINDOW
/* Reflect the changed Z order */
winReorderWindowsMultiWindow();
{
winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
if (pScreenInfo->fMultiWindow)
/* Reflect the changed Z order */
winReorderWindowsMultiWindow();
}
#endif
return TRUE;
case CMD_RELOAD:
ReloadPrefs();
ReloadPrefs(pScreenPriv);
return TRUE;
default:

View File

@ -1,5 +1,3 @@
#if !defined(WINPREFS_H)
#define WINPREFS_H
/*
* Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
* Copyright (C) Colin Harrison 2005-2008
@ -32,6 +30,9 @@
* Colin Harrison
*/
#if !defined(WINPREFS_H)
#define WINPREFS_H
/* Need Bool */
#include <X11/Xdefs.h>
/* Need TRUE */
@ -42,6 +43,8 @@
/* Xwindows redefines PATH_MAX to at least 1024 */
#include <X11/Xwindows.h>
#include "winwindow.h"
#ifndef NAME_MAX
#define NAME_MAX PATH_MAX
#endif
@ -159,7 +162,7 @@ void
HandleCustomWM_INITMENU(HWND hwnd, HMENU hmenu);
Bool
HandleCustomWM_COMMAND(HWND hwnd, int command);
HandleCustomWM_COMMAND(HWND hwnd, WORD command, winPrivScreenPtr pScreenPriv);
int
winIconIsOverride(HICON hicon);

View File

@ -1215,7 +1215,7 @@ winWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
default:
/* It's probably one of the custom menus... */
if (HandleCustomWM_COMMAND(0, LOWORD(wParam)))
if (HandleCustomWM_COMMAND(0, LOWORD(wParam), s_pScreenPriv))
return 0;
}
break;