From 615694c95e44ef1f4649428d01e99af1c8a1d03f Mon Sep 17 00:00:00 2001 From: Marco Bonardo Date: Thu, 9 Jul 2009 14:39:54 +0200 Subject: [PATCH] Bug 503195 - Using Places nodes' PropertyBags leaks, r=sdwilsh --- .../places/src/nsNavHistoryResult.cpp | 23 +++-- .../tests/unit/test_nodes_propertyBag.js | 85 +++++++++++++++++++ 2 files changed, 103 insertions(+), 5 deletions(-) create mode 100644 toolkit/components/places/tests/unit/test_nodes_propertyBag.js diff --git a/toolkit/components/places/src/nsNavHistoryResult.cpp b/toolkit/components/places/src/nsNavHistoryResult.cpp index bba7ecf9285..4b1538a7dbf 100644 --- a/toolkit/components/places/src/nsNavHistoryResult.cpp +++ b/toolkit/components/places/src/nsNavHistoryResult.cpp @@ -3847,13 +3847,12 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END static PLDHashOperator TraverseBookmarkFolderObservers(nsTrimInt64HashKey::KeyType aKey, - nsNavHistoryResult::FolderObserverList*& aData, - void* aUserArg) + nsNavHistoryResult::FolderObserverList* &aData, + void *aClosure) { nsCycleCollectionTraversalCallback* cb = - static_cast(aUserArg); - PRUint32 i, count = aData->Length(); - for (i = 0; i < count; ++i) { + static_cast(aClosure); + for (PRUint32 i = 0; i < aData->Length(); ++i) { NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(*cb, "mBookmarkFolderObservers value[i]"); nsNavHistoryResultNode* node = aData->ElementAt(i); @@ -3862,10 +3861,24 @@ TraverseBookmarkFolderObservers(nsTrimInt64HashKey::KeyType aKey, return PL_DHASH_NEXT; } +static PLDHashOperator +TraversePropertyBags(nsISupportsHashKey::KeyType aKey, + nsCOMPtr &aData, + void *aClosure) +{ + nsCycleCollectionTraversalCallback* cb = + static_cast(aClosure); + NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(*cb, "mPropertyBags key"); + cb->NoteXPCOMChild(aKey); + + return PL_DHASH_NEXT; +} + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsNavHistoryResult) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mRootNode, nsINavHistoryContainerResultNode) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mView) tmp->mBookmarkFolderObservers.Enumerate(&TraverseBookmarkFolderObservers, &cb); + tmp->mPropertyBags.Enumerate(&TraversePropertyBags, &cb); NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSTARRAY_MEMBER(mAllBookmarksObservers, nsNavHistoryQueryResultNode) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSTARRAY_MEMBER(mHistoryObservers, nsNavHistoryQueryResultNode) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END diff --git a/toolkit/components/places/tests/unit/test_nodes_propertyBag.js b/toolkit/components/places/tests/unit/test_nodes_propertyBag.js new file mode 100644 index 00000000000..0a22c871c61 --- /dev/null +++ b/toolkit/components/places/tests/unit/test_nodes_propertyBag.js @@ -0,0 +1,85 @@ +/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et: */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Places unit test code. + * + * The Initial Developer of the Original Code is + * Mozilla Corporation + * Portions created by the Initial Developer are Copyright (C) 2009 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Marco Bonardo + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/** + * This test checks for propertyBag functionality associated with every node + * in a result. + */ +function run_test() +{ + var hs = Cc["@mozilla.org/browser/nav-history-service;1"]. + getService(Ci.nsINavHistoryService); + var bs = Cc["@mozilla.org/browser/nav-bookmarks-service;1"]. + getService(Ci.nsINavBookmarksService); + + var itemId = bs.insertBookmark(bs.unfiledBookmarksFolder, + uri("http://www.mozilla.org/"), + bs.DEFAULT_INDEX, + "we love mozilla"); + // Query for toolbar folder. + var options = hs.getNewQueryOptions(); + var query = hs.getNewQuery(); + query.setFolders([bs.unfiledBookmarksFolder], 1); + var result = hs.executeQuery(query, options); + var rootNode = result.root; + + rootNode.containerOpen = true; + do_check_eq(rootNode.childCount, 1); + rootNode.propertyBag.setProperty("testProperty", "testValue"); + do_check_eq(rootNode.propertyBag.getProperty("testProperty"), "testValue"); + rootNode.containerOpen = false; + do_check_eq(rootNode.propertyBag.getProperty("testProperty"), "testValue"); + + rootNode.containerOpen = true; + do_check_eq(rootNode.propertyBag.getProperty("testProperty"), "testValue"); + rootNode.propertyBag.deleteProperty("testProperty"); + try { + rootNode.propertyBag.getProperty("testProperty"); + do_throw("Found property in the propertyBag after removing it"); + } + catch(ex) {} + rootNode.containerOpen = false; + try { + rootNode.propertyBag.getProperty("testProperty"); + do_throw("Found property in the propertyBag after removing it"); + } + catch(ex) {} + + bs.removeItem(itemId); +}