Fix bad reference counting of atoms so we don't manipulate garbage atom pointers. b=422546 r=timeless sr=roc a=damon

This commit is contained in:
dbaron@dbaron.org 2008-03-13 11:54:01 -07:00
parent 36c58bd88a
commit acbec26224
9 changed files with 26 additions and 67 deletions

View File

@ -1522,3 +1522,8 @@ GK_ATOM(Chinese, "zh-CN")
GK_ATOM(Taiwanese, "zh-TW")
GK_ATOM(HongKongChinese, "zh-HK")
GK_ATOM(Unicode, "x-unicode")
// Names for editor transactions
GK_ATOM(TypingTxnName, "Typing")
GK_ATOM(IMETxnName, "IME")
GK_ATOM(DeleteTxnName, "Deleting")

View File

@ -104,3 +104,6 @@ FORCE_STATIC_LIB = 1
include $(topsrcdir)/config/rules.mk
INCLUDES += \
-I$(topsrcdir)/content/base/src \
$(NULL)

View File

@ -39,6 +39,7 @@
#include "PlaceholderTxn.h"
#include "nsEditor.h"
#include "IMETextTxn.h"
#include "nsGkAtoms.h"
PlaceholderTxn::PlaceholderTxn() : EditAggregateTxn(),
mAbsorb(PR_TRUE),
@ -170,9 +171,9 @@ NS_IMETHODIMP PlaceholderTxn::Merge(nsITransaction *aTransaction, PRBool *aDidMe
}
else
{ // merge typing or IME or deletion transactions if the selection matches
if (((mName.get() == nsEditor::gTypingTxnName) ||
(mName.get() == nsEditor::gIMETxnName) ||
(mName.get() == nsEditor::gDeleteTxnName))
if (((mName.get() == nsGkAtoms::TypingTxnName) ||
(mName.get() == nsGkAtoms::IMETxnName) ||
(mName.get() == nsGkAtoms::DeleteTxnName))
&& !mCommitted )
{
nsCOMPtr<nsIAbsorbingTransaction> plcTxn;// = do_QueryInterface(editTxn);

View File

@ -131,10 +131,6 @@ extern nsIParserService *sParserService;
//
//---------------------------------------------------------------------------
nsIAtom *nsEditor::gTypingTxnName;
nsIAtom *nsEditor::gIMETxnName;
nsIAtom *nsEditor::gDeleteTxnName;
nsEditor::nsEditor()
: mModCount(0)
, mPresShellWeak(nsnull)
@ -161,56 +157,11 @@ nsEditor::nsEditor()
, mPhonetic(nsnull)
{
//initialize member variables here
if (!gTypingTxnName)
gTypingTxnName = NS_NewAtom("Typing");
else
NS_ADDREF(gTypingTxnName);
if (!gIMETxnName)
gIMETxnName = NS_NewAtom("IME");
else
NS_ADDREF(gIMETxnName);
if (!gDeleteTxnName)
gDeleteTxnName = NS_NewAtom("Deleting");
else
NS_ADDREF(gDeleteTxnName);
}
nsEditor::~nsEditor()
{
/* first, delete the transaction manager if there is one.
this will release any remaining transactions.
this is important because transactions can hold onto the atoms (gTypingTxnName, ...)
and to make the optimization (holding refcounted statics) work correctly,
the editor instance needs to hold the last refcount.
If you get this wrong, expect to deref a garbage gTypingTxnName pointer if you bring up a second editor.
*/
if (mTxnMgr) {
mTxnMgr = 0;
}
nsrefcnt refCount=0;
if (gTypingTxnName) // we addref'd in the constructor
{ // want to release it without nulling out the pointer.
refCount = gTypingTxnName->Release();
if (0==refCount) {
gTypingTxnName = nsnull;
}
}
if (gIMETxnName) // we addref'd in the constructor
{ // want to release it without nulling out the pointer.
refCount = gIMETxnName->Release();
if (0==refCount) {
gIMETxnName = nsnull;
}
}
if (gDeleteTxnName) // we addref'd in the constructor
{ // want to release it without nulling out the pointer.
refCount = gDeleteTxnName->Release();
if (0==refCount) {
gDeleteTxnName = nsnull;
}
}
mTxnMgr = nsnull;
delete mPhonetic;

View File

@ -581,13 +581,6 @@ public:
// Fast non-refcounting editor root element accessor
nsIDOMElement *GetRoot();
public:
// Argh! These transaction names are used by PlaceholderTxn and
// nsPlaintextEditor. They should be localized to those classes.
static nsIAtom *gTypingTxnName;
static nsIAtom *gIMETxnName;
static nsIAtom *gDeleteTxnName;
protected:
PRUint32 mModCount; // number of modifications (for undo/redo stack)

View File

@ -102,4 +102,6 @@ FORCE_STATIC_LIB = 1
include $(topsrcdir)/config/rules.mk
INCLUDES += -I$(topsrcdir)/editor/libeditor/base \
-I$(topsrcdir)/editor/libeditor/text
-I$(topsrcdir)/editor/libeditor/text \
-I$(topsrcdir)/content/base/src \
$(NULL)

View File

@ -125,6 +125,7 @@
#include "nsEditorUtils.h"
#include "nsWSRunObject.h"
#include "nsHTMLObjectResizer.h"
#include "nsGkAtoms.h"
#include "nsIFrame.h"
#include "nsIView.h"
@ -1345,7 +1346,7 @@ NS_IMETHODIMP nsHTMLEditor::HandleKeyPress(nsIDOMKeyEvent* aKeyEvent)
NS_IMETHODIMP nsHTMLEditor::TypedText(const nsAString& aString,
PRInt32 aAction)
{
nsAutoPlaceHolderBatch batch(this, gTypingTxnName);
nsAutoPlaceHolderBatch batch(this, nsGkAtoms::TypingTxnName);
switch (aAction)
{

View File

@ -81,5 +81,7 @@ FORCE_STATIC_LIB = 1
include $(topsrcdir)/config/rules.mk
INCLUDES += -I$(topsrcdir)/editor/libeditor/base
INCLUDES += \
-I$(topsrcdir)/editor/libeditor/base \
-I$(topsrcdir)/content/base/src \
$(NULL)

View File

@ -79,6 +79,7 @@
#include "nsAOLCiter.h"
#include "nsInternetCiter.h"
#include "nsEventDispatcher.h"
#include "nsGkAtoms.h"
// Drag & Drop, Clipboard
#include "nsIClipboard.h"
@ -417,7 +418,7 @@ NS_IMETHODIMP nsPlaintextEditor::HandleKeyPress(nsIDOMKeyEvent* aKeyEvent)
NS_IMETHODIMP nsPlaintextEditor::TypedText(const nsAString& aString,
PRInt32 aAction)
{
nsAutoPlaceHolderBatch batch(this, gTypingTxnName);
nsAutoPlaceHolderBatch batch(this, nsGkAtoms::TypingTxnName);
switch (aAction)
{
@ -643,7 +644,7 @@ NS_IMETHODIMP nsPlaintextEditor::DeleteSelection(nsIEditor::EDirection aAction)
nsresult result;
// delete placeholder txns merge.
nsAutoPlaceHolderBatch batch(this, gDeleteTxnName);
nsAutoPlaceHolderBatch batch(this, nsGkAtoms::DeleteTxnName);
nsAutoRules beginRulesSniffing(this, kOpDeleteSelection, aAction);
// pre-process
@ -1712,7 +1713,7 @@ nsPlaintextEditor::SetCompositionString(const nsAString& aCompositionString, nsI
// GetCaretCoordinates so the states in Frame system sync with content
// therefore, we put the nsAutoPlaceHolderBatch into a inner block
{
nsAutoPlaceHolderBatch batch(this, gIMETxnName);
nsAutoPlaceHolderBatch batch(this, nsGkAtoms::IMETxnName);
SetIsIMEComposing(); // We set mIsIMEComposing properly.