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.
This commit is contained in:
parent
4086418069
commit
a2404407ce
1
NEWS
1
NEWS
@ -10,6 +10,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
|
||||
|
@ -511,6 +511,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,
|
||||
@ -528,7 +531,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);
|
||||
@ -543,7 +546,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)) {
|
||||
unsigned char *alt = get_attr_val(attr, "alt", options);
|
||||
@ -656,6 +659,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;
|
||||
|
||||
@ -676,10 +680,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