diff --git a/dom/base/ContentIterator.cpp b/dom/base/ContentIterator.cpp index 63d959e7098b..185e29c9f512 100644 --- a/dom/base/ContentIterator.cpp +++ b/dom/base/ContentIterator.cpp @@ -262,7 +262,7 @@ nsresult ContentIteratorBase::InitInternal(const RawRangeBoundary& aStart, NS_WARNING_ASSERTION(mLast, "PrevNode returned null"); if (mLast && mLast != mFirst && NS_WARN_IF(!NodeIsInTraversalRange( - mLast, mPre, RawRangeBoundary(mFirst, 0), aEnd))) { + mLast, mPre, RawRangeBoundary(mFirst, 0u), aEnd))) { mLast = nullptr; } } else { @@ -558,8 +558,8 @@ nsresult ContentIteratorBase::PositionAt(nsINode* aCurNode) { // Check to see if the node falls within the traversal range. - RawRangeBoundary first(mFirst, 0); - RawRangeBoundary last(mLast, 0); + RawRangeBoundary first(mFirst, 0u); + RawRangeBoundary last(mLast, 0u); if (mFirst && mLast) { if (mPre) { diff --git a/dom/base/RangeBoundary.h b/dom/base/RangeBoundary.h index 606f63d125dd..567e8ef12fc5 100644 --- a/dom/base/RangeBoundary.h +++ b/dom/base/RangeBoundary.h @@ -64,13 +64,13 @@ class RangeBoundaryBase { } } - RangeBoundaryBase(nsINode* aContainer, int32_t aOffset) + RangeBoundaryBase(nsINode* aContainer, uint32_t aOffset) : mParent(aContainer), mRef(nullptr), mOffset(mozilla::Some(aOffset)) { if (mParent && mParent->IsContainerNode()) { // Find a reference node - if (aOffset == static_cast(mParent->GetChildCount())) { + if (aOffset == mParent->GetChildCount()) { mRef = mParent->GetLastChild(); - } else if (aOffset != 0) { + } else if (aOffset > 0) { mRef = mParent->GetChildAt_Deprecated(aOffset - 1); } diff --git a/dom/base/Selection.cpp b/dom/base/Selection.cpp index 3c00193ac800..e994aac44363 100644 --- a/dom/base/Selection.cpp +++ b/dom/base/Selection.cpp @@ -2766,7 +2766,7 @@ void Selection::SelectAllChildren(nsINode& aNode, ErrorResult& aRv) { // Chrome moves focus when aNode is outside of active editing host. // So, we don't need to respect the limiter with this method. - SetStartAndEndInternal(InLimiter::eNo, RawRangeBoundary(&aNode, 0), + SetStartAndEndInternal(InLimiter::eNo, RawRangeBoundary(&aNode, 0u), RawRangeBoundary(&aNode, aNode.GetChildCount()), eDirNext, aRv); } diff --git a/dom/base/nsIMutationObserver.h b/dom/base/nsIMutationObserver.h index db169414c27b..f62bd7b4feef 100644 --- a/dom/base/nsIMutationObserver.h +++ b/dom/base/nsIMutationObserver.h @@ -9,6 +9,8 @@ #include "nsISupports.h" +#include "mozilla/Assertions.h" + class nsAttrValue; class nsAtom; class nsIContent; @@ -50,6 +52,12 @@ struct CharacterDataChangeInfo { */ uint32_t mChangeEnd; + uint32_t LengthOfRemovedText() const { + MOZ_ASSERT(mChangeStart <= mChangeEnd); + + return mChangeEnd - mChangeStart; + } + /** * The length of the text that was inserted in place of the removed text. If * this was a pure text removal, this is 0. diff --git a/dom/base/nsRange.cpp b/dom/base/nsRange.cpp index b40d645f8789..e7ec347def0d 100644 --- a/dom/base/nsRange.cpp +++ b/dom/base/nsRange.cpp @@ -459,7 +459,7 @@ void nsRange::CharacterDataChanged(nsIContent* aContent, "only a split can start before the end"); NS_ASSERTION(mStart.Offset() <= aInfo.mChangeEnd + 1, "mStart.Offset() is beyond the end of this node"); - int32_t newStartOffset = mStart.Offset() - aInfo.mChangeStart; + const uint32_t newStartOffset = mStart.Offset() - aInfo.mChangeStart; newStart = {aInfo.mDetails->mNextSibling, newStartOffset}; if (MOZ_UNLIKELY(aContent == mRoot)) { newRoot = RangeUtils::ComputeRootNode(newStart.Container()); @@ -479,12 +479,18 @@ void nsRange::CharacterDataChanged(nsIContent* aContent, } else { // If boundary is inside changed text, position it before change // else adjust start offset for the change in length. - int32_t newStartOffset = mStart.Offset() <= aInfo.mChangeEnd - ? aInfo.mChangeStart - : mStart.Offset() + aInfo.mChangeStart - - aInfo.mChangeEnd + - aInfo.mReplaceLength; - newStart = {mStart.Container(), newStartOffset}; + CheckedUint32 newStartOffset{0}; + if (mStart.Offset() <= aInfo.mChangeEnd) { + newStartOffset = aInfo.mChangeStart; + } else { + newStartOffset = mStart.Offset(); + newStartOffset -= aInfo.LengthOfRemovedText(); + newStartOffset += aInfo.mReplaceLength; + } + + // newStartOffset.isValid() isn't checked explicitly here, because + // newStartOffset.value() contains an assertion. + newStart = {mStart.Container(), newStartOffset.value()}; } } @@ -500,9 +506,8 @@ void nsRange::CharacterDataChanged(nsIContent* aContent, MOZ_ASSERT(mEnd.Offset() <= aInfo.mChangeEnd + 1, "mEnd.Offset() is beyond the end of this node"); - const CheckedInt newEndOffset{mEnd.Offset() - - aInfo.mChangeStart}; - newEnd = {aInfo.mDetails->mNextSibling, newEndOffset.value()}; + const uint32_t newEndOffset{mEnd.Offset() - aInfo.mChangeStart}; + newEnd = {aInfo.mDetails->mNextSibling, newEndOffset}; bool isCommonAncestor = IsInSelection() && mStart.Container() == mEnd.Container(); @@ -516,11 +521,18 @@ void nsRange::CharacterDataChanged(nsIContent* aContent, newEnd.Container()->SetDescendantOfCommonAncestorForRangeInSelection(); } } else { - int32_t newEndOffset = mEnd.Offset() <= aInfo.mChangeEnd - ? aInfo.mChangeStart - : mEnd.Offset() + aInfo.mChangeStart - - aInfo.mChangeEnd + aInfo.mReplaceLength; - newEnd = {mEnd.Container(), newEndOffset}; + CheckedUint32 newEndOffset{0}; + if (mEnd.Offset() <= aInfo.mChangeEnd) { + newEndOffset = aInfo.mChangeStart; + } else { + newEndOffset = mEnd.Offset(); + newEndOffset -= aInfo.LengthOfRemovedText(); + newEndOffset += aInfo.mReplaceLength; + } + + // newEndOffset.isValid() isn't checked explicitly here, because + // newEndOffset.value() contains an assertion. + newEnd = {mEnd.Container(), newEndOffset.value()}; } } @@ -530,17 +542,22 @@ void nsRange::CharacterDataChanged(nsIContent* aContent, // that will be removed nsIContent* removed = aInfo.mDetails->mNextSibling; if (removed == mStart.Container()) { - const CheckedInt newStartOffset{mStart.Offset() + - aInfo.mChangeStart}; + CheckedUint32 newStartOffset{mStart.Offset()}; + newStartOffset += aInfo.mChangeStart; + + // newStartOffset.isValid() isn't checked explicitly here, because + // newStartOffset.value() contains an assertion. newStart = {aContent, newStartOffset.value()}; if (MOZ_UNLIKELY(removed == mRoot)) { newRoot = RangeUtils::ComputeRootNode(newStart.Container()); } } if (removed == mEnd.Container()) { - const CheckedInt newEndOffset{mEnd.Offset() + - aInfo.mChangeStart}; + CheckedUint32 newEndOffset{mEnd.Offset()}; + newEndOffset += aInfo.mChangeStart; + // newEndOffset.isValid() isn't checked explicitly here, because + // newEndOffset.value() contains an assertion. newEnd = {aContent, newEndOffset.value()}; if (MOZ_UNLIKELY(removed == mRoot)) { newRoot = RangeUtils::ComputeRootNode(newEnd.Container()); @@ -556,14 +573,12 @@ void nsRange::CharacterDataChanged(nsIContent* aContent, if (parentNode == mStart.Container() && mStart.Offset() > 0 && mStart.Offset() < parentNode->GetChildCount() && removed == mStart.GetChildAtOffset()) { - const CheckedInt newStartOffset{aInfo.mChangeStart}; - newStart = {aContent, newStartOffset.value()}; + newStart = {aContent, aInfo.mChangeStart}; } if (parentNode == mEnd.Container() && mEnd.Offset() > 0 && mEnd.Offset() < parentNode->GetChildCount() && removed == mEnd.GetChildAtOffset()) { - const CheckedInt newEndOffset{aInfo.mChangeEnd}; - newEnd = {aContent, newEndOffset.value()}; + newEnd = {aContent, aInfo.mChangeEnd}; } } @@ -1262,7 +1277,7 @@ void nsRange::SelectNodeContents(nsINode& aNode, ErrorResult& aRv) { } AutoInvalidateSelection atEndOfBlock(this); - DoSetRange(RawRangeBoundary(&aNode, 0), + DoSetRange(RawRangeBoundary(&aNode, 0u), RawRangeBoundary(&aNode, aNode.Length()), newRoot); } diff --git a/dom/events/ContentEventHandler.cpp b/dom/events/ContentEventHandler.cpp index f546f59082ef..7b8555c1a144 100644 --- a/dom/events/ContentEventHandler.cpp +++ b/dom/events/ContentEventHandler.cpp @@ -355,7 +355,7 @@ nsresult ContentEventHandler::InitCommon(SelectionType aSelectionType, // But otherwise, we need to assume that there is a selection range at the // beginning of the root content if aSelectionType is eNormal. - rv = mFirstSelectedRawRange.CollapseTo(RawRangeBoundary(mRootContent, 0)); + rv = mFirstSelectedRawRange.CollapseTo(RawRangeBoundary(mRootContent, 0u)); if (NS_WARN_IF(NS_FAILED(rv))) { return NS_ERROR_UNEXPECTED; } @@ -1012,7 +1012,7 @@ nsresult ContentEventHandler::SetRawRangeFromFlatTextOffset( // Special case like
if (!mRootContent->HasChildren()) { - nsresult rv = aRawRange->CollapseTo(RawRangeBoundary(mRootContent, 0)); + nsresult rv = aRawRange->CollapseTo(RawRangeBoundary(mRootContent, 0u)); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } @@ -2853,7 +2853,7 @@ nsresult ContentEventHandler::AdjustCollapsedRangeMaybeIntoTextNode( return NS_OK; } nsresult rv = aRawRange.CollapseTo( - RawRangeBoundary(startPoint.Container()->GetFirstChild(), 0)); + RawRangeBoundary(startPoint.Container()->GetFirstChild(), 0u)); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } diff --git a/editor/libeditor/HTMLEditSubActionHandler.cpp b/editor/libeditor/HTMLEditSubActionHandler.cpp index 20bb0797c654..0a2a6c960cd5 100644 --- a/editor/libeditor/HTMLEditSubActionHandler.cpp +++ b/editor/libeditor/HTMLEditSubActionHandler.cpp @@ -241,7 +241,7 @@ nsresult HTMLEditor::InitEditorContentAndSelection() { } rv = InsertBRElementToEmptyListItemsAndTableCellsInRange( - RawRangeBoundary(bodyOrDocumentElement, 0), + RawRangeBoundary(bodyOrDocumentElement, 0u), RawRangeBoundary(bodyOrDocumentElement, bodyOrDocumentElement->GetChildCount())); if (NS_WARN_IF(rv == NS_ERROR_EDITOR_DESTROYED)) { @@ -7464,9 +7464,8 @@ void HTMLEditor::SelectBRElementIfCollapsedInEmptyBlock( bool isEmptyNode = false; IsEmptyNode(block, &isEmptyNode, true, false); if (isEmptyNode) { - aStartRef = {block, 0}; - const CheckedInt offset{block->Length()}; - aEndRef = {block, offset.value()}; + aStartRef = {block, 0u}; + aEndRef = {block, block->Length()}; } } @@ -8213,7 +8212,7 @@ nsresult HTMLEditor::HandleInsertParagraphInHeadingElement(Element& aHeader, // Put selection at front of righthand heading ErrorResult error; - SelectionRefPtr()->Collapse(RawRangeBoundary(&aHeader, 0), error); + SelectionRefPtr()->Collapse(RawRangeBoundary(&aHeader, 0u), error); if (NS_WARN_IF(Destroyed())) { error.SuppressException(); return NS_ERROR_EDITOR_DESTROYED; @@ -8556,7 +8555,7 @@ nsresult HTMLEditor::HandleInsertParagraphInListItemElement(Element& aListItem, return rv; } ErrorResult error; - SelectionRefPtr()->Collapse(RawRangeBoundary(&aListItem, 0), error); + SelectionRefPtr()->Collapse(RawRangeBoundary(&aListItem, 0u), error); if (NS_WARN_IF(Destroyed())) { error.SuppressException(); return NS_ERROR_EDITOR_DESTROYED; @@ -10268,7 +10267,7 @@ nsresult HTMLEditor::EnsureSelectionInBodyOrDocumentElement() { // If we aren't in the element, force the issue. if (!temp) { IgnoredErrorResult ignoredError; - SelectionRefPtr()->Collapse(RawRangeBoundary(bodyOrDocumentElement, 0), + SelectionRefPtr()->Collapse(RawRangeBoundary(bodyOrDocumentElement, 0u), ignoredError); if (NS_WARN_IF(Destroyed())) { return NS_ERROR_EDITOR_DESTROYED; @@ -10295,7 +10294,7 @@ nsresult HTMLEditor::EnsureSelectionInBodyOrDocumentElement() { // If we aren't in the element, force the issue. if (!temp) { IgnoredErrorResult ignoredError; - SelectionRefPtr()->Collapse(RawRangeBoundary(bodyOrDocumentElement, 0), + SelectionRefPtr()->Collapse(RawRangeBoundary(bodyOrDocumentElement, 0u), ignoredError); if (NS_WARN_IF(Destroyed())) { return NS_ERROR_EDITOR_DESTROYED; @@ -10808,7 +10807,7 @@ nsresult HTMLEditor::MoveSelectedContentsToDivElementToMakeItAbsolutePosition( // Don't restore the selection restoreSelectionLater.Abort(); ErrorResult error; - SelectionRefPtr()->Collapse(RawRangeBoundary(newDivElement, 0), error); + SelectionRefPtr()->Collapse(RawRangeBoundary(newDivElement, 0u), error); if (NS_WARN_IF(Destroyed())) { error.SuppressException(); return NS_ERROR_EDITOR_DESTROYED; diff --git a/editor/libeditor/HTMLTableEditor.cpp b/editor/libeditor/HTMLTableEditor.cpp index 6dd732279671..265b5fd8e443 100644 --- a/editor/libeditor/HTMLTableEditor.cpp +++ b/editor/libeditor/HTMLTableEditor.cpp @@ -523,7 +523,7 @@ nsresult HTMLEditor::InsertTableColumnsWithTransaction( // Simply set selection to the current cell. So, we can let // InsertTableCellsWithTransaction() do the work. Insert a new cell // before current one. - SelectionRefPtr()->Collapse(RawRangeBoundary(cellData.mElement, 0), + SelectionRefPtr()->Collapse(RawRangeBoundary(cellData.mElement, 0u), ignoredError); NS_WARNING_ASSERTION(!ignoredError.Failed(), "Failed to collapse Selection into the cell"); @@ -570,7 +570,7 @@ nsresult HTMLEditor::InsertTableColumnsWithTransaction( // cell indexes for current cell, the effects of colspan > 1 in some cells // makes this futile. We must use NormalizeTableInternal() first to assure // that there are cells in each cellmap location. - SelectionRefPtr()->Collapse(RawRangeBoundary(lastCellNode, 0), + SelectionRefPtr()->Collapse(RawRangeBoundary(lastCellNode, 0u), ignoredError); NS_WARNING_ASSERTION(!ignoredError.Failed(), "Failed to collapse Selection into the cell"); diff --git a/editor/libeditor/TextEditor.cpp b/editor/libeditor/TextEditor.cpp index 0d05a109af7b..15a3d374e881 100644 --- a/editor/libeditor/TextEditor.cpp +++ b/editor/libeditor/TextEditor.cpp @@ -2082,7 +2082,7 @@ nsresult TextEditor::SelectEntireDocument() { if (childNode && EditorBase::IsPaddingBRElementForEmptyLastLine(*childNode)) { ErrorResult error; MOZ_KnownLive(SelectionRefPtr()) - ->SetStartAndEndInLimiter(RawRangeBoundary(anonymousDivElement, 0), + ->SetStartAndEndInLimiter(RawRangeBoundary(anonymousDivElement, 0u), EditorRawDOMPoint(childNode), error); NS_WARNING_ASSERTION(!error.Failed(), "Failed to select all children of the editor root " diff --git a/editor/libeditor/WSRunObject.cpp b/editor/libeditor/WSRunObject.cpp index 01874bc0b959..93c24fb8358c 100644 --- a/editor/libeditor/WSRunObject.cpp +++ b/editor/libeditor/WSRunObject.cpp @@ -1711,7 +1711,7 @@ WSRunScanner::WSPoint WSRunScanner::GetNextCharPointInternal( while (curNum != lastNum) { Text* curNode = mNodeArray[curNum]; int16_t cmp = nsContentUtils::ComparePoints(aPoint.ToRawRangeBoundary(), - RawRangeBoundary(curNode, 0)); + RawRangeBoundary(curNode, 0u)); if (cmp < 0) { lastNum = curNum; } else { @@ -1761,7 +1761,7 @@ WSRunScanner::WSPoint WSRunScanner::GetPreviousCharPointInternal( while (curNum != lastNum) { Text* curNode = mNodeArray[curNum]; cmp = nsContentUtils::ComparePoints(aPoint.ToRawRangeBoundary(), - RawRangeBoundary(curNode, 0)); + RawRangeBoundary(curNode, 0u)); if (cmp < 0) { lastNum = curNum; } else {