Please test these patches for 0.11.5.GIT and 0.12pre2.GIT. (The latter should also apply to 0.13.GIT, except there's a conflict in NEWS.)
Actually I think we should add this to Bugzilla too, and update the commit messages and NEWS entry accordingly.
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 أحمد المحمودي. --- commit b85c8a744ef7f6d75fca302afe01dc9dac65b4fe tree 0ed2ce4704e7e8c9eb7a30afc0a43d5aadc30f54 parent 983419b6060bd97e372019c2bdfde32ad2157661 author Kalle Olavi Niemitalo <[EMAIL PROTECTED]> Tue, 30 Sep 2008 10:06:20 +0300 committer Kalle Olavi Niemitalo <[EMAIL PROTECTED]> Tue, 30 Sep 2008 10:12:09 +0300 NEWS | 8 ++++++++ src/session/download.c | 27 +++++++++++++++++++++++++++ src/session/download.h | 1 + src/terminal/terminal.c | 16 ++++++++++++++++ src/terminal/terminal.h | 6 ++++++ 5 files changed, 58 insertions(+), 0 deletions(-) diff --git a/NEWS b/NEWS index 87e6590..5ac4fdd 100644 --- a/NEWS +++ b/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 file for details. +ELinks 0.11.5.GIT now: +---------------------- + +To be released as 0.11.6. + +* critical: fix crash if a download finishes after ELinks has closed + the terminal from which the download was started. + ELinks 0.11.5: -------------- diff --git a/src/session/download.c b/src/session/download.c index a34a6f8..10e5e8c 100644 --- a/src/session/download.c +++ b/src/session/download.c @@ -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 download_error_dialog(struct file_download *file_download, int saved_errno) @@ -307,6 +330,10 @@ download_data_store(struct download *download, struct file_download *file_downlo { struct terminal *term = file_download->term; + if (term) { + assert_terminal_is_in_list(term); + if_assert_failed term = file_download->term = NULL; + } if (!term) { /* No term here, so no beep. --Zas */ abort_download(file_download); diff --git a/src/session/download.h b/src/session/download.h index 1bcc4aa..b27cd3b 100644 --- a/src/session/download.h +++ b/src/session/download.h @@ -107,6 +107,7 @@ void create_download_file(struct terminal *, unsigned char *, unsigned char **, void abort_all_downloads(void); void destroy_downloads(struct session *); +void detach_downloads_from_terminal(struct terminal *); int setup_download_handler(struct session *, struct download *, struct cache_entry *, int); diff --git a/src/terminal/terminal.c b/src/terminal/terminal.c index 895e898..3943951 100644 --- a/src/terminal/terminal.c +++ b/src/terminal/terminal.c @@ -115,6 +115,7 @@ destroy_terminal(struct terminal *term) #ifdef CONFIG_BOOKMARKS bookmark_auto_save_tabs(term); #endif + detach_downloads_from_terminal(term); while (!list_empty(term->windows)) delete_window(term->windows.next); @@ -197,6 +198,21 @@ unblock_terminal(struct terminal *term) textarea_edit(1, NULL, NULL, NULL, NULL); } +#ifndef CONFIG_FASTMEM +void +assert_terminal_is_in_list(const struct terminal *suspect) +{ + struct terminal *term; + + foreach (term, terminals) { + if (term == suspect) + return; + } + + assertm(0, "Dangling pointer to struct terminal"); +} +#endif /* !CONFIG_FASTMEM */ + void exec_on_terminal(struct terminal *term, unsigned char *path, unsigned char *delete, int fg) diff --git a/src/terminal/terminal.h b/src/terminal/terminal.h index 0689f09..c4633d0 100644 --- a/src/terminal/terminal.h +++ b/src/terminal/terminal.h @@ -150,6 +150,12 @@ void destroy_all_terminals(void); void exec_thread(unsigned char *, int); void close_handle(void *); +#ifdef CONFIG_FASTMEM +#define assert_terminal_is_in_list(term) ((void) 0) +#else /* assert() does something */ +void assert_terminal_is_in_list(const struct terminal *term); +#endif + #define TERM_FN_TITLE 1 #define TERM_FN_RESIZE 2
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 b85c8a744ef7f6d75fca302afe01dc9dac65b4fe) --- commit d498732a959a5b8ef95840c36b7d4788c008592d tree 2e19a9a8b7dfa651bfe459418429ed18e7049ecc parent 6ee45c710a32615742664e5edab436b016df75d2 author Kalle Olavi Niemitalo <[EMAIL PROTECTED]> Tue, 30 Sep 2008 10:06:20 +0300 committer Kalle Olavi Niemitalo <[EMAIL PROTECTED]> Tue, 30 Sep 2008 10:25:49 +0300 NEWS | 17 +++++++++++++---- src/session/download.c | 27 +++++++++++++++++++++++++++ src/session/download.h | 1 + src/terminal/terminal.c | 15 +++++++++++++++ src/terminal/terminal.h | 6 ++++++ 5 files changed, 62 insertions(+), 4 deletions(-) diff --git a/NEWS b/NEWS index 3375d7d..57625d0 100644 --- a/NEWS +++ b/NEWS @@ -8,7 +8,8 @@ file for details. 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 XML::LibXML::SAX does. @@ -17,7 +18,7 @@ ELinks 0.12pre2: ---------------- 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 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: ---------------- -Released on 2008-07-01. This release also included all the bug fixes -of ELinks 0.11.4, but not the ones made in 0.11.4.GIT. +Released on 2008-07-01. This release also included the changes listed +under ``ELinks 0.11.4'' below. Notable new features: @@ -227,6 +228,14 @@ Changes in the experimental SGML/DOM implementation: * enhancement: incremental parsing * and more. +ELinks 0.11.5.GIT now: +---------------------- + +To be released as 0.11.6. + +* critical: fix crash if a download finishes after ELinks has closed + the terminal from which the download was started. + ELinks 0.11.5: -------------- diff --git a/src/session/download.c b/src/session/download.c index e8c76b6..58d9061 100644 --- a/src/session/download.c +++ b/src/session/download.c @@ -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 download_error_dialog(struct file_download *file_download, int saved_errno) @@ -306,6 +329,10 @@ download_data_store(struct download *download, struct file_download *file_downlo { struct terminal *term = file_download->term; + if (term) { + assert_terminal_is_in_list(term); + if_assert_failed term = file_download->term = NULL; + } if (!term) { /* No term here, so no beep. --Zas */ abort_download(file_download); diff --git a/src/session/download.h b/src/session/download.h index a2b198d..c3aacce 100644 --- a/src/session/download.h +++ b/src/session/download.h @@ -108,6 +108,7 @@ void create_download_file(struct terminal *, unsigned char *, unsigned char **, void abort_all_downloads(void); void destroy_downloads(struct session *); +void detach_downloads_from_terminal(struct terminal *); int setup_download_handler(struct session *, struct download *, struct cache_entry *, int); diff --git a/src/terminal/terminal.c b/src/terminal/terminal.c index 5217cc6..688c930 100644 --- a/src/terminal/terminal.c +++ b/src/terminal/terminal.c @@ -118,6 +118,7 @@ destroy_terminal(struct terminal *term) #ifdef CONFIG_BOOKMARKS bookmark_auto_save_tabs(term); #endif + detach_downloads_from_terminal(term); /* delete_window doesn't update term->current_tab, but it calls redraw_terminal, which requires term->current_tab @@ -206,6 +207,20 @@ unblock_terminal(struct terminal *term) textarea_edit(1, NULL, NULL, NULL, NULL); } +#ifndef CONFIG_FASTMEM +void +assert_terminal_is_in_list(const struct terminal *suspect) +{ + struct terminal *term; + + foreach (term, terminals) { + if (term == suspect) + return; + } + + assertm(0, "Dangling pointer to struct terminal"); +} +#endif /* !CONFIG_FASTMEM */ static void exec_on_master_terminal(struct terminal *term, diff --git a/src/terminal/terminal.h b/src/terminal/terminal.h index b87ac2c..74690d1 100644 --- a/src/terminal/terminal.h +++ b/src/terminal/terminal.h @@ -178,6 +178,12 @@ void destroy_all_terminals(void); void exec_thread(unsigned char *, int); void close_handle(void *); +#ifdef CONFIG_FASTMEM +#define assert_terminal_is_in_list(term) ((void) 0) +#else /* assert() does something */ +void assert_terminal_is_in_list(const struct terminal *term); +#endif + /** Operations that can be requested with do_terminal_function(). * The interlink protocol passes these values as one byte in a * null-terminated string, so zero cannot be used. */
pgpGubxNd6kyd.pgp
Description: PGP signature
_______________________________________________ elinks-dev mailing list elinks-dev@linuxfromscratch.org http://linuxfromscratch.org/mailman/listinfo/elinks-dev