We discussed this on #ELinks with Miciah Dashiel Butler Masters.
The bug is triggered by configure --enable-html-highlight, which
also enables the RSS renderer.  configure --enable-debug can hide
the bug, at least in some circumstances.  Here is a relevant part
of a valgrind log:

==25631== Invalid read of size 2
==25631==    at 0x80B2438: call_dom_stack_callbacks (stack.c:145)
==25631==    by 0x80B2822: pop_dom_node (stack.c:222)
==25631==    by 0x8092E3A: render_dom_document (renderer.c:1078)
==25631==    by 0x808AC6E: render_encoded_document (renderer.c:262)
==25631==    by 0x808AEFE: render_document (renderer.c:345)
==25631==    by 0x808B420: render_document_frames (renderer.c:472)
==25631==    by 0x810D697: draw_formatted (draw.c:350)
==25631==    by 0x80F57FE: display_timer (session.c:454)
==25631==    by 0x80F8CF8: loading_callback (task.c:538)
==25631==    by 0x80D105C: notify_connection_callbacks (connection.c:428)
==25631==    by 0x80D0D93: set_connection_state (connection.c:367)
==25631==    by 0x80D08CB: set_connection_socket_state (connection.c:234)
==25631==  Address 0x4db1c78 is 0 bytes inside a block of size 32 free'd
==25631==    at 0x4021B8A: free (vg_replace_malloc.c:323)
==25631==    by 0x8106C53: mem_free (memory.c:96)
==25631==    by 0x80AF858: done_dom_node_data (node.c:430)
==25631==    by 0x80AF944: done_dom_node (node.c:461)
==25631==    by 0x8092A55: dom_rss_pop_document (renderer.c:950)
==25631==    by 0x80B2486: call_dom_stack_callbacks (stack.c:151)
==25631==    by 0x80B2822: pop_dom_node (stack.c:222)
==25631==    by 0x8092E3A: render_dom_document (renderer.c:1078)
==25631==    by 0x808AC6E: render_encoded_document (renderer.c:262)
==25631==    by 0x808AEFE: render_document (renderer.c:345)
==25631==    by 0x808B420: render_document_frames (renderer.c:472)
==25631==    by 0x810D697: draw_formatted (draw.c:350)

The struct dom_node was freed and then used during the same call
to call_dom_stack_callbacks.  There were three contexts using the
DOM stack.  The first one didn't have any callbacks.  The second
one was dom_rss_renderer_context_info, whose dom_rss_pop_document
callback freed the document node.  The third context was
dom_config_normalizer_context, whose dom_normalize_node_end
callback wouldn't have done anything to DOM_NODE_DOCUMENT.
When call_dom_stack_callbacks was examining the third context,
it read state->node->type, whose value was invalid because
state->node had already been freed.  This then caused
call_dom_stack_callbacks to call an invalid function pointer.

The following patch attempts to fix this bug by keeping the node
in memory until call_dom_stack_callbacks has called the callbacks
of all contexts.  This change removes the valgrind error report
and avoids the crash.  However, I'm really unfamiliar with the
DOM code, so I cannot be sure this is the right solution.

--- src/document/dom/renderer.c.~1~     2008-06-30 01:40:02.000000000 +0300
+++ src/document/dom/renderer.c 2009-02-09 02:57:09.000000000 +0200
@@ -947,9 +947,7 @@ dom_rss_pop_document(struct dom_stack *s
                done_dom_string(&renderer->text);
        mem_free_if(renderer->items);
 
-       done_dom_node(root);
-
-       return DOM_CODE_OK;
+       return DOM_CODE_FREE_NODE;
 }
 
 

Attachment: pgpJDf2EaMY10.pgp
Description: PGP signature

Reply via email to