If the parent parameter of get_dom_node_list_index referred to a node
that did not have children, then get_dom_node_list called by it could
return the address of a null pointer, and get_dom_node_list_index would
then pass that null pointer to get_dom_node_list_pos, which would crash.
That would be the same kind of crash as the one in get_dom_node_child.
It never happened in practice though: because all calls are in the form
get_dom_node_list_index(node->parent, node), the list must contain at
least the given node, and the pointer cannot be null. The documentation
of get_dom_node_list_index allows arbitrary nodes as arguments however,
so it's best to add a check.
struct dom_node contains a union that contains various structs that
have members of type struct dom_node * in them.
get_dom_node_list_by_type returns the address (struct dom_node **) of
one of those members, or NULL. However the member itself can also be
NULL if no nodes have been added to the list and the list has thus not
yet been allocated. (add_to_dom_node_list lazily allocates the lists.)
get_dom_node_child did not expect a null pointer there and crashed, as
shown in bug 1071. Fix by adding a check so that it treats a NULL list
as an empty list.
In bug 1067, dom_rss_pop_document() freed a node with done_dom_node()
even though call_dom_node_callbacks() was still using that node. This
made call_dom_node_callbacks() read a function pointer from beyond the
end of an array and call that. Add assertions to detect out-of-range
node types, and comments to warn about the bug.
Take a quick stroll through the unchartered corners of the DOM node data
structures:
- Remove ununsed struct dom_node_id_item.
- Make the document node reference a future struct dom_document.
- Describe ideas for node data, e.g. the entity reference node should use
it for storing the unicode_val_T.
This was cause by the recent change to allocate string during incremental
parsing where the node string was set after insertion. Test for this in the
works.
Fixes: b6b6d3c67e
This changes init_dom_node_() to take an allocated argument saying whether
to allocate or not. If the value is -1, node->allocated will be set to the
value of node->parent->allocated. This way the value is inherited like we
do it in the menu code. It should be a sane default since we eventually
want not to rely on the 'underlying' source of the document and there will
be less variables to pass around.