diff --git a/content/base/src/nsContentList.cpp b/content/base/src/nsContentList.cpp index ff32dc3ebb5b..11c83ce32cf3 100644 --- a/content/base/src/nsContentList.cpp +++ b/content/base/src/nsContentList.cpp @@ -88,8 +88,7 @@ NS_IMETHODIMP nsBaseContentList::Item(PRUint32 aIndex, nsIDOMNode** aReturn) { nsISupports *tmp = NS_REINTERPRET_CAST(nsISupports *, - mElements.ElementAt(aIndex)); - + mElements.SafeElementAt(aIndex)); if (!tmp) { *aReturn = nsnull; @@ -410,8 +409,8 @@ nsContentList::Item(PRUint32 aIndex, nsIDOMNode** aReturn, PRBool aDoFlush) } nsISupports *element = NS_STATIC_CAST(nsISupports *, - mElements.ElementAt(aIndex)); - + mElements.SafeElementAt(aIndex)); + if (element) { result = CallQueryInterface(element, aReturn); } diff --git a/content/base/src/nsDocument.cpp b/content/base/src/nsDocument.cpp index d20ac952fe70..615e7b4c5c4f 100644 --- a/content/base/src/nsDocument.cpp +++ b/content/base/src/nsDocument.cpp @@ -488,8 +488,10 @@ nsDocument::~nsDocument() mInDestructor = PR_TRUE; PRInt32 indx; for (indx = 0; indx < mObservers.Count(); indx++) { + // XXX Should this be a kungfudeathgrip?!!!! nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers.ElementAt(indx); observer->DocumentWillBeDestroyed(this); + // Test to see if the observer was removed if (observer != (nsIDocumentObserver*)mObservers.ElementAt(indx)) { indx--; } @@ -1102,8 +1104,9 @@ PRInt32 nsDocument::GetNumberOfShells() NS_IMETHODIMP nsDocument::GetShellAt(PRInt32 aIndex, nsIPresShell** aShell) { - *aShell = (nsIPresShell*) mPresShells.ElementAt(aIndex); + *aShell = (nsIPresShell*) mPresShells.SafeElementAt(aIndex); NS_IF_ADDREF(*aShell); + return NS_OK; } @@ -1143,8 +1146,9 @@ nsDocument::GetNumberOfSubDocuments(PRInt32* aCount) NS_IMETHODIMP nsDocument::GetSubDocumentAt(PRInt32 aIndex, nsIDocument** aSubDoc) { - *aSubDoc = (nsIDocument*) mSubDocuments.ElementAt(aIndex); + *aSubDoc = (nsIDocument*) mSubDocuments.SafeElementAt(aIndex); NS_IF_ADDREF(*aSubDoc); + return NS_OK; } @@ -1207,8 +1211,9 @@ nsDocument::GetNumberOfStyleSheets(PRInt32* aCount) NS_IMETHODIMP nsDocument::GetStyleSheetAt(PRInt32 aIndex, nsIStyleSheet** aSheet) { - *aSheet = (nsIStyleSheet*)mStyleSheets.ElementAt(aIndex); + *aSheet = (nsIStyleSheet*)mStyleSheets.SafeElementAt(aIndex); NS_IF_ADDREF(*aSheet); + return NS_OK; } @@ -1256,6 +1261,7 @@ void nsDocument::AddStyleSheet(nsIStyleSheet* aSheet) for (PRInt32 indx = 0; indx < mObservers.Count(); indx++) { nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers.ElementAt(indx); observer->StyleSheetAdded(this, aSheet); + // handle the observer removing itself! if (observer != (nsIDocumentObserver*)mObservers.ElementAt(indx)) { indx--; } @@ -1293,6 +1299,7 @@ void nsDocument::RemoveStyleSheet(nsIStyleSheet* aSheet) for (PRInt32 indx = 0; indx < mObservers.Count(); indx++) { nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers.ElementAt(indx); observer->StyleSheetRemoved(this, aSheet); + // handle the observer removing itself! if (observer != (nsIDocumentObserver*)mObservers.ElementAt(indx)) { indx--; } @@ -1352,6 +1359,7 @@ nsDocument::UpdateStyleSheets(nsISupportsArray* aOldSheets, nsISupportsArray* aN for (PRInt32 indx = 0; indx < mObservers.Count(); indx++) { nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers.ElementAt(indx); observer->StyleSheetRemoved(this, sheet); + // handle the observer removing itself! if (observer != (nsIDocumentObserver*)mObservers.ElementAt(indx)) { indx--; } @@ -1396,6 +1404,7 @@ nsDocument::InsertStyleSheetAt(nsIStyleSheet* aSheet, PRInt32 aIndex, PRBool aNo for (indx = 0; indx < mObservers.Count(); indx++) { nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers.ElementAt(indx); observer->StyleSheetAdded(this, aSheet); + // handle the observer removing itself! if (observer != (nsIDocumentObserver*)mObservers.ElementAt(indx)) { indx--; } @@ -1433,6 +1442,7 @@ void nsDocument::SetStyleSheetDisabledState(nsIStyleSheet* aSheet, for (indx = 0; indx < mObservers.Count(); indx++) { nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers.ElementAt(indx); observer->StyleSheetDisabledStateChanged(this, aSheet, aDisabled); + // handle the observer removing itself! if (observer != (nsIDocumentObserver*)mObservers.ElementAt(indx)) { indx--; } @@ -2328,6 +2338,7 @@ nsDocument::GetDefaultView(nsIDOMAbstractView** aDefaultView) NS_ENSURE_ARG_POINTER(aDefaultView); *aDefaultView = nsnull; + NS_ENSURE_TRUE(mPresShells.Count() != 0, NS_OK); nsIPresShell *shell = NS_STATIC_CAST(nsIPresShell *, mPresShells.ElementAt(0)); NS_ENSURE_TRUE(shell, NS_OK); @@ -2361,6 +2372,7 @@ nsDocument::GetPlugins(nsIDOMPluginArray** aPlugins) *aPlugins = nsnull; // XXX Could also get this through mScriptGlobalObject + NS_ENSURE_TRUE(mPresShells.Count() != 0, NS_OK); nsIPresShell *shell = NS_STATIC_CAST(nsIPresShell *, mPresShells.ElementAt(0)); NS_ENSURE_TRUE(shell, NS_OK); @@ -2564,7 +2576,7 @@ NS_IMETHODIMP nsDocument::GetDir(nsAWritableString& aDirection) { #ifdef IBMBIDI - nsIPresShell* shell = (nsIPresShell*) mPresShells.ElementAt(0); + nsIPresShell* shell = (nsIPresShell*) mPresShells.SafeElementAt(0); if (shell) { nsCOMPtr context; shell->GetPresContext(getter_AddRefs(context) ); @@ -2594,22 +2606,24 @@ NS_IMETHODIMP nsDocument::SetDir(const nsAReadableString& aDirection) { #ifdef IBMBIDI - nsIPresShell* shell = (nsIPresShell*) mPresShells.ElementAt(0); - if (shell) { - nsCOMPtr context; - shell->GetPresContext(getter_AddRefs(context) ); - if (context) { - PRUint32 options; - context->GetBidi(&options); - for (const DirTable* elt = dirAttributes; elt->mName; elt++) { - if (aDirection == NS_ConvertASCIItoUCS2(elt->mName) ) { - if (GET_BIDI_OPTION_DIRECTION(options) != elt->mValue) { - SET_BIDI_OPTION_DIRECTION(options, elt->mValue); - context->SetBidi(options, PR_TRUE); + if (mPresShells.Count() != 0) { + nsIPresShell* shell = (nsIPresShell*) mPresShells.ElementAt(0); + if (shell) { + nsCOMPtr context; + shell->GetPresContext(getter_AddRefs(context) ); + if (context) { + PRUint32 options; + context->GetBidi(&options); + for (const DirTable* elt = dirAttributes; elt->mName; elt++) { + if (aDirection == NS_ConvertASCIItoUCS2(elt->mName) ) { + if (GET_BIDI_OPTION_DIRECTION(options) != elt->mValue) { + SET_BIDI_OPTION_DIRECTION(options, elt->mValue); + context->SetBidi(options, PR_TRUE); + } + break; } - break; - } - } // for + } // for + } } } #endif // IBMBIDI @@ -3161,6 +3175,8 @@ nsDocument::DispatchEvent(nsIDOMEvent* aEvent, PRBool *_retval) nsCOMPtr shell; GetShellAt(0, getter_AddRefs(shell)); + if (!shell) + return NS_ERROR_FAILURE; // Retrieve the context nsCOMPtr presContext; @@ -3189,6 +3205,8 @@ nsDocument::CreateEvent(const nsAReadableString& aEventType, nsCOMPtr shell; GetShellAt(0, getter_AddRefs(shell)); + if (!shell) + return NS_ERROR_FAILURE; // Retrieve the context nsCOMPtr presContext; diff --git a/content/base/src/nsDocumentEncoder.cpp b/content/base/src/nsDocumentEncoder.cpp index b8c9a470ee07..e8ad28c075ee 100644 --- a/content/base/src/nsDocumentEncoder.cpp +++ b/content/base/src/nsDocumentEncoder.cpp @@ -660,9 +660,14 @@ nsDocumentEncoder::SerializeRangeNodes(nsIDOMRange* aRange, // get start and end nodes for this recursion level nsCOMPtr startNode, endNode; - startNode = NS_STATIC_CAST(nsIContent *, mStartNodes[mStartRootIndex - aDepth]); - endNode = NS_STATIC_CAST(nsIContent *, mEndNodes[mEndRootIndex - aDepth]); - + PRInt32 start = mStartRootIndex - aDepth; + if (start >= 0 && start <= mStartNodes.Count()) + startNode = NS_STATIC_CAST(nsIContent *, mStartNodes[start]); + + PRInt32 end = mEndRootIndex - aDepth; + if (end >= 0 && end <= mEndNodes.Count()) + endNode = NS_STATIC_CAST(nsIContent *, mEndNodes[end]); + if ((startNode != content) && (endNode != content)) { // node is completely contained in range. Serialize the whole subtree @@ -713,9 +718,9 @@ nsDocumentEncoder::SerializeRangeNodes(nsIDOMRange* aRange, nsCOMPtr child; nsCOMPtr childAsNode; PRInt32 startOffset = 0, endOffset = -1; - if (startNode == content) + if (startNode == content && mStartRootIndex >= aDepth) startOffset = NS_PTR_TO_INT32(mStartOffsets[mStartRootIndex - aDepth]); - if (endNode == content) + if (endNode == content && mEndRootIndex >= aDepth) endOffset = NS_PTR_TO_INT32(mEndOffsets[mEndRootIndex - aDepth]) ; // generated content will cause offset values of -1 to be returned. PRInt32 j, childCount=0; @@ -769,7 +774,7 @@ nsDocumentEncoder::SerializeRangeContextStart(const nsVoidArray& aAncestorArray, PRInt32 i = aAncestorArray.Count(); nsresult rv = NS_OK; - while (i) { + while (i > 0) { nsIDOMNode *node = (nsIDOMNode *)aAncestorArray.ElementAt(--i); if (!node) @@ -791,9 +796,10 @@ nsDocumentEncoder::SerializeRangeContextEnd(const nsVoidArray& aAncestorArray, nsAWritableString& aString) { PRInt32 i = 0; + PRInt32 count = aAncestorArray.Count(); nsresult rv = NS_OK; - while (1) { + while (i < count) { nsIDOMNode *node = (nsIDOMNode *)aAncestorArray.ElementAt(i++); if (!node) @@ -1222,33 +1228,33 @@ nsHTMLCopyEncoder::EncodeToStringWithContext(nsAWritableString& aEncodedString, // where all the cells are in the same table. // leaf of ancestors might be text node. If so discard it. + PRInt32 count = mCommonAncestors.Count(); + PRInt32 i; nsCOMPtr node; - node = NS_STATIC_CAST(nsIDOMNode *, mCommonAncestors.ElementAt(0)); + if (count > 0) + node = NS_STATIC_CAST(nsIDOMNode *, mCommonAncestors.ElementAt(0)); + if (node && IsTextNode(node)) { mCommonAncestors.RemoveElementAt(0); // don't forget to adjust range depth info if (mStartDepth) mStartDepth--; if (mEndDepth) mEndDepth--; + // and the count + count--; } - PRInt32 i = mCommonAncestors.Count(); - - node = NS_STATIC_CAST(nsIDOMNode *, mCommonAncestors.ElementAt(--i)); - - while (node) + i = count; + while (i > 0) { - SerializeNodeStart(node, 0, -1, aContextString); node = NS_STATIC_CAST(nsIDOMNode *, mCommonAncestors.ElementAt(--i)); + SerializeNodeStart(node, 0, -1, aContextString); } - - i = 0; - node = NS_STATIC_CAST(nsIDOMNode *, mCommonAncestors.ElementAt(i)); - - while (node) + //i = 0; guaranteed by above + while (i < count) { + node = NS_STATIC_CAST(nsIDOMNode *, mCommonAncestors.ElementAt(i++)); SerializeNodeEnd(node, aContextString); - node = NS_STATIC_CAST(nsIDOMNode *, mCommonAncestors.ElementAt(++i)); } // encode range info : the start and end depth of the selection, where the depth is diff --git a/content/base/src/nsGenericDOMDataNode.cpp b/content/base/src/nsGenericDOMDataNode.cpp index ba08166d1521..9b18ed591c1e 100644 --- a/content/base/src/nsGenericDOMDataNode.cpp +++ b/content/base/src/nsGenericDOMDataNode.cpp @@ -230,7 +230,7 @@ nsGenericDOMDataNode::GetPreviousSibling(nsIDOMNode** aPrevSibling) if (parent_weak) { PRInt32 pos; parent_weak->IndexOf(this, pos); - if (pos > -1 ) { + if (pos > 0 ) { parent_weak->ChildAt(--pos, *getter_AddRefs(sibling)); } } else if (mDocument) { @@ -238,7 +238,7 @@ nsGenericDOMDataNode::GetPreviousSibling(nsIDOMNode** aPrevSibling) // document) need to go to the document to find their next sibling. PRInt32 pos; mDocument->IndexOf(this, pos); - if (pos > -1 ) { + if (pos > 0 ) { mDocument->ChildAt(--pos, *getter_AddRefs(sibling)); } } diff --git a/content/base/src/nsGenericElement.cpp b/content/base/src/nsGenericElement.cpp index bb23378ff395..f55835fbfd3a 100644 --- a/content/base/src/nsGenericElement.cpp +++ b/content/base/src/nsGenericElement.cpp @@ -171,227 +171,6 @@ nsChildContentList::DropReference() mContent = nsnull; } -//---------------------------------------------------------------------- - -nsCheapVoidArray::nsCheapVoidArray() -{ - mChildren = nsnull; -} - -nsCheapVoidArray::~nsCheapVoidArray() -{ - if (!HasSingleChild()) { - nsVoidArray* vector = GetChildVector(); - if (vector) { - delete vector; - } - } -} - -PRInt32 -nsCheapVoidArray::Count() const -{ - if (HasSingleChild()) { - return 1; - } - else { - nsVoidArray* vector = GetChildVector(); - if (vector) { - return vector->Count(); - } - } - - return 0; -} - -void* -nsCheapVoidArray::ElementAt(PRInt32 aIndex) const -{ - if (HasSingleChild()) { - if (0 == aIndex) { - return (void*)GetSingleChild(); - } - } - else { - nsVoidArray* vector = GetChildVector(); - if (vector) { - return vector->ElementAt(aIndex); - } - } - - return nsnull; -} - -PRInt32 -nsCheapVoidArray::IndexOf(void* aPossibleElement) const -{ - if (HasSingleChild()) { - if (aPossibleElement == (void*)GetSingleChild()) { - return 0; - } - } - else { - nsVoidArray* vector = GetChildVector(); - if (vector) { - return vector->IndexOf(aPossibleElement); - } - } - - return -1; -} - -PRBool -nsCheapVoidArray::InsertElementAt(void* aElement, PRInt32 aIndex) -{ - nsVoidArray* vector; - if (HasSingleChild()) { - vector = SwitchToVector(); - } - else { - vector = GetChildVector(); - if (!vector) { - if (0 == aIndex) { - SetSingleChild(aElement); - return PR_TRUE; - } - else { - return PR_FALSE; - } - } - } - - return vector->InsertElementAt(aElement, aIndex); -} - -PRBool -nsCheapVoidArray::ReplaceElementAt(void* aElement, PRInt32 aIndex) -{ - if (HasSingleChild()) { - if (aIndex == 0) { - SetSingleChild(aElement); - return PR_TRUE; - } - else { - return PR_FALSE; - } - } - else { - nsVoidArray* vector = GetChildVector(); - if (vector) { - return vector->ReplaceElementAt(aElement, aIndex); - } - else { - return PR_FALSE; - } - } -} - -PRBool -nsCheapVoidArray::AppendElement(void* aElement) -{ - nsVoidArray* vector; - if (HasSingleChild()) { - vector = SwitchToVector(); - } - else { - vector = GetChildVector(); - if (!vector) { - SetSingleChild(aElement); - return PR_TRUE; - } - } - - return vector->AppendElement(aElement); -} - -PRBool -nsCheapVoidArray::RemoveElement(void* aElement) -{ - if (HasSingleChild()) { - if (aElement == GetSingleChild()) { - SetSingleChild(nsnull); - return PR_TRUE; - } - } - else { - nsVoidArray* vector = GetChildVector(); - if (vector) { - return vector->RemoveElement(aElement); - } - } - - return PR_FALSE; -} - -PRBool -nsCheapVoidArray::RemoveElementAt(PRInt32 aIndex) -{ - if (HasSingleChild()) { - if (0 == aIndex) { - SetSingleChild(nsnull); - return PR_TRUE; - } - } - else { - nsVoidArray* vector = GetChildVector(); - if (vector) { - return vector->RemoveElementAt(aIndex); - } - } - - return PR_FALSE; -} - -void -nsCheapVoidArray::Compact() -{ - if (!HasSingleChild()) { - nsVoidArray* vector = GetChildVector(); - if (vector) { - vector->Compact(); - } - } -} - -void -nsCheapVoidArray::Clear() -{ - if (HasSingleChild()) { - SetSingleChild(nsnull); - - return; - } - - nsVoidArray* vector = GetChildVector(); - if (vector) { - vector->Clear(); - } -} - -void -nsCheapVoidArray::SetSingleChild(void* aChild) -{ - if (aChild) - mChildren = (void*)(PtrBits(aChild) | 0x1); - else - mChildren = nsnull; -} - -nsVoidArray* -nsCheapVoidArray::SwitchToVector() -{ - void* child = GetSingleChild(); - - mChildren = (void*)new nsAutoVoidArray(); - nsVoidArray* vector = GetChildVector(); - if (vector && child) { - vector->AppendElement(child); - } - - return vector; -} - - NS_IMETHODIMP nsNode3Tearoff::QueryInterface(REFNSIID aIID, void** aInstancePtr) { @@ -927,7 +706,7 @@ nsGenericElement::GetPreviousSibling(nsIDOMNode** aPrevSibling) if (nsnull != mParent) { PRInt32 pos; mParent->IndexOf(this, pos); - if (pos > -1 ) { + if (pos > 0 ) { mParent->ChildAt(--pos, sibling); } } @@ -936,7 +715,7 @@ nsGenericElement::GetPreviousSibling(nsIDOMNode** aPrevSibling) // document) need to go to the document to find their next sibling. PRInt32 pos; mDocument->IndexOf(this, pos); - if (pos > -1 ) { + if (pos > 0 ) { mDocument->ChildAt(--pos, sibling); } } @@ -3086,7 +2865,7 @@ nsGenericContainerElement::HasChildNodes(PRBool* aReturn) nsresult nsGenericContainerElement::GetFirstChild(nsIDOMNode** aNode) { - nsIContent *child = (nsIContent *)mChildren.ElementAt(0); + nsIContent *child = (nsIContent *)mChildren.SafeElementAt(0); if (nsnull != child) { nsresult res = child->QueryInterface(NS_GET_IID(nsIDOMNode), (void**)aNode); @@ -3100,12 +2879,14 @@ nsGenericContainerElement::GetFirstChild(nsIDOMNode** aNode) nsresult nsGenericContainerElement::GetLastChild(nsIDOMNode** aNode) { - nsIContent *child = (nsIContent *)mChildren.ElementAt(mChildren.Count()-1); - if (nsnull != child) { - nsresult res = child->QueryInterface(NS_GET_IID(nsIDOMNode), - (void**)aNode); - NS_ASSERTION(NS_OK == res, "Must be a DOM Node"); // must be a DOM Node - return res; + if (mChildren.Count() != 0) { + nsIContent *child = (nsIContent *)mChildren.ElementAt(mChildren.Count()-1); + if (nsnull != child) { + nsresult res = child->QueryInterface(NS_GET_IID(nsIDOMNode), + (void**)aNode); + NS_ASSERTION(NS_OK == res, "Must be a DOM Node"); // must be a DOM Node + return res; + } } *aNode = nsnull; return NS_OK; @@ -3624,11 +3405,12 @@ nsresult nsGenericContainerElement::ChildAt(PRInt32 aIndex, nsIContent*& aResult) const { - nsIContent *child = (nsIContent *)mChildren.ElementAt(aIndex); - if (nsnull != child) { - NS_ADDREF(child); - } + // I really prefer NOT to do this test on all ChildAt calls - perhaps we + // should add FastChildAt(). + nsIContent *child = (nsIContent *)mChildren.SafeElementAt(aIndex); + NS_IF_ADDREF(child); aResult = child; + return NS_OK; } diff --git a/content/base/src/nsGenericElement.h b/content/base/src/nsGenericElement.h index de4351180b4e..179ed5698f49 100644 --- a/content/base/src/nsGenericElement.h +++ b/content/base/src/nsGenericElement.h @@ -85,49 +85,6 @@ private: nsIContent *mContent; }; -class nsCheapVoidArray { -public: - nsCheapVoidArray(); - ~nsCheapVoidArray(); - - PRInt32 Count() const; - void* ElementAt(PRInt32 aIndex) const; - PRInt32 IndexOf(void* aPossibleElement) const; - PRBool InsertElementAt(void* aElement, PRInt32 aIndex); - PRBool ReplaceElementAt(void* aElement, PRInt32 aIndex); - PRBool AppendElement(void* aElement); - PRBool RemoveElement(void* aElement); - PRBool RemoveElementAt(PRInt32 aIndex); - void Compact(); - void Clear(); - - void* operator[](PRInt32 aIndex) const { return ElementAt(aIndex); } - -private: - typedef unsigned long PtrBits; - - PRBool HasSingleChild() const - { - return (mChildren && (PtrBits(mChildren) & 0x1)); - } - void* GetSingleChild() const - { - return (mChildren ? ((void*)(PtrBits(mChildren) & ~0x1)) : nsnull); - } - void SetSingleChild(void *aChild); - nsVoidArray* GetChildVector() const - { - return (nsVoidArray*)mChildren; - } - nsVoidArray* SwitchToVector(); - - // A tagged pointer that's either a pointer to a single child - // or a pointer to a vector of multiple children. This is a space - // optimization since a large number of containers have only a - // single child. - void *mChildren; -}; - // There are a set of DOM- and scripting-specific instance variables // that may only be instantiated when a content object is accessed // through the DOM. Rather than burn actual slots in the content @@ -519,7 +476,7 @@ protected: #endif nsVoidArray* mAttributes; - nsCheapVoidArray mChildren; + nsSmallVoidArray mChildren; }; diff --git a/content/base/src/nsNameSpaceManager.cpp b/content/base/src/nsNameSpaceManager.cpp index a8949712182f..51b23a035cac 100644 --- a/content/base/src/nsNameSpaceManager.cpp +++ b/content/base/src/nsNameSpaceManager.cpp @@ -158,7 +158,7 @@ static PRInt32 FindNameSpaceID(const nsAReadableString& aURI) static const nsString* FindNameSpaceURI(PRInt32 aID) { NS_ASSERTION(nsnull != gURIArray, "no URI array"); - return (const nsString*)gURIArray->ElementAt(aID - 1); + return (const nsString*)gURIArray->SafeElementAt(aID - 1); } //----------------------------------------------------------- diff --git a/content/base/src/nsRange.cpp b/content/base/src/nsRange.cpp index 0773c22dc603..4654a68b6c92 100644 --- a/content/base/src/nsRange.cpp +++ b/content/base/src/nsRange.cpp @@ -777,19 +777,19 @@ PRBool nsRange::IsIncreasing(nsIDOMNode* aStartN, PRInt32 aStartOffset, --numStartAncestors; // adjusting for 0-based counting --numEndAncestors; // back through the ancestors, starting from the root, until first non-matching ancestor found - while (mStartAncestors->ElementAt(numStartAncestors) == mEndAncestors->ElementAt(numEndAncestors)) + while (numStartAncestors >= 0 && numEndAncestors >= 0 && + mStartAncestors->ElementAt(numStartAncestors) == mEndAncestors->ElementAt(numEndAncestors)) { --numStartAncestors; --numEndAncestors; - if (numStartAncestors<0) - break; // this will only happen if one endpoint's node is the common ancestor of the other - if (numEndAncestors<0) - break; + // numStartAncestors will only be <0 if one endpoint's node is the + // common ancestor of the other } // now back up one and that's the last common ancestor from the root, // or the first common ancestor from the leaf perspective numStartAncestors++; numEndAncestors++; + // both indexes are now >= 0 commonNodeStartOffset = NS_PTR_TO_INT32(mStartAncestorOffsets->ElementAt(numStartAncestors)); commonNodeEndOffset = NS_PTR_TO_INT32(mEndAncestorOffsets->ElementAt(numEndAncestors)); @@ -951,18 +951,17 @@ nsCOMPtr nsRange::CommonParent(nsIDOMNode* aNode1, nsIDOMNode* aNode // back through the ancestors, starting from the root, until // first different ancestor found. - while (array1.ElementAt(i) == array2.ElementAt(j)) + while (i >= 0 && j >= 0 && array1.ElementAt(i) == array2.ElementAt(j)) { --i; --j; - if (i<0) - break; // this will only happen if one endpoint's node is the common ancestor of the other - if (j<0) - break; + // i < 0 will only happen if one endpoint's node is the common ancestor + // of the other } // now back up one and that's the last common ancestor from the root, // or the first common ancestor from the leaf perspective i++; + // i >= 0 now nsIDOMNode *node = NS_STATIC_CAST(nsIDOMNode*, array1.ElementAt(i)); theParent = do_QueryInterface(node); return theParent; @@ -1465,17 +1464,18 @@ nsresult nsRange::DeleteContents() } // remove the nodes on the delete list - while (deleteList.Count()) + // reverse order delete is faster since the nodes will tend to be in order + for (PRInt32 i = deleteList.Count()-1; i >= 0; --i) { - cN = do_QueryInterface(NS_STATIC_CAST(nsIContent*, deleteList.ElementAt(0))); + cN = do_QueryInterface(NS_STATIC_CAST(nsIContent*, deleteList.ElementAt(i))); res = cN->GetParent(*getter_AddRefs(cParent)); if (NS_FAILED(res)) return res; res = cParent->IndexOf(cN,indx); if (NS_FAILED(res)) return res; res = cParent->RemoveChildAt(indx, PR_TRUE); if (NS_FAILED(res)) return res; - deleteList.RemoveElementAt(0); } + //deleteList.Clear(); not needed, this will be deleted on function exit // If mStartParent is a text node, delete the text after start offset nsCOMPtr textNode( do_QueryInterface(mStartParent) ); @@ -2088,10 +2088,13 @@ nsresult nsRange::OwnerChildInserted(nsIContent* aParentNode, PRInt32 aOffset) if (NS_FAILED(res)) return res; if (!domNode) return NS_ERROR_UNEXPECTED; - PRInt32 loop = 0; - nsRange* theRange = NS_STATIC_CAST(nsRange*, (theRangeList->ElementAt(loop))); - while (theRange) + + PRInt32 count = theRangeList->Count(); + for (PRInt32 loop = 0; loop < count; loop++) { + nsRange* theRange = NS_STATIC_CAST(nsRange*, (theRangeList->ElementAt(loop))); + NS_ASSERTION(theRange, "oops, no range"); + // sanity check - do range and content agree over ownership? res = theRange->ContentOwnsUs(domNode); NS_PRECONDITION(NS_SUCCEEDED(res), "range and content disagree over range ownership"); @@ -2109,8 +2112,6 @@ nsresult nsRange::OwnerChildInserted(nsIContent* aParentNode, PRInt32 aOffset) } NS_PRECONDITION(NS_SUCCEEDED(res), "error updating range list"); } - loop++; - theRange = NS_STATIC_CAST(nsRange*, (theRangeList->ElementAt(loop))); } return NS_OK; } @@ -2137,10 +2138,12 @@ nsresult nsRange::OwnerChildRemoved(nsIContent* aParentNode, PRInt32 aOffset, ns parent->GetRangeList(theRangeList); if (!theRangeList) return NS_OK; - PRInt32 loop = 0; - nsRange* theRange = NS_STATIC_CAST(nsRange*, (theRangeList->ElementAt(loop))); - while (theRange) + PRInt32 count = theRangeList->Count(); + for (PRInt32 loop = 0; loop < count; loop++) { + nsRange* theRange = NS_STATIC_CAST(nsRange*, (theRangeList->ElementAt(loop))); + NS_ASSERTION(theRange, "oops, no range"); + // sanity check - do range and content agree over ownership? res = theRange->ContentOwnsUs(domNode); NS_PRECONDITION(NS_SUCCEEDED(res), "range and content disagree over range ownership"); @@ -2160,8 +2163,6 @@ nsresult nsRange::OwnerChildRemoved(nsIContent* aParentNode, PRInt32 aOffset, ns } } } - loop++; - theRange = NS_STATIC_CAST(nsRange*, (theRangeList->ElementAt(loop))); } return NS_OK; @@ -2209,10 +2210,12 @@ nsresult nsRange::TextOwnerChanged(nsIContent* aTextNode, PRInt32 aStartChanged, if (NS_FAILED(res)) return res; if (!domNode) return NS_ERROR_UNEXPECTED; - PRInt32 loop = 0; - nsRange* theRange = NS_STATIC_CAST(nsRange*, (theRangeList->ElementAt(loop))); - while (theRange) + PRInt32 count = theRangeList->Count(); + for (PRInt32 loop = 0; loop < count; loop++) { + nsRange* theRange = NS_STATIC_CAST(nsRange*, (theRangeList->ElementAt(loop))); + NS_ASSERTION(theRange, "oops, no range"); + // sanity check - do range and content agree over ownership? res = theRange->ContentOwnsUs(domNode); NS_PRECONDITION(NS_SUCCEEDED(res), "range and content disagree over range ownership"); @@ -2247,8 +2250,6 @@ nsresult nsRange::TextOwnerChanged(nsIContent* aTextNode, PRInt32 aStartChanged, theRange->mEndOffset += aStartChanged + aReplaceLength - aEndChanged; } } - loop++; - theRange = NS_STATIC_CAST(nsRange*, (theRangeList->ElementAt(loop))); } return NS_OK; diff --git a/content/events/src/nsEventListenerManager.cpp b/content/events/src/nsEventListenerManager.cpp index a9ea7d2bba58..a42d119ffbc7 100644 --- a/content/events/src/nsEventListenerManager.cpp +++ b/content/events/src/nsEventListenerManager.cpp @@ -111,13 +111,13 @@ GenericListenersHashEnum(nsHashKey *aKey, void *aData, void* closure) PRInt32 i, count = listeners->Count(); nsListenerStruct *ls; PRBool* scriptOnly = NS_STATIC_CAST(PRBool*, closure); - for (i = 0; i < count; i++) { + for (i = count-1; i >= 0; --i) { ls = (nsListenerStruct*)listeners->ElementAt(i); if (ls != nsnull) { if (*scriptOnly) { if (ls->mFlags & NS_PRIV_EVENT_FLAG_SCRIPT) { NS_RELEASE(ls->mListener); - listeners->RemoveElement((void*)ls); + //listeners->RemoveElement((void*)ls); we delete the entire array anyways, no need to RemoveElement PR_DELETE(ls); } } @@ -153,7 +153,8 @@ nsresult nsEventListenerManager::RemoveAllListeners(PRBool aScriptOnly) } if (mMultiListeners) { - for (int i=0; iCount(); i++) { nsVoidArray* listeners; listeners = NS_STATIC_CAST(nsVoidArray*, mMultiListeners->ElementAt(i)); ReleaseListeners(&listeners, aScriptOnly); @@ -195,6 +196,7 @@ nsVoidArray* nsEventListenerManager::GetListenersByType(EventArrayType aType, nsHashKey* aKey, PRBool aCreate) { + NS_ASSERTION(aType >= 0,"Negative EventListenerType?"); //Look for existing listeners if (aType == eEventArrayType_Hash && aKey && (mManagerType & NS_ELM_HASH)) { if (mGenericListeners && mGenericListeners->Exists(aKey)) { @@ -210,7 +212,7 @@ nsVoidArray* nsEventListenerManager::GetListenersByType(EventArrayType aType, else if (mManagerType & NS_ELM_MULTI) { if (mMultiListeners) { PRInt32 index = aType; - if (index >= 0) { + if (index < mMultiListeners->Count()) { nsVoidArray* listeners; listeners = NS_STATIC_CAST(nsVoidArray*, mMultiListeners->ElementAt(index)); if (listeners) { @@ -265,7 +267,7 @@ nsVoidArray* nsEventListenerManager::GetListenersByType(EventArrayType aType, PRInt32 index = aType; if (index >= 0) { nsVoidArray* listeners; - NS_ASSERTION(!mMultiListeners->ElementAt(index), "Found existing listeners, should be none"); + NS_ASSERTION(index >= mMultiListeners->Count() || !mMultiListeners->ElementAt(index), "Found existing listeners, should be none"); listeners = new nsAutoVoidArray(); if (!listeners) { //out of memory @@ -352,7 +354,7 @@ void nsEventListenerManager::ReleaseListeners(nsVoidArray** aListeners, PRBool a if (aScriptOnly) { if (ls->mFlags & NS_PRIV_EVENT_FLAG_SCRIPT) { NS_RELEASE(ls->mListener); - (*aListeners)->RemoveElement((void*)ls); + //(*aListeners)->RemoveElement((void*)ls); We're going to delete the array anyways PR_DELETE(ls); } } @@ -511,6 +513,7 @@ nsEventListenerManager::RemoveEventListener(nsIDOMEventListener *aListener, listeners->RemoveElement((void*)ls); PR_DELETE(ls); listenerRemoved = PR_TRUE; + break; // otherwise we'd need to adjust loop count... } } } @@ -2031,7 +2034,7 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext, } if (NS_OK == ret) { for (int i=0; !mListenersRemoved && listeners && iCount(); i++) { - nsListenerStruct* ls = (nsListenerStruct*)listeners->ElementAt(i); + nsListenerStruct *ls = (nsListenerStruct*)listeners->ElementAt(i); if (ls->mFlags & aFlags) { nsCOMPtr scrollListener(do_QueryInterface(ls->mListener)); diff --git a/content/html/content/src/nsGenericHTMLElement.cpp b/content/html/content/src/nsGenericHTMLElement.cpp index c95fad8a149a..22227442eb07 100644 --- a/content/html/content/src/nsGenericHTMLElement.cpp +++ b/content/html/content/src/nsGenericHTMLElement.cpp @@ -3596,10 +3596,10 @@ nsGenericHTMLContainerElement::CopyInnerTo(nsIContent* aSrcContent, } if (aDeep) { - PRInt32 index; + PRInt32 indx; PRInt32 count = mChildren.Count(); - for (index = 0; index < count; index++) { - nsIContent* child = (nsIContent*)mChildren.ElementAt(index); + for (indx = 0; indx < count; indx++) { + nsIContent* child = (nsIContent*)mChildren.ElementAt(indx); nsCOMPtr node(do_QueryInterface(child)); @@ -3653,7 +3653,7 @@ nsGenericHTMLContainerElement::HasChildNodes(PRBool* aReturn) NS_IMETHODIMP nsGenericHTMLContainerElement::GetFirstChild(nsIDOMNode** aNode) { - nsIContent *child = (nsIContent *)mChildren.ElementAt(0); + nsIContent *child = (nsIContent *)mChildren.SafeElementAt(0); if (child) { nsresult res = child->QueryInterface(NS_GET_IID(nsIDOMNode), (void**)aNode); @@ -3668,13 +3668,15 @@ nsGenericHTMLContainerElement::GetFirstChild(nsIDOMNode** aNode) NS_IMETHODIMP nsGenericHTMLContainerElement::GetLastChild(nsIDOMNode** aNode) { - nsIContent *child = (nsIContent *)mChildren.ElementAt(mChildren.Count()-1); - if (child) { - nsresult res = child->QueryInterface(NS_GET_IID(nsIDOMNode), - (void**)aNode); - - NS_ASSERTION(NS_OK == res, "Must be a DOM Node"); // must be a DOM Node - return res; + if (0 != mChildren.Count()) { + nsIContent *child = (nsIContent *)mChildren.ElementAt(mChildren.Count()-1); + if (child) { + nsresult res = child->QueryInterface(NS_GET_IID(nsIDOMNode), + (void**)aNode); + + NS_ASSERTION(NS_OK == res, "Must be a DOM Node"); // must be a DOM Node + return res; + } } *aNode = nsnull; return NS_OK; @@ -3705,11 +3707,12 @@ NS_IMETHODIMP nsGenericHTMLContainerElement::ChildAt(PRInt32 aIndex, nsIContent*& aResult) const { - nsIContent *child = (nsIContent *)mChildren.ElementAt(aIndex); - if (nsnull != child) { - NS_ADDREF(child); - } + // I really prefer NOT to do this test on all ChildAt calls - perhaps we + // should add FastChildAt(). + nsIContent *child = (nsIContent *)mChildren.SafeElementAt(aIndex); + NS_IF_ADDREF(child); aResult = child; + return NS_OK; } @@ -3772,7 +3775,8 @@ nsGenericHTMLContainerElement::ReplaceChildAt(nsIContent* aKid, PRBool aDeepSetDocument) { NS_PRECONDITION(nsnull != aKid, "null ptr"); - nsIContent* oldKid = (nsIContent *)mChildren.ElementAt(aIndex); + nsIContent* oldKid = NS_STATIC_CAST(nsIContent *, + mChildren.SafeElementAt(aIndex)); nsIDocument* doc = mDocument; if (aNotify && (nsnull != doc)) { doc->BeginUpdate(); @@ -3788,9 +3792,11 @@ nsGenericHTMLContainerElement::ReplaceChildAt(nsIContent* aKid, doc->ContentReplaced(this, oldKid, aKid, aIndex); } } - oldKid->SetDocument(nsnull, PR_TRUE, PR_TRUE); - oldKid->SetParent(nsnull); - NS_RELEASE(oldKid); + if (oldKid) { + oldKid->SetDocument(nsnull, PR_TRUE, PR_TRUE); + oldKid->SetParent(nsnull); + NS_RELEASE(oldKid); + } } if (aNotify && (nsnull != doc)) { doc->EndUpdate(); @@ -3846,7 +3852,8 @@ nsGenericHTMLContainerElement::RemoveChildAt(PRInt32 aIndex, PRBool aNotify) if (aNotify && (nsnull != doc)) { doc->BeginUpdate(); } - nsIContent* oldKid = (nsIContent *)mChildren.ElementAt(aIndex); + nsIContent* oldKid = NS_STATIC_CAST(nsIContent *, + mChildren.SafeElementAt(aIndex)); if (nsnull != oldKid ) { if (nsGenericElement::HasMutationListeners(this, NS_EVENT_BITS_MUTATION_NODEREMOVED)) { diff --git a/content/html/content/src/nsGenericHTMLElement.h b/content/html/content/src/nsGenericHTMLElement.h index aab37461a406..c5c222ba940a 100644 --- a/content/html/content/src/nsGenericHTMLElement.h +++ b/content/html/content/src/nsGenericHTMLElement.h @@ -566,7 +566,7 @@ public: PRBool aDeepSetDocument); NS_IMETHOD RemoveChildAt(PRInt32 aIndex, PRBool aNotify); - nsCheapVoidArray mChildren; + nsSmallVoidArray mChildren; }; //---------------------------------------------------------------------- diff --git a/content/html/content/src/nsHTMLFormElement.cpp b/content/html/content/src/nsHTMLFormElement.cpp index d43311d69ae1..1b3e6467549e 100644 --- a/content/html/content/src/nsHTMLFormElement.cpp +++ b/content/html/content/src/nsHTMLFormElement.cpp @@ -583,9 +583,11 @@ nsHTMLFormElement::GetElementCount(PRUint32* aCount) const NS_IMETHODIMP nsHTMLFormElement::GetElementAt(PRInt32 aIndex, nsIFormControl** aFormControl) const -{ - *aFormControl = (nsIFormControl*) mControls->mElements.ElementAt(aIndex); +{ + *aFormControl = NS_STATIC_CAST(nsIFormControl *, + mControls->mElements.SafeElementAt(aIndex)); NS_IF_ADDREF(*aFormControl); + return NS_OK; } @@ -794,12 +796,11 @@ nsFormControlList::GetLength(PRUint32* aLength) NS_IMETHODIMP nsFormControlList::Item(PRUint32 aIndex, nsIDOMNode** aReturn) { - nsIFormControl *control = (nsIFormControl*)mElements.ElementAt(aIndex); - + nsIFormControl *control = NS_STATIC_CAST(nsIFormControl *, + mElements.SafeElementAt(aIndex)); if (control) { return CallQueryInterface(control, aReturn); } - *aReturn = nsnull; return NS_OK; diff --git a/content/html/document/src/nsHTMLDocument.cpp b/content/html/document/src/nsHTMLDocument.cpp index f3a73adc3aa2..ba5eb274d3db 100644 --- a/content/html/document/src/nsHTMLDocument.cpp +++ b/content/html/document/src/nsHTMLDocument.cpp @@ -987,7 +987,8 @@ nsHTMLDocument::InternalAddStyleSheet(nsIStyleSheet* aSheet) // subclass hook f mStyleSheets.AppendElement(aSheet); } else { - if (mStyleAttrStyleSheet == mStyleSheets.ElementAt(mStyleSheets.Count() - 1)) { + if (mStyleSheets.Count() != 0 && + mStyleAttrStyleSheet == mStyleSheets.ElementAt(mStyleSheets.Count() - 1)) { // keep attr sheet last mStyleSheets.InsertElementAt(aSheet, mStyleSheets.Count() - 1); } @@ -1117,16 +1118,15 @@ nsHTMLDocument::SetDTDMode(nsDTDMode aMode) if (mCSSLoader) { mCSSLoader->SetQuirkMode(PRBool(eDTDMode_strict!= mDTDMode)); } - - nsIPresShell* shell = (nsIPresShell*) mPresShells.ElementAt(0); + nsIPresShell* shell = (nsIPresShell*) mPresShells.SafeElementAt(0); if (nsnull != shell) { nsCOMPtr pc; shell->GetPresContext(getter_AddRefs(pc)); - if (pc) { - pc->SetCompatibilityMode(((eDTDMode_strict== mDTDMode) ? - eCompatibility_Standard : - eCompatibility_NavQuirks)); - } + if (pc) { + pc->SetCompatibilityMode(((eDTDMode_strict== mDTDMode) ? + eCompatibility_Standard : + eCompatibility_NavQuirks)); + } } return NS_OK; @@ -2180,7 +2180,7 @@ nsHTMLDocument::OpenCommon(nsIURI* aSourceURL) nsCOMPtr webShell; // Get the webshell of our primary presentation shell - nsIPresShell* shell = (nsIPresShell*) mPresShells.ElementAt(0); + nsIPresShell* shell = (nsIPresShell*) mPresShells.SafeElementAt(0); if (shell) { nsCOMPtr cx; shell->GetPresContext(getter_AddRefs(cx)); @@ -3013,7 +3013,7 @@ nsHTMLDocument::GetSelection(nsAWritableString& aReturn) consoleService->LogStringMessage(NS_LITERAL_STRING("Deprecated method document.getSelection() called. Please use window.getSelection() instead.").get()); } - nsIPresShell* shell = (nsIPresShell*)mPresShells.ElementAt(0); + nsIPresShell* shell = (nsIPresShell*)mPresShells.SafeElementAt(0); if (!shell) { return NS_OK; diff --git a/content/html/document/src/nsHTMLFragmentContentSink.cpp b/content/html/document/src/nsHTMLFragmentContentSink.cpp index 363a313d7c58..0135916985ee 100644 --- a/content/html/document/src/nsHTMLFragmentContentSink.cpp +++ b/content/html/document/src/nsHTMLFragmentContentSink.cpp @@ -740,7 +740,8 @@ nsHTMLFragmentContentSink::GetCurrentContent() { if (nsnull != mContentStack) { PRInt32 indx = mContentStack->Count() - 1; - return (nsIContent *)mContentStack->ElementAt(indx); + if (indx >= 0) + return (nsIContent *)mContentStack->ElementAt(indx); } return nsnull; } @@ -762,8 +763,10 @@ nsHTMLFragmentContentSink::PopContent() nsIContent* content = nsnull; if (nsnull != mContentStack) { PRInt32 indx = mContentStack->Count() - 1; - content = (nsIContent *)mContentStack->ElementAt(indx); - mContentStack->RemoveElementAt(indx); + if (indx >= 0) { + content = (nsIContent *)mContentStack->ElementAt(indx); + mContentStack->RemoveElementAt(indx); + } } return content; } diff --git a/content/html/style/src/nsCSSDeclaration.cpp b/content/html/style/src/nsCSSDeclaration.cpp index c0d496dd7f2b..867e19414097 100644 --- a/content/html/style/src/nsCSSDeclaration.cpp +++ b/content/html/style/src/nsCSSDeclaration.cpp @@ -5137,6 +5137,10 @@ CSSDeclarationImpl::AllPropertiesSameValue(PRInt32 aFirst, PRInt32 aSecond, PRInt32 aThird, PRInt32 aFourth) { nsCSSValue firstValue, otherValue; + // TryBorderShorthand does the bounds-checking for us; valid values there + // are > 0; 0 is a flag for "not set". We here are passed the actual + // index, which comes from finding the value in the mOrder property array. + // Of course, re-getting the mOrder value here is pretty silly. GetValue((nsCSSProperty)NS_PTR_TO_INT32(mOrder->ElementAt(aFirst)), firstValue); GetValue((nsCSSProperty)NS_PTR_TO_INT32(mOrder->ElementAt(aSecond)), otherValue); if (firstValue != otherValue) { @@ -5181,6 +5185,7 @@ CSSDeclarationImpl::TryBorderShorthand(nsAWritableString & aString, PRInt32 & aBorderRightColor) { PRInt32 border = 0; + // 0 means not in the mOrder array; otherwise it's index+1 if (aBorderTopWidth && aBorderBottomWidth && aBorderLeftWidth && aBorderRightWidth && AllPropertiesSameValue(aBorderTopWidth-1, aBorderBottomWidth-1, @@ -5246,6 +5251,7 @@ CSSDeclarationImpl::TryBorderSideShorthand(nsAWritableString & aString, PRInt32 & aBorderStyle, PRInt32 & aBorderColor) { + // 0 means not in the mOrder array; otherwise it's index+1 if ((aBorderWidth && aBorderStyle) || (aBorderWidth && aBorderColor) || (aBorderStyle && aBorderColor)) { @@ -5282,6 +5288,7 @@ CSSDeclarationImpl::TryMarginOrPaddingShorthand(nsAWritableString & aString, PRInt32 & aLeft, PRInt32 & aRight) { + // 0 means not in the mOrder array; otherwise it's index+1 if (aTop && aBottom && aLeft && aRight) { // all 4 properties are set, we can output a shorthand aString.Append(NS_ConvertASCIItoUCS2(nsCSSProps::GetStringValue(aShorthand)) @@ -5322,6 +5329,7 @@ CSSDeclarationImpl::TryBackgroundShorthand(nsAWritableString & aString, PRInt32 & aBgPositionX, PRInt32 & aBgPositionY) { + // 0 means not in the mOrder array; otherwise it's index+1 // check if we have at least two properties set; otherwise, no need to // use a shorthand PRInt8 numberPropertiesSpecified = (aBgColor ? 1 : 0) + (aBgImage ? 1 : 0) @@ -5363,6 +5371,7 @@ CSSDeclarationImpl::TryBackgroundPosition(nsAWritableString & aString, PRInt32 & aBgPositionX, PRInt32 & aBgPositionY) { + // 0 means not in the mOrder array; otherwise it's index+1 if (aBgPositionX && aBgPositionY) { nsAutoString backgroundXValue, backgroundYValue; AppendValueToString(eCSSProperty_background_x_position, backgroundXValue); @@ -5392,6 +5401,7 @@ CSSDeclarationImpl::ToString(nsAWritableString& aString) if (nsnull != mOrder) { PRInt32 count = mOrder->Count(); PRInt32 index; + // 0 means not in the mOrder array; otherwise it's index+1 PRInt32 borderTopWidth = 0, borderTopStyle = 0, borderTopColor = 0; PRInt32 borderBottomWidth = 0, borderBottomStyle = 0, borderBottomColor = 0; PRInt32 borderLeftWidth = 0, borderLeftStyle = 0, borderLeftColor = 0; @@ -5495,6 +5505,7 @@ CSSDeclarationImpl::ToString(nsAWritableString& aString) case eCSSProperty_background_x_position: case eCSSProperty_background_y_position: + // 0 means not in the mOrder array; otherwise it's index+1 if (bgPositionX && bgPositionY) { aString.Append(NS_ConvertASCIItoUCS2(nsCSSProps::GetStringValue(eCSSProperty_background_position)) + NS_LITERAL_STRING(": ")); @@ -5687,7 +5698,7 @@ NS_IMETHODIMP CSSDeclarationImpl::GetNthProperty(PRUint32 aIndex, nsAWritableString& aReturn) { aReturn.Truncate(); - if (nsnull != mOrder) { + if (nsnull != mOrder && aIndex < mOrder->Count()) { nsCSSProperty property = (nsCSSProperty)NS_PTR_TO_INT32(mOrder->ElementAt(aIndex)); if (0 <= property) { aReturn.Append(NS_ConvertASCIItoUCS2(nsCSSProps::GetStringValue(property))); diff --git a/content/html/style/src/nsCSSLoader.cpp b/content/html/style/src/nsCSSLoader.cpp index 28cbf553febf..d99f62577339 100644 --- a/content/html/style/src/nsCSSLoader.cpp +++ b/content/html/style/src/nsCSSLoader.cpp @@ -605,12 +605,11 @@ CSSLoaderImpl::RecycleParser(nsICSSParser* aParser) nsresult result = NS_ERROR_NULL_POINTER; if (aParser) { - result = NS_OK; if (! mParsers) { result = NS_NewISupportsArray(&mParsers); } if (mParsers) { - mParsers->AppendElement(aParser); + result = mParsers->AppendElement(aParser); } } return result; diff --git a/content/html/style/src/nsCSSStruct.cpp b/content/html/style/src/nsCSSStruct.cpp index c0d496dd7f2b..867e19414097 100644 --- a/content/html/style/src/nsCSSStruct.cpp +++ b/content/html/style/src/nsCSSStruct.cpp @@ -5137,6 +5137,10 @@ CSSDeclarationImpl::AllPropertiesSameValue(PRInt32 aFirst, PRInt32 aSecond, PRInt32 aThird, PRInt32 aFourth) { nsCSSValue firstValue, otherValue; + // TryBorderShorthand does the bounds-checking for us; valid values there + // are > 0; 0 is a flag for "not set". We here are passed the actual + // index, which comes from finding the value in the mOrder property array. + // Of course, re-getting the mOrder value here is pretty silly. GetValue((nsCSSProperty)NS_PTR_TO_INT32(mOrder->ElementAt(aFirst)), firstValue); GetValue((nsCSSProperty)NS_PTR_TO_INT32(mOrder->ElementAt(aSecond)), otherValue); if (firstValue != otherValue) { @@ -5181,6 +5185,7 @@ CSSDeclarationImpl::TryBorderShorthand(nsAWritableString & aString, PRInt32 & aBorderRightColor) { PRInt32 border = 0; + // 0 means not in the mOrder array; otherwise it's index+1 if (aBorderTopWidth && aBorderBottomWidth && aBorderLeftWidth && aBorderRightWidth && AllPropertiesSameValue(aBorderTopWidth-1, aBorderBottomWidth-1, @@ -5246,6 +5251,7 @@ CSSDeclarationImpl::TryBorderSideShorthand(nsAWritableString & aString, PRInt32 & aBorderStyle, PRInt32 & aBorderColor) { + // 0 means not in the mOrder array; otherwise it's index+1 if ((aBorderWidth && aBorderStyle) || (aBorderWidth && aBorderColor) || (aBorderStyle && aBorderColor)) { @@ -5282,6 +5288,7 @@ CSSDeclarationImpl::TryMarginOrPaddingShorthand(nsAWritableString & aString, PRInt32 & aLeft, PRInt32 & aRight) { + // 0 means not in the mOrder array; otherwise it's index+1 if (aTop && aBottom && aLeft && aRight) { // all 4 properties are set, we can output a shorthand aString.Append(NS_ConvertASCIItoUCS2(nsCSSProps::GetStringValue(aShorthand)) @@ -5322,6 +5329,7 @@ CSSDeclarationImpl::TryBackgroundShorthand(nsAWritableString & aString, PRInt32 & aBgPositionX, PRInt32 & aBgPositionY) { + // 0 means not in the mOrder array; otherwise it's index+1 // check if we have at least two properties set; otherwise, no need to // use a shorthand PRInt8 numberPropertiesSpecified = (aBgColor ? 1 : 0) + (aBgImage ? 1 : 0) @@ -5363,6 +5371,7 @@ CSSDeclarationImpl::TryBackgroundPosition(nsAWritableString & aString, PRInt32 & aBgPositionX, PRInt32 & aBgPositionY) { + // 0 means not in the mOrder array; otherwise it's index+1 if (aBgPositionX && aBgPositionY) { nsAutoString backgroundXValue, backgroundYValue; AppendValueToString(eCSSProperty_background_x_position, backgroundXValue); @@ -5392,6 +5401,7 @@ CSSDeclarationImpl::ToString(nsAWritableString& aString) if (nsnull != mOrder) { PRInt32 count = mOrder->Count(); PRInt32 index; + // 0 means not in the mOrder array; otherwise it's index+1 PRInt32 borderTopWidth = 0, borderTopStyle = 0, borderTopColor = 0; PRInt32 borderBottomWidth = 0, borderBottomStyle = 0, borderBottomColor = 0; PRInt32 borderLeftWidth = 0, borderLeftStyle = 0, borderLeftColor = 0; @@ -5495,6 +5505,7 @@ CSSDeclarationImpl::ToString(nsAWritableString& aString) case eCSSProperty_background_x_position: case eCSSProperty_background_y_position: + // 0 means not in the mOrder array; otherwise it's index+1 if (bgPositionX && bgPositionY) { aString.Append(NS_ConvertASCIItoUCS2(nsCSSProps::GetStringValue(eCSSProperty_background_position)) + NS_LITERAL_STRING(": ")); @@ -5687,7 +5698,7 @@ NS_IMETHODIMP CSSDeclarationImpl::GetNthProperty(PRUint32 aIndex, nsAWritableString& aReturn) { aReturn.Truncate(); - if (nsnull != mOrder) { + if (nsnull != mOrder && aIndex < mOrder->Count()) { nsCSSProperty property = (nsCSSProperty)NS_PTR_TO_INT32(mOrder->ElementAt(aIndex)); if (0 <= property) { aReturn.Append(NS_ConvertASCIItoUCS2(nsCSSProps::GetStringValue(property))); diff --git a/content/xml/document/src/nsXMLDocument.cpp b/content/xml/document/src/nsXMLDocument.cpp index 18708f2e40f9..1c6b725785fa 100644 --- a/content/xml/document/src/nsXMLDocument.cpp +++ b/content/xml/document/src/nsXMLDocument.cpp @@ -684,9 +684,10 @@ void nsXMLDocument::InternalAddStyleSheet(nsIStyleSheet* aSheet) // subclass ho mStyleSheets.AppendElement(aSheet); } else { - if (mInlineStyleSheet == mStyleSheets.ElementAt(mStyleSheets.Count() - 1)) { + PRInt32 count = mStyleSheets.Count(); + if (count != 0 && mInlineStyleSheet == mStyleSheets.ElementAt(count - 1)) { // keep attr sheet last - mStyleSheets.InsertElementAt(aSheet, mStyleSheets.Count() - 1); + mStyleSheets.InsertElementAt(aSheet, count - 1); } else { mStyleSheets.AppendElement(aSheet); diff --git a/content/xul/content/src/nsXULElement.cpp b/content/xul/content/src/nsXULElement.cpp index 01e93a7c7da5..90f494093ad7 100644 --- a/content/xul/content/src/nsXULElement.cpp +++ b/content/xul/content/src/nsXULElement.cpp @@ -893,7 +893,7 @@ nsXULElement::GetPreviousSibling(nsIDOMNode** aPreviousSibling) if (nsnull != mParent) { PRInt32 pos; mParent->IndexOf(NS_STATIC_CAST(nsIStyledContent*, this), pos); - if (pos > -1) { + if (pos > 0) { nsCOMPtr prev; mParent->ChildAt(--pos, *getter_AddRefs(prev)); if (prev) { @@ -2219,8 +2219,10 @@ nsXULElement::ChildAt(PRInt32 aIndex, nsIContent*& aResult) const return rv; } - nsIContent* content = NS_STATIC_CAST(nsIContent*, mChildren[aIndex]); - NS_IF_ADDREF(aResult = content); + nsIContent* content = NS_STATIC_CAST(nsIContent*, mChildren.SafeElementAt(aIndex)); + aResult = content; + NS_IF_ADDREF(aResult); + return NS_OK; } @@ -3024,15 +3026,17 @@ nsXULElement::GetAttrNameAt(PRInt32 aIndex, PRBool haveLocalAttributes = PR_FALSE; if (Attributes()) { haveLocalAttributes = PR_TRUE; - nsXULAttribute* attr = NS_REINTERPRET_CAST(nsXULAttribute*, Attributes()->ElementAt(aIndex)); - if (nsnull != attr) { - attr->GetNodeInfo()->GetNamespaceID(aNameSpaceID); - attr->GetNodeInfo()->GetNameAtom(aName); - attr->GetNodeInfo()->GetPrefixAtom(aPrefix); + if (aIndex < Attributes()->Count()) { + nsXULAttribute* attr = NS_REINTERPRET_CAST(nsXULAttribute*, Attributes()->ElementAt(aIndex)); + if (nsnull != attr) { + attr->GetNodeInfo()->GetNamespaceID(aNameSpaceID); + attr->GetNodeInfo()->GetNameAtom(aName); + attr->GetNodeInfo()->GetPrefixAtom(aPrefix); #ifdef DEBUG_ATTRIBUTE_STATS - fprintf(stderr, " local!\n"); + fprintf(stderr, " local!\n"); #endif - return NS_OK; + return NS_OK; + } } } diff --git a/content/xul/content/src/nsXULElement.h b/content/xul/content/src/nsXULElement.h index a5e6100339e4..cdeb94fe0a2c 100644 --- a/content/xul/content/src/nsXULElement.h +++ b/content/xul/content/src/nsXULElement.h @@ -537,7 +537,7 @@ protected: nsXULPrototypeElement* mPrototype; nsIDocument* mDocument; // [WEAK] nsIContent* mParent; // [WEAK] - nsCheapVoidArray mChildren; // [OWNER] + nsSmallVoidArray mChildren; // [OWNER] nsCOMPtr mListenerManager; // [OWNER] /** diff --git a/content/xul/content/src/nsXULPopupListener.cpp b/content/xul/content/src/nsXULPopupListener.cpp index d8ffeb3fc284..0d7471f92121 100644 --- a/content/xul/content/src/nsXULPopupListener.cpp +++ b/content/xul/content/src/nsXULPopupListener.cpp @@ -319,6 +319,9 @@ XULPopupListenerImpl::FireFocusOnTargetContent(nsIDOMNode* aTargetNode) nsCOMPtr context; nsCOMPtr tempdoc = do_QueryInterface(domDoc); tempdoc->GetShellAt(0, getter_AddRefs(shell)); // Get nsIDOMElement for targetNode + if (!shell) + return NS_ERROR_FAILURE; + shell->GetPresContext(getter_AddRefs(context)); nsCOMPtr content = do_QueryInterface(aTargetNode); diff --git a/content/xul/document/src/nsXULControllers.cpp b/content/xul/document/src/nsXULControllers.cpp index 7ac05614e6d1..25f911fb6e5c 100644 --- a/content/xul/document/src/nsXULControllers.cpp +++ b/content/xul/document/src/nsXULControllers.cpp @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: NPL 1.1/GPL 2.0/LGPL 2.1 * @@ -59,7 +59,7 @@ nsXULControllers::nsXULControllers() : mCurControllerID(0) { - NS_INIT_REFCNT(); + NS_INIT_REFCNT(); } nsXULControllers::~nsXULControllers(void) @@ -85,19 +85,19 @@ nsXULControllers::DeleteControllers() NS_IMETHODIMP NS_NewXULControllers(nsISupports* aOuter, REFNSIID aIID, void** aResult) { - NS_PRECONDITION(aOuter == nsnull, "no aggregation"); - if (aOuter) - return NS_ERROR_NO_AGGREGATION; + NS_PRECONDITION(aOuter == nsnull, "no aggregation"); + if (aOuter) + return NS_ERROR_NO_AGGREGATION; - nsXULControllers* controllers = new nsXULControllers(); - if (! controllers) - return NS_ERROR_OUT_OF_MEMORY; - - nsresult rv; - NS_ADDREF(controllers); - rv = controllers->QueryInterface(aIID, aResult); - NS_RELEASE(controllers); - return rv; + nsXULControllers* controllers = new nsXULControllers(); + if (! controllers) + return NS_ERROR_OUT_OF_MEMORY; + + nsresult rv; + NS_ADDREF(controllers); + rv = controllers->QueryInterface(aIID, aResult); + NS_RELEASE(controllers); + return rv; } // QueryInterface implementation for nsXULControllers @@ -115,25 +115,25 @@ NS_IMPL_RELEASE(nsXULControllers) NS_IMETHODIMP nsXULControllers::GetCommandDispatcher(nsIDOMXULCommandDispatcher** _result) { - nsCOMPtr dispatcher = do_QueryReferent(mCommandDispatcher); - *_result = dispatcher; - NS_IF_ADDREF(*_result); - return NS_OK; + nsCOMPtr dispatcher = do_QueryReferent(mCommandDispatcher); + *_result = dispatcher; + NS_IF_ADDREF(*_result); + return NS_OK; } NS_IMETHODIMP nsXULControllers::SetCommandDispatcher(nsIDOMXULCommandDispatcher* aCommandDispatcher) { - mCommandDispatcher = getter_AddRefs(NS_GetWeakReference(aCommandDispatcher)); - return NS_OK; + mCommandDispatcher = getter_AddRefs(NS_GetWeakReference(aCommandDispatcher)); + return NS_OK; } NS_IMETHODIMP nsXULControllers::GetControllerForCommand(const nsAReadableString& aCommand, nsIController** _retval) { NS_ENSURE_ARG_POINTER(_retval); - *_retval = nsnull; + *_retval = nsnull; PRUint32 count = mControllers.Count(); for (PRUint32 i=0; i < count; i++) @@ -141,59 +141,60 @@ nsXULControllers::GetControllerForCommand(const nsAReadableString& aCommand, nsI nsXULControllerData* controllerData = NS_STATIC_CAST(nsXULControllerData*, mControllers.ElementAt(i)); if (controllerData) { - nsCOMPtr controller; + nsCOMPtr controller; controllerData->GetController(getter_AddRefs(controller)); if (controller) { - PRBool supportsCommand; + PRBool supportsCommand; controller->SupportsCommand(aCommand, &supportsCommand); if (supportsCommand) { - *_retval = controller; - NS_ADDREF(*_retval); - return NS_OK; - } + *_retval = controller; + NS_ADDREF(*_retval); + return NS_OK; } + } } } - return NS_OK; + return NS_OK; } NS_IMETHODIMP -nsXULControllers::InsertControllerAt(PRUint32 index, nsIController *controller) +nsXULControllers::InsertControllerAt(PRUint32 aIndex, nsIController *controller) { nsXULControllerData* controllerData = new nsXULControllerData(mCurControllerID++, controller); if (!controllerData) return NS_ERROR_OUT_OF_MEMORY; - PRBool inserted = mControllers.InsertElementAt((void *)controllerData, index); + PRBool inserted = mControllers.InsertElementAt((void *)controllerData, aIndex); NS_ASSERTION(inserted, "Insertion of controller failed"); - return NS_OK; + return NS_OK; } NS_IMETHODIMP -nsXULControllers::RemoveControllerAt(PRUint32 index, nsIController **_retval) +nsXULControllers::RemoveControllerAt(PRUint32 aIndex, nsIController **_retval) { NS_ENSURE_ARG_POINTER(_retval); - *_retval = nsnull; - nsXULControllerData* controllerData = NS_STATIC_CAST(nsXULControllerData*, mControllers.ElementAt(index)); + *_retval = nsnull; + + nsXULControllerData* controllerData = NS_STATIC_CAST(nsXULControllerData*, mControllers.SafeElementAt(aIndex)); if (!controllerData) return NS_ERROR_FAILURE; - PRBool removed = mControllers.RemoveElementAt(index); + PRBool removed = mControllers.RemoveElementAt(aIndex); NS_ASSERTION(removed, "Removal of controller failed"); controllerData->GetController(_retval); delete controllerData; - return NS_OK; + return NS_OK; } NS_IMETHODIMP -nsXULControllers::GetControllerAt(PRUint32 index, nsIController **_retval) +nsXULControllers::GetControllerAt(PRUint32 aIndex, nsIController **_retval) { NS_ENSURE_ARG_POINTER(_retval); - *_retval = nsnull; + *_retval = nsnull; - nsXULControllerData* controllerData = NS_STATIC_CAST(nsXULControllerData*, mControllers.ElementAt(index)); + nsXULControllerData* controllerData = NS_STATIC_CAST(nsXULControllerData*, mControllers.SafeElementAt(aIndex)); if (!controllerData) return NS_ERROR_FAILURE; return controllerData->GetController(_retval); // does the addref @@ -206,7 +207,7 @@ nsXULControllers::AppendController(nsIController *controller) if (!controllerData) return NS_ERROR_OUT_OF_MEMORY; PRBool appended = mControllers.AppendElement((void *)controllerData); NS_ASSERTION(appended, "Appending controller failed"); - return NS_OK; + return NS_OK; } NS_IMETHODIMP @@ -252,7 +253,7 @@ nsXULControllers::GetControllerId(nsIController *controller, PRUint32 *_retval) if (thisController.get() == controller) { *_retval = controllerData->GetControllerID(); - return NS_OK; + return NS_OK; } } } @@ -282,5 +283,5 @@ nsXULControllers::GetControllerCount(PRUint32 *_retval) { NS_ENSURE_ARG_POINTER(_retval); *_retval = mControllers.Count(); - return NS_OK; + return NS_OK; } diff --git a/content/xul/document/src/nsXULDocument.cpp b/content/xul/document/src/nsXULDocument.cpp index 64f6996e80e7..173178e5dbc8 100644 --- a/content/xul/document/src/nsXULDocument.cpp +++ b/content/xul/document/src/nsXULDocument.cpp @@ -421,7 +421,7 @@ PlaceHolderRequest::~PlaceHolderRequest() struct BroadcasterMapEntry : public PLDHashEntryHdr { nsIDOMElement* mBroadcaster; // [WEAK] - nsCheapVoidArray mListeners; // [OWNING] of BroadcastListener objects + nsSmallVoidArray mListeners; // [OWNING] of BroadcastListener objects }; struct BroadcastListener { @@ -483,6 +483,7 @@ nsXULDocument::~nsXULDocument() PL_DHashTableDestroy(mBroadcasterMap); // Notify observer that we're about to go away + // if an observer removes itself, we're ok (not if it removes others though) PRInt32 i; for (i = mObservers.Count() - 1; i >= 0; --i) { nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers.ElementAt(i); @@ -950,6 +951,7 @@ nsXULDocument::SetDocumentCharacterSet(const nsAReadableString& aCharSetID) if (!mCharSetID.Equals(aCharSetID)) { mCharSetID.Assign(aCharSetID); PRInt32 n = mCharSetObservers.Count(); + // if an observer removes itself, we're NOT ok for (PRInt32 i = 0; i < n; i++) { nsIObserver* observer = (nsIObserver*) mCharSetObservers.ElementAt(i); observer->Observe((nsIDocument*) this, "charset", @@ -1104,7 +1106,7 @@ nsXULDocument::GetNumberOfShells() NS_IMETHODIMP nsXULDocument::GetShellAt(PRInt32 aIndex, nsIPresShell** aShell) { - *aShell = NS_STATIC_CAST(nsIPresShell*, mPresShells[aIndex]); + *aShell = NS_STATIC_CAST(nsIPresShell*, mPresShells.SafeElementAt(aIndex)); NS_IF_ADDREF(*aShell); return NS_OK; } @@ -1143,7 +1145,7 @@ nsXULDocument::GetNumberOfSubDocuments(PRInt32 *aCount) NS_IMETHODIMP nsXULDocument::GetSubDocumentAt(PRInt32 aIndex, nsIDocument** aSubDoc) { - *aSubDoc = (nsIDocument*) mSubDocuments.ElementAt(aIndex); + *aSubDoc = (nsIDocument*) mSubDocuments.SafeElementAt(aIndex); NS_IF_ADDREF(*aSubDoc); return NS_OK; } @@ -1241,9 +1243,11 @@ nsXULDocument::AddStyleSheet(nsIStyleSheet* aSheet) mStyleSheets.AppendElement(aSheet); } else { - if ((nsIHTMLCSSStyleSheet*)mInlineStyleSheet == mStyleSheets.ElementAt(mStyleSheets.Count() - 1)) { + PRInt32 count = mStyleSheets.Count(); + if (count != 0 && + (nsIHTMLCSSStyleSheet*)mInlineStyleSheet == mStyleSheets.ElementAt(count - 1)) { // keep attr sheet last - mStyleSheets.InsertElementAt(aSheet, mStyleSheets.Count() - 1); + mStyleSheets.InsertElementAt(aSheet, count - 1); } else { mStyleSheets.AppendElement(aSheet); @@ -1260,6 +1264,7 @@ nsXULDocument::AddStyleSheet(nsIStyleSheet* aSheet) AddStyleSheetToStyleSets(aSheet); // XXX should observers be notified for disabled sheets??? I think not, but I could be wrong + // if an observer removes itself, we're ok (not if it removes others though) for (PRInt32 i = mObservers.Count() - 1; i >= 0; --i) { nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers.ElementAt(i); observer->StyleSheetAdded(this, aSheet); @@ -1302,7 +1307,9 @@ nsXULDocument::UpdateStyleSheets(nsISupportsArray* aOldSheets, nsISupportsArray* mStyleSheets.AppendElement(sheet); } else { - if ((nsIHTMLCSSStyleSheet*)mInlineStyleSheet == mStyleSheets.ElementAt(mStyleSheets.Count() - 1)) { + PRInt32 count = mStyleSheets.Count(); + if (count != 0 && + (nsIHTMLCSSStyleSheet*)mInlineStyleSheet == mStyleSheets.ElementAt(count - 1)) { // keep attr sheet last mStyleSheets.InsertElementAt(sheet, mStyleSheets.Count() - 1); } @@ -1324,6 +1331,7 @@ nsXULDocument::UpdateStyleSheets(nsISupportsArray* aOldSheets, nsISupportsArray* } } + // if an observer removes itself, we're ok (not if it removes others though) for (PRInt32 indx = mObservers.Count() - 1; indx >= 0; --indx) { nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers.ElementAt(indx); observer->StyleSheetRemoved(this, sheet); @@ -1361,6 +1369,7 @@ nsXULDocument::RemoveStyleSheet(nsIStyleSheet* aSheet) RemoveStyleSheetFromStyleSets(aSheet); // XXX should observers be notified for disabled sheets??? I think not, but I could be wrong + // if an observer removes itself, we're ok (not if it removes others though) for (PRInt32 indx = mObservers.Count() - 1; indx >= 0; --indx) { nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers.ElementAt(indx); observer->StyleSheetRemoved(this, aSheet); @@ -1398,6 +1407,7 @@ nsXULDocument::InsertStyleSheetAt(nsIStyleSheet* aSheet, PRInt32 aIndex, PRBool } } if (aNotify) { // notify here even if disabled, there may have been others that weren't notified + // if an observer removes itself, we're ok (not if it removes others though) for (i = mObservers.Count() - 1; i >= 0; --i) { nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers.ElementAt(i); observer->StyleSheetAdded(this, aSheet); @@ -1433,6 +1443,7 @@ nsXULDocument::SetStyleSheetDisabledState(nsIStyleSheet* aSheet, } } + // if an observer removes itself, we're ok (not if it removes others though) for (i = mObservers.Count() - 1; i >= 0; --i) { nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers.ElementAt(i); observer->StyleSheetDisabledStateChanged(this, aSheet, aDisabled); @@ -1717,8 +1728,8 @@ ClearBroadcasterMapEntry(PLDHashTable* aTable, PLDHashEntryHdr* aEntry) NS_STATIC_CAST(BroadcasterMapEntry*, aEntry); // N.B. that we need to manually run the dtor because we - // constructed the nsCheapVoidArray object in-place. - entry->mListeners.~nsCheapVoidArray(); + // constructed the nsSmallVoidArray object in-place. + entry->mListeners.~nsSmallVoidArray(); } static PRBool @@ -1839,9 +1850,9 @@ nsXULDocument::AddBroadcastListenerFor(nsIDOMElement* aBroadcaster, entry->mBroadcaster = aBroadcaster; - // N.B. placement new to construct the nsCheapVoidArray object + // N.B. placement new to construct the nsSmallVoidArray object // in-place - new (&entry->mListeners) nsCheapVoidArray(); + new (&entry->mListeners) nsSmallVoidArray(); } // Only add the listener if it's not there already! @@ -3063,7 +3074,7 @@ nsXULDocument::GetDefaultView(nsIDOMAbstractView** aDefaultView) *aDefaultView = nsnull; nsIPresShell *shell = NS_STATIC_CAST(nsIPresShell *, - mPresShells.ElementAt(0)); + mPresShells.SafeElementAt(0)); NS_ENSURE_TRUE(shell, NS_OK); nsCOMPtr ctx; @@ -4617,13 +4628,16 @@ nsXULDocument::DispatchEvent(nsIDOMEvent* aEvent, PRBool *_retval) nsCOMPtr shell; GetShellAt(0, getter_AddRefs(shell)); - // Retrieve the context - nsCOMPtr presContext; - shell->GetPresContext(getter_AddRefs(presContext)); + if (shell) { + // Retrieve the context + nsCOMPtr presContext; + shell->GetPresContext(getter_AddRefs(presContext)); - nsCOMPtr esm; - if (NS_SUCCEEDED(presContext->GetEventStateManager(getter_AddRefs(esm)))) { - return esm->DispatchNewEvent(NS_STATIC_CAST(nsIDocument*, this), aEvent, _retval); + nsCOMPtr esm; + if (presContext && + NS_SUCCEEDED(presContext->GetEventStateManager(getter_AddRefs(esm)))) { + return esm->DispatchNewEvent(NS_STATIC_CAST(nsIDocument*, this), aEvent, _retval); + } } return NS_ERROR_FAILURE; @@ -4641,14 +4655,16 @@ nsXULDocument::CreateEvent(const nsAReadableString& aEventType, nsCOMPtr shell; GetShellAt(0, getter_AddRefs(shell)); - // Retrieve the context - nsCOMPtr presContext; - shell->GetPresContext(getter_AddRefs(presContext)); + if (shell) { + // Retrieve the context + nsCOMPtr presContext; + shell->GetPresContext(getter_AddRefs(presContext)); - if (presContext) { - nsCOMPtr lm; - if (NS_SUCCEEDED(GetListenerManager(getter_AddRefs(lm)))) { - return lm->CreateEvent(presContext, nsnull, aEventType, aReturn); + if (presContext) { + nsCOMPtr lm; + if (NS_SUCCEEDED(GetListenerManager(getter_AddRefs(lm)))) { + return lm->CreateEvent(presContext, nsnull, aEventType, aReturn); + } } } diff --git a/content/xul/templates/src/nsXULSortService.cpp b/content/xul/templates/src/nsXULSortService.cpp index bfe704306071..91e5fcaa86b5 100644 --- a/content/xul/templates/src/nsXULSortService.cpp +++ b/content/xul/templates/src/nsXULSortService.cpp @@ -1950,7 +1950,9 @@ XULSortServiceImpl::InsertContainerNode(nsIRDFCompositeDataSource *db, nsRDFSort ((sortInfo.naturalOrderSort == PR_TRUE) && (isContainerRDFSeq == PR_TRUE))) { - nsCOMPtr child; + // because numChildren gets modified + PRInt32 realNumChildren = numChildren; + nsCOMPtr child; // rjc says: determine where static XUL ends and generated XUL/RDF begins PRInt32 staticCount = 0; @@ -2033,12 +2035,12 @@ XULSortServiceImpl::InsertContainerNode(nsIRDFCompositeDataSource *db, nsRDFSort } else if (sortState->lastWasLast == PR_TRUE) { - container->ChildAt(numChildren-1, *getter_AddRefs(child)); + container->ChildAt(realNumChildren-1, *getter_AddRefs(child)); temp = child.get(); direction = inplaceSortCallback(&node, &temp, &sortInfo); if (direction > 0) { - container->InsertChildAt(node, numChildren, aNotify, + container->InsertChildAt(node, realNumChildren, aNotify, PR_FALSE); childAdded = PR_TRUE; } @@ -2048,7 +2050,7 @@ XULSortServiceImpl::InsertContainerNode(nsIRDFCompositeDataSource *db, nsRDFSort } } - PRInt32 left = staticCount+1, right = numChildren, x; + PRInt32 left = staticCount+1, right = realNumChildren, x; while ((childAdded == PR_FALSE) && (right >= left)) { x = (left + right) / 2; @@ -2066,7 +2068,7 @@ XULSortServiceImpl::InsertContainerNode(nsIRDFCompositeDataSource *db, nsRDFSort childAdded = PR_TRUE; sortState->lastWasFirst = (thePos == staticCount) ? PR_TRUE: PR_FALSE; - sortState->lastWasLast = (thePos == numChildren) ? PR_TRUE: PR_FALSE; + sortState->lastWasLast = (thePos >= realNumChildren) ? PR_TRUE: PR_FALSE; break; } diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index 52888cfa9539..3bca0d7c1a0a 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -1907,6 +1907,7 @@ nsDocShell::GetChildAt(PRInt32 aIndex, nsIDocShellTreeItem ** aChild) { NS_ENSURE_ARG_POINTER(aChild); + NS_ASSERTION(aIndex >= 0 && aIndex < mChildren.Count(),"Bad docshell ChildAt index"); *aChild = (nsIDocShellTreeItem *) mChildren.ElementAt(aIndex); NS_IF_ADDREF(*aChild); diff --git a/editor/libeditor/base/nsSelectionState.cpp b/editor/libeditor/base/nsSelectionState.cpp index 297ff476e861..b10e4bdc5278 100644 --- a/editor/libeditor/base/nsSelectionState.cpp +++ b/editor/libeditor/base/nsSelectionState.cpp @@ -82,10 +82,11 @@ nsSelectionState::SaveSelection(nsISelection *aSel) // else if we have too many, delete them else if (arrayCount>rangeCount) { - while ((item = (nsRangeStore*)mArray.ElementAt(rangeCount))) + for (i = arrayCount-1; i >= rangeCount; i--) { + item = (nsRangeStore*)mArray.ElementAt(i); delete item; - mArray.RemoveElementAt(rangeCount); + mArray.RemoveElementAt(i); } } @@ -180,11 +181,12 @@ nsSelectionState::MakeEmpty() { // free any items in the array nsRangeStore *item; - while ((item = (nsRangeStore*)mArray.ElementAt(0))) + for (PRInt32 i = mArray.Count()-1; i >= 0; --i) { + item = (nsRangeStore*)mArray.ElementAt(i); delete item; - mArray.RemoveElementAt(0); } + mArray.Clear(); } PRBool @@ -203,11 +205,12 @@ nsRangeUpdater::~nsRangeUpdater() { // free any items in the array nsRangeStore *item; - while ((item = (nsRangeStore*)mArray.ElementAt(0))) + for (PRInt32 i = mArray.Count()-1; i >= 0; --i) { + item = (nsRangeStore*)mArray.ElementAt(i); delete item; - mArray.RemoveElementAt(0); } + //mArray.Clear(); not really needed } void* diff --git a/editor/libeditor/html/nsHTMLEditor.cpp b/editor/libeditor/html/nsHTMLEditor.cpp index f49a5736b29d..8055108d3830 100644 --- a/editor/libeditor/html/nsHTMLEditor.cpp +++ b/editor/libeditor/html/nsHTMLEditor.cpp @@ -4140,11 +4140,13 @@ nsHTMLEditor::CollapseAdjacentTextNodes(nsIDOMRange *aInRange) // now that I have a list of text nodes, collapse adjacent text nodes // NOTE: assumption that JoinNodes keeps the righthand node - nsIDOMNode *leftTextNode = (nsIDOMNode *)(textNodes.ElementAt(0)); - nsIDOMNode *rightTextNode = (nsIDOMNode *)(textNodes.ElementAt(1)); - - while (leftTextNode && rightTextNode) + while (textNodes.Count() > 1) { + // we assume a textNodes entry can't be nsnull + nsIDOMNode *leftTextNode = (nsIDOMNode *)(textNodes.ElementAt(0)); + nsIDOMNode *rightTextNode = (nsIDOMNode *)(textNodes.ElementAt(1)); + NS_ASSERTION(leftTextNode && rightTextNode,"left or rightTextNode null in CollapseAdjacentTextNodes"); + // get the prev sibling of the right node, and see if it's leftTextNode nsCOMPtr prevSibOfRightNode; result = GetPriorHTMLSibling(rightTextNode, address_of(prevSibOfRightNode)); @@ -4160,8 +4162,6 @@ nsHTMLEditor::CollapseAdjacentTextNodes(nsIDOMRange *aInRange) } textNodes.RemoveElementAt(0); // remove the leftmost text node from the list - leftTextNode = (nsIDOMNode *)(textNodes.ElementAt(0)); - rightTextNode = (nsIDOMNode *)(textNodes.ElementAt(1)); } return result; diff --git a/extensions/cookie/nsCookies.cpp b/extensions/cookie/nsCookies.cpp index f99479699930..91a143232c42 100644 --- a/extensions/cookie/nsCookies.cpp +++ b/extensions/cookie/nsCookies.cpp @@ -1712,6 +1712,10 @@ COOKIE_Enumerate return NS_ERROR_FAILURE; } cookie_CookieStruct *cookie; + NS_ASSERTION(count >= 0 && count < cookie_list->Count(), "bad cookie index"); + if (count < 0 || count >= cookie_list->Count()) { + return NS_ERROR_UNEXPECTED; + } cookie = NS_STATIC_CAST(cookie_CookieStruct*, cookie_list->ElementAt(count)); NS_ASSERTION(cookie, "corrupt cookie list"); diff --git a/extensions/cookie/nsPermissions.cpp b/extensions/cookie/nsPermissions.cpp index 5e21a7d4ac57..1646ab44c690 100644 --- a/extensions/cookie/nsPermissions.cpp +++ b/extensions/cookie/nsPermissions.cpp @@ -559,6 +559,9 @@ PERMISSION_TypeCount(PRInt32 host) { } permission_HostStruct *hostStruct; + if (host >= PERMISSION_HostCount()) { + return NS_ERROR_FAILURE; + } hostStruct = NS_STATIC_CAST(permission_HostStruct*, permission_list->ElementAt(host)); NS_ASSERTION(hostStruct, "corrupt permission list"); return hostStruct->permissionList->Count(); @@ -567,7 +570,7 @@ PERMISSION_TypeCount(PRInt32 host) { PUBLIC nsresult PERMISSION_Enumerate (PRInt32 hostNumber, PRInt32 typeNumber, char **host, PRInt32 *type, PRBool *capability) { - if (hostNumber > PERMISSION_HostCount() || typeNumber > PERMISSION_TypeCount(hostNumber)) { + if (hostNumber >= PERMISSION_HostCount() || typeNumber >= PERMISSION_TypeCount(hostNumber)) { return NS_ERROR_FAILURE; } permission_HostStruct *hostStruct; @@ -591,6 +594,9 @@ permission_remove (PRInt32 hostNumber, PRInt32 type) { if (!permission_list) { return; } + if (hostNumber >= PERMISSION_HostCount() || type >= PERMISSION_TypeCount(hostNumber)) { + return; + } permission_HostStruct * hostStruct; hostStruct = NS_STATIC_CAST(permission_HostStruct*, permission_list->ElementAt(hostNumber)); diff --git a/gfx/src/gtk/nsFontMetricsGTK.cpp b/gfx/src/gtk/nsFontMetricsGTK.cpp index a3c27bc698c5..4fd2574db6f5 100644 --- a/gfx/src/gtk/nsFontMetricsGTK.cpp +++ b/gfx/src/gtk/nsFontMetricsGTK.cpp @@ -655,14 +655,11 @@ FreeStretch(nsFontStretch* aStretch) { PR_smprintf_free(aStretch->mScalable); - PRInt32 count; - while ((count = aStretch->mScaledFonts.Count())) { - // go backwards to keep nsVoidArray from memmoving everything each time - count--; // nsVoidArray is zero based + for (PRInt32 count = aStretch->mScaledFonts.Count()-1; count >= 0; --count) { nsFontGTK *font = (nsFontGTK*)aStretch->mScaledFonts.ElementAt(count); - aStretch->mScaledFonts.RemoveElementAt(count); if (font) delete font; } + // aStretch->mScaledFonts.Clear(); handled by delete of aStretch for (int i = 0; i < aStretch->mSizesCount; i++) { delete aStretch->mSizes[i]; @@ -3209,10 +3206,13 @@ SetFontLangGroupInfo(nsFontCharSetMap* aCharSetMap) // apply fontLangGroup operations to it // eg: search for related groups, check for scaling prefs const char *langGroup = fontLangGroup->mFontLangGroupName; + + // the font.scale prefs don't make sense without a langGroup + // XXX FIX!!! if langGroup is "", we need to bypass the font.scale stuff if (!langGroup) langGroup = ""; if (!fontLangGroup->mFontLangGroupAtom) { - fontLangGroup->mFontLangGroupAtom = NS_NewAtom(langGroup); + fontLangGroup->mFontLangGroupAtom = NS_NewAtom(langGroup); } // get the font scaling controls diff --git a/gfx/src/windows/nsFontMetricsWin.cpp b/gfx/src/windows/nsFontMetricsWin.cpp index 39d398d365cd..a41513509c33 100644 --- a/gfx/src/windows/nsFontMetricsWin.cpp +++ b/gfx/src/windows/nsFontMetricsWin.cpp @@ -2137,6 +2137,7 @@ nsFontMetricsWin::InitializeGlobalFonts(HDC aDC) int nsFontMetricsWin::SameAsPreviousMap(int aIndex) { + // aIndex is 0...gGlobalFonts.Count()-1 in caller nsGlobalFont* font = (nsGlobalFont*)gGlobalFonts->ElementAt(aIndex); for (int i = 0; i < aIndex; ++i) { nsGlobalFont* tmp = (nsGlobalFont*)gGlobalFonts->ElementAt(i); @@ -4675,6 +4676,7 @@ nsFontMetricsWinA::FindGlobalFont(HDC aDC, PRUnichar c) if (subset) { return subset; } + // assumes that LoadGlobalFont leaves the new font at the end mLoadedFonts.RemoveElementAt(mLoadedFonts.Count()-1); delete font; } @@ -4728,6 +4730,7 @@ nsFontMetricsWinA::FindSubstituteFont(HDC aDC, PRUnichar aChar) mSubstituteFont = (nsFontWin*)substituteFont; return substituteSubset; } + // assumes that LoadSubstituteFont leaves the new font at the end mLoadedFonts.RemoveElementAt(mLoadedFonts.Count()-1); delete substituteFont; } diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index 6cac18f97a69..b814a01db9e4 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -3764,18 +3764,20 @@ PresShell::CancelAllReflowCommands() PRInt32 i; for (i = 0; i < n; i++) { rc = NS_STATIC_CAST(nsHTMLReflowCommand*, mReflowCommands.ElementAt(0)); - mReflowCommands.RemoveElementAt(0); ReflowCommandRemoved(rc); delete rc; } + NS_ASSERTION(n == mReflowCommands.Count(),"reflow command list changed during cancel!"); + mReflowCommands.Clear(); n = mTimeoutReflowCommands.Count(); for (i = 0; i < n; i++) { rc = NS_STATIC_CAST(nsHTMLReflowCommand*, mTimeoutReflowCommands.ElementAt(0)); - mTimeoutReflowCommands.RemoveElementAt(0); ReflowCommandRemoved(rc); delete rc; } + NS_ASSERTION(n == mTimeoutReflowCommands.Count(),"timeout reflow command list changed during cancel!"); + mTimeoutReflowCommands.Clear(); DoneRemovingReflowCommands(); diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index 97b9acb525f5..a2e6905423f2 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -4562,6 +4562,7 @@ void DR_State::AddFrameTypeInfo(nsIAtom* aFrameType, DR_FrameTypeInfo* DR_State::GetFrameTypeInfo(nsIAtom* aFrameType) { PRInt32 numEntries = mFrameTypeTable.Count(); + NS_ASSERTION(numEntries != 0,"empty FrameTypeTable"); for (PRInt32 i = 0; i < numEntries; i++) { DR_FrameTypeInfo* info = (DR_FrameTypeInfo*)mFrameTypeTable.ElementAt(i); if (info && (info->mType == aFrameType)) { @@ -4574,6 +4575,7 @@ DR_FrameTypeInfo* DR_State::GetFrameTypeInfo(nsIAtom* aFrameType) DR_FrameTypeInfo* DR_State::GetFrameTypeInfo(char* aFrameName) { PRInt32 numEntries = mFrameTypeTable.Count(); + NS_ASSERTION(numEntries != 0,"empty FrameTypeTable"); for (PRInt32 i = 0; i < numEntries; i++) { DR_FrameTypeInfo* info = (DR_FrameTypeInfo*)mFrameTypeTable.ElementAt(i); if (info && ((strcmp(aFrameName, info->mName) == 0) || (strcmp(aFrameName, info->mNameAbbrev) == 0))) { diff --git a/layout/html/base/src/nsFrame.cpp b/layout/html/base/src/nsFrame.cpp index 97b9acb525f5..a2e6905423f2 100644 --- a/layout/html/base/src/nsFrame.cpp +++ b/layout/html/base/src/nsFrame.cpp @@ -4562,6 +4562,7 @@ void DR_State::AddFrameTypeInfo(nsIAtom* aFrameType, DR_FrameTypeInfo* DR_State::GetFrameTypeInfo(nsIAtom* aFrameType) { PRInt32 numEntries = mFrameTypeTable.Count(); + NS_ASSERTION(numEntries != 0,"empty FrameTypeTable"); for (PRInt32 i = 0; i < numEntries; i++) { DR_FrameTypeInfo* info = (DR_FrameTypeInfo*)mFrameTypeTable.ElementAt(i); if (info && (info->mType == aFrameType)) { @@ -4574,6 +4575,7 @@ DR_FrameTypeInfo* DR_State::GetFrameTypeInfo(nsIAtom* aFrameType) DR_FrameTypeInfo* DR_State::GetFrameTypeInfo(char* aFrameName) { PRInt32 numEntries = mFrameTypeTable.Count(); + NS_ASSERTION(numEntries != 0,"empty FrameTypeTable"); for (PRInt32 i = 0; i < numEntries; i++) { DR_FrameTypeInfo* info = (DR_FrameTypeInfo*)mFrameTypeTable.ElementAt(i); if (info && ((strcmp(aFrameName, info->mName) == 0) || (strcmp(aFrameName, info->mNameAbbrev) == 0))) { diff --git a/layout/html/base/src/nsPresShell.cpp b/layout/html/base/src/nsPresShell.cpp index 6cac18f97a69..b814a01db9e4 100644 --- a/layout/html/base/src/nsPresShell.cpp +++ b/layout/html/base/src/nsPresShell.cpp @@ -3764,18 +3764,20 @@ PresShell::CancelAllReflowCommands() PRInt32 i; for (i = 0; i < n; i++) { rc = NS_STATIC_CAST(nsHTMLReflowCommand*, mReflowCommands.ElementAt(0)); - mReflowCommands.RemoveElementAt(0); ReflowCommandRemoved(rc); delete rc; } + NS_ASSERTION(n == mReflowCommands.Count(),"reflow command list changed during cancel!"); + mReflowCommands.Clear(); n = mTimeoutReflowCommands.Count(); for (i = 0; i < n; i++) { rc = NS_STATIC_CAST(nsHTMLReflowCommand*, mTimeoutReflowCommands.ElementAt(0)); - mTimeoutReflowCommands.RemoveElementAt(0); ReflowCommandRemoved(rc); delete rc; } + NS_ASSERTION(n == mTimeoutReflowCommands.Count(),"timeout reflow command list changed during cancel!"); + mTimeoutReflowCommands.Clear(); DoneRemovingReflowCommands(); diff --git a/layout/html/forms/src/nsFormFrame.cpp b/layout/html/forms/src/nsFormFrame.cpp index e5603281f82d..b43ea74a194d 100644 --- a/layout/html/forms/src/nsFormFrame.cpp +++ b/layout/html/forms/src/nsFormFrame.cpp @@ -141,11 +141,10 @@ nsFormFrame::~nsFormFrame() RemoveRadioGroups(); PRInt32 numControls = mFormControls.Count(); PRInt32 i; - // Traverse list from end to 0 -> void array remove method does less work + for (i = (numControls-1); i>=0; i--) { nsIFormControlFrame* fcFrame = (nsIFormControlFrame*) mFormControls.ElementAt(i); fcFrame->SetFormFrame(nsnull); - mFormControls.RemoveElement(fcFrame); } } diff --git a/layout/html/forms/src/nsRadioControlGroup.cpp b/layout/html/forms/src/nsRadioControlGroup.cpp index 0e6742162ca8..af3567818e5b 100644 --- a/layout/html/forms/src/nsRadioControlGroup.cpp +++ b/layout/html/forms/src/nsRadioControlGroup.cpp @@ -56,7 +56,7 @@ nsRadioControlGroup::GetRadioCount() const nsGfxRadioControlFrame* nsRadioControlGroup::GetRadioAt(PRInt32 aIndex) const { - return (nsGfxRadioControlFrame*) mRadios.ElementAt(aIndex); + return (nsGfxRadioControlFrame*) mRadios.SafeElementAt(aIndex); } PRBool diff --git a/layout/html/table/src/nsCellMap.cpp b/layout/html/table/src/nsCellMap.cpp index 9b8d5c768d68..167268997e0b 100644 --- a/layout/html/table/src/nsCellMap.cpp +++ b/layout/html/table/src/nsCellMap.cpp @@ -72,6 +72,7 @@ nsTableCellMap::nsTableCellMap(nsIPresContext* aPresContext, nsTableFrame& aTabl nsAutoVoidArray orderedRowGroups; PRUint32 numRowGroups; aTableFrame.OrderRowGroups(orderedRowGroups, numRowGroups); + NS_ASSERTION(orderedRowGroups.Count() == (PRInt32) numRowGroups,"problem in OrderRowGroups"); for (PRUint32 rgX = 0; rgX < numRowGroups; rgX++) { nsTableRowGroupFrame* rgFrame = @@ -222,7 +223,7 @@ nsTableCellMap::GetColInfoAt(PRInt32 aColIndex) { PRInt32 numColsToAdd = aColIndex + 1 - mCols.Count(); if (numColsToAdd > 0) { - AddColsAtEnd(numColsToAdd); + AddColsAtEnd(numColsToAdd); // XXX this could fail to add cols in theory } return (nsColInfo*)mCols.ElementAt(aColIndex); } @@ -586,9 +587,9 @@ nsCellMap::GetCellFrame(PRInt32 aRowIndexIn, } } - nsVoidArray* row = (nsVoidArray*) mRows.ElementAt(rowIndex); + nsVoidArray* row = (nsVoidArray*) mRows.SafeElementAt(rowIndex); if (row) { - CellData* data = (CellData*)row->ElementAt(colIndex); + CellData* data = (CellData*)row->SafeElementAt(colIndex); if (data) { return data->GetCellFrame(); } @@ -875,9 +876,9 @@ PRBool nsCellMap::CellsSpanInOrOut(nsTableCellMap& aMap, if (cellData && (cellData->IsColSpan())) { return PR_TRUE; // there is a col span into the region } - nsVoidArray* row = (nsVoidArray *)(mRows.ElementAt(rowX)); + nsVoidArray* row = (nsVoidArray *)(mRows.SafeElementAt(rowX)); if (row) { - cellData = (CellData *)(row->ElementAt(aEndColIndex + 1)); + cellData = (CellData *)(row->SafeElementAt(aEndColIndex + 1)); if (cellData && (cellData->IsColSpan())) { return PR_TRUE; // there is a col span out of the region } @@ -1093,7 +1094,7 @@ void nsCellMap::ShrinkWithoutRows(nsTableCellMap& aMap, { PRInt32 endRowIndex = aStartRowIndex + aNumRowsToRemove - 1; PRInt32 colCount = aMap.GetColCount(); - for (PRInt32 rowX = endRowIndex; rowX >= aStartRowIndex; rowX--) { + for (PRInt32 rowX = endRowIndex; rowX >= aStartRowIndex; --rowX) { nsVoidArray* row = (nsVoidArray *)(mRows.ElementAt(rowX)); PRInt32 colX; for (colX = 0; colX < colCount; colX++) { @@ -1156,7 +1157,7 @@ PRInt32 nsCellMap::GetEffectiveColSpan(nsTableCellMap& aMap, PRInt32 numColsInTable = aMap.GetColCount(); aZeroColSpan = PR_FALSE; PRInt32 colSpan = 1; - nsVoidArray* row = (nsVoidArray *)(mRows.ElementAt(aRowIndex)); + nsVoidArray* row = (nsVoidArray *)(mRows.SafeElementAt(aRowIndex)); if (row) { PRInt32 colX; CellData* data; @@ -1597,9 +1598,9 @@ PRBool nsCellMap::IsZeroColSpan(PRInt32 aRowIndex, PRInt32 aColIndex) const { - nsVoidArray* row = (nsVoidArray*)mRows.ElementAt(aRowIndex); + nsVoidArray* row = (nsVoidArray*)mRows.SafeElementAt(aRowIndex); if (row) { - CellData* data = (CellData*)row->ElementAt(aColIndex); + CellData* data = (CellData*)row->SafeElementAt(aColIndex); if (data && data->IsZeroColSpan()) { return PR_TRUE; } @@ -1683,7 +1684,7 @@ nsCellMap::GetMapCellAt(nsTableCellMap& aMap, nsVoidArray* row = (nsVoidArray *)(mRows.ElementAt(aMapRowIndex)); if (!row) return nsnull; - CellData* data = (CellData *)(row->ElementAt(aColIndex)); + CellData* data = (CellData *)(row->SafeElementAt(aColIndex)); if (!data && aUpdateZeroSpan) { PRBool didZeroExpand = PR_FALSE; // check for special zero row span @@ -1691,7 +1692,7 @@ nsCellMap::GetMapCellAt(nsTableCellMap& aMap, // find the last non null data in the same col for ( ; prevRowX > 0; prevRowX--) { nsVoidArray* prevRow = (nsVoidArray *)(mRows.ElementAt(prevRowX)); - CellData* prevData = (CellData *)(prevRow->ElementAt(aColIndex)); + CellData* prevData = (CellData *)(prevRow->SafeElementAt(aColIndex)); if (prevData) { if (prevData->IsZeroRowSpan()) { PRInt32 rowIndex = prevRowX - prevData->GetRowSpanOffset(); @@ -1752,7 +1753,7 @@ void nsCellMap::SetMapCellAt(nsTableCellMap& aMap, PRInt32 aColIndex, PRBool aCountZeroSpanAsSpan) { - nsVoidArray* row = (nsVoidArray *)(mRows.ElementAt(aMapRowIndex)); + nsVoidArray* row = (nsVoidArray *)(mRows.SafeElementAt(aMapRowIndex)); if (row) { // the table map may need cols added PRInt32 numColsToAdd = aColIndex + 1 - aMap.GetColCount(); diff --git a/layout/html/table/src/nsTableBorderCollapser.cpp b/layout/html/table/src/nsTableBorderCollapser.cpp index 3e3772af5116..74e7ff405f29 100644 --- a/layout/html/table/src/nsTableBorderCollapser.cpp +++ b/layout/html/table/src/nsTableBorderCollapser.cpp @@ -51,11 +51,10 @@ nsTableBorderCollapser::nsTableBorderCollapser(nsTableFrame& aTableFrame) nsTableBorderCollapser::~nsTableBorderCollapser() { for (PRInt32 sideX = 0; sideX < 4; sideX++) { - nsBorderEdge* border = (nsBorderEdge *)(mBorderEdges.mEdges[sideX].ElementAt(0)); - while (border) { + PRInt32 count; + for (count = mBorderEdges.mEdges[sideX].Count()-1; count >= 0; --count) { + nsBorderEdge* border = (nsBorderEdge *)(mBorderEdges.mEdges[sideX].ElementAt(0)); delete border; - mBorderEdges.mEdges[sideX].RemoveElementAt(0); - border = (nsBorderEdge *)(mBorderEdges.mEdges[sideX].ElementAt(0)); } } } @@ -64,7 +63,7 @@ void nsTableBorderCollapser::SetBorderEdgeLength(PRUint8 aSide, PRInt32 aIndex, nscoord aLength) { - nsBorderEdge* border = (nsBorderEdge *)(mBorderEdges.mEdges[aSide].ElementAt(aIndex)); + nsBorderEdge* border = (nsBorderEdge *)(mBorderEdges.mEdges[aSide].SafeElementAt(aIndex)); if (border) { border->mLength = aLength; } @@ -84,13 +83,13 @@ void nsTableBorderCollapser::DidComputeHorizontalBorders(nsIPresContext* aPresCo nsIFrame* rowFrame; cellFrame->GetParent(&rowFrame); rowFrame->GetRect(rowRect); - nsBorderEdge* leftBorder = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_LEFT].ElementAt(0)); - nsBorderEdge* rightBorder = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_RIGHT].ElementAt(0)); - nsBorderEdge* topBorder = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_TOP].ElementAt(0)); + nsBorderEdge* leftBorder = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_LEFT].SafeElementAt(0)); + nsBorderEdge* rightBorder = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_RIGHT].SafeElementAt(0)); + nsBorderEdge* topBorder = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_TOP].SafeElementAt(0)); if (leftBorder) leftBorder->mLength = rowRect.height + topBorder->mWidth; if (topBorder) - topBorder = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_TOP].ElementAt(lastColIndex)); + topBorder = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_TOP].SafeElementAt(lastColIndex)); if (rightBorder) rightBorder->mLength = rowRect.height + topBorder->mWidth; } @@ -103,20 +102,20 @@ void nsTableBorderCollapser::DidComputeHorizontalBorders(nsIPresContext* aPresCo nsIFrame* rowFrame; cellFrame->GetParent(&rowFrame); rowFrame->GetRect(rowRect); - nsBorderEdge* leftBorder = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_LEFT].ElementAt(lastRowIndex)); - nsBorderEdge* rightBorder = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_RIGHT].ElementAt(lastRowIndex)); - nsBorderEdge* bottomBorder = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_BOTTOM].ElementAt(0)); + nsBorderEdge* leftBorder = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_LEFT].SafeElementAt(lastRowIndex)); + nsBorderEdge* rightBorder = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_RIGHT].SafeElementAt(lastRowIndex)); + nsBorderEdge* bottomBorder = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_BOTTOM].SafeElementAt(0)); if (leftBorder) leftBorder->mLength = rowRect.height + bottomBorder->mWidth; if (bottomBorder) - bottomBorder = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_BOTTOM].ElementAt(lastColIndex)); + bottomBorder = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_BOTTOM].SafeElementAt(lastColIndex)); if (rightBorder) rightBorder->mLength = rowRect.height + bottomBorder->mWidth; } } for (PRInt32 borderX = NS_SIDE_TOP; borderX <= NS_SIDE_LEFT; borderX++) { - if (!mBorderEdges.mEdges[borderX].ElementAt(0)) { + if (!mBorderEdges.mEdges[borderX].SafeElementAt(0)) { mBorderEdges.mEdges[borderX].AppendElement(new nsBorderEdge()); } } @@ -194,7 +193,7 @@ void nsTableBorderCollapser::ComputeLeftBorderForEdgeAt(nsIPresContext* aPresCon numSegments++; } // "border" is the border segment we are going to set - nsBorderEdge *border = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_LEFT].ElementAt(aRowIndex)); + nsBorderEdge *border = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_LEFT].SafeElementAt(aRowIndex)); if (!border) return; @@ -399,7 +398,7 @@ void nsTableBorderCollapser::ComputeTopBorderForEdgeAt(nsIPresContext* aPresCont numSegments++; } // "border" is the border segment we are going to set - nsBorderEdge *border = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_TOP].ElementAt(aColIndex)); + nsBorderEdge *border = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_TOP].SafeElementAt(aColIndex)); if (!border) return; @@ -455,13 +454,13 @@ void nsTableBorderCollapser::ComputeTopBorderForEdgeAt(nsIPresContext* aPresCont } if (0 == aColIndex) { // if we're the first column, factor in the thickness of the left table border - nsBorderEdge *leftBorder = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_LEFT].ElementAt(0)); + nsBorderEdge *leftBorder = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_LEFT].SafeElementAt(0)); if (leftBorder) border->mLength += leftBorder->mWidth; } if ((cellMap->GetColCount() - 1) == aColIndex) { // if we're the last column, factor in the thickness of the right table border - nsBorderEdge* rightBorder = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_RIGHT].ElementAt(0)); + nsBorderEdge* rightBorder = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_RIGHT].SafeElementAt(0)); if (rightBorder) border->mLength += rightBorder->mWidth; } @@ -588,13 +587,13 @@ void nsTableBorderCollapser::ComputeBottomBorderForEdgeAt(nsIPresContext* aPresC PRInt32 lastColIndex = cellMap->GetColCount()-1; if (0 == aColIndex) { // if we're the first column, factor in the thickness of the left table border - nsBorderEdge *leftBorder = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_LEFT].ElementAt(rowCount-1)); + nsBorderEdge *leftBorder = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_LEFT].SafeElementAt(rowCount-1)); if (leftBorder) tableBorder->mLength += leftBorder->mWidth; } if (lastColIndex == aColIndex) { // if we're the last column, factor in the thickness of the right table border - nsBorderEdge *rightBorder = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_RIGHT].ElementAt(rowCount-1)); + nsBorderEdge *rightBorder = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_RIGHT].SafeElementAt(rowCount-1)); if (rightBorder) tableBorder->mLength += rightBorder->mWidth; } @@ -847,19 +846,19 @@ void nsTableBorderCollapser::GetBorderAt(PRInt32 aRowIndex, PRInt32 aColIndex, nsMargin& aBorder) { - nsBorderEdge* border = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_LEFT].ElementAt(aRowIndex)); + nsBorderEdge* border = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_LEFT].SafeElementAt(aRowIndex)); if (border) { aBorder.left = border->mWidth; } - border = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_RIGHT].ElementAt(aRowIndex)); + border = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_RIGHT].SafeElementAt(aRowIndex)); if (border) { aBorder.right = border->mWidth; } - border = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_TOP].ElementAt(aColIndex)); + border = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_TOP].SafeElementAt(aColIndex)); if (border) { aBorder.top = border->mWidth; } - border = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_BOTTOM].ElementAt(aColIndex)); + border = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_BOTTOM].SafeElementAt(aColIndex)); if (border) { aBorder.bottom = border->mWidth; } diff --git a/layout/html/table/src/nsTableColGroupFrame.cpp b/layout/html/table/src/nsTableColGroupFrame.cpp index d157c02819d0..396ac94418b1 100644 --- a/layout/html/table/src/nsTableColGroupFrame.cpp +++ b/layout/html/table/src/nsTableColGroupFrame.cpp @@ -156,8 +156,9 @@ nsTableColGroupFrame::FindParentForAppendedCol(nsTableFrame* aTableFrame, nsVoidArray& cols = aTableFrame->GetColCache(); PRInt32 numCols = cols.Count(); nsIFrame* lastColGroup; + if (numCols == 0) return nsnull; // no columns so no colgroups nsIFrame* lastCol = (nsIFrame*)cols.ElementAt(numCols - 1); - if (!lastCol) return nsnull; // no columns so no colgroups + NS_ASSERTION(lastCol,"null entry in column array"); lastCol->GetParent(&lastColGroup); if (!lastColGroup) return nsnull; // shouldn't happen diff --git a/layout/html/table/src/nsTableFrame.cpp b/layout/html/table/src/nsTableFrame.cpp index 1e4b9d4a0dfe..8a5f3c17ce88 100644 --- a/layout/html/table/src/nsTableFrame.cpp +++ b/layout/html/table/src/nsTableFrame.cpp @@ -2606,7 +2606,7 @@ nsTableFrame::RemoveFrame(nsIPresContext* aPresContext, // remove the cols from the table PRInt32 colX; for (colX = lastColIndex; colX >= firstColIndex; colX--) { - nsTableColFrame* colFrame = (nsTableColFrame*)mColFrames.ElementAt(colX); + nsTableColFrame* colFrame = (nsTableColFrame*)mColFrames.SafeElementAt(colX); if (colFrame) { RemoveCol(*aPresContext, colGroup, colX, PR_TRUE, PR_FALSE); } diff --git a/layout/mathml/base/src/nsMathMLChar.cpp b/layout/mathml/base/src/nsMathMLChar.cpp index db02266160de..7e3b73091cc3 100644 --- a/layout/mathml/base/src/nsMathMLChar.cpp +++ b/layout/mathml/base/src/nsMathMLChar.cpp @@ -632,7 +632,7 @@ public: nsGlyphTable* ElementAt(PRInt32 aIndex) { - return NS_STATIC_CAST(nsGlyphTable*, mTableList.ElementAt(aIndex)); + return NS_STATIC_CAST(nsGlyphTable*, mTableList.SafeElementAt(aIndex)); } PRInt32 Count(PRBool aEverything = PR_FALSE) diff --git a/layout/style/nsCSSDeclaration.cpp b/layout/style/nsCSSDeclaration.cpp index c0d496dd7f2b..867e19414097 100644 --- a/layout/style/nsCSSDeclaration.cpp +++ b/layout/style/nsCSSDeclaration.cpp @@ -5137,6 +5137,10 @@ CSSDeclarationImpl::AllPropertiesSameValue(PRInt32 aFirst, PRInt32 aSecond, PRInt32 aThird, PRInt32 aFourth) { nsCSSValue firstValue, otherValue; + // TryBorderShorthand does the bounds-checking for us; valid values there + // are > 0; 0 is a flag for "not set". We here are passed the actual + // index, which comes from finding the value in the mOrder property array. + // Of course, re-getting the mOrder value here is pretty silly. GetValue((nsCSSProperty)NS_PTR_TO_INT32(mOrder->ElementAt(aFirst)), firstValue); GetValue((nsCSSProperty)NS_PTR_TO_INT32(mOrder->ElementAt(aSecond)), otherValue); if (firstValue != otherValue) { @@ -5181,6 +5185,7 @@ CSSDeclarationImpl::TryBorderShorthand(nsAWritableString & aString, PRInt32 & aBorderRightColor) { PRInt32 border = 0; + // 0 means not in the mOrder array; otherwise it's index+1 if (aBorderTopWidth && aBorderBottomWidth && aBorderLeftWidth && aBorderRightWidth && AllPropertiesSameValue(aBorderTopWidth-1, aBorderBottomWidth-1, @@ -5246,6 +5251,7 @@ CSSDeclarationImpl::TryBorderSideShorthand(nsAWritableString & aString, PRInt32 & aBorderStyle, PRInt32 & aBorderColor) { + // 0 means not in the mOrder array; otherwise it's index+1 if ((aBorderWidth && aBorderStyle) || (aBorderWidth && aBorderColor) || (aBorderStyle && aBorderColor)) { @@ -5282,6 +5288,7 @@ CSSDeclarationImpl::TryMarginOrPaddingShorthand(nsAWritableString & aString, PRInt32 & aLeft, PRInt32 & aRight) { + // 0 means not in the mOrder array; otherwise it's index+1 if (aTop && aBottom && aLeft && aRight) { // all 4 properties are set, we can output a shorthand aString.Append(NS_ConvertASCIItoUCS2(nsCSSProps::GetStringValue(aShorthand)) @@ -5322,6 +5329,7 @@ CSSDeclarationImpl::TryBackgroundShorthand(nsAWritableString & aString, PRInt32 & aBgPositionX, PRInt32 & aBgPositionY) { + // 0 means not in the mOrder array; otherwise it's index+1 // check if we have at least two properties set; otherwise, no need to // use a shorthand PRInt8 numberPropertiesSpecified = (aBgColor ? 1 : 0) + (aBgImage ? 1 : 0) @@ -5363,6 +5371,7 @@ CSSDeclarationImpl::TryBackgroundPosition(nsAWritableString & aString, PRInt32 & aBgPositionX, PRInt32 & aBgPositionY) { + // 0 means not in the mOrder array; otherwise it's index+1 if (aBgPositionX && aBgPositionY) { nsAutoString backgroundXValue, backgroundYValue; AppendValueToString(eCSSProperty_background_x_position, backgroundXValue); @@ -5392,6 +5401,7 @@ CSSDeclarationImpl::ToString(nsAWritableString& aString) if (nsnull != mOrder) { PRInt32 count = mOrder->Count(); PRInt32 index; + // 0 means not in the mOrder array; otherwise it's index+1 PRInt32 borderTopWidth = 0, borderTopStyle = 0, borderTopColor = 0; PRInt32 borderBottomWidth = 0, borderBottomStyle = 0, borderBottomColor = 0; PRInt32 borderLeftWidth = 0, borderLeftStyle = 0, borderLeftColor = 0; @@ -5495,6 +5505,7 @@ CSSDeclarationImpl::ToString(nsAWritableString& aString) case eCSSProperty_background_x_position: case eCSSProperty_background_y_position: + // 0 means not in the mOrder array; otherwise it's index+1 if (bgPositionX && bgPositionY) { aString.Append(NS_ConvertASCIItoUCS2(nsCSSProps::GetStringValue(eCSSProperty_background_position)) + NS_LITERAL_STRING(": ")); @@ -5687,7 +5698,7 @@ NS_IMETHODIMP CSSDeclarationImpl::GetNthProperty(PRUint32 aIndex, nsAWritableString& aReturn) { aReturn.Truncate(); - if (nsnull != mOrder) { + if (nsnull != mOrder && aIndex < mOrder->Count()) { nsCSSProperty property = (nsCSSProperty)NS_PTR_TO_INT32(mOrder->ElementAt(aIndex)); if (0 <= property) { aReturn.Append(NS_ConvertASCIItoUCS2(nsCSSProps::GetStringValue(property))); diff --git a/layout/style/nsCSSLoader.cpp b/layout/style/nsCSSLoader.cpp index 28cbf553febf..d99f62577339 100644 --- a/layout/style/nsCSSLoader.cpp +++ b/layout/style/nsCSSLoader.cpp @@ -605,12 +605,11 @@ CSSLoaderImpl::RecycleParser(nsICSSParser* aParser) nsresult result = NS_ERROR_NULL_POINTER; if (aParser) { - result = NS_OK; if (! mParsers) { result = NS_NewISupportsArray(&mParsers); } if (mParsers) { - mParsers->AppendElement(aParser); + result = mParsers->AppendElement(aParser); } } return result; diff --git a/layout/style/nsCSSStruct.cpp b/layout/style/nsCSSStruct.cpp index c0d496dd7f2b..867e19414097 100644 --- a/layout/style/nsCSSStruct.cpp +++ b/layout/style/nsCSSStruct.cpp @@ -5137,6 +5137,10 @@ CSSDeclarationImpl::AllPropertiesSameValue(PRInt32 aFirst, PRInt32 aSecond, PRInt32 aThird, PRInt32 aFourth) { nsCSSValue firstValue, otherValue; + // TryBorderShorthand does the bounds-checking for us; valid values there + // are > 0; 0 is a flag for "not set". We here are passed the actual + // index, which comes from finding the value in the mOrder property array. + // Of course, re-getting the mOrder value here is pretty silly. GetValue((nsCSSProperty)NS_PTR_TO_INT32(mOrder->ElementAt(aFirst)), firstValue); GetValue((nsCSSProperty)NS_PTR_TO_INT32(mOrder->ElementAt(aSecond)), otherValue); if (firstValue != otherValue) { @@ -5181,6 +5185,7 @@ CSSDeclarationImpl::TryBorderShorthand(nsAWritableString & aString, PRInt32 & aBorderRightColor) { PRInt32 border = 0; + // 0 means not in the mOrder array; otherwise it's index+1 if (aBorderTopWidth && aBorderBottomWidth && aBorderLeftWidth && aBorderRightWidth && AllPropertiesSameValue(aBorderTopWidth-1, aBorderBottomWidth-1, @@ -5246,6 +5251,7 @@ CSSDeclarationImpl::TryBorderSideShorthand(nsAWritableString & aString, PRInt32 & aBorderStyle, PRInt32 & aBorderColor) { + // 0 means not in the mOrder array; otherwise it's index+1 if ((aBorderWidth && aBorderStyle) || (aBorderWidth && aBorderColor) || (aBorderStyle && aBorderColor)) { @@ -5282,6 +5288,7 @@ CSSDeclarationImpl::TryMarginOrPaddingShorthand(nsAWritableString & aString, PRInt32 & aLeft, PRInt32 & aRight) { + // 0 means not in the mOrder array; otherwise it's index+1 if (aTop && aBottom && aLeft && aRight) { // all 4 properties are set, we can output a shorthand aString.Append(NS_ConvertASCIItoUCS2(nsCSSProps::GetStringValue(aShorthand)) @@ -5322,6 +5329,7 @@ CSSDeclarationImpl::TryBackgroundShorthand(nsAWritableString & aString, PRInt32 & aBgPositionX, PRInt32 & aBgPositionY) { + // 0 means not in the mOrder array; otherwise it's index+1 // check if we have at least two properties set; otherwise, no need to // use a shorthand PRInt8 numberPropertiesSpecified = (aBgColor ? 1 : 0) + (aBgImage ? 1 : 0) @@ -5363,6 +5371,7 @@ CSSDeclarationImpl::TryBackgroundPosition(nsAWritableString & aString, PRInt32 & aBgPositionX, PRInt32 & aBgPositionY) { + // 0 means not in the mOrder array; otherwise it's index+1 if (aBgPositionX && aBgPositionY) { nsAutoString backgroundXValue, backgroundYValue; AppendValueToString(eCSSProperty_background_x_position, backgroundXValue); @@ -5392,6 +5401,7 @@ CSSDeclarationImpl::ToString(nsAWritableString& aString) if (nsnull != mOrder) { PRInt32 count = mOrder->Count(); PRInt32 index; + // 0 means not in the mOrder array; otherwise it's index+1 PRInt32 borderTopWidth = 0, borderTopStyle = 0, borderTopColor = 0; PRInt32 borderBottomWidth = 0, borderBottomStyle = 0, borderBottomColor = 0; PRInt32 borderLeftWidth = 0, borderLeftStyle = 0, borderLeftColor = 0; @@ -5495,6 +5505,7 @@ CSSDeclarationImpl::ToString(nsAWritableString& aString) case eCSSProperty_background_x_position: case eCSSProperty_background_y_position: + // 0 means not in the mOrder array; otherwise it's index+1 if (bgPositionX && bgPositionY) { aString.Append(NS_ConvertASCIItoUCS2(nsCSSProps::GetStringValue(eCSSProperty_background_position)) + NS_LITERAL_STRING(": ")); @@ -5687,7 +5698,7 @@ NS_IMETHODIMP CSSDeclarationImpl::GetNthProperty(PRUint32 aIndex, nsAWritableString& aReturn) { aReturn.Truncate(); - if (nsnull != mOrder) { + if (nsnull != mOrder && aIndex < mOrder->Count()) { nsCSSProperty property = (nsCSSProperty)NS_PTR_TO_INT32(mOrder->ElementAt(aIndex)); if (0 <= property) { aReturn.Append(NS_ConvertASCIItoUCS2(nsCSSProps::GetStringValue(property))); diff --git a/layout/tables/nsCellMap.cpp b/layout/tables/nsCellMap.cpp index 9b8d5c768d68..167268997e0b 100644 --- a/layout/tables/nsCellMap.cpp +++ b/layout/tables/nsCellMap.cpp @@ -72,6 +72,7 @@ nsTableCellMap::nsTableCellMap(nsIPresContext* aPresContext, nsTableFrame& aTabl nsAutoVoidArray orderedRowGroups; PRUint32 numRowGroups; aTableFrame.OrderRowGroups(orderedRowGroups, numRowGroups); + NS_ASSERTION(orderedRowGroups.Count() == (PRInt32) numRowGroups,"problem in OrderRowGroups"); for (PRUint32 rgX = 0; rgX < numRowGroups; rgX++) { nsTableRowGroupFrame* rgFrame = @@ -222,7 +223,7 @@ nsTableCellMap::GetColInfoAt(PRInt32 aColIndex) { PRInt32 numColsToAdd = aColIndex + 1 - mCols.Count(); if (numColsToAdd > 0) { - AddColsAtEnd(numColsToAdd); + AddColsAtEnd(numColsToAdd); // XXX this could fail to add cols in theory } return (nsColInfo*)mCols.ElementAt(aColIndex); } @@ -586,9 +587,9 @@ nsCellMap::GetCellFrame(PRInt32 aRowIndexIn, } } - nsVoidArray* row = (nsVoidArray*) mRows.ElementAt(rowIndex); + nsVoidArray* row = (nsVoidArray*) mRows.SafeElementAt(rowIndex); if (row) { - CellData* data = (CellData*)row->ElementAt(colIndex); + CellData* data = (CellData*)row->SafeElementAt(colIndex); if (data) { return data->GetCellFrame(); } @@ -875,9 +876,9 @@ PRBool nsCellMap::CellsSpanInOrOut(nsTableCellMap& aMap, if (cellData && (cellData->IsColSpan())) { return PR_TRUE; // there is a col span into the region } - nsVoidArray* row = (nsVoidArray *)(mRows.ElementAt(rowX)); + nsVoidArray* row = (nsVoidArray *)(mRows.SafeElementAt(rowX)); if (row) { - cellData = (CellData *)(row->ElementAt(aEndColIndex + 1)); + cellData = (CellData *)(row->SafeElementAt(aEndColIndex + 1)); if (cellData && (cellData->IsColSpan())) { return PR_TRUE; // there is a col span out of the region } @@ -1093,7 +1094,7 @@ void nsCellMap::ShrinkWithoutRows(nsTableCellMap& aMap, { PRInt32 endRowIndex = aStartRowIndex + aNumRowsToRemove - 1; PRInt32 colCount = aMap.GetColCount(); - for (PRInt32 rowX = endRowIndex; rowX >= aStartRowIndex; rowX--) { + for (PRInt32 rowX = endRowIndex; rowX >= aStartRowIndex; --rowX) { nsVoidArray* row = (nsVoidArray *)(mRows.ElementAt(rowX)); PRInt32 colX; for (colX = 0; colX < colCount; colX++) { @@ -1156,7 +1157,7 @@ PRInt32 nsCellMap::GetEffectiveColSpan(nsTableCellMap& aMap, PRInt32 numColsInTable = aMap.GetColCount(); aZeroColSpan = PR_FALSE; PRInt32 colSpan = 1; - nsVoidArray* row = (nsVoidArray *)(mRows.ElementAt(aRowIndex)); + nsVoidArray* row = (nsVoidArray *)(mRows.SafeElementAt(aRowIndex)); if (row) { PRInt32 colX; CellData* data; @@ -1597,9 +1598,9 @@ PRBool nsCellMap::IsZeroColSpan(PRInt32 aRowIndex, PRInt32 aColIndex) const { - nsVoidArray* row = (nsVoidArray*)mRows.ElementAt(aRowIndex); + nsVoidArray* row = (nsVoidArray*)mRows.SafeElementAt(aRowIndex); if (row) { - CellData* data = (CellData*)row->ElementAt(aColIndex); + CellData* data = (CellData*)row->SafeElementAt(aColIndex); if (data && data->IsZeroColSpan()) { return PR_TRUE; } @@ -1683,7 +1684,7 @@ nsCellMap::GetMapCellAt(nsTableCellMap& aMap, nsVoidArray* row = (nsVoidArray *)(mRows.ElementAt(aMapRowIndex)); if (!row) return nsnull; - CellData* data = (CellData *)(row->ElementAt(aColIndex)); + CellData* data = (CellData *)(row->SafeElementAt(aColIndex)); if (!data && aUpdateZeroSpan) { PRBool didZeroExpand = PR_FALSE; // check for special zero row span @@ -1691,7 +1692,7 @@ nsCellMap::GetMapCellAt(nsTableCellMap& aMap, // find the last non null data in the same col for ( ; prevRowX > 0; prevRowX--) { nsVoidArray* prevRow = (nsVoidArray *)(mRows.ElementAt(prevRowX)); - CellData* prevData = (CellData *)(prevRow->ElementAt(aColIndex)); + CellData* prevData = (CellData *)(prevRow->SafeElementAt(aColIndex)); if (prevData) { if (prevData->IsZeroRowSpan()) { PRInt32 rowIndex = prevRowX - prevData->GetRowSpanOffset(); @@ -1752,7 +1753,7 @@ void nsCellMap::SetMapCellAt(nsTableCellMap& aMap, PRInt32 aColIndex, PRBool aCountZeroSpanAsSpan) { - nsVoidArray* row = (nsVoidArray *)(mRows.ElementAt(aMapRowIndex)); + nsVoidArray* row = (nsVoidArray *)(mRows.SafeElementAt(aMapRowIndex)); if (row) { // the table map may need cols added PRInt32 numColsToAdd = aColIndex + 1 - aMap.GetColCount(); diff --git a/layout/tables/nsTableColGroupFrame.cpp b/layout/tables/nsTableColGroupFrame.cpp index d157c02819d0..396ac94418b1 100644 --- a/layout/tables/nsTableColGroupFrame.cpp +++ b/layout/tables/nsTableColGroupFrame.cpp @@ -156,8 +156,9 @@ nsTableColGroupFrame::FindParentForAppendedCol(nsTableFrame* aTableFrame, nsVoidArray& cols = aTableFrame->GetColCache(); PRInt32 numCols = cols.Count(); nsIFrame* lastColGroup; + if (numCols == 0) return nsnull; // no columns so no colgroups nsIFrame* lastCol = (nsIFrame*)cols.ElementAt(numCols - 1); - if (!lastCol) return nsnull; // no columns so no colgroups + NS_ASSERTION(lastCol,"null entry in column array"); lastCol->GetParent(&lastColGroup); if (!lastColGroup) return nsnull; // shouldn't happen diff --git a/layout/tables/nsTableFrame.cpp b/layout/tables/nsTableFrame.cpp index 1e4b9d4a0dfe..8a5f3c17ce88 100644 --- a/layout/tables/nsTableFrame.cpp +++ b/layout/tables/nsTableFrame.cpp @@ -2606,7 +2606,7 @@ nsTableFrame::RemoveFrame(nsIPresContext* aPresContext, // remove the cols from the table PRInt32 colX; for (colX = lastColIndex; colX >= firstColIndex; colX--) { - nsTableColFrame* colFrame = (nsTableColFrame*)mColFrames.ElementAt(colX); + nsTableColFrame* colFrame = (nsTableColFrame*)mColFrames.SafeElementAt(colX); if (colFrame) { RemoveCol(*aPresContext, colGroup, colX, PR_TRUE, PR_FALSE); } diff --git a/modules/libpr0n/src/imgContainer.h b/modules/libpr0n/src/imgContainer.h index 773b6478370b..973737d6c9c5 100644 --- a/modules/libpr0n/src/imgContainer.h +++ b/modules/libpr0n/src/imgContainer.h @@ -74,6 +74,7 @@ private: } inline nsresult inlinedGetFrameAt(PRUint32 index, gfxIImageFrame **_retval) { + // callers DO try to go past the end nsISupports *_elem = mFrames.ElementAt(index); if (!_elem) return NS_ERROR_FAILURE; *_retval = NS_STATIC_CAST(gfxIImageFrame*, _elem); diff --git a/netwerk/base/src/nsIOService.cpp b/netwerk/base/src/nsIOService.cpp index da1db1be9f93..1cb52ee7d952 100644 --- a/netwerk/base/src/nsIOService.cpp +++ b/netwerk/base/src/nsIOService.cpp @@ -359,7 +359,7 @@ nsIOService::CacheURLParser(const char *scheme, nsIURLParser *parser) { NS_ENSURE_ARG_POINTER(scheme); NS_ENSURE_ARG_POINTER(parser); - for (unsigned int i=0; imErrorCode = 0; - MigrateProfileItem* item = (MigrateProfileItem*)migrator->mProfilesToMigrate.ElementAt(index); + MigrateProfileItem* item = nsnull; + + if (migrator->mProfilesToMigrate.Count() != 0) + item = (MigrateProfileItem*)migrator->mProfilesToMigrate.ElementAt(index); if (item) { rv = migrator->ProcessPrefsCallback(item->oldFile, item->newFile); diff --git a/rdf/base/src/nsRDFContentSink.cpp b/rdf/base/src/nsRDFContentSink.cpp index 72040bbed14a..9f2158dc1645 100644 --- a/rdf/base/src/nsRDFContentSink.cpp +++ b/rdf/base/src/nsRDFContentSink.cpp @@ -816,7 +816,9 @@ RDFContentSinkImpl::Init(nsIURI* aURL) NS_IMETHODIMP RDFContentSinkImpl::SetDataSource(nsIRDFDataSource* aDataSource) { + NS_PRECONDITION(aDataSource != nsnull, "SetDataSource null ptr"); mDataSource = dont_QueryInterface(aDataSource); + NS_ASSERTION(mDataSource != nsnull,"Couldn't QI RDF DataSource"); return NS_OK; } diff --git a/widget/src/windows/nsDataObj.cpp b/widget/src/windows/nsDataObj.cpp index 451e561eef21..c8778e15efb3 100644 --- a/widget/src/windows/nsDataObj.cpp +++ b/widget/src/windows/nsDataObj.cpp @@ -180,7 +180,7 @@ STDMETHODIMP nsDataObj::GetData(LPFORMATETC pFE, LPSTGMEDIUM pSTM) FORMATETC fe; m_enumFE->Reset(); while (NOERROR == m_enumFE->Next(1, &fe, &count)) { - nsCAutoString * df = NS_REINTERPRET_CAST(nsCAutoString*, mDataFlavors->ElementAt(dfInx)); + nsCAutoString * df = NS_REINTERPRET_CAST(nsCAutoString*, mDataFlavors->SafeElementAt(dfInx)); if ( df ) { if (FormatsMatch(fe, *pFE)) { pSTM->pUnkForRelease = NULL; // caller is responsible for deleting this data diff --git a/widget/src/windows/nsDataObjCollection.h b/widget/src/windows/nsDataObjCollection.h index 03f51ff8d0b7..72bcd6a472f7 100644 --- a/widget/src/windows/nsDataObjCollection.h +++ b/widget/src/windows/nsDataObjCollection.h @@ -102,13 +102,13 @@ class nsDataObjCollection : public IDataObject //, public nsPIDataObjCollection // from nsPIDataObjCollection STDMETHODIMP AddDataObject(IDataObject * aDataObj); STDMETHODIMP GetNumDataObjects(PRInt32* outNum) { *outNum = mDataObjects->Count(); } - STDMETHODIMP GetDataObjectAt(PRUint32 aItem, IDataObject** outItem) { *outItem = (IDataObject *)mDataObjects->ElementAt(aItem); } + STDMETHODIMP GetDataObjectAt(PRUint32 aItem, IDataObject** outItem) { *outItem = (IDataObject *)mDataObjects->SafeElementAt(aItem); } #endif // from nsPIDataObjCollection void AddDataObject(IDataObject * aDataObj); PRInt32 GetNumDataObjects() { return mDataObjects->Count(); } - IDataObject* GetDataObjectAt(PRUint32 aItem) { return (IDataObject *)mDataObjects->ElementAt(aItem); } + IDataObject* GetDataObjectAt(PRUint32 aItem) { return (IDataObject *)mDataObjects->SafeElementAt(aItem); } // Return the registered OLE class ID of this object's CfDataObj. CLSID GetClassID() const; diff --git a/xpcom/build/dlldeps.cpp b/xpcom/build/dlldeps.cpp index 1b3aa4f76233..ec669e596522 100644 --- a/xpcom/build/dlldeps.cpp +++ b/xpcom/build/dlldeps.cpp @@ -113,6 +113,7 @@ void XXXNeverCalled() nsTextFormatter::smprintf_free(nsnull); dummyComparitor dummy; nsVoidArray(); + nsSmallVoidArray(); nsVoidBTree(); nsAVLTree(dummy, nsnull); nsSupportsArray(); diff --git a/xpcom/ds/nsSupportsArray.h b/xpcom/ds/nsSupportsArray.h index 7cbcdd5993ca..51bf4db02263 100644 --- a/xpcom/ds/nsSupportsArray.h +++ b/xpcom/ds/nsSupportsArray.h @@ -71,16 +71,14 @@ public: return NS_ERROR_FAILURE; } NS_IMETHOD SetElementAt(PRUint32 aIndex, nsISupports* value) { - PRBool ok = ReplaceElementAt(value, aIndex); - return ok ? NS_OK : NS_ERROR_FAILURE; + return ReplaceElementAt(value, aIndex) ? NS_OK : NS_ERROR_FAILURE; } NS_IMETHOD AppendElement(nsISupports *aElement) { - // XXX This incorrectly returns a PRBool instead of an nsresult. - return InsertElementAt(aElement, mCount); + return InsertElementAt(aElement, mCount)/* ? NS_OK : NS_ERROR_FAILURE*/; } + // XXX this is badly named - should be RemoveFirstElement NS_IMETHOD RemoveElement(nsISupports *aElement) { - // XXX This incorrectly returns a PRBool instead of an nsresult. - return RemoveElement(aElement, 0); + return RemoveElement(aElement, 0)/* ? NS_OK : NS_ERROR_FAILURE*/; } NS_IMETHOD_(PRBool) MoveElement(PRInt32 aFrom, PRInt32 aTo); NS_IMETHOD Enumerate(nsIEnumerator* *result); diff --git a/xpcom/ds/nsVoidArray.cpp b/xpcom/ds/nsVoidArray.cpp index 8d1c85492668..9eb9c1a76e5f 100644 --- a/xpcom/ds/nsVoidArray.cpp +++ b/xpcom/ds/nsVoidArray.cpp @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; c-file-offsets: ((substatement-open . 0)) -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: NPL 1.1/GPL 2.0/LGPL 2.1 * @@ -35,6 +35,7 @@ * * ***** END LICENSE BLOCK ***** */ #include "nsVoidArray.h" +#include "nsQuickSort.h" #include "prmem.h" #include "nsCRT.h" #include "nsISizeOfHandler.h" @@ -45,6 +46,7 @@ * Grow the array by at least this many elements at a time. */ static const PRInt32 kMinGrowArrayBy = 8; +static const PRInt32 kMaxGrowArrayBy = 1024; /** * This is the threshold (in bytes) of the mImpl struct, past which @@ -261,10 +263,17 @@ PRBool nsVoidArray::GrowArrayBy(PRInt32 aGrowBy) // newCount includes enough space for at least kMinGrowArrayBy new // slots. Select the next power-of-two size in bytes above or // equal to that. - newSize = PR_BIT(PR_CeilingLog2(newSize)); - - // Request an appropriate number of elements. - newCapacity = CAPACITYOF_IMPL(newSize); + // Also, limit the increase in size to about a VM page or two. + if (GetArraySize() >= kMaxGrowArrayBy) + { + newCapacity = GetArraySize() + PR_MAX(kMaxGrowArrayBy,aGrowBy); + newSize = SIZEOF_IMPL(newCapacity); + } + else + { + newSize = PR_BIT(PR_CeilingLog2(newSize)); + newCapacity = CAPACITYOF_IMPL(newSize); + } } // frees old mImpl IF this succeeds if (!SizeTo(newCapacity)) @@ -364,15 +373,6 @@ nsVoidArray::SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const } #endif -void* nsVoidArray::ElementAt(PRInt32 aIndex) const -{ - if (aIndex < 0 || aIndex >= Count()) - { - return nsnull; - } - return mImpl->mArray[aIndex]; -} - PRInt32 nsVoidArray::IndexOf(void* aPossibleElement) const { if (mImpl) @@ -394,6 +394,7 @@ PRInt32 nsVoidArray::IndexOf(void* aPossibleElement) const PRBool nsVoidArray::InsertElementAt(void* aElement, PRInt32 aIndex) { PRInt32 oldCount = Count(); + NS_ASSERTION(aIndex >= 0,"InsertElementAt(negative index)"); if (PRUint32(aIndex) > PRUint32(oldCount)) { // An invalid index causes the insertion to fail @@ -438,6 +439,7 @@ PRBool nsVoidArray::InsertElementsAt(const nsVoidArray& other, PRInt32 aIndex) PRInt32 oldCount = Count(); PRInt32 otherCount = other.Count(); + NS_ASSERTION(aIndex >= 0,"InsertElementsAt(negative index)"); if (PRUint32(aIndex) > PRUint32(oldCount)) { // An invalid index causes the insertion to fail @@ -483,6 +485,10 @@ PRBool nsVoidArray::InsertElementsAt(const nsVoidArray& other, PRInt32 aIndex) PRBool nsVoidArray::ReplaceElementAt(void* aElement, PRInt32 aIndex) { + NS_ASSERTION(aIndex >= 0,"ReplaceElementAt(negative index)"); + if (aIndex < 0) + return PR_FALSE; + // Unlike InsertElementAt, ReplaceElementAt can implicitly add more // than just the one element to the array. if (PRUint32(aIndex) >= PRUint32(GetArraySize())) @@ -535,7 +541,8 @@ PRBool nsVoidArray::MoveElement(PRInt32 aFrom, PRInt32 aTo) if (aTo == aFrom) return PR_TRUE; - if (aTo < 0 || aFrom < 0 || aTo >= Count() || aFrom >= Count()) + NS_ASSERTION(aTo >= 0 && aFrom >= 0,"MoveElement(negative index)"); + if (aTo >= Count() || aFrom >= Count()) { // can't extend the array when moving an element. Also catches mImpl = null return PR_FALSE; @@ -563,6 +570,7 @@ PRBool nsVoidArray::MoveElement(PRInt32 aFrom, PRInt32 aTo) PRBool nsVoidArray::RemoveElementsAt(PRInt32 aIndex, PRInt32 aCount) { PRInt32 oldCount = Count(); + NS_ASSERTION(aIndex >= 0,"RemoveElementsAt(negative index)"); if (PRUint32(aIndex) >= PRUint32(oldCount)) { // An invalid index causes the replace to fail @@ -1157,3 +1165,430 @@ nsCStringArray::EnumerateBackwards(nsCStringArrayEnumFunc aFunc, void* aData) } return running; } + + +//---------------------------------------------------------------------- +// NOTE: nsSmallVoidArray elements MUST all have the low bit as 0. +// This means that normally it's only used for pointers, and in particular +// structures or objects. +nsSmallVoidArray::nsSmallVoidArray() +{ + mChildren = nsnull; +} + +nsSmallVoidArray::~nsSmallVoidArray() +{ + if (HasVector()) + { + nsVoidArray* vector = GetChildVector(); + delete vector; + } +} + +nsSmallVoidArray& +nsSmallVoidArray::operator=(nsSmallVoidArray& other) +{ + nsVoidArray* ourArray = GetChildVector(); + nsVoidArray* otherArray = other.GetChildVector(); + + if (HasVector()) + { + if (other.HasVector()) + { + // if both are real arrays, just use array= */ + *ourArray = *otherArray; + } + else + { + // we have an array, but the other doesn't. + otherArray = other.SwitchToVector(); + if (otherArray) + *ourArray = *otherArray; + } + } + else + { + if (other.HasVector()) + { + // we have no array, but other does + ourArray = SwitchToVector(); + if (ourArray) + *ourArray = *otherArray; + } + else + { + // neither has an array (either may have 0 or 1 items) + SetSingleChild(other.GetSingleChild()); + } + } + return *this; +} + +void +nsSmallVoidArray::SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const +{ + if (aResult) + { + PRUint32 size = 0; + if (HasVector()) + { + nsVoidArray* ourArray = GetChildVector(); + ourArray->SizeOf(aHandler,&size); + } + *aResult = sizeof(*this) + size; + } +} + +PRInt32 +nsSmallVoidArray::GetArraySize() const +{ + nsVoidArray* vector = GetChildVector(); + if (vector) + return vector->GetArraySize(); + + return 1; +} + +PRInt32 +nsSmallVoidArray::Count() const +{ + if (HasSingleChild()) + { + return 1; + } + else { + nsVoidArray* vector = GetChildVector(); + if (vector) + return vector->Count(); + } + + return 0; +} + +void* +nsSmallVoidArray::ElementAt(PRInt32 aIndex) const +{ + if (HasSingleChild()) + { + if (0 == aIndex) + return (void*)GetSingleChild(); + } + else + { + nsVoidArray* vector = GetChildVector(); + if (vector) + return vector->ElementAt(aIndex); + } + + return nsnull; +} + +PRInt32 +nsSmallVoidArray::IndexOf(void* aPossibleElement) const +{ + if (HasSingleChild()) + { + if (aPossibleElement == (void*)GetSingleChild()) + return 0; + } + else + { + nsVoidArray* vector = GetChildVector(); + if (vector) + return vector->IndexOf(aPossibleElement); + } + + return -1; +} + +PRBool +nsSmallVoidArray::InsertElementAt(void* aElement, PRInt32 aIndex) +{ + nsVoidArray* vector; + NS_ASSERTION(!(PtrBits(aElement) & 0x1),"Attempt to add element with 0x1 bit set to nsSmallVoidArray"); + + if (HasSingleChild()) + { + vector = SwitchToVector(); + } + else + { + vector = GetChildVector(); + if (!vector) + { + if (0 == aIndex) + { + SetSingleChild(aElement); + return PR_TRUE; + } + return PR_FALSE; + } + } + + return vector->InsertElementAt(aElement, aIndex); +} + +PRBool nsSmallVoidArray::InsertElementsAt(const nsVoidArray &other, PRInt32 aIndex) +{ + nsVoidArray* vector; + PRInt32 count = other.Count(); + if (count == 0) + return PR_TRUE; + +#ifdef DEBUG + for (int i = 0; i < count; i++) + NS_ASSERTION(!(PtrBits(other.ElementAt(i)) & 0x1),"Attempt to add element with 0x1 bit set to nsSmallVoidArray"); +#endif + + if (!HasVector()) + { + if (HasSingleChild() || count > 1 || aIndex > 0) + { + vector = SwitchToVector(); + } + else + { + // count == 1, aIndex == 0, no elements already + SetSingleChild(other[0]); + return PR_TRUE; + } + } + else + { + vector = GetChildVector(); + } + + if (vector) + { + return vector->InsertElementsAt(other,aIndex); + } + return PR_TRUE; +} + +PRBool +nsSmallVoidArray::ReplaceElementAt(void* aElement, PRInt32 aIndex) +{ + NS_ASSERTION(!(PtrBits(aElement) & 0x1),"Attempt to add element with 0x1 bit set to nsSmallVoidArray"); + + if (HasSingleChild()) + { + if (aIndex == 0) + { + SetSingleChild(aElement); + return PR_TRUE; + } + return PR_FALSE; + } + else + { + nsVoidArray* vector = GetChildVector(); + if (vector) + return vector->ReplaceElementAt(aElement, aIndex); + + return PR_FALSE; + } +} + +PRBool +nsSmallVoidArray::AppendElement(void* aElement) +{ + NS_ASSERTION(!(PtrBits(aElement) & 0x1),"Attempt to add element with 0x1 bit set to nsSmallVoidArray"); + + nsVoidArray* vector; + if (HasSingleChild()) + { + vector = SwitchToVector(); + } + else + { + vector = GetChildVector(); + if (!vector) + { + SetSingleChild(aElement); + return PR_TRUE; + } + } + + return vector->AppendElement(aElement); +} + +PRBool +nsSmallVoidArray::RemoveElement(void* aElement) +{ + if (HasSingleChild()) + { + if (aElement == GetSingleChild()) + { + SetSingleChild(nsnull); + return PR_TRUE; + } + } + else + { + nsVoidArray* vector = GetChildVector(); + if (vector) + return vector->RemoveElement(aElement); + } + + return PR_FALSE; +} + +PRBool +nsSmallVoidArray::RemoveElementAt(PRInt32 aIndex) +{ + if (HasSingleChild()) + { + if (0 == aIndex) + { + SetSingleChild(nsnull); + return PR_TRUE; + } + } + else + { + nsVoidArray* vector = GetChildVector(); + if (vector) + { + return vector->RemoveElementAt(aIndex); + } + } + + return PR_FALSE; +} + +PRBool +nsSmallVoidArray::RemoveElementsAt(PRInt32 aIndex, PRInt32 aCount) +{ + nsVoidArray* vector = GetChildVector(); + + if (aCount == 0) + return PR_TRUE; + + if (HasSingleChild()) + { + if (aIndex == 0) + SetSingleChild(nsnull); + return PR_TRUE; + } + + if (!vector) + return PR_TRUE; + + // complex case; remove entries from an array + return vector->RemoveElementsAt(aIndex,aCount); +} + +void +nsSmallVoidArray::Clear() +{ + if (HasVector()) + { + nsVoidArray* vector = GetChildVector(); + vector->Clear(); + } + else + { + SetSingleChild(nsnull); + } +} + +PRBool +nsSmallVoidArray::SizeTo(PRInt32 aMin) +{ + nsVoidArray* vector; + if (!HasVector()) + { + if (aMin <= 1) + return PR_TRUE; + vector = SwitchToVector(); + } + else + { + vector = GetChildVector(); + if (aMin <= 1) + { + void *prev = nsnull; + if (vector->Count() == 1) + { + prev = vector->ElementAt(0); + } + delete vector; + SetSingleChild(prev); + return PR_TRUE; + } + } + return vector->SizeTo(aMin); +} + +void +nsSmallVoidArray::Compact() +{ + if (!HasSingleChild()) + { + nsVoidArray* vector = GetChildVector(); + if (vector) + vector->Compact(); + } +} + +void +nsSmallVoidArray::Sort(nsVoidArrayComparatorFunc aFunc, void* aData) +{ + if (HasVector()) + { + nsVoidArray* vector = GetChildVector(); + vector->Sort(aFunc,aData); + } +} + +PRBool +nsSmallVoidArray::EnumerateForwards(nsVoidArrayEnumFunc aFunc, void* aData) +{ + if (HasVector()) + { + nsVoidArray* vector = GetChildVector(); + return vector->EnumerateForwards(aFunc,aData); + } + if (HasSingleChild()) + { + return (*aFunc)(GetSingleChild(), aData); + } + return PR_TRUE; +} + +PRBool +nsSmallVoidArray::EnumerateBackwards(nsVoidArrayEnumFunc aFunc, void* aData) +{ + if (HasVector()) + { + nsVoidArray* vector = GetChildVector(); + return vector->EnumerateBackwards(aFunc,aData); + } + if (HasSingleChild()) + { + return (*aFunc)(GetSingleChild(), aData); + } + return PR_TRUE; +} + +void +nsSmallVoidArray::SetSingleChild(void* aChild) +{ + if (aChild) + mChildren = (void*)(PtrBits(aChild) | 0x1); + else + mChildren = nsnull; +} + +nsVoidArray* +nsSmallVoidArray::SwitchToVector() +{ + void* child = GetSingleChild(); + + mChildren = (void*)new nsAutoVoidArray(); + nsVoidArray* vector = GetChildVector(); + if (vector && child) + vector->AppendElement(child); + + return vector; +} diff --git a/xpcom/ds/nsVoidArray.h b/xpcom/ds/nsVoidArray.h index 24cef5b33c36..86581ec5a8a5 100644 --- a/xpcom/ds/nsVoidArray.h +++ b/xpcom/ds/nsVoidArray.h @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; c-file-offsets: ((substatement-open . 0)) -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: NPL 1.1/GPL 2.0/LGPL 2.1 * @@ -41,7 +41,6 @@ #include "nscore.h" #include "nsAWritableString.h" -#include "nsQuickSort.h" class nsISizeOfHandler; @@ -73,7 +72,30 @@ public: return mImpl ? PRInt32(mImpl->mBits & kArraySizeMask) : 0; } - void* ElementAt(PRInt32 aIndex) const; + void* nsVoidArray::ElementAt(PRInt32 aIndex) const + { + NS_ASSERTION(aIndex >= 0,"nsVoidArray::ElementAt(negative index) - note on bug 96108"); + NS_ASSERTION(aIndex < Count(),"nsVoidArray::ElementAt(index past end array) - note on bug 96108"); + // This will go away once all assertions are handled and we feel + // comfortable that there aren't any more out there. Negative values + // are all handled I think. + if (aIndex >= Count()) + { + return nsnull; + } + return mImpl->mArray[aIndex]; + } + + // bounds-checked version + void* nsVoidArray::SafeElementAt(PRInt32 aIndex) const + { + if (aIndex < 0 || aIndex >= Count()) + { + return nsnull; + } + return mImpl->mArray[aIndex]; + } + void* operator[](PRInt32 aIndex) const { return ElementAt(aIndex); } PRInt32 IndexOf(void* aPossibleElement) const; @@ -90,6 +112,10 @@ public: return InsertElementAt(aElement, Count()); } + PRBool AppendElements(nsVoidArray& aElements) { + return InsertElementsAt(aElements, Count()); + } + PRBool RemoveElement(void* aElement); PRBool RemoveElementsAt(PRInt32 aIndex, PRInt32 aCount); PRBool RemoveElementAt(PRInt32 aIndex) { return RemoveElementsAt(aIndex,1); } @@ -289,4 +315,92 @@ private: }; +//=================================================================== +// nsSmallVoidArray is not a general-purpose replacement for +// ns(Auto)VoidArray because there is (some) extra CPU overhead for arrays +// larger than 1 element, though not a lot. It is appropriate for +// space-sensitive uses where sizes of 0 or 1 are moderately common or +// more, and where we're NOT storing arbitrary integers or arbitrary +// pointers. + +// NOTE: nsSmallVoidArray can ONLY be used for holding items that always +// have the low bit as a 0 - i.e. element & 1 == 0. This happens to be +// true for allocated and object pointers for all the architectures we run +// on, but conceivably there might be some architectures/compilers for +// which it is NOT true. We know this works for all existing architectures +// because if it didn't then nsCheapVoidArray would have failed. Also note +// that we will ASSERT if this assumption is violated in DEBUG builds. + +// XXX we're really re-implementing the whole nsVoidArray interface here - +// some form of abstract class would be useful +class NS_COM nsSmallVoidArray +{ +public: + nsSmallVoidArray(); + virtual ~nsSmallVoidArray(); + + nsSmallVoidArray& operator=(nsSmallVoidArray& other); + void* operator[](PRInt32 aIndex) const { return ElementAt(aIndex); } + + virtual void SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const; + PRInt32 GetArraySize() const; + + PRInt32 Count() const; + void* ElementAt(PRInt32 aIndex) const; + void* SafeElementAt(PRInt32 aIndex) const { + // let compiler inline; it may be able to remove these checks + if (aIndex < 0 || aIndex >= Count()) + return nsnull; + return ElementAt(aIndex); + } + PRInt32 IndexOf(void* aPossibleElement) const; + PRBool InsertElementAt(void* aElement, PRInt32 aIndex); + PRBool InsertElementsAt(const nsVoidArray &other, PRInt32 aIndex); + PRBool ReplaceElementAt(void* aElement, PRInt32 aIndex); + PRBool MoveElement(PRInt32 aFrom, PRInt32 aTo); + PRBool AppendElement(void* aElement); + PRBool AppendElements(nsVoidArray& aElements) { + return InsertElementsAt(aElements, Count()); + } + PRBool RemoveElement(void* aElement); + PRBool RemoveElementsAt(PRInt32 aIndex, PRInt32 aCount); + PRBool RemoveElementAt(PRInt32 aIndex); + + void Clear(); + PRBool SizeTo(PRInt32 aMin); + void Compact(); + void Sort(nsVoidArrayComparatorFunc aFunc, void* aData); + + PRBool EnumerateForwards(nsVoidArrayEnumFunc aFunc, void* aData); + PRBool EnumerateBackwards(nsVoidArrayEnumFunc aFunc, void* aData); + +private: + typedef unsigned long PtrBits; + + PRBool HasSingleChild() const + { + return (mChildren && (PtrBits(mChildren) & 0x1)); + } + PRBool HasVector() const + { + return (mChildren && !(PtrBits(mChildren) & 0x1)); + } + void* GetSingleChild() const + { + return (mChildren ? ((void*)(PtrBits(mChildren) & ~0x1)) : nsnull); + } + void SetSingleChild(void *aChild); + nsVoidArray* GetChildVector() const + { + return (nsVoidArray*)mChildren; + } + nsVoidArray* SwitchToVector(); + + // A tagged pointer that's either a pointer to a single child + // or a pointer to a vector of multiple children. This is a space + // optimization since a large number of containers have only a + // single child. + void *mChildren; +}; + #endif /* nsVoidArray_h___ */ diff --git a/xpcom/ds/nsVoidBTree.cpp b/xpcom/ds/nsVoidBTree.cpp index f9642cbba533..c062d32883ed 100644 --- a/xpcom/ds/nsVoidBTree.cpp +++ b/xpcom/ds/nsVoidBTree.cpp @@ -180,6 +180,8 @@ nsVoidBTree::Count() const void* nsVoidBTree::ElementAt(PRInt32 aIndex) const { + NS_ASSERTION(aIndex >= 0,"nsVoidBTree::ElementAt negative index!"); + NS_ASSERTION(aIndex < Count(),"nsVoidBTree::ElementAt past end"); if (aIndex < 0 || aIndex >= Count()) return nsnull; diff --git a/xpfe/appshell/src/nsCommandLineService.cpp b/xpfe/appshell/src/nsCommandLineService.cpp index 6fe63c4bb7e1..475dbd0638d5 100644 --- a/xpfe/appshell/src/nsCommandLineService.cpp +++ b/xpfe/appshell/src/nsCommandLineService.cpp @@ -212,7 +212,7 @@ nsCmdLineService::GetProgramName(char ** aResult) { nsresult rv = NS_OK; - *aResult = (char *)mArgValueList.ElementAt(0); + *aResult = (char *)mArgValueList.SafeElementAt(0); return rv; diff --git a/xpfe/components/intl/nsCharsetMenu.cpp b/xpfe/components/intl/nsCharsetMenu.cpp index 0f9e8144b307..2a8d1c0a2e25 100644 --- a/xpfe/components/intl/nsCharsetMenu.cpp +++ b/xpfe/components/intl/nsCharsetMenu.cpp @@ -1584,13 +1584,15 @@ nsresult nsCharsetMenu::RemoveLastMenuItem(nsIRDFContainer * aContainer, nsresult res = NS_OK; PRInt32 last = aArray->Count() - 1; - nsMenuEntry * item = (nsMenuEntry *) aArray->ElementAt(last); - if (item != NULL) { - res = AddMenuItemToContainer(aContainer, item, NULL, "charset.", -2); - if (NS_FAILED(res)) return res; + if (last >= 0) { + nsMenuEntry * item = (nsMenuEntry *) aArray->ElementAt(last); + if (item != NULL) { + res = AddMenuItemToContainer(aContainer, item, NULL, "charset.", -2); + if (NS_FAILED(res)) return res; - res = aArray->RemoveElementAt(last); - if (NS_FAILED(res)) return res; + res = aArray->RemoveElementAt(last); + if (NS_FAILED(res)) return res; + } } return res; diff --git a/xpfe/components/shistory/src/nsSHEntry.cpp b/xpfe/components/shistory/src/nsSHEntry.cpp index aab01808c470..884ec3c4768a 100644 --- a/xpfe/components/shistory/src/nsSHEntry.cpp +++ b/xpfe/components/shistory/src/nsSHEntry.cpp @@ -354,13 +354,8 @@ NS_IMETHODIMP nsSHEntry::GetChildAt(PRInt32 aIndex, nsISHEntry ** aResult) { NS_ENSURE_ARG_POINTER(aResult); - if (PRUint32(aIndex) >= PRUint32(mChildren.Count())) { - *aResult = nsnull; - } - else { - *aResult = (nsISHEntry*) mChildren.ElementAt(aIndex); - NS_IF_ADDREF(*aResult); - } + *aResult = (nsISHEntry*) mChildren.SafeElementAt(aIndex); + NS_IF_ADDREF(*aResult); return NS_OK; } diff --git a/xpfe/components/startup/src/nsCommandLineService.cpp b/xpfe/components/startup/src/nsCommandLineService.cpp index 6fe63c4bb7e1..475dbd0638d5 100644 --- a/xpfe/components/startup/src/nsCommandLineService.cpp +++ b/xpfe/components/startup/src/nsCommandLineService.cpp @@ -212,7 +212,7 @@ nsCmdLineService::GetProgramName(char ** aResult) { nsresult rv = NS_OK; - *aResult = (char *)mArgValueList.ElementAt(0); + *aResult = (char *)mArgValueList.SafeElementAt(0); return rv; diff --git a/xpinstall/src/nsSoftwareUpdate.cpp b/xpinstall/src/nsSoftwareUpdate.cpp index aaec175b7b46..5d0ad5a36bca 100644 --- a/xpinstall/src/nsSoftwareUpdate.cpp +++ b/xpinstall/src/nsSoftwareUpdate.cpp @@ -1,4 +1,3 @@ - /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * The contents of this file are subject to the Netscape Public @@ -368,11 +367,14 @@ nsSoftwareUpdate::InstallJarCallBack() { PR_Lock(mLock); - nsInstallInfo *nextInstall = (nsInstallInfo*)mJarInstallQueue.ElementAt(0); - if (nextInstall != nsnull) - delete nextInstall; + if (mJarInstallQueue.Count() != 0) // paranoia + { + nsInstallInfo *nextInstall = (nsInstallInfo*)mJarInstallQueue.ElementAt(0); + if (nextInstall != nsnull) + delete nextInstall; - mJarInstallQueue.RemoveElementAt(0); + mJarInstallQueue.RemoveElementAt(0); + } mInstalling = PR_FALSE; PR_Unlock(mLock); diff --git a/xpinstall/src/nsTopProgressNotifier.cpp b/xpinstall/src/nsTopProgressNotifier.cpp index 7aceea64ad67..a6e304d809cc 100644 --- a/xpinstall/src/nsTopProgressNotifier.cpp +++ b/xpinstall/src/nsTopProgressNotifier.cpp @@ -1,4 +1,4 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * The contents of this file are subject to the Netscape Public * License Version 1.1 (the "License"); you may not use this file @@ -77,9 +77,12 @@ void nsTopProgressListener::UnregisterListener(long id) { if (mLock) PR_Lock(mLock); - nsIXPIListener *item = (nsIXPIListener*)mListeners->ElementAt(id); - mListeners->ReplaceElementAt(nsnull, id); - NS_IF_RELEASE(item); + if (id < mListeners->Count()) + { + nsIXPIListener *item = (nsIXPIListener*)mListeners->ElementAt(id); + mListeners->ReplaceElementAt(nsnull, id); + NS_IF_RELEASE(item); + } if (mLock) PR_Unlock(mLock); }