Fix PropItem leak by using nsAutoPtr (bug 407074). r+sr=peterv, a=damon
authorjruderman@hmc.edu
Tue, 11 Dec 2007 19:23:34 -0800
changeset 8943 84eddf6dcba1a45ed434ed766ba92a87cb0f0c61
parent 8942 3b9b504e803225e53991baafc259e745b69724ac
child 8944 9c8b71759034f13bdee24d8d03631a6336c5b0de
push idunknown
push userunknown
push dateunknown
reviewersdamon
bugs407074
milestone1.9b3pre
Fix PropItem leak by using nsAutoPtr (bug 407074). r+sr=peterv, a=damon
editor/libeditor/html/TypeInState.cpp
editor/libeditor/html/TypeInState.h
editor/libeditor/html/nsHTMLEditRules.cpp
editor/libeditor/html/nsHTMLEditRules.h
--- a/editor/libeditor/html/TypeInState.cpp
+++ b/editor/libeditor/html/TypeInState.cpp
@@ -445,18 +445,28 @@ PRBool TypeInState::FindPropInList(nsIAt
 }
 
 
 
 /********************************************************************
  *    PropItem: helper struct for TypeInState
  *******************************************************************/
 
+PropItem::PropItem() : 
+ tag(nsnull)
+,attr()
+,value()
+{
+  MOZ_COUNT_CTOR(PropItem);
+}
+
 PropItem::PropItem(nsIAtom *aTag, const nsAString &aAttr, const nsAString &aValue) :
  tag(aTag)
 ,attr(aAttr)
 ,value(aValue)
 {
+  MOZ_COUNT_CTOR(PropItem);
 }
 
 PropItem::~PropItem()
 {
+  MOZ_COUNT_DTOR(PropItem);
 }
--- a/editor/libeditor/html/TypeInState.h
+++ b/editor/libeditor/html/TypeInState.h
@@ -47,17 +47,17 @@
 #include "nsVoidArray.h"
 
 struct PropItem
 {
   nsIAtom *tag;
   nsString attr;
   nsString value;
   
-  PropItem() : tag(nsnull), attr(), value() {}
+  PropItem();
   PropItem(nsIAtom *aTag, const nsAString &aAttr, const nsAString &aValue);
   ~PropItem();
 };
 
 class TypeInState : public nsISelectionListener
 {
 public:
 
@@ -76,22 +76,22 @@ public:
   nsresult SetProp(nsIAtom *aProp, const nsString &aAttr);
   nsresult SetProp(nsIAtom *aProp, const nsString &aAttr, const nsString &aValue);
 
   nsresult ClearAllProps();
   nsresult ClearProp(nsIAtom *aProp);
   nsresult ClearProp(nsIAtom *aProp, const nsString &aAttr);
   
   //**************************************************************************
-  //    TakeClearProperty: hands back next poroperty item on the clear list.
+  //    TakeClearProperty: hands back next property item on the clear list.
   //                       caller assumes ownership of PropItem and must delete it.
   nsresult TakeClearProperty(PropItem **outPropItem);
 
   //**************************************************************************
-  //    TakeSetProperty: hands back next poroperty item on the set list.
+  //    TakeSetProperty: hands back next property item on the set list.
   //                     caller assumes ownership of PropItem and must delete it.
   nsresult TakeSetProperty(PropItem **outPropItem);
 
   //**************************************************************************
   //    TakeRelativeFontSize: hands back relative font value, which is then
   //                          cleared out.
   nsresult TakeRelativeFontSize(PRInt32 *outRelSize);
 
--- a/editor/libeditor/html/nsHTMLEditRules.cpp
+++ b/editor/libeditor/html/nsHTMLEditRules.cpp
@@ -4311,32 +4311,32 @@ nsHTMLEditRules::CreateStyleForInsertTex
 {
   if (!aSelection || !aDoc) return NS_ERROR_NULL_POINTER;
   if (!mHTMLEditor->mTypeInState) return NS_ERROR_NULL_POINTER;
   
   PRBool weDidSometing = PR_FALSE;
   nsCOMPtr<nsIDOMNode> node, tmp;
   PRInt32 offset;
   nsresult res = mHTMLEditor->GetStartNodeAndOffset(aSelection, address_of(node), &offset);
-  if (NS_FAILED(res)) return res;
-  PropItem *item = nsnull;
+  NS_ENSURE_SUCCESS(res, res);
+  nsAutoPtr<PropItem> item;
   
   // if we deleted selection then also for cached styles
   if (mDidDeleteSelection && 
       ((mTheAction == nsEditor::kOpInsertText ) ||
        (mTheAction == nsEditor::kOpInsertIMEText) ||
        (mTheAction == nsEditor::kOpInsertBreak) ||
        (mTheAction == nsEditor::kOpDeleteSelection)))
   {
     res = ReapplyCachedStyles();
-    if (NS_FAILED(res)) return res;
+    NS_ENSURE_SUCCESS(res, res);
   }
   // either way we clear the cached styles array
   res = ClearCachedStyles();  
-  if (NS_FAILED(res)) return res;  
+  NS_ENSURE_SUCCESS(res, res);
 
   // next examine our present style and make sure default styles are either present or
   // explicitly overridden.  If neither, add the default style to the TypeInState
   PRInt32 j, defcon = mHTMLEditor->mDefaultStyles.Count();
   for (j=0; j<defcon; j++)
   {
     PropItem *propItem = (PropItem*)mHTMLEditor->mDefaultStyles[j];
     if (!propItem) 
@@ -4348,40 +4348,40 @@ nsHTMLEditRules::CreateStyleForInsertTex
     // that default styles will always be multivalue styles (like font face or size) where
     // clearing the style means we want to go back to the default.  If we ever wanted a 
     // "toggle" style like bold for a default, though, I'll have to add code to detect the
     // difference between unset and explicitly cleared, else user would never be able to
     // unbold, for instance.
     nsAutoString curValue;
     res = mHTMLEditor->GetInlinePropertyBase(propItem->tag, &(propItem->attr), nsnull, 
                                              &bFirst, &bAny, &bAll, &curValue, PR_FALSE);
-    if (NS_FAILED(res)) return res;
+    NS_ENSURE_SUCCESS(res, res);
     
     if (!bAny)  // no style set for this prop/attr
     {
       mHTMLEditor->mTypeInState->SetProp(propItem->tag, propItem->attr, propItem->value);
     }
   }
   
   // process clearing any styles first
-  mHTMLEditor->mTypeInState->TakeClearProperty(&item);
+  mHTMLEditor->mTypeInState->TakeClearProperty(getter_Transfers(item));
   while (item)
   {
     nsCOMPtr<nsIDOMNode> leftNode, rightNode, secondSplitParent, newSelParent, savedBR;
     res = mHTMLEditor->SplitStyleAbovePoint(address_of(node), &offset, item->tag, &item->attr, address_of(leftNode), address_of(rightNode));
-    if (NS_FAILED(res)) return res;
+    NS_ENSURE_SUCCESS(res, res);
     PRBool bIsEmptyNode;
     if (leftNode)
     {
       mHTMLEditor->IsEmptyNode(leftNode, &bIsEmptyNode, PR_FALSE, PR_TRUE);
       if (bIsEmptyNode)
       {
         // delete leftNode if it became empty
         res = mEditor->DeleteNode(leftNode);
-        if (NS_FAILED(res)) return res;
+        NS_ENSURE_SUCCESS(res, res);
       }
     }
     if (rightNode)
     {
       secondSplitParent = mHTMLEditor->GetLeftmostChild(rightNode);
       // don't try to split non-containers (br's, images, hr's, etc)
       if (!secondSplitParent) secondSplitParent = rightNode;
       if (!mHTMLEditor->IsContainer(secondSplitParent))
@@ -4389,106 +4389,102 @@ nsHTMLEditRules::CreateStyleForInsertTex
         if (nsTextEditUtils::IsBreak(secondSplitParent))
           savedBR = secondSplitParent;
 
         secondSplitParent->GetParentNode(getter_AddRefs(tmp));
         secondSplitParent = tmp;
       }
       offset = 0;
       res = mHTMLEditor->SplitStyleAbovePoint(address_of(secondSplitParent), &offset, item->tag, &(item->attr), address_of(leftNode), address_of(rightNode));
-      if (NS_FAILED(res)) return res;
+      NS_ENSURE_SUCCESS(res, res);
       // should be impossible to not get a new leftnode here
       if (!leftNode) return NS_ERROR_FAILURE;
       newSelParent = mHTMLEditor->GetLeftmostChild(leftNode);
       if (!newSelParent) newSelParent = leftNode;
       // if rightNode starts with a br, suck it out of right node and into leftNode.
       // This is so we you don't revert back to the previous style if you happen to click at the end of a line.
       if (savedBR)
       {
         res = mEditor->MoveNode(savedBR, newSelParent, 0);
-        if (NS_FAILED(res)) return res;
+        NS_ENSURE_SUCCESS(res, res);
       }
       mHTMLEditor->IsEmptyNode(rightNode, &bIsEmptyNode, PR_FALSE, PR_TRUE);
       if (bIsEmptyNode)
       {
         // delete rightNode if it became empty
         res = mEditor->DeleteNode(rightNode);
-        if (NS_FAILED(res)) return res;
+        NS_ENSURE_SUCCESS(res, res);
       }
       // remove the style on this new heirarchy
       PRInt32 newSelOffset = 0;
       {
         // track the point at the new heirarchy.
         // This is so we can know where to put the selection after we call
         // RemoveStyleInside().  RemoveStyleInside() could remove any and all of those nodes,
         // so I have to use the range tracking system to find the right spot to put selection.
         nsAutoTrackDOMPoint tracker(mHTMLEditor->mRangeUpdater, address_of(newSelParent), &newSelOffset);
         res = mHTMLEditor->RemoveStyleInside(leftNode, item->tag, &(item->attr));
-        if (NS_FAILED(res)) return res;
+        NS_ENSURE_SUCCESS(res, res);
       }
       // reset our node offset values to the resulting new sel point
       node = newSelParent;
       offset = newSelOffset;
     }
-    // we own item now (TakeClearProperty hands ownership to us)
-    delete item;
-    mHTMLEditor->mTypeInState->TakeClearProperty(&item);
+    mHTMLEditor->mTypeInState->TakeClearProperty(getter_Transfers(item));
     weDidSometing = PR_TRUE;
   }
   
   // then process setting any styles
   PRInt32 relFontSize;
   
   res = mHTMLEditor->mTypeInState->TakeRelativeFontSize(&relFontSize);
-  if (NS_FAILED(res)) return res;
-  res = mHTMLEditor->mTypeInState->TakeSetProperty(&item);
-  if (NS_FAILED(res)) return res;
+  NS_ENSURE_SUCCESS(res, res);
+  res = mHTMLEditor->mTypeInState->TakeSetProperty(getter_Transfers(item));
+  NS_ENSURE_SUCCESS(res, res);
   
   if (item || relFontSize) // we have at least one style to add; make a
   {                        // new text node to insert style nodes above.
     if (mHTMLEditor->IsTextNode(node))
     {
       // if we are in a text node, split it
       res = mHTMLEditor->SplitNodeDeep(node, node, offset, &offset);
-      if (NS_FAILED(res)) return res;
+      NS_ENSURE_SUCCESS(res, res);
       node->GetParentNode(getter_AddRefs(tmp));
       node = tmp;
     }
     nsCOMPtr<nsIDOMNode> newNode;
     nsCOMPtr<nsIDOMText> nodeAsText;
     res = aDoc->CreateTextNode(EmptyString(), getter_AddRefs(nodeAsText));
-    if (NS_FAILED(res)) return res;
+    NS_ENSURE_SUCCESS(res, res);
     if (!nodeAsText) return NS_ERROR_NULL_POINTER;
     newNode = do_QueryInterface(nodeAsText);
     res = mHTMLEditor->InsertNode(newNode, node, offset);
-    if (NS_FAILED(res)) return res;
+    NS_ENSURE_SUCCESS(res, res);
     node = newNode;
     offset = 0;
     weDidSometing = PR_TRUE;
 
     if (relFontSize)
     {
       PRInt32 j, dir;
       // dir indicated bigger versus smaller.  1 = bigger, -1 = smaller
       if (relFontSize > 0) dir=1;
       else dir = -1;
       for (j=0; j<abs(relFontSize); j++)
       {
         res = mHTMLEditor->RelativeFontChangeOnTextNode(dir, nodeAsText, 0, -1);
-        if (NS_FAILED(res)) return res;
+        NS_ENSURE_SUCCESS(res, res);
       }
     }
     
     while (item)
     {
       res = mHTMLEditor->SetInlinePropertyOnNode(node, item->tag, &item->attr, &item->value);
-      if (NS_FAILED(res)) return res;
-      // we own item now (TakeSetProperty hands ownership to us)
-      delete item;
-      mHTMLEditor->mTypeInState->TakeSetProperty(&item);
+      NS_ENSURE_SUCCESS(res, res);
+      mHTMLEditor->mTypeInState->TakeSetProperty(getter_Transfers(item));
     }
   }
   if (weDidSometing)
     return aSelection->Collapse(node, offset);
     
   return res;
 }
 
--- a/editor/libeditor/html/nsHTMLEditRules.h
+++ b/editor/libeditor/html/nsHTMLEditRules.h
@@ -53,20 +53,28 @@ class nsVoidArray;
 class nsIDOMElement;
 class nsIEditor;
 class nsHTMLEditor;
 
 struct StyleCache : public PropItem
 {
   PRBool mPresent;
   
-  StyleCache() : PropItem(nsnull, EmptyString(), EmptyString()), mPresent(PR_FALSE){}
+  StyleCache() : PropItem(), mPresent(PR_FALSE) {
+    MOZ_COUNT_CTOR(StyleCache);
+  }
+
   StyleCache(nsIAtom *aTag, const nsAString &aAttr, const nsAString &aValue) : 
-             PropItem(aTag, aAttr, aValue), mPresent(PR_FALSE) {}
-  ~StyleCache() {}
+             PropItem(aTag, aAttr, aValue), mPresent(PR_FALSE) {
+    MOZ_COUNT_CTOR(StyleCache);
+  }
+
+  ~StyleCache() {
+    MOZ_COUNT_DTOR(StyleCache);
+  }
 };
 
 
 #define SIZE_STYLE_TABLE 19
 
 class nsHTMLEditRules : public nsIHTMLEditRules, public nsTextEditRules, public nsIEditActionListener
 {
 public: