summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohannes Hofmann <Johannes.Hofmann@gmx.de>2011-08-28 21:26:50 +0200
committerJohannes Hofmann <Johannes.Hofmann@gmx.de>2011-08-28 21:26:50 +0200
commit9be62abf7bc5badb405aadf40295a1a84f9d363a (patch)
tree4738f186ea83531fb04fa0d941a242bc8fab4b11
parent538b2797414cbd0682fc58dad84d8e9af2557522 (diff)
fix doctree leak
HTML like <div>hello</div> </body> </html> <div>hello</div> 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 <corvid@lavabit.com>
-rw-r--r--src/css.cc6
-rw-r--r--src/doctree.hh35
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;
};
};