diff options
author | Sebastien Helleu <flashcode@flashtux.org> | 2013-12-01 08:37:22 +0100 |
---|---|---|
committer | Sebastien Helleu <flashcode@flashtux.org> | 2013-12-01 08:37:22 +0100 |
commit | 9a160509d74c521f2de005e0daf3762866ef8e04 (patch) | |
tree | fbb18ae34201162eec9e3352e6d903d6aaf7cd8f /src/gui/gui-buffer.c | |
parent | 983791de847a93e487aa28b8397bb12ee4b0f17b (diff) | |
download | weechat-9a160509d74c521f2de005e0daf3762866ef8e04.zip |
core: fix random crash when closing a buffer
The problem happened because we used a pointer to a
"struct t_gui_buffer_visited" for the switch to another buffer,
when the buffer is closed. This is executed in all windows displaying
the buffer, but on each switch to buffer, the visited buffers are
updated and therefore the address can change. The pointer becomes
invalid, and WeeChat still uses it on next windows for the buffer
switch.
It happened rarely because the visited buffer is freed and allocated
immediately after, so the address is often the same in memory.
Thanks to silverd for the tests on OS X to track the problem.
Diffstat (limited to 'src/gui/gui-buffer.c')
-rw-r--r-- | src/gui/gui-buffer.c | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/src/gui/gui-buffer.c b/src/gui/gui-buffer.c index daa461ac0..4d08d71c2 100644 --- a/src/gui/gui-buffer.c +++ b/src/gui/gui-buffer.c @@ -2126,6 +2126,7 @@ gui_buffer_close (struct t_gui_buffer *buffer) { struct t_gui_window *ptr_window; struct t_gui_buffer *ptr_buffer, *ptr_back_to_buffer; + struct t_gui_buffer *ptr_buffer_visited_buffer; int index; struct t_gui_buffer_visited *ptr_buffer_visited; @@ -2152,7 +2153,7 @@ gui_buffer_close (struct t_gui_buffer *buffer) * find other buffer to display: previously visited buffer if current * window is displaying buffer, or buffer # - 1 */ - ptr_buffer_visited = NULL; + ptr_buffer_visited_buffer = NULL; if (CONFIG_BOOLEAN(config_look_jump_previous_buffer_when_closing) && gui_current_window && (gui_current_window->buffer == buffer)) { @@ -2160,8 +2161,11 @@ gui_buffer_close (struct t_gui_buffer *buffer) if (index >= 0) { ptr_buffer_visited = gui_buffer_visited_search_by_number (index); - if (ptr_buffer_visited->buffer == buffer) - ptr_buffer_visited = NULL; + if (ptr_buffer_visited + && (ptr_buffer_visited->buffer != buffer)) + { + ptr_buffer_visited_buffer = ptr_buffer_visited->buffer; + } } } @@ -2181,10 +2185,10 @@ gui_buffer_close (struct t_gui_buffer *buffer) ptr_back_to_buffer, 1); } - else if (ptr_buffer_visited) + else if (ptr_buffer_visited_buffer) { gui_window_switch_to_buffer (ptr_window, - ptr_buffer_visited->buffer, + ptr_buffer_visited_buffer, 1); } else if (ptr_window->buffer->prev_buffer) |