1
0
mirror of https://github.com/rkd77/elinks.git synced 2024-12-04 14:46:47 -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 أحمد المحمودي.
(cherry picked from commit 6e2476ea4d)
This commit is contained in:
Kalle Olavi Niemitalo 2008-09-30 10:06:20 +03:00 committed by Kalle Olavi Niemitalo
parent 6ee45c710a
commit 4c2ddac289
5 changed files with 64 additions and 4 deletions

17
NEWS
View File

@ -8,7 +8,8 @@ file for details.
ELinks 0.12pre2.GIT now: ELinks 0.12pre2.GIT now:
------------------------ ------------------------
To be released as 0.12pre3, 0.12rc1, or even 0.12.0. To be released as 0.12pre3, 0.12rc1, or even 0.12.0. This branch also
includes the changes listed under ``ELinks 0.11.5.GIT'' below.
* Perl scripts can use modules that dynamically load C libraries, like * Perl scripts can use modules that dynamically load C libraries, like
XML::LibXML::SAX does. XML::LibXML::SAX does.
@ -17,7 +18,7 @@ ELinks 0.12pre2:
---------------- ----------------
Released on 2008-09-21. This release also included the changes listed Released on 2008-09-21. This release also included the changes listed
under "ELinks 0.11.5" below. under ``ELinks 0.11.5'' below.
* bug 954, enhancement 952: Keep track of ECMAScript form and input * bug 954, enhancement 952: Keep track of ECMAScript form and input
objects instead of constructing new ones on every access. When the objects instead of constructing new ones on every access. When the
@ -73,8 +74,8 @@ Bugs that should be removed from NEWS before the 0.12.0 release:
ELinks 0.12pre1: ELinks 0.12pre1:
---------------- ----------------
Released on 2008-07-01. This release also included all the bug fixes Released on 2008-07-01. This release also included the changes listed
of ELinks 0.11.4, but not the ones made in 0.11.4.GIT. under ``ELinks 0.11.4'' below.
Notable new features: Notable new features:
@ -227,6 +228,14 @@ Changes in the experimental SGML/DOM implementation:
* enhancement: incremental parsing * enhancement: incremental parsing
* and more. * and more.
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:
-------------- --------------

View File

@ -219,6 +219,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)
@ -306,6 +329,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);

View File

@ -108,6 +108,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);

View File

@ -118,6 +118,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);
/* delete_window doesn't update term->current_tab, but it /* delete_window doesn't update term->current_tab, but it
calls redraw_terminal, which requires term->current_tab calls redraw_terminal, which requires term->current_tab
@ -206,6 +207,23 @@ 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 */
static void static void
exec_on_master_terminal(struct terminal *term, exec_on_master_terminal(struct terminal *term,

View File

@ -178,6 +178,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
/** Operations that can be requested with do_terminal_function(). /** Operations that can be requested with do_terminal_function().
* The interlink protocol passes these values as one byte in a * The interlink protocol passes these values as one byte in a
* null-terminated string, so zero cannot be used. */ * null-terminated string, so zero cannot be used. */