summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorluken@chromium.org <luken@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-09 02:24:34 +0000
committerluken@chromium.org <luken@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-09 02:24:34 +0000
commit346e45aa47b6821867b46539c89b64e13445fadf (patch)
tree08a6431c425731f10dbb8889196e0f322c01310f
parent8cd6c223ca41a6788783db5ab2ea90f774e8c10f (diff)
downloadchromium_src-346e45aa47b6821867b46539c89b64e13445fadf.zip
chromium_src-346e45aa47b6821867b46539c89b64e13445fadf.tar.gz
chromium_src-346e45aa47b6821867b46539c89b64e13445fadf.tar.bz2
fix leak in RTree::Remove()
Caused in the common case when RTree::RemoveNode would remove a non-record-node child but would have more than min_children_ remaining nodes. BUG=370779 Review URL: https://codereview.chromium.org/270373002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@269154 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--ui/gfx/geometry/r_tree.cc13
1 files changed, 8 insertions, 5 deletions
diff --git a/ui/gfx/geometry/r_tree.cc b/ui/gfx/geometry/r_tree.cc
index e62e546..00e75eb 100644
--- a/ui/gfx/geometry/r_tree.cc
+++ b/ui/gfx/geometry/r_tree.cc
@@ -627,8 +627,7 @@ void RTree::Remove(intptr_t key) {
// Lastly check the root. If it has only one non-leaf child, delete it and
// replace it with its child.
if (root_->count() == 1 && root_->level() > 0) {
- scoped_ptr<Node> new_root(root_->RemoveAndReturnLastChild());
- root_.swap(new_root);
+ root_ = root_->RemoveAndReturnLastChild();
}
}
@@ -716,10 +715,14 @@ void RTree::RemoveNode(Node* node) {
// Traverse up the tree, removing the child from each parent and deleting
// parent nodes, until we either encounter the root of the tree or a parent
// that still has sufficient children.
- while (parent && parent->RemoveChild(child, &orphans) < min_children_) {
- if (child != node) {
+ while (parent) {
+ size_t children_remaining = parent->RemoveChild(child, &orphans);
+ if (child != node)
delete child;
- }
+
+ if (children_remaining >= min_children_)
+ break;
+
child = parent;
parent = parent->parent();
}