mirror of
https://github.com/rkd77/elinks.git
synced 2024-12-04 14:46:47 -05:00
Fix double-free crash if EOF immediately follows </MAP>.
look_for_link() used to return 0 both when it found the closing </MAP>
tag, and when it hit the end of the file. In the first case, it also
added *menu to the memory_list; in the second case, it did not. The
caller get_image_map() supposedly distinguished between these cases by
checking whether pos >= eof, and freed *menu separately if so.
However, if the </MAP> was at the very end of the HTML file, so that
not even a newline followed it, then look_for_link() left pos == eof
even though it had found the </MAP> and added *menu to the memory_list.
This made get_image_map() misinterpret the result and mem_free(*menu)
even though *menu had already been freed as part of the memory_list;
thus the crash.
To fix this, make look_for_link() return -1 instead of 0 if it hits
EOF without finding the </MAP>. Then make get_image_map() check the
return value instead of comparing pos to eof. And add a test case,
although not an automated one.
Alternatively, look_for_link() could have been changed to decrement
pos between finding the </MAP> and returning 0. Then, the pos >= eof
comparison in get_image_map() would have been false. That scheme
would however have been a bit more difficult to understand and
maintain, I think.
Reported by Paul B. Mahol.
(cherry picked from commit a2404407ce
)
This commit is contained in:
parent
d668b3b6aa
commit
25da8085b3
1
NEWS
1
NEWS
@ -237,6 +237,7 @@ ELinks 0.11.5.GIT now:
|
||||
|
||||
To be released as 0.11.6.
|
||||
|
||||
* critical: fix double-free crash if EOF immediately follows </MAP>
|
||||
* critical bug 1053: fix crash if a download finishes after ELinks has
|
||||
closed the terminal from which the download was started
|
||||
* major bug 1004: ignore locales when comparing HTML element names and
|
||||
|
@ -615,6 +615,9 @@ look_for_tag(unsigned char **pos, unsigned char *eof,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** @return -1 if EOF is hit without the closing tag; 0 if the closing
|
||||
* tag is found (in which case this also adds *@a menu to *@a ml); or
|
||||
* 1 if this should be called again. */
|
||||
static int
|
||||
look_for_link(unsigned char **pos, unsigned char *eof, struct menu_item **menu,
|
||||
struct memory_list **ml, struct uri *href_base,
|
||||
@ -632,7 +635,7 @@ look_for_link(unsigned char **pos, unsigned char *eof, struct menu_item **menu,
|
||||
(*pos)++;
|
||||
}
|
||||
|
||||
if (*pos >= eof) return 0;
|
||||
if (*pos >= eof) return -1;
|
||||
|
||||
if (*pos + 2 <= eof && ((*pos)[1] == '!' || (*pos)[1] == '?')) {
|
||||
*pos = skip_comment(*pos, eof);
|
||||
@ -647,7 +650,7 @@ look_for_link(unsigned char **pos, unsigned char *eof, struct menu_item **menu,
|
||||
if (!c_strlcasecmp(name, namelen, "A", 1)) {
|
||||
while (look_for_tag(pos, eof, name, namelen, &label));
|
||||
|
||||
if (*pos >= eof) return 0;
|
||||
if (*pos >= eof) return -1;
|
||||
|
||||
} else if (!c_strlcasecmp(name, namelen, "AREA", 4)) {
|
||||
/* FIXME (bug 784): options->cp is the terminal charset;
|
||||
@ -765,6 +768,7 @@ get_image_map(unsigned char *head, unsigned char *pos, unsigned char *eof,
|
||||
{
|
||||
struct conv_table *ct;
|
||||
struct string hd;
|
||||
int look_result;
|
||||
|
||||
if (!init_string(&hd)) return -1;
|
||||
|
||||
@ -785,10 +789,13 @@ get_image_map(unsigned char *head, unsigned char *pos, unsigned char *eof,
|
||||
|
||||
*ml = NULL;
|
||||
|
||||
while (look_for_link(&pos, eof, menu, ml, uri, target_base, ct, options))
|
||||
;
|
||||
do {
|
||||
/* This call can modify both *ml and *menu. */
|
||||
look_result = look_for_link(&pos, eof, menu, ml, uri,
|
||||
target_base, ct, options);
|
||||
} while (look_result > 0);
|
||||
|
||||
if (pos >= eof) {
|
||||
if (look_result < 0) {
|
||||
freeml(*ml);
|
||||
mem_free(*menu);
|
||||
return -1;
|
||||
|
5
test/imgmap2.html
Normal file
5
test/imgmap2.html
Normal file
@ -0,0 +1,5 @@
|
||||
<TITLE>Double-free crash in USEMAP</TITLE>
|
||||
<P><IMG src="/dev/null" usemap="#crasher"></P>
|
||||
<MAP name="crasher">
|
||||
<AREA shape="rect" coords="42,42,69,69" href="http://elinks.cz/" alt="see this?">
|
||||
<!-- no newline at the end of this line --></MAP>
|
Loading…
Reference in New Issue
Block a user