From 9be62abf7bc5badb405aadf40295a1a84f9d363a Mon Sep 17 00:00:00 2001 From: Johannes Hofmann Date: Sun, 28 Aug 2011 21:26:50 +0200 Subject: fix doctree leak HTML like
hello
hello
currently causes the document tree to be a forest with two root nodes. To ensure we don't leak the first tree, an additional root node is introduced to hold all document trees. Catched by: Jeremy's valgrind logs Reported by: corvid --- src/css.cc | 6 +++--- src/doctree.hh | 35 ++++++++++++++++++++++------------- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/src/css.cc b/src/css.cc index aa799002..e9a8eb56 100644 --- a/src/css.cc +++ b/src/css.cc @@ -150,7 +150,7 @@ bool CssSelector::match (Doctree *docTree, const DoctreeNode *node) { if (sel->match (node)) break; - node = node->parent; + node = docTree->parent (node); } break; default: @@ -160,9 +160,9 @@ bool CssSelector::match (Doctree *docTree, const DoctreeNode *node) { comb = cs->combinator; if (comb == ADJACENT_SIBLING) - node = node->sibling; + node = docTree->sibling (node); else - node = node->parent; + node = docTree->parent (node); } return true; diff --git a/src/doctree.hh b/src/doctree.hh index c46a5a10..92cf6f0d 100644 --- a/src/doctree.hh +++ b/src/doctree.hh @@ -53,37 +53,46 @@ class Doctree { public: Doctree () { - topNode = NULL; - rootNode = NULL; + rootNode = new DoctreeNode; + topNode = rootNode; num = 0; }; ~Doctree () { - if (rootNode) - delete rootNode; + delete rootNode; }; DoctreeNode *push () { DoctreeNode *dn = new DoctreeNode (); dn->parent = topNode; - if (dn->parent) { - dn->sibling = dn->parent->lastChild; - dn->parent->lastChild = dn; - } + dn->sibling = dn->parent->lastChild; + dn->parent->lastChild = dn; dn->num = num++; - if (!rootNode) - rootNode = dn; topNode = dn; return dn; }; void pop () { - if (topNode) - topNode = topNode->parent; + assert (topNode != rootNode); // never pop the root node + topNode = topNode->parent; }; inline DoctreeNode *top () { - return topNode; + if (topNode != rootNode) + return topNode; + else + return NULL; + }; + + inline DoctreeNode *parent (const DoctreeNode *node) { + if (node->parent != rootNode) + return node->parent; + else + return NULL; + }; + + inline DoctreeNode *sibling (const DoctreeNode *node) { + return node->sibling; }; }; -- cgit v1.2.3