diff --git a/NEWS b/NEWS index 24b78b63a..d52363b2d 100644 --- a/NEWS +++ b/NEWS @@ -11,6 +11,8 @@ ELinks 0.12pre2.GIT now: 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. +* critical: Fix assertion failure if IMG/@usemap refers to a different + file. * Preserve newlines in hidden input fields, and submit them as CRLF. Previously, they could turn into spaces or disappear entirely. * Perl scripts can use modules that dynamically load C libraries, like diff --git a/src/session/session.c b/src/session/session.c index fd7d042e9..99a6ddc7a 100644 --- a/src/session/session.c +++ b/src/session/session.c @@ -518,17 +518,23 @@ maybe_pre_format_html(struct cache_entry *cached, struct session *ses) * were 0, it could then be freed, and the * cached->preformatted assignment at the end of this function * would crash. Normally, the document has a reference to the - * cache entry, and that suffices. If the following assertion - * ever fails, object_lock(cached) and object_unlock(cached) - * must be added to this function. */ - assert(cached->object.refcount > 0); - if_assert_failed return; + * cache entry, and that suffices. However, if the cache + * entry was loaded to satisfy e.g. USEMAP="imgmap.html#map", + * then cached->object.refcount == 0 here, and must be + * incremented. + * + * cached->object.refcount == 0 is safe while the cache entry + * is being loaded, because garbage_collection() calls + * is_entry_used(), which checks whether any connection is + * using the cache entry. But loading has ended before this + * point. */ + object_lock(cached); fragment = get_cache_fragment(cached); - if (!fragment) return; + if (!fragment) goto unlock_and_return; /* We cannot do anything if the data are fragmented. */ - if (!list_is_singleton(cached->frag)) return; + if (!list_is_singleton(cached->frag)) goto unlock_and_return; set_event_id(pre_format_html_event, "pre-format-html"); trigger_event(pre_format_html_event, ses, cached); @@ -536,6 +542,9 @@ maybe_pre_format_html(struct cache_entry *cached, struct session *ses) /* XXX: Keep this after the trigger_event, because hooks might call * normalize_cache_entry()! */ cached->preformatted = 1; + +unlock_and_return: + object_unlock(cached); } #endif diff --git a/test/imgmap2.html b/test/imgmap2.html index e96e1846e..7a503feb6 100644 --- a/test/imgmap2.html +++ b/test/imgmap2.html @@ -1,5 +1,6 @@ -Double-free crash in USEMAP -

- -see this? - \ No newline at end of file +Crashes in client-side image maps +

ImageMap in another file

+

ImageMap at the very end of this file

+ +see this? +