1
0
mirror of https://git.FreeBSD.org/ports.git synced 2024-12-19 03:52:17 +00:00
freebsd-ports/www/firefox-esr/files/patch-ff-449006
Joe Marcus Clarke 87d7a27d12 Back-port some more patches to fix CVE-2009-0352.
Obtained from:	Mozilla Bugzilla
Reported by:	simon
2009-02-23 20:40:55 +00:00

1174 lines
28 KiB
Plaintext

diff --git a/editor/txmgr/src/nsTransactionItem.cpp b/editor/txmgr/src/nsTransactionItem.cpp
--- editor/txmgr/src/nsTransactionItem.cpp
+++ editor/txmgr/src/nsTransactionItem.cpp
@@ -35,31 +35,51 @@
*
* ***** END LICENSE BLOCK ***** */
#include "nsITransaction.h"
#include "nsTransactionStack.h"
#include "nsTransactionManager.h"
#include "nsTransactionItem.h"
#include "nsCOMPtr.h"
+#include "nsAutoPtr.h"
nsTransactionItem::nsTransactionItem(nsITransaction *aTransaction)
: mTransaction(aTransaction), mUndoStack(0), mRedoStack(0)
{
}
nsTransactionItem::~nsTransactionItem()
{
if (mRedoStack)
delete mRedoStack;
if (mUndoStack)
delete mUndoStack;
+}
- NS_IF_RELEASE(mTransaction);
+nsrefcnt
+nsTransactionItem::AddRef()
+{
+ ++mRefCnt;
+ NS_LOG_ADDREF(this, mRefCnt, "nsTransactionItem",
+ sizeof(nsTransactionItem));
+ return mRefCnt;
+}
+
+nsrefcnt
+nsTransactionItem::Release() {
+ --mRefCnt;
+ NS_LOG_RELEASE(this, mRefCnt, "nsTransactionItem");
+ if (mRefCnt == 0) {
+ mRefCnt = 1;
+ delete this;
+ return 0;
+ }
+ return mRefCnt;
}
nsresult
nsTransactionItem::AddChild(nsTransactionItem *aTransactionItem)
{
if (!aTransactionItem)
return NS_ERROR_NULL_POINTER;
@@ -75,17 +95,17 @@ nsTransactionItem::AddChild(nsTransactio
}
nsresult
nsTransactionItem::GetTransaction(nsITransaction **aTransaction)
{
if (!aTransaction)
return NS_ERROR_NULL_POINTER;
- *aTransaction = mTransaction;
+ NS_IF_ADDREF(*aTransaction = mTransaction);
return NS_OK;
}
nsresult
nsTransactionItem::GetIsBatch(PRBool *aIsBatch)
{
if (!aIsBatch)
@@ -202,17 +222,17 @@ nsTransactionItem::UndoTransaction(nsTra
}
return NS_OK;
}
nsresult
nsTransactionItem::UndoChildren(nsTransactionManager *aTxMgr)
{
- nsTransactionItem *item;
+ nsRefPtr<nsTransactionItem> item;
nsresult result = NS_OK;
PRInt32 sz = 0;
if (mUndoStack) {
if (!mRedoStack && mUndoStack) {
mRedoStack = new nsTransactionRedoStack();
if (!mRedoStack)
return NS_ERROR_OUT_OF_MEMORY;
@@ -220,25 +240,25 @@ nsTransactionItem::UndoChildren(nsTransa
/* Undo all of the transaction items children! */
result = mUndoStack->GetSize(&sz);
if (NS_FAILED(result))
return result;
while (sz-- > 0) {
- result = mUndoStack->Peek(&item);
+ result = mUndoStack->Peek(getter_AddRefs(item));
if (NS_FAILED(result)) {
return result;
}
- nsITransaction *t = 0;
+ nsCOMPtr<nsITransaction> t;
- result = item->GetTransaction(&t);
+ result = item->GetTransaction(getter_AddRefs(t));
if (NS_FAILED(result)) {
return result;
}
PRBool doInterrupt = PR_FALSE;
result = aTxMgr->WillUndoNotify(t, &doInterrupt);
@@ -249,17 +269,17 @@ nsTransactionItem::UndoChildren(nsTransa
if (doInterrupt) {
return NS_OK;
}
result = item->UndoTransaction(aTxMgr);
if (NS_SUCCEEDED(result)) {
- result = mUndoStack->Pop(&item);
+ result = mUndoStack->Pop(getter_AddRefs(item));
if (NS_SUCCEEDED(result)) {
result = mRedoStack->Push(item);
/* XXX: If we got an error here, I doubt we can recover!
* XXX: Should we just push the item back on the undo stack?
*/
}
@@ -276,16 +296,17 @@ nsTransactionItem::UndoChildren(nsTransa
return result;
}
nsresult
nsTransactionItem::RedoTransaction(nsTransactionManager *aTxMgr)
{
nsresult result;
+ nsCOMPtr<nsITransaction> kungfuDeathGrip(mTransaction);
if (mTransaction) {
result = mTransaction->RedoTransaction();
if (NS_FAILED(result))
return result;
}
result = RedoChildren(aTxMgr);
@@ -296,40 +317,40 @@ nsTransactionItem::RedoTransaction(nsTra
}
return NS_OK;
}
nsresult
nsTransactionItem::RedoChildren(nsTransactionManager *aTxMgr)
{
- nsTransactionItem *item;
+ nsRefPtr<nsTransactionItem> item;
nsresult result = NS_OK;
PRInt32 sz = 0;
if (!mRedoStack)
return NS_OK;
/* Redo all of the transaction items children! */
result = mRedoStack->GetSize(&sz);
if (NS_FAILED(result))
return result;
while (sz-- > 0) {
- result = mRedoStack->Peek(&item);
+ result = mRedoStack->Peek(getter_AddRefs(item));
if (NS_FAILED(result)) {
return result;
}
- nsITransaction *t = 0;
+ nsCOMPtr<nsITransaction> t;
- result = item->GetTransaction(&t);
+ result = item->GetTransaction(getter_AddRefs(t));
if (NS_FAILED(result)) {
return result;
}
PRBool doInterrupt = PR_FALSE;
result = aTxMgr->WillRedoNotify(t, &doInterrupt);
@@ -340,17 +361,17 @@ nsTransactionItem::RedoChildren(nsTransa
if (doInterrupt) {
return NS_OK;
}
result = item->RedoTransaction(aTxMgr);
if (NS_SUCCEEDED(result)) {
- result = mRedoStack->Pop(&item);
+ result = mRedoStack->Pop(getter_AddRefs(item));
if (NS_SUCCEEDED(result)) {
result = mUndoStack->Push(item);
// XXX: If we got an error here, I doubt we can recover!
// XXX: Should we just push the item back on the redo stack?
}
}
diff --git a/editor/txmgr/src/nsTransactionItem.h b/editor/txmgr/src/nsTransactionItem.h
--- editor/txmgr/src/nsTransactionItem.h
+++ editor/txmgr/src/nsTransactionItem.h
@@ -33,31 +33,36 @@
* 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 ***** */
#ifndef nsTransactionItem_h__
#define nsTransactionItem_h__
-class nsITransaction;
+#include "nsITransaction.h"
+#include "nsCOMPtr.h"
+
class nsTransactionStack;
class nsTransactionRedoStack;
class nsTransactionManager;
class nsTransactionItem
{
- nsITransaction *mTransaction;
- nsTransactionStack *mUndoStack;
- nsTransactionRedoStack *mRedoStack;
+ nsCOMPtr<nsITransaction> mTransaction;
+ nsTransactionStack *mUndoStack;
+ nsTransactionRedoStack *mRedoStack;
+ nsAutoRefCnt mRefCnt;
public:
nsTransactionItem(nsITransaction *aTransaction);
virtual ~nsTransactionItem();
+ nsrefcnt AddRef();
+ nsrefcnt Release();
virtual nsresult AddChild(nsTransactionItem *aTransactionItem);
virtual nsresult GetTransaction(nsITransaction **aTransaction);
virtual nsresult GetIsBatch(PRBool *aIsBatch);
virtual nsresult GetNumberOfChildren(PRInt32 *aNumChildren);
virtual nsresult GetChild(PRInt32 aIndex, nsTransactionItem **aChild);
virtual nsresult DoTransaction(void);
diff --git a/editor/txmgr/src/nsTransactionList.cpp b/editor/txmgr/src/nsTransactionList.cpp
--- editor/txmgr/src/nsTransactionList.cpp
+++ editor/txmgr/src/nsTransactionList.cpp
@@ -95,24 +95,24 @@ NS_IMETHODIMP nsTransactionList::ItemIsB
*aIsBatch = PR_FALSE;
nsCOMPtr<nsITransactionManager> txMgr = do_QueryReferent(mTxnMgr);
if (!txMgr)
return NS_ERROR_FAILURE;
- nsTransactionItem *item = 0;
+ nsRefPtr<nsTransactionItem> item;
nsresult result = NS_ERROR_FAILURE;
if (mTxnStack)
- result = mTxnStack->GetItem(aIndex, &item);
+ result = mTxnStack->GetItem(aIndex, getter_AddRefs(item));
else if (mTxnItem)
- result = mTxnItem->GetChild(aIndex, &item);
+ result = mTxnItem->GetChild(aIndex, getter_AddRefs(item));
if (NS_FAILED(result))
return result;
if (!item)
return NS_ERROR_FAILURE;
return item->GetIsBatch(aIsBatch);
@@ -126,62 +126,55 @@ NS_IMETHODIMP nsTransactionList::GetItem
*aItem = 0;
nsCOMPtr<nsITransactionManager> txMgr = do_QueryReferent(mTxnMgr);
if (!txMgr)
return NS_ERROR_FAILURE;
- nsTransactionItem *item = 0;
+ nsRefPtr<nsTransactionItem> item;
nsresult result = NS_ERROR_FAILURE;
if (mTxnStack)
- result = mTxnStack->GetItem(aIndex, &item);
+ result = mTxnStack->GetItem(aIndex, getter_AddRefs(item));
else if (mTxnItem)
- result = mTxnItem->GetChild(aIndex, &item);
+ result = mTxnItem->GetChild(aIndex, getter_AddRefs(item));
if (NS_FAILED(result))
return result;
if (!item)
return NS_ERROR_FAILURE;
- result = item->GetTransaction(aItem);
-
- if (NS_FAILED(result))
- return result;
-
- NS_IF_ADDREF(*aItem);
-
- return NS_OK;
+ return item->GetTransaction(aItem);
}
/* long getNumChildrenForItem (in long aIndex); */
NS_IMETHODIMP nsTransactionList::GetNumChildrenForItem(PRInt32 aIndex, PRInt32 *aNumChildren)
{
if (!aNumChildren)
return NS_ERROR_NULL_POINTER;
*aNumChildren = 0;
nsCOMPtr<nsITransactionManager> txMgr = do_QueryReferent(mTxnMgr);
if (!txMgr)
return NS_ERROR_FAILURE;
- nsTransactionItem *item = 0;
+ nsRefPtr<nsTransactionItem> item;
nsresult result = NS_ERROR_FAILURE;
if (mTxnStack)
- result = mTxnStack->GetItem(aIndex, &item);
+ result = mTxnStack->GetItem(aIndex, getter_AddRefs(item));
else if (mTxnItem)
- result = mTxnItem->GetChild(aIndex, &item);
+ result = mTxnItem->GetChild(aIndex, getter_AddRefs(item));
if (NS_FAILED(result))
return result;
if (!item)
return NS_ERROR_FAILURE;
return item->GetNumberOfChildren(aNumChildren);
@@ -195,24 +188,24 @@ NS_IMETHODIMP nsTransactionList::GetChil
*aTxnList = 0;
nsCOMPtr<nsITransactionManager> txMgr = do_QueryReferent(mTxnMgr);
if (!txMgr)
return NS_ERROR_FAILURE;
- nsTransactionItem *item = 0;
+ nsRefPtr<nsTransactionItem> item;
nsresult result = NS_ERROR_FAILURE;
if (mTxnStack)
- result = mTxnStack->GetItem(aIndex, &item);
+ result = mTxnStack->GetItem(aIndex, getter_AddRefs(item));
else if (mTxnItem)
- result = mTxnItem->GetChild(aIndex, &item);
+ result = mTxnItem->GetChild(aIndex, getter_AddRefs(item));
if (NS_FAILED(result))
return result;
if (!item)
return NS_ERROR_FAILURE;
*aTxnList = (nsITransactionList *)new nsTransactionList(txMgr, item);
diff --git a/editor/txmgr/src/nsTransactionList.h b/editor/txmgr/src/nsTransactionList.h
--- editor/txmgr/src/nsTransactionList.h
+++ editor/txmgr/src/nsTransactionList.h
@@ -35,33 +35,34 @@
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsTransactionList_h__
#define nsTransactionList_h__
#include "nsWeakReference.h"
#include "nsITransactionList.h"
+#include "nsTransactionItem.h"
+#include "nsAutoPtr.h"
class nsITransaction;
class nsITransactionManager;
-class nsTransactionItem;
class nsTransactionStack;
class nsTransactionRedoStack;
/** implementation of a transaction list object.
*
*/
class nsTransactionList : public nsITransactionList
{
private:
- nsWeakPtr mTxnMgr;
- nsTransactionStack *mTxnStack;
- nsTransactionItem *mTxnItem;
+ nsWeakPtr mTxnMgr;
+ nsTransactionStack *mTxnStack;
+ nsRefPtr<nsTransactionItem> mTxnItem;
public:
nsTransactionList(nsITransactionManager *aTxnMgr, nsTransactionStack *aTxnStack);
nsTransactionList(nsITransactionManager *aTxnMgr, nsTransactionItem *aTxnItem);
virtual ~nsTransactionList();
diff --git a/editor/txmgr/src/nsTransactionManager.cpp b/editor/txmgr/src/nsTransactionManager.cpp
--- editor/txmgr/src/nsTransactionManager.cpp
+++ editor/txmgr/src/nsTransactionManager.cpp
@@ -38,17 +38,17 @@
#include "nsITransaction.h"
#include "nsITransactionListener.h"
#include "nsTransactionItem.h"
#include "nsTransactionStack.h"
#include "nsVoidArray.h"
#include "nsTransactionManager.h"
#include "nsTransactionList.h"
-
+#include "nsAutoPtr.h"
#include "nsCOMPtr.h"
#define LOCK_TX_MANAGER(mgr) (mgr)->Lock()
#define UNLOCK_TX_MANAGER(mgr) (mgr)->Unlock()
nsTransactionManager::nsTransactionManager(PRInt32 aMaxTransactionCount)
: mMaxTransactionCount(aMaxTransactionCount), mListeners(0)
@@ -148,54 +148,54 @@ nsTransactionManager::DoTransaction(nsIT
return result;
}
NS_IMETHODIMP
nsTransactionManager::UndoTransaction()
{
nsresult result = NS_OK;
- nsTransactionItem *tx = 0;
+ nsRefPtr<nsTransactionItem> tx;
LOCK_TX_MANAGER(this);
// It is illegal to call UndoTransaction() while the transaction manager is
// executing a transaction's DoTransaction() method! If this happens,
// the UndoTransaction() request is ignored, and we return NS_ERROR_FAILURE.
- result = mDoStack.Peek(&tx);
+ result = mDoStack.Peek(getter_AddRefs(tx));
if (NS_FAILED(result)) {
UNLOCK_TX_MANAGER(this);
return result;
}
if (tx) {
UNLOCK_TX_MANAGER(this);
return NS_ERROR_FAILURE;
}
// Peek at the top of the undo stack. Don't remove the transaction
// until it has successfully completed.
- result = mUndoStack.Peek(&tx);
+ result = mUndoStack.Peek(getter_AddRefs(tx));
if (NS_FAILED(result)) {
UNLOCK_TX_MANAGER(this);
return result;
}
// Bail if there's nothing on the stack.
if (!tx) {
UNLOCK_TX_MANAGER(this);
return NS_OK;
}
- nsITransaction *t = 0;
+ nsCOMPtr<nsITransaction> t;
- result = tx->GetTransaction(&t);
+ result = tx->GetTransaction(getter_AddRefs(t));
if (NS_FAILED(result)) {
UNLOCK_TX_MANAGER(this);
return result;
}
PRBool doInterrupt = PR_FALSE;
@@ -209,17 +209,17 @@ nsTransactionManager::UndoTransaction()
if (doInterrupt) {
UNLOCK_TX_MANAGER(this);
return NS_OK;
}
result = tx->UndoTransaction(this);
if (NS_SUCCEEDED(result)) {
- result = mUndoStack.Pop(&tx);
+ result = mUndoStack.Pop(getter_AddRefs(tx));
if (NS_SUCCEEDED(result))
result = mRedoStack.Push(tx);
}
nsresult result2 = DidUndoNotify(t, result);
if (NS_SUCCEEDED(result))
@@ -229,54 +229,54 @@ nsTransactionManager::UndoTransaction()
return result;
}
NS_IMETHODIMP
nsTransactionManager::RedoTransaction()
{
nsresult result = NS_OK;
- nsTransactionItem *tx = 0;
+ nsRefPtr<nsTransactionItem> tx;
LOCK_TX_MANAGER(this);
// It is illegal to call RedoTransaction() while the transaction manager is
// executing a transaction's DoTransaction() method! If this happens,
// the RedoTransaction() request is ignored, and we return NS_ERROR_FAILURE.
- result = mDoStack.Peek(&tx);
+ result = mDoStack.Peek(getter_AddRefs(tx));
if (NS_FAILED(result)) {
UNLOCK_TX_MANAGER(this);
return result;
}
if (tx) {
UNLOCK_TX_MANAGER(this);
return NS_ERROR_FAILURE;
}
// Peek at the top of the redo stack. Don't remove the transaction
// until it has successfully completed.
- result = mRedoStack.Peek(&tx);
+ result = mRedoStack.Peek(getter_AddRefs(tx));
if (NS_FAILED(result)) {
UNLOCK_TX_MANAGER(this);
return result;
}
// Bail if there's nothing on the stack.
if (!tx) {
UNLOCK_TX_MANAGER(this);
return NS_OK;
}
- nsITransaction *t = 0;
+ nsCOMPtr<nsITransaction> t;
- result = tx->GetTransaction(&t);
+ result = tx->GetTransaction(getter_AddRefs(t));
if (NS_FAILED(result)) {
UNLOCK_TX_MANAGER(this);
return result;
}
PRBool doInterrupt = PR_FALSE;
@@ -290,17 +290,17 @@ nsTransactionManager::RedoTransaction()
if (doInterrupt) {
UNLOCK_TX_MANAGER(this);
return NS_OK;
}
result = tx->RedoTransaction(this);
if (NS_SUCCEEDED(result)) {
- result = mRedoStack.Pop(&tx);
+ result = mRedoStack.Pop(getter_AddRefs(tx));
if (NS_SUCCEEDED(result))
result = mUndoStack.Push(tx);
}
nsresult result2 = DidRedoNotify(t, result);
if (NS_SUCCEEDED(result))
@@ -368,42 +368,42 @@ nsTransactionManager::BeginBatch()
UNLOCK_TX_MANAGER(this);
return result;
}
NS_IMETHODIMP
nsTransactionManager::EndBatch()
{
- nsTransactionItem *tx = 0;
- nsITransaction *ti = 0;
+ nsRefPtr<nsTransactionItem> tx;
+ nsCOMPtr<nsITransaction> ti;
nsresult result;
LOCK_TX_MANAGER(this);
// XXX: Need to add some mechanism to detect the case where the transaction
// at the top of the do stack isn't the dummy transaction, so we can
// throw an error!! This can happen if someone calls EndBatch() within
// the DoTransaction() method of a transaction.
//
// For now, we can detect this case by checking the value of the
// dummy transaction's mTransaction field. If it is our dummy
// transaction, it should be NULL. This may not be true in the
// future when we allow users to execute a transaction when beginning
// a batch!!!!
- result = mDoStack.Peek(&tx);
+ result = mDoStack.Peek(getter_AddRefs(tx));
if (NS_FAILED(result)) {
UNLOCK_TX_MANAGER(this);
return result;
}
if (tx)
- tx->GetTransaction(&ti);
+ tx->GetTransaction(getter_AddRefs(ti));
if (!tx || ti) {
UNLOCK_TX_MANAGER(this);
return NS_ERROR_FAILURE;
}
PRBool doInterrupt = PR_FALSE;
@@ -467,28 +467,28 @@ nsTransactionManager::GetMaxTransactionC
return NS_OK;
}
NS_IMETHODIMP
nsTransactionManager::SetMaxTransactionCount(PRInt32 aMaxCount)
{
PRInt32 numUndoItems = 0, numRedoItems = 0, total = 0;
- nsTransactionItem *tx = 0;
+ nsRefPtr<nsTransactionItem> tx;
nsresult result;
LOCK_TX_MANAGER(this);
// It is illegal to call SetMaxTransactionCount() while the transaction
// manager is executing a transaction's DoTransaction() method because
// the undo and redo stacks might get pruned! If this happens, the
// SetMaxTransactionCount() request is ignored, and we return
// NS_ERROR_FAILURE.
- result = mDoStack.Peek(&tx);
+ result = mDoStack.Peek(getter_AddRefs(tx));
if (NS_FAILED(result)) {
UNLOCK_TX_MANAGER(this);
return result;
}
if (tx) {
UNLOCK_TX_MANAGER(this);
@@ -529,107 +529,97 @@ nsTransactionManager::SetMaxTransactionC
UNLOCK_TX_MANAGER(this);
return result;
}
// Try getting rid of some transactions on the undo stack! Start at
// the bottom of the stack and pop towards the top.
while (numUndoItems > 0 && (numRedoItems + numUndoItems) > aMaxCount) {
- tx = 0;
- result = mUndoStack.PopBottom(&tx);
+ result = mUndoStack.PopBottom(getter_AddRefs(tx));
if (NS_FAILED(result) || !tx) {
UNLOCK_TX_MANAGER(this);
return result;
}
-
- delete tx;
--numUndoItems;
}
// If necessary, get rid of some transactions on the redo stack! Start at
// the bottom of the stack and pop towards the top.
while (numRedoItems > 0 && (numRedoItems + numUndoItems) > aMaxCount) {
- tx = 0;
- result = mRedoStack.PopBottom(&tx);
+ result = mRedoStack.PopBottom(getter_AddRefs(tx));
if (NS_FAILED(result) || !tx) {
UNLOCK_TX_MANAGER(this);
return result;
}
-
- delete tx;
--numRedoItems;
}
mMaxTransactionCount = aMaxCount;
UNLOCK_TX_MANAGER(this);
return result;
}
NS_IMETHODIMP
nsTransactionManager::PeekUndoStack(nsITransaction **aTransaction)
{
- nsTransactionItem *tx = 0;
+ nsRefPtr<nsTransactionItem> tx;
nsresult result;
if (!aTransaction)
return NS_ERROR_NULL_POINTER;
*aTransaction = 0;
LOCK_TX_MANAGER(this);
- result = mUndoStack.Peek(&tx);
+ result = mUndoStack.Peek(getter_AddRefs(tx));
if (NS_FAILED(result) || !tx) {
UNLOCK_TX_MANAGER(this);
return result;
}
result = tx->GetTransaction(aTransaction);
UNLOCK_TX_MANAGER(this);
- NS_IF_ADDREF(*aTransaction);
-
return result;
}
NS_IMETHODIMP
nsTransactionManager::PeekRedoStack(nsITransaction **aTransaction)
{
- nsTransactionItem *tx = 0;
+ nsRefPtr<nsTransactionItem> tx;
nsresult result;
if (!aTransaction)
return NS_ERROR_NULL_POINTER;
*aTransaction = 0;
LOCK_TX_MANAGER(this);
- result = mRedoStack.Peek(&tx);
+ result = mRedoStack.Peek(getter_AddRefs(tx));
if (NS_FAILED(result) || !tx) {
UNLOCK_TX_MANAGER(this);
return result;
}
result = tx->GetTransaction(aTransaction);
UNLOCK_TX_MANAGER(this);
-
- NS_IF_ADDREF(*aTransaction);
return result;
}
NS_IMETHODIMP
nsTransactionManager::GetUndoList(nsITransactionList **aTransactionList)
{
if (!aTransactionList)
@@ -1039,109 +1029,101 @@ nsTransactionManager::DidMergeNotify(nsI
}
return result;
}
nsresult
nsTransactionManager::BeginTransaction(nsITransaction *aTransaction)
{
- nsTransactionItem *tx;
nsresult result = NS_OK;
// No need for LOCK/UNLOCK_TX_MANAGER() calls since the calling routine
// should have done this already!
- NS_IF_ADDREF(aTransaction);
-
// XXX: POSSIBLE OPTIMIZATION
// We could use a factory that pre-allocates/recycles transaction items.
- tx = new nsTransactionItem(aTransaction);
+ nsRefPtr<nsTransactionItem> tx = new nsTransactionItem(aTransaction);
if (!tx) {
- NS_IF_RELEASE(aTransaction);
return NS_ERROR_OUT_OF_MEMORY;
}
result = mDoStack.Push(tx);
if (NS_FAILED(result)) {
- delete tx;
return result;
}
result = tx->DoTransaction();
if (NS_FAILED(result)) {
- mDoStack.Pop(&tx);
- delete tx;
+ mDoStack.Pop(getter_AddRefs(tx));
return result;
}
return NS_OK;
}
nsresult
nsTransactionManager::EndTransaction()
{
- nsITransaction *tint = 0;
- nsTransactionItem *tx = 0;
+ nsCOMPtr<nsITransaction> tint;
+ nsRefPtr<nsTransactionItem> tx;
nsresult result = NS_OK;
// No need for LOCK/UNLOCK_TX_MANAGER() calls since the calling routine
// should have done this already!
- result = mDoStack.Pop(&tx);
+ result = mDoStack.Pop(getter_AddRefs(tx));
if (NS_FAILED(result) || !tx)
return result;
- result = tx->GetTransaction(&tint);
+ result = tx->GetTransaction(getter_AddRefs(tint));
if (NS_FAILED(result)) {
// XXX: What do we do with the transaction item at this point?
return result;
}
if (!tint) {
PRInt32 nc = 0;
// If we get here, the transaction must be a dummy batch transaction
// created by BeginBatch(). If it contains no children, get rid of it!
tx->GetNumberOfChildren(&nc);
if (!nc) {
- delete tx;
return result;
}
}
// Check if the transaction is transient. If it is, there's nothing
// more to do, just return.
PRBool isTransient = PR_FALSE;
if (tint)
result = tint->GetIsTransient(&isTransient);
if (NS_FAILED(result) || isTransient || !mMaxTransactionCount) {
// XXX: Should we be clearing the redo stack if the transaction
// is transient and there is nothing on the do stack?
- delete tx;
return result;
}
- nsTransactionItem *top = 0;
+ nsRefPtr<nsTransactionItem> top;
// Check if there is a transaction on the do stack. If there is,
// the current transaction is a "sub" transaction, and should
// be added to the transaction at the top of the do stack.
- result = mDoStack.Peek(&top);
+ result = mDoStack.Peek(getter_AddRefs(top));
if (top) {
result = top->AddChild(tx);
// XXX: What do we do if this fails?
return result;
}
@@ -1152,23 +1134,23 @@ nsTransactionManager::EndTransaction()
if (NS_FAILED(result)) {
// XXX: What do we do if this fails?
}
// Check if we can coalesce this transaction with the one at the top
// of the undo stack.
top = 0;
- result = mUndoStack.Peek(&top);
+ result = mUndoStack.Peek(getter_AddRefs(top));
if (tint && top) {
PRBool didMerge = PR_FALSE;
- nsITransaction *topTransaction = 0;
+ nsCOMPtr<nsITransaction> topTransaction;
- result = top->GetTransaction(&topTransaction);
+ result = top->GetTransaction(getter_AddRefs(topTransaction));
if (topTransaction) {
PRBool doInterrupt = PR_FALSE;
result = WillMergeNotify(topTransaction, tint, &doInterrupt);
if (NS_FAILED(result))
@@ -1182,39 +1164,35 @@ nsTransactionManager::EndTransaction()
if (NS_SUCCEEDED(result))
result = result2;
if (NS_FAILED(result)) {
// XXX: What do we do if this fails?
}
if (didMerge) {
- delete tx;
return result;
}
}
}
}
// Check to see if we've hit the max level of undo. If so,
// pop the bottom transaction off the undo stack and release it!
PRInt32 sz = 0;
result = mUndoStack.GetSize(&sz);
if (mMaxTransactionCount > 0 && sz >= mMaxTransactionCount) {
- nsTransactionItem *overflow = 0;
+ nsRefPtr<nsTransactionItem> overflow;
- result = mUndoStack.PopBottom(&overflow);
+ result = mUndoStack.PopBottom(getter_AddRefs(overflow));
// XXX: What do we do in the case where this fails?
-
- if (overflow)
- delete overflow;
}
// Push the transaction on the undo stack:
result = mUndoStack.Push(tx);
if (NS_FAILED(result)) {
// XXX: What do we do in the case where a clear fails?
diff --git a/editor/txmgr/src/nsTransactionStack.cpp b/editor/txmgr/src/nsTransactionStack.cpp
--- editor/txmgr/src/nsTransactionStack.cpp
+++ editor/txmgr/src/nsTransactionStack.cpp
@@ -34,38 +34,38 @@
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsITransaction.h"
#include "nsTransactionItem.h"
#include "nsTransactionStack.h"
#include "nsCOMPtr.h"
+#include "nsAutoPtr.h"
nsTransactionStack::nsTransactionStack()
: mQue(0)
{
- nsTransactionReleaseFunctor* theFunctor=new nsTransactionReleaseFunctor();
- mQue.SetDeallocator(theFunctor);
}
nsTransactionStack::~nsTransactionStack()
{
Clear();
}
nsresult
nsTransactionStack::Push(nsTransactionItem *aTransaction)
{
if (!aTransaction)
return NS_ERROR_NULL_POINTER;
/* nsDeque's Push() method adds new items at the back
* of the deque.
*/
+ NS_ADDREF(aTransaction);
mQue.Push(aTransaction);
return NS_OK;
}
nsresult
nsTransactionStack::Pop(nsTransactionItem **aTransaction)
{
@@ -100,52 +100,51 @@ nsTransactionStack::Peek(nsTransactionIt
if (!aTransaction)
return NS_ERROR_NULL_POINTER;
if (!mQue.GetSize()) {
*aTransaction = 0;
return NS_OK;
}
- *aTransaction = (nsTransactionItem *)(mQue.Last());
+ NS_IF_ADDREF(*aTransaction = static_cast<nsTransactionItem*>(mQue.Last()));
return NS_OK;
}
nsresult
nsTransactionStack::GetItem(PRInt32 aIndex, nsTransactionItem **aTransaction)
{
if (!aTransaction)
return NS_ERROR_NULL_POINTER;
if (aIndex < 0 || aIndex >= mQue.GetSize())
return NS_ERROR_FAILURE;
- *aTransaction = (nsTransactionItem *)(mQue.ObjectAt(aIndex));
+ NS_IF_ADDREF(*aTransaction =
+ static_cast<nsTransactionItem*>(mQue.ObjectAt(aIndex)));
return NS_OK;
}
nsresult
nsTransactionStack::Clear(void)
{
- nsTransactionItem *tx = 0;
+ nsRefPtr<nsTransactionItem> tx;
nsresult result = NS_OK;
/* Pop all transactions off the stack and release them. */
- result = Pop(&tx);
+ result = Pop(getter_AddRefs(tx));
if (NS_FAILED(result))
return result;
while (tx) {
- delete tx;
-
- result = Pop(&tx);
+ result = Pop(getter_AddRefs(tx));
if (NS_FAILED(result))
return result;
}
return NS_OK;
}
@@ -163,39 +162,30 @@ nsTransactionRedoStack::~nsTransactionRe
nsTransactionRedoStack::~nsTransactionRedoStack()
{
Clear();
}
nsresult
nsTransactionRedoStack::Clear(void)
{
- nsTransactionItem *tx = 0;
+ nsRefPtr<nsTransactionItem> tx;
nsresult result = NS_OK;
/* When clearing a Redo stack, we have to clear from the
* bottom of the stack towards the top!
*/
- result = PopBottom(&tx);
+ result = PopBottom(getter_AddRefs(tx));
if (NS_FAILED(result))
return result;
while (tx) {
- delete tx;
-
- result = PopBottom(&tx);
+ result = PopBottom(getter_AddRefs(tx));
if (NS_FAILED(result))
return result;
}
return NS_OK;
}
-void *
-nsTransactionReleaseFunctor::operator()(void *aObject)
-{
- nsTransactionItem *item = (nsTransactionItem *)aObject;
- delete item;
- return 0;
-}
diff --git a/editor/txmgr/src/nsTransactionStack.h b/editor/txmgr/src/nsTransactionStack.h
--- editor/txmgr/src/nsTransactionStack.h
+++ editor/txmgr/src/nsTransactionStack.h
@@ -37,25 +37,16 @@
#ifndef nsTransactionStack_h__
#define nsTransactionStack_h__
#include "nsDeque.h"
class nsTransactionItem;
-class nsTransactionReleaseFunctor : public nsDequeFunctor
-{
-public:
-
- nsTransactionReleaseFunctor() {}
- virtual ~nsTransactionReleaseFunctor() {}
- virtual void *operator()(void *aObject);
-};
-
class nsTransactionStack
{
nsDeque mQue;
public:
nsTransactionStack();
virtual ~nsTransactionStack();