From 329bdb344c268f91ed726e000028cf52806ef5cb Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Sat, 8 May 2021 18:13:06 +0100 Subject: [PATCH] Make TermWin's palette_get_overrides() take a Terminal *. Less than 12 hours after 0.75 went out of the door, a user pointed out that enabling the 'Use system colours' config option causes an immediate NULL-dereference crash. The reason is because a chain of calls from term_init() ends up calling back to the Windows implementation of the palette_get_overrides() method, which responds by trying to call functions on the static variable 'term' in window.c, which won't be initialised until term_init() has returned. Simple fix: palette_get_overrides() is now given a pointer to the Terminal that it should be updating, because it can't find it out any other way. (cherry picked from commit 571fa3388d61f3270d958503c62f09669665f6f8) --- fuzzterm.c | 2 +- putty.h | 14 ++++++++++---- terminal.c | 2 +- unix/gtkwin.c | 2 +- windows/window.c | 4 ++-- 5 files changed, 15 insertions(+), 9 deletions(-) diff --git a/fuzzterm.c b/fuzzterm.c index c5c29ef4..f53c0a9c 100644 --- a/fuzzterm.c +++ b/fuzzterm.c @@ -93,7 +93,7 @@ static void fuzz_move(TermWin *tw, int x, int y) {} static void fuzz_set_zorder(TermWin *tw, bool top) {} static void fuzz_palette_set(TermWin *tw, unsigned start, unsigned ncolours, const rgb *colours) {} -static void fuzz_palette_get_overrides(TermWin *tw) {} +static void fuzz_palette_get_overrides(TermWin *tw, Terminal *term) {} static const TermWinVtable fuzz_termwin_vt = { .setup_draw_ctx = fuzz_setup_draw_ctx, diff --git a/putty.h b/putty.h index a73817af..6f1f914c 100644 --- a/putty.h +++ b/putty.h @@ -1299,8 +1299,14 @@ struct TermWinVtable { /* Query the front end for any OS-local overrides to the default * colours stored in Conf. The front end should set any it cares - * about by calling term_palette_override. */ - void (*palette_get_overrides)(TermWin *); + * about by calling term_palette_override. + * + * The Terminal object is passed in as a parameter, because this + * can be called as a callback from term_init(). So the TermWin + * itself won't yet have been told where to find its Terminal + * object, because that doesn't happen until term_init + * returns. */ + void (*palette_get_overrides)(TermWin *, Terminal *); }; static inline bool win_setup_draw_ctx(TermWin *win) @@ -1354,8 +1360,8 @@ static inline void win_set_zorder(TermWin *win, bool top) static inline void win_palette_set( TermWin *win, unsigned start, unsigned ncolours, const rgb *colours) { win->vt->palette_set(win, start, ncolours, colours); } -static inline void win_palette_get_overrides(TermWin *win) -{ win->vt->palette_get_overrides(win); } +static inline void win_palette_get_overrides(TermWin *win, Terminal *term) +{ win->vt->palette_get_overrides(win, term); } /* * Global functions not specific to a connection instance. diff --git a/terminal.c b/terminal.c index 0673623a..4bb47352 100644 --- a/terminal.c +++ b/terminal.c @@ -1874,7 +1874,7 @@ static void palette_reset(Terminal *term, bool overrides_only) */ for (unsigned i = 0; i < OSC4_NCOLOURS; i++) term->subpalettes[SUBPAL_PLATFORM].present[i] = false; - win_palette_get_overrides(term->win); + win_palette_get_overrides(term->win, term); /* * Rebuild the composite palette. diff --git a/unix/gtkwin.c b/unix/gtkwin.c index 2a2353d4..61e77187 100644 --- a/unix/gtkwin.c +++ b/unix/gtkwin.c @@ -2614,7 +2614,7 @@ static void gtkwin_palette_set(TermWin *tw, unsigned start, unsigned ncolours, } } -static void gtkwin_palette_get_overrides(TermWin *tw) +static void gtkwin_palette_get_overrides(TermWin *tw, Terminal *term) { /* GTK has no analogue of Windows's 'standard system colours', so GTK PuTTY * has no config option to override the normally configured colours from diff --git a/windows/window.c b/windows/window.c index 091838b4..ccf7b259 100644 --- a/windows/window.c +++ b/windows/window.c @@ -263,7 +263,7 @@ static void wintw_set_maximised(TermWin *, bool maximised); static void wintw_move(TermWin *, int x, int y); static void wintw_set_zorder(TermWin *, bool top); static void wintw_palette_set(TermWin *, unsigned, unsigned, const rgb *); -static void wintw_palette_get_overrides(TermWin *); +static void wintw_palette_get_overrides(TermWin *, Terminal *); static const TermWinVtable windows_termwin_vt = { .setup_draw_ctx = wintw_setup_draw_ctx, @@ -1214,7 +1214,7 @@ static inline rgb rgb_from_colorref(COLORREF cr) return toret; } -static void wintw_palette_get_overrides(TermWin *tw) +static void wintw_palette_get_overrides(TermWin *tw, Terminal *term) { if (conf_get_bool(conf, CONF_system_colour)) { rgb rgb;