mirror of
https://github.com/rkd77/elinks.git
synced 2025-01-03 14:57:44 -05:00
Bug 1053: Fix crash when download ends.
ELinks attempted to display a message box on file_download.term, but it had already closed that terminal and freed the struct terminal. To fix this, reset file_download.term pointers to NULL when the terminal is about to be destroyed. Also, assert in download_data_store() that file_download.term is either NULL or in the global "terminals" list. Reported by أحمد المحمودي.
This commit is contained in:
parent
983419b606
commit
6e2476ea4d
8
NEWS
8
NEWS
@ -5,6 +5,14 @@ You can see the complete list of recent changes, bugfixes and new features
|
|||||||
in the http://repo.or.cz/w/elinks.git[gitweb interface]. See the ChangeLog
|
in the http://repo.or.cz/w/elinks.git[gitweb interface]. See the ChangeLog
|
||||||
file for details.
|
file for details.
|
||||||
|
|
||||||
|
ELinks 0.11.5.GIT now:
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
To be released as 0.11.6.
|
||||||
|
|
||||||
|
* critical bug 1053: fix crash if a download finishes after ELinks has
|
||||||
|
closed the terminal from which the download was started
|
||||||
|
|
||||||
ELinks 0.11.5:
|
ELinks 0.11.5:
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
|
@ -220,6 +220,29 @@ destroy_downloads(struct session *ses)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
detach_downloads_from_terminal(struct terminal *term)
|
||||||
|
{
|
||||||
|
struct file_download *file_download, *next;
|
||||||
|
|
||||||
|
assert(term != NULL);
|
||||||
|
if_assert_failed return;
|
||||||
|
|
||||||
|
foreachsafe (file_download, next, downloads) {
|
||||||
|
if (file_download->term != term)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!file_download->external_handler) {
|
||||||
|
file_download->term = NULL;
|
||||||
|
if (file_download->ses
|
||||||
|
&& file_download->ses->tab->term == term)
|
||||||
|
file_download->ses = NULL;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
abort_download(file_download);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
download_error_dialog(struct file_download *file_download, int saved_errno)
|
download_error_dialog(struct file_download *file_download, int saved_errno)
|
||||||
@ -307,6 +330,9 @@ download_data_store(struct download *download, struct file_download *file_downlo
|
|||||||
{
|
{
|
||||||
struct terminal *term = file_download->term;
|
struct terminal *term = file_download->term;
|
||||||
|
|
||||||
|
assert_terminal_ptr_not_dangling(term);
|
||||||
|
if_assert_failed term = file_download->term = NULL;
|
||||||
|
|
||||||
if (!term) {
|
if (!term) {
|
||||||
/* No term here, so no beep. --Zas */
|
/* No term here, so no beep. --Zas */
|
||||||
abort_download(file_download);
|
abort_download(file_download);
|
||||||
|
@ -107,6 +107,7 @@ void create_download_file(struct terminal *, unsigned char *, unsigned char **,
|
|||||||
|
|
||||||
void abort_all_downloads(void);
|
void abort_all_downloads(void);
|
||||||
void destroy_downloads(struct session *);
|
void destroy_downloads(struct session *);
|
||||||
|
void detach_downloads_from_terminal(struct terminal *);
|
||||||
|
|
||||||
int setup_download_handler(struct session *, struct download *, struct cache_entry *, int);
|
int setup_download_handler(struct session *, struct download *, struct cache_entry *, int);
|
||||||
|
|
||||||
|
@ -115,6 +115,7 @@ destroy_terminal(struct terminal *term)
|
|||||||
#ifdef CONFIG_BOOKMARKS
|
#ifdef CONFIG_BOOKMARKS
|
||||||
bookmark_auto_save_tabs(term);
|
bookmark_auto_save_tabs(term);
|
||||||
#endif
|
#endif
|
||||||
|
detach_downloads_from_terminal(term);
|
||||||
|
|
||||||
while (!list_empty(term->windows))
|
while (!list_empty(term->windows))
|
||||||
delete_window(term->windows.next);
|
delete_window(term->windows.next);
|
||||||
@ -197,6 +198,24 @@ unblock_terminal(struct terminal *term)
|
|||||||
textarea_edit(1, NULL, NULL, NULL, NULL);
|
textarea_edit(1, NULL, NULL, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef CONFIG_FASTMEM
|
||||||
|
void
|
||||||
|
assert_terminal_ptr_not_dangling(const struct terminal *suspect)
|
||||||
|
{
|
||||||
|
struct terminal *term;
|
||||||
|
|
||||||
|
if (suspect == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
foreach (term, terminals) {
|
||||||
|
if (term == suspect)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
assertm(0, "Dangling pointer to struct terminal");
|
||||||
|
}
|
||||||
|
#endif /* !CONFIG_FASTMEM */
|
||||||
|
|
||||||
void
|
void
|
||||||
exec_on_terminal(struct terminal *term, unsigned char *path,
|
exec_on_terminal(struct terminal *term, unsigned char *path,
|
||||||
unsigned char *delete, int fg)
|
unsigned char *delete, int fg)
|
||||||
|
@ -150,6 +150,12 @@ void destroy_all_terminals(void);
|
|||||||
void exec_thread(unsigned char *, int);
|
void exec_thread(unsigned char *, int);
|
||||||
void close_handle(void *);
|
void close_handle(void *);
|
||||||
|
|
||||||
|
#ifdef CONFIG_FASTMEM
|
||||||
|
#define assert_terminal_ptr_not_dangling(suspect) ((void) 0)
|
||||||
|
#else /* assert() does something */
|
||||||
|
void assert_terminal_ptr_not_dangling(const struct terminal *);
|
||||||
|
#endif
|
||||||
|
|
||||||
#define TERM_FN_TITLE 1
|
#define TERM_FN_TITLE 1
|
||||||
#define TERM_FN_RESIZE 2
|
#define TERM_FN_RESIZE 2
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user