Bug 1377978 - Make nsRange use uint32_t to offset r=smaug
authorMasayuki Nakano <masayuki@d-toybox.com>
Wed, 19 Jul 2017 22:49:52 +0900
changeset 418546 9c0436b452d6df7ab0eddf0fa1787e305630fc0b
parent 418545 dc7a346e62fc7053e0519c324ab232898e184320
child 418547 07490393bd507e575f9728358d43f83741472b15
push id7566
push usermtabara@mozilla.com
push dateWed, 02 Aug 2017 08:25:16 +0000
treeherdermozilla-beta@86913f512c3c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1377978
milestone56.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1377978 - Make nsRange use uint32_t to offset r=smaug DOM Standard defines that offset of Range is unsigned long. However, nsRange uses int32_t to them. This patch makes nsRange use uint32_t instead. However, this patch does NOT allow to set over INT32_MAX as offset values since a lot of users of nsRange cannot treat the values as over INT32_MAX because a lot of internal APIs take int32_t as offsets. For easier to search such points, this patch adds static_cast<int32_t> to uint32_t variables when they are used for int32_t arguments. And note that nsContentUtils::ComparePoints() behaves odd. It accepts negative offset and compares such value with valid offset simply. This patch still uses int32_t offset variables in nsRange::CompareNodeToRange() even though it may be negative value if nsINode::IndexOf() returns -1 because the caller of it depends on this behavior. MozReview-Commit-ID: 8RbOgA86JuT
dom/base/Selection.cpp
dom/base/nsContentUtils.cpp
dom/base/nsContentUtils.h
dom/base/nsDocumentEncoder.cpp
dom/base/nsFocusManager.cpp
dom/base/nsRange.cpp
dom/base/nsRange.h
dom/interfaces/range/nsIDOMRange.idl
editor/libeditor/EditorBase.cpp
editor/libeditor/HTMLEditRules.cpp
editor/libeditor/HTMLEditor.cpp
editor/libeditor/HTMLEditorDataTransfer.cpp
editor/libeditor/HTMLStyleEditor.cpp
editor/libeditor/HTMLTableEditor.cpp
editor/txtsvc/nsFilteredContentIterator.cpp
editor/txtsvc/nsTextServicesDocument.cpp
extensions/spellcheck/src/mozInlineSpellChecker.cpp
layout/base/PresShell.cpp
layout/generic/nsImageFrame.cpp
toolkit/components/find/nsFind.cpp
toolkit/components/find/nsWebBrowserFind.cpp
toolkit/components/typeaheadfind/nsTypeAheadFind.cpp
--- a/dom/base/Selection.cpp
+++ b/dom/base/Selection.cpp
@@ -1397,23 +1397,24 @@ Selection::GetType(int16_t* aType)
 //
 //    Compares the range beginning or ending point, and returns true if it
 //    exactly matches the given DOM point.
 
 static inline bool
 RangeMatchesBeginPoint(nsRange* aRange, nsINode* aNode, int32_t aOffset)
 {
   return aRange->GetStartContainer() == aNode &&
-         aRange->StartOffset() == aOffset;
+         static_cast<int32_t>(aRange->StartOffset()) == aOffset;
 }
 
 static inline bool
 RangeMatchesEndPoint(nsRange* aRange, nsINode* aNode, int32_t aOffset)
 {
-  return aRange->GetEndContainer() == aNode && aRange->EndOffset() == aOffset;
+  return aRange->GetEndContainer() == aNode &&
+         static_cast<int32_t>(aRange->EndOffset()) == aOffset;
 }
 
 // Selection::EqualsRangeAtPoint
 //
 //    Utility method for checking equivalence of two ranges.
 
 bool
 Selection::EqualsRangeAtPoint(
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -2769,16 +2769,19 @@ nsContentUtils::PositionIsBefore(nsINode
 
 /* static */
 int32_t
 nsContentUtils::ComparePoints(nsINode* aParent1, int32_t aOffset1,
                               nsINode* aParent2, int32_t aOffset2,
                               bool* aDisconnected)
 {
   if (aParent1 == aParent2) {
+    // XXX This is odd.  aOffset1 and/or aOffset2 may be -1, e.g., it's result
+    //     of nsINode::IndexOf(), but this compares such invalid offset with
+    //     valid offset.
     return aOffset1 < aOffset2 ? -1 :
            aOffset1 > aOffset2 ? 1 :
            0;
   }
 
   AutoTArray<nsINode*, 32> parents1, parents2;
   nsINode* node1 = aParent1;
   nsINode* node2 = aParent2;
@@ -2819,20 +2822,24 @@ nsContentUtils::ComparePoints(nsINode* a
   // The parent chains never differed, so one of the nodes is an ancestor of
   // the other
 
   NS_ASSERTION(!pos1 || !pos2,
                "should have run out of parent chain for one of the nodes");
 
   if (!pos1) {
     nsINode* child2 = parents2.ElementAt(--pos2);
+    // XXX aOffset1 may be -1 as mentioned above.  So, why does this return
+    //     it's *before* of the valid DOM point?
     return aOffset1 <= parent->IndexOf(child2) ? -1 : 1;
   }
 
   nsINode* child1 = parents1.ElementAt(--pos1);
+  // XXX aOffset2 may be -1 as mentioned above.  So, why does this return it's
+  //     *after* of the valid DOM point?
   return parent->IndexOf(child1) < aOffset2 ? -1 : 1;
 }
 
 /* static */
 int32_t
 nsContentUtils::ComparePoints(nsIDOMNode* aParent1, int32_t aOffset1,
                               nsIDOMNode* aParent2, int32_t aOffset2,
                               bool* aDisconnected)
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -399,16 +399,23 @@ public:
   /**
    *  Utility routine to compare two "points", where a point is a
    *  node/offset pair
    *  Returns -1 if point1 < point2, 1, if point1 > point2,
    *  0 if error or if point1 == point2.
    *  NOTE! If the two nodes aren't in the same connected subtree,
    *  the result is 1, and the optional aDisconnected parameter
    *  is set to true.
+   *
+   *  XXX aOffset1 and aOffset2 should be uint32_t since valid offset value is
+   *      between 0 - UINT32_MAX.  However, these methods work even with
+   *      negative offset values!  E.g., when aOffset1 is -1 and aOffset is 0,
+   *      these methods return -1.  Some root callers depend on this behavior.
+   *      On the other hand, nsINode can have ATTRCHILD_ARRAY_MAX_CHILD_COUN
+   *      (0x3FFFFF) at most.  Therefore, they can be int32_t for now.
    */
   static int32_t ComparePoints(nsINode* aParent1, int32_t aOffset1,
                                nsINode* aParent2, int32_t aOffset2,
                                bool* aDisconnected = nullptr);
   static int32_t ComparePoints(nsIDOMNode* aParent1, int32_t aOffset1,
                                nsIDOMNode* aParent2, int32_t aOffset2,
                                bool* aDisconnected = nullptr);
 
--- a/dom/base/nsDocumentEncoder.cpp
+++ b/dom/base/nsDocumentEncoder.cpp
@@ -1564,20 +1564,23 @@ nsHTMLCopyEncoder::IncludeInContext(nsIN
                                       nsGkAtoms::h5,
                                       nsGkAtoms::h6);
 }
 
 
 nsresult
 nsHTMLCopyEncoder::PromoteRange(nsIDOMRange *inRange)
 {
-  if (!inRange) return NS_ERROR_NULL_POINTER;
+  RefPtr<nsRange> range = static_cast<nsRange*>(inRange);
+  if (!range) {
+    return NS_ERROR_NULL_POINTER;
+  }
   nsresult rv;
   nsCOMPtr<nsIDOMNode> startNode, endNode, common;
-  int32_t startOffset, endOffset;
+  uint32_t startOffset, endOffset;
 
   rv = inRange->GetCommonAncestorContainer(getter_AddRefs(common));
   NS_ENSURE_SUCCESS(rv, rv);
   rv = inRange->GetStartContainer(getter_AddRefs(startNode));
   NS_ENSURE_SUCCESS(rv, rv);
   rv = inRange->GetStartOffset(&startOffset);
   NS_ENSURE_SUCCESS(rv, rv);
   rv = inRange->GetEndContainer(getter_AddRefs(endNode));
@@ -1585,33 +1588,35 @@ nsHTMLCopyEncoder::PromoteRange(nsIDOMRa
   rv = inRange->GetEndOffset(&endOffset);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIDOMNode> opStartNode;
   nsCOMPtr<nsIDOMNode> opEndNode;
   int32_t opStartOffset, opEndOffset;
 
   // examine range endpoints.
-  rv = GetPromotedPoint( kStart, startNode, startOffset, address_of(opStartNode), &opStartOffset, common);
+  rv = GetPromotedPoint(kStart, startNode, static_cast<int32_t>(startOffset),
+                        address_of(opStartNode), &opStartOffset, common);
   NS_ENSURE_SUCCESS(rv, rv);
-  rv = GetPromotedPoint( kEnd, endNode, endOffset, address_of(opEndNode), &opEndOffset, common);
+  rv = GetPromotedPoint(kEnd, endNode, static_cast<int32_t>(endOffset),
+                        address_of(opEndNode), &opEndOffset, common);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // if both range endpoints are at the common ancestor, check for possible inclusion of ancestors
   if ( (opStartNode == common) && (opEndNode == common) )
   {
     rv = PromoteAncestorChain(address_of(opStartNode), &opStartOffset, &opEndOffset);
     NS_ENSURE_SUCCESS(rv, rv);
     opEndNode = opStartNode;
   }
 
   // set the range to the new values
-  rv = inRange->SetStart(opStartNode, opStartOffset);
+  rv = inRange->SetStart(opStartNode, static_cast<uint32_t>(opStartOffset));
   NS_ENSURE_SUCCESS(rv, rv);
-  rv = inRange->SetEnd(opEndNode, opEndOffset);
+  rv = inRange->SetEnd(opEndNode, static_cast<uint32_t>(opEndOffset));
   return rv;
 }
 
 
 // PromoteAncestorChain will promote a range represented by [{*ioNode,*ioStartOffset} , {*ioNode,*ioEndOffset}]
 // The promotion is different from that found in getPromotedPoint: it will only promote one endpoint if it can
 // promote the other.  Thus, instead of having a startnode/endNode, there is just the one ioNode.
 nsresult
--- a/dom/base/nsFocusManager.cpp
+++ b/dom/base/nsFocusManager.cpp
@@ -2507,42 +2507,40 @@ nsFocusManager::GetSelectionLocation(nsI
   nsCOMPtr<nsISelection> domSelection;
   if (frameSelection) {
     domSelection = frameSelection->GetSelection(SelectionType::eNormal);
   }
 
   nsCOMPtr<nsIDOMNode> startNode, endNode;
   bool isCollapsed = false;
   nsCOMPtr<nsIContent> startContent, endContent;
-  int32_t startOffset = 0;
+  uint32_t startOffset = 0;
   if (domSelection) {
     domSelection->GetIsCollapsed(&isCollapsed);
     nsCOMPtr<nsIDOMRange> domRange;
     rv = domSelection->GetRangeAt(0, getter_AddRefs(domRange));
     if (domRange) {
       domRange->GetStartContainer(getter_AddRefs(startNode));
       domRange->GetEndContainer(getter_AddRefs(endNode));
       domRange->GetStartOffset(&startOffset);
 
       nsIContent *childContent = nullptr;
 
       startContent = do_QueryInterface(startNode);
       if (startContent && startContent->IsElement()) {
-        NS_ASSERTION(startOffset >= 0, "Start offset cannot be negative");
         childContent = startContent->GetChildAt(startOffset);
         if (childContent) {
           startContent = childContent;
         }
       }
 
       endContent = do_QueryInterface(endNode);
       if (endContent && endContent->IsElement()) {
-        int32_t endOffset = 0;
+        uint32_t endOffset = 0;
         domRange->GetEndOffset(&endOffset);
-        NS_ASSERTION(endOffset >= 0, "End offset cannot be negative");
         childContent = endContent->GetChildAt(endOffset);
         if (childContent) {
           endContent = childContent;
         }
       }
     }
   }
   else {
@@ -2560,17 +2558,17 @@ nsFocusManager::GetSelectionLocation(nsI
 
       if (startContent->NodeType() == nsIDOMNode::TEXT_NODE) {
         nsAutoString nodeValue;
         startContent->AppendTextTo(nodeValue);
 
         bool isFormControl =
           startContent->IsNodeOfType(nsINode::eHTML_FORM_CONTROL);
 
-        if (nodeValue.Length() == (uint32_t)startOffset && !isFormControl &&
+        if (nodeValue.Length() == startOffset && !isFormControl &&
             startContent != aDocument->GetRootElement()) {
           // Yes, indeed we were at the end of the last node
           nsCOMPtr<nsIFrameEnumerator> frameTraversal;
           nsresult rv = NS_NewFrameTraversal(getter_AddRefs(frameTraversal),
                                              presContext, startFrame,
                                              eLeaf,
                                              false, // aVisual
                                              false, // aLockInScrollView
--- a/dom/base/nsRange.cpp
+++ b/dom/base/nsRange.cpp
@@ -106,41 +106,47 @@ nsRange::CompareNodeToRange(nsINode* aNo
   int32_t nodeStart, nodeEnd;
   nsINode* parent = aNode->GetParentNode();
   if (!parent) {
     // can't make a parent/offset pair to represent start or
     // end of the root node, because it has no parent.
     // so instead represent it by (node,0) and (node,numChildren)
     parent = aNode;
     nodeStart = 0;
-    nodeEnd = aNode->GetChildCount();
+    uint32_t childCount = aNode->GetChildCount();
+    MOZ_ASSERT(childCount <= INT32_MAX,
+               "There shouldn't be over INT32_MAX children");
+    nodeEnd = static_cast<int32_t>(childCount);
   }
   else {
     nodeStart = parent->IndexOf(aNode);
     nodeEnd = nodeStart + 1;
+    MOZ_ASSERT(nodeStart < nodeEnd, "nodeStart shouldn't be INT32_MAX");
   }
 
   nsINode* rangeStartContainer = aRange->GetStartContainer();
   nsINode* rangeEndContainer = aRange->GetEndContainer();
-  int32_t rangeStartOffset = aRange->StartOffset();
-  int32_t rangeEndOffset = aRange->EndOffset();
+  uint32_t rangeStartOffset = aRange->StartOffset();
+  uint32_t rangeEndOffset = aRange->EndOffset();
 
   // is RANGE(start) <= NODE(start) ?
   bool disconnected = false;
-  *outNodeBefore = nsContentUtils::ComparePoints(rangeStartContainer,
-                                                 rangeStartOffset,
-                                                 parent, nodeStart,
-                                                 &disconnected) > 0;
+  *outNodeBefore =
+    nsContentUtils::ComparePoints(rangeStartContainer,
+                                  static_cast<int32_t>(rangeStartOffset),
+                                  parent, nodeStart,
+                                  &disconnected) > 0;
   NS_ENSURE_TRUE(!disconnected, NS_ERROR_DOM_WRONG_DOCUMENT_ERR);
 
   // is RANGE(end) >= NODE(end) ?
-  *outNodeAfter = nsContentUtils::ComparePoints(rangeEndContainer,
-                                                rangeEndOffset,
-                                                parent, nodeEnd,
-                                                &disconnected) < 0;
+  *outNodeAfter =
+    nsContentUtils::ComparePoints(rangeEndContainer,
+                                  static_cast<int32_t>(rangeEndOffset),
+                                  parent, nodeEnd,
+                                  &disconnected) < 0;
   NS_ENSURE_TRUE(!disconnected, NS_ERROR_DOM_WRONG_DOCUMENT_ERR);
   return NS_OK;
 }
 
 static nsINode*
 GetNextRangeCommonAncestor(nsINode* aNode)
 {
   while (aNode && !aNode->IsCommonAncestorForRangeInSelection()) {
@@ -159,23 +165,27 @@ GetNextRangeCommonAncestor(nsINode* aNod
 struct IsItemInRangeComparator
 {
   nsINode* mNode;
   uint32_t mStartOffset;
   uint32_t mEndOffset;
 
   int operator()(const nsRange* const aRange) const
   {
-    int32_t cmp = nsContentUtils::ComparePoints(mNode, mEndOffset,
-                                                aRange->GetStartContainer(),
-                                                aRange->StartOffset());
+    int32_t cmp =
+      nsContentUtils::ComparePoints(
+        mNode, static_cast<int32_t>(mEndOffset),
+        aRange->GetStartContainer(),
+        static_cast<int32_t>(aRange->StartOffset()));
     if (cmp == 1) {
-      cmp = nsContentUtils::ComparePoints(mNode, mStartOffset,
-                                          aRange->GetEndContainer(),
-                                          aRange->EndOffset());
+      cmp =
+        nsContentUtils::ComparePoints(
+          mNode, static_cast<int32_t>(mStartOffset),
+          aRange->GetEndContainer(),
+          static_cast<int32_t>(aRange->EndOffset()));
       if (cmp == -1) {
         return 0;
       }
       return 1;
     }
     return -1;
   }
 };
@@ -261,18 +271,18 @@ nsRange::nsRange(nsINode* aNode)
 #endif
 {
   MOZ_ASSERT(aNode, "range isn't in a document!");
   mOwner = aNode->OwnerDoc();
 }
 
 /* static */
 nsresult
-nsRange::CreateRange(nsINode* aStartContainer, int32_t aStartOffset,
-                     nsINode* aEndParent, int32_t aEndOffset,
+nsRange::CreateRange(nsINode* aStartContainer, uint32_t aStartOffset,
+                     nsINode* aEndParent, uint32_t aEndOffset,
                      nsRange** aRange)
 {
   MOZ_ASSERT(aRange);
   *aRange = nullptr;
 
   RefPtr<nsRange> range = new nsRange(aStartContainer);
   nsresult rv = range->SetStartAndEnd(aStartContainer, aStartOffset,
                                       aEndParent, aEndOffset);
@@ -280,30 +290,30 @@ nsRange::CreateRange(nsINode* aStartCont
     return rv;
   }
   range.forget(aRange);
   return NS_OK;
 }
 
 /* static */
 nsresult
-nsRange::CreateRange(nsIDOMNode* aStartContainer, int32_t aStartOffset,
-                     nsIDOMNode* aEndParent, int32_t aEndOffset,
+nsRange::CreateRange(nsIDOMNode* aStartContainer, uint32_t aStartOffset,
+                     nsIDOMNode* aEndParent, uint32_t aEndOffset,
                      nsRange** aRange)
 {
   nsCOMPtr<nsINode> startContainer = do_QueryInterface(aStartContainer);
   nsCOMPtr<nsINode> endContainer = do_QueryInterface(aEndParent);
   return CreateRange(startContainer, aStartOffset,
                      endContainer, aEndOffset, aRange);
 }
 
 /* static */
 nsresult
-nsRange::CreateRange(nsIDOMNode* aStartContainer, int32_t aStartOffset,
-                     nsIDOMNode* aEndParent, int32_t aEndOffset,
+nsRange::CreateRange(nsIDOMNode* aStartContainer, uint32_t aStartOffset,
+                     nsIDOMNode* aEndParent, uint32_t aEndOffset,
                      nsIDOMRange** aRange)
 {
   RefPtr<nsRange> range;
   nsresult rv = nsRange::CreateRange(aStartContainer, aStartOffset, aEndParent,
                                      aEndOffset, getter_AddRefs(range));
   range.forget(aRange);
   return rv;
 }
@@ -451,49 +461,58 @@ nsRange::CharacterDataChanged(nsIDocumen
     // If the splitted text node is immediately before a range boundary point
     // that refers to a child index (i.e. its parent is the boundary container)
     // then we need to increment the corresponding offset to account for the new
     // text node that will be inserted.  If so, we need to prevent the next
     // ContentInserted or ContentAppended for this range from incrementing it
     // again (when the new text node is notified).
     nsINode* parentNode = aContent->GetParentNode();
     int32_t index = -1;
-    if (parentNode == mEndContainer && mEndOffset > 0 &&
-        (index = parentNode->IndexOf(aContent)) + 1 == mEndOffset) {
-      newEndNode = mEndContainer;
-      newEndOffset = mEndOffset + 1;
-      mEndOffsetWasIncremented = true;
+    if (parentNode == mEndContainer && mEndOffset > 0) {
+      index = parentNode->IndexOf(aContent);
+      NS_WARNING_ASSERTION(index >= 0,
+        "Shouldn't be called during removing the node or something");
+      if (static_cast<uint32_t>(index + 1) == mEndOffset) {
+        newEndNode = mEndContainer;
+        newEndOffset = mEndOffset + 1;
+        MOZ_ASSERT(IsValidOffset(newEndOffset));
+        mEndOffsetWasIncremented = true;
+      }
     }
-    if (parentNode == mStartContainer && mStartOffset > 0 &&
-        (index != -1 ? index : parentNode->IndexOf(aContent)) + 1 == mStartOffset) {
-      newStartNode = mStartContainer;
-      newStartOffset = mStartOffset + 1;
-      mStartOffsetWasIncremented = true;
+    if (parentNode == mStartContainer && mStartOffset > 0) {
+      if (index <= 0) {
+        index = parentNode->IndexOf(aContent);
+      }
+      if (static_cast<uint32_t>(index + 1) == mStartOffset) {
+        newStartNode = mStartContainer;
+        newStartOffset = mStartOffset + 1;
+        MOZ_ASSERT(IsValidOffset(newStartOffset));
+        mStartOffsetWasIncremented = true;
+      }
     }
 #ifdef DEBUG
     if (mStartOffsetWasIncremented || mEndOffsetWasIncremented) {
       mAssertNextInsertOrAppendIndex =
         (mStartOffsetWasIncremented ? newStartOffset : newEndOffset) - 1;
       mAssertNextInsertOrAppendNode = aInfo->mDetails->mNextSibling;
     }
 #endif
   }
 
   // If the changed node contains our start boundary and the change starts
   // before the boundary we'll need to adjust the offset.
-  if (aContent == mStartContainer &&
-      aInfo->mChangeStart < static_cast<uint32_t>(mStartOffset)) {
+  if (aContent == mStartContainer && aInfo->mChangeStart < mStartOffset) {
     if (aInfo->mDetails) {
       // splitText(), aInfo->mDetails->mNextSibling is the new text node
       NS_ASSERTION(aInfo->mDetails->mType ==
                    CharacterDataChangeInfo::Details::eSplit,
                    "only a split can start before the end");
-      NS_ASSERTION(static_cast<uint32_t>(mStartOffset) <= aInfo->mChangeEnd + 1,
+      NS_ASSERTION(mStartOffset <= aInfo->mChangeEnd + 1,
                    "mStartOffset is beyond the end of this node");
-      newStartOffset = static_cast<uint32_t>(mStartOffset) - aInfo->mChangeStart;
+      newStartOffset = mStartOffset - aInfo->mChangeStart;
       newStartNode = aInfo->mDetails->mNextSibling;
       if (MOZ_UNLIKELY(aContent == mRoot)) {
         newRoot = IsValidBoundary(newStartNode);
       }
 
       bool isCommonAncestor =
         IsInSelection() && mStartContainer == mEndContainer;
       if (isCommonAncestor) {
@@ -502,92 +521,91 @@ nsRange::CharacterDataChanged(nsIDocumen
       }
       if (mStartContainer->IsDescendantOfCommonAncestorForRangeInSelection()) {
         newStartNode->SetDescendantOfCommonAncestorForRangeInSelection();
       }
     } else {
       // If boundary is inside changed text, position it before change
       // else adjust start offset for the change in length.
       newStartNode = mStartContainer;
-      newStartOffset = static_cast<uint32_t>(mStartOffset) <= aInfo->mChangeEnd ?
+      newStartOffset = mStartOffset <= aInfo->mChangeEnd ?
         aInfo->mChangeStart :
         mStartOffset + aInfo->mChangeStart - aInfo->mChangeEnd +
           aInfo->mReplaceLength;
     }
   }
 
   // Do the same thing for the end boundary, except for splitText of a node
   // with no parent then only switch to the new node if the start boundary
   // did so too (otherwise the range would end up with disconnected nodes).
-  if (aContent == mEndContainer &&
-      aInfo->mChangeStart < static_cast<uint32_t>(mEndOffset)) {
+  if (aContent == mEndContainer && aInfo->mChangeStart < mEndOffset) {
     if (aInfo->mDetails && (aContent->GetParentNode() || newStartNode)) {
       // splitText(), aInfo->mDetails->mNextSibling is the new text node
       NS_ASSERTION(aInfo->mDetails->mType ==
                    CharacterDataChangeInfo::Details::eSplit,
                    "only a split can start before the end");
-      NS_ASSERTION(static_cast<uint32_t>(mEndOffset) <= aInfo->mChangeEnd + 1,
+      NS_ASSERTION(mEndOffset <= aInfo->mChangeEnd + 1,
                    "mEndOffset is beyond the end of this node");
-      newEndOffset = static_cast<uint32_t>(mEndOffset) - aInfo->mChangeStart;
+      newEndOffset = mEndOffset - aInfo->mChangeStart;
       newEndNode = aInfo->mDetails->mNextSibling;
 
       bool isCommonAncestor =
         IsInSelection() && mStartContainer == mEndContainer;
       if (isCommonAncestor && !newStartNode) {
         // The split occurs inside the range.
         UnregisterCommonAncestor(mStartContainer);
         RegisterCommonAncestor(mStartContainer->GetParentNode());
         newEndNode->SetDescendantOfCommonAncestorForRangeInSelection();
       } else if (mEndContainer->
                    IsDescendantOfCommonAncestorForRangeInSelection()) {
         newEndNode->SetDescendantOfCommonAncestorForRangeInSelection();
       }
     } else {
       newEndNode = mEndContainer;
-      newEndOffset = static_cast<uint32_t>(mEndOffset) <= aInfo->mChangeEnd ?
+      newEndOffset = mEndOffset <= aInfo->mChangeEnd ?
         aInfo->mChangeStart :
         mEndOffset + aInfo->mChangeStart - aInfo->mChangeEnd +
           aInfo->mReplaceLength;
     }
   }
 
   if (aInfo->mDetails &&
       aInfo->mDetails->mType == CharacterDataChangeInfo::Details::eMerge) {
     // normalize(), aInfo->mDetails->mNextSibling is the merged text node
     // that will be removed
     nsIContent* removed = aInfo->mDetails->mNextSibling;
     if (removed == mStartContainer) {
-      newStartOffset = static_cast<uint32_t>(mStartOffset) + aInfo->mChangeStart;
+      newStartOffset = mStartOffset + aInfo->mChangeStart;
       newStartNode = aContent;
       if (MOZ_UNLIKELY(removed == mRoot)) {
         newRoot = IsValidBoundary(newStartNode);
       }
     }
     if (removed == mEndContainer) {
-      newEndOffset = static_cast<uint32_t>(mEndOffset) + aInfo->mChangeStart;
+      newEndOffset = mEndOffset + aInfo->mChangeStart;
       newEndNode = aContent;
       if (MOZ_UNLIKELY(removed == mRoot)) {
         newRoot = IsValidBoundary(newEndNode);
       }
     }
     // When the removed text node's parent is one of our boundary nodes we may
     // need to adjust the offset to account for the removed node. However,
     // there will also be a ContentRemoved notification later so the only cases
     // we need to handle here is when the removed node is the text node after
     // the boundary.  (The m*Offset > 0 check is an optimization - a boundary
     // point before the first child is never affected by normalize().)
     nsINode* parentNode = aContent->GetParentNode();
     if (parentNode == mStartContainer && mStartOffset > 0 &&
-        uint32_t(mStartOffset) < parentNode->GetChildCount() &&
+        mStartOffset < parentNode->GetChildCount() &&
         removed == parentNode->GetChildAt(mStartOffset)) {
       newStartNode = aContent;
       newStartOffset = aInfo->mChangeStart;
     }
     if (parentNode == mEndContainer && mEndOffset > 0 &&
-        uint32_t(mEndOffset) < parentNode->GetChildCount() &&
+        mEndOffset < parentNode->GetChildCount() &&
         removed == parentNode->GetChildAt(mEndOffset)) {
       newEndNode = aContent;
       newEndOffset = aInfo->mChangeEnd;
     }
   }
 
   if (newStartNode || newEndNode) {
     if (!newStartNode) {
@@ -645,24 +663,30 @@ nsRange::ContentInserted(nsIDocument* aD
   NS_ASSERTION(mIsPositioned, "shouldn't be notified if not positioned");
 
   bool rangeChanged = false;
   uint32_t newStartOffset = mStartOffset;
   uint32_t newEndOffset = mEndOffset;
   nsINode* container = NODE_FROM(aContainer, aDocument);
 
   // Adjust position if a sibling was inserted.
-  if (container == mStartContainer && aIndexInContainer < mStartOffset &&
+  if (container == mStartContainer &&
+      (NS_WARN_IF(aIndexInContainer < 0) ||
+       static_cast<uint32_t>(aIndexInContainer) < mStartOffset) &&
       !mStartOffsetWasIncremented) {
     ++newStartOffset;
+    MOZ_ASSERT(IsValidOffset(newStartOffset));
     rangeChanged = true;
   }
-  if (container == mEndContainer && aIndexInContainer < mEndOffset &&
+  if (container == mEndContainer &&
+      (NS_WARN_IF(aIndexInContainer < 0) ||
+       static_cast<uint32_t>(aIndexInContainer) < mEndOffset) &&
       !mEndOffsetWasIncremented) {
     ++newEndOffset;
+    MOZ_ASSERT(IsValidOffset(newEndOffset));
     rangeChanged = true;
   }
   if (container->IsSelectionDescendant() &&
       !aChild->IsDescendantOfCommonAncestorForRangeInSelection()) {
     MarkDescendants(aChild);
     aChild->SetDescendantOfCommonAncestorForRangeInSelection();
   }
 
@@ -700,29 +724,29 @@ nsRange::ContentRemoved(nsIDocument* aDo
   bool gravitateEnd = false;
   bool didCheckStartParentDescendant = false;
   bool rangeChanged = false;
   uint32_t newStartOffset = mStartOffset;
   uint32_t newEndOffset = mEndOffset;
 
   // Adjust position if a sibling was removed...
   if (container == mStartContainer) {
-    if (aIndexInContainer < mStartOffset) {
+    if (aIndexInContainer < static_cast<int32_t>(mStartOffset)) {
       --newStartOffset;
       rangeChanged = true;
     }
   } else { // ...or gravitate if an ancestor was removed.
     didCheckStartParentDescendant = true;
     gravitateStart =
       nsContentUtils::ContentIsDescendantOf(mStartContainer, aChild);
   }
 
   // Do same thing for end boundry.
   if (container == mEndContainer) {
-    if (aIndexInContainer < mEndOffset) {
+    if (aIndexInContainer < static_cast<int32_t>(mEndOffset)) {
       --newEndOffset;
       rangeChanged = true;
     }
   } else if (didCheckStartParentDescendant &&
              mStartContainer == mEndContainer) {
     gravitateEnd = gravitateStart;
   } else {
     gravitateEnd = nsContentUtils::ContentIsDescendantOf(mEndContainer, aChild);
@@ -768,22 +792,25 @@ nsRange::ParentChainChanged(nsIContent *
   // of mRoot is the last thing in DoSetRange.
   DoSetRange(mStartContainer, mStartOffset, mEndContainer, mEndOffset, newRoot);
 }
 
 /******************************************************
  * Utilities for comparing points: API from nsIDOMRange
  ******************************************************/
 NS_IMETHODIMP
-nsRange::IsPointInRange(nsIDOMNode* aContainer, int32_t aOffset, bool* aResult)
+nsRange::IsPointInRange(nsIDOMNode* aContainer, uint32_t aOffset, bool* aResult)
 {
   nsCOMPtr<nsINode> container = do_QueryInterface(aContainer);
   if (!container) {
     return NS_ERROR_DOM_NOT_OBJECT_ERR;
   }
+  if (NS_WARN_IF(!IsValidOffset(aOffset))) {
+    return NS_ERROR_DOM_INDEX_SIZE_ERR;
+  }
 
   ErrorResult rv;
   *aResult = IsPointInRange(*container, aOffset, rv);
   return rv.StealNSResult();
 }
 
 bool
 nsRange::IsPointInRange(nsINode& aContainer, uint32_t aOffset, ErrorResult& aRv)
@@ -796,17 +823,18 @@ nsRange::IsPointInRange(nsINode& aContai
   }
 
   return compareResult == 0;
 }
 
 // returns -1 if point is before range, 0 if point is in range,
 // 1 if point is after range.
 NS_IMETHODIMP
-nsRange::ComparePoint(nsIDOMNode* aContainer, int32_t aOffset, int16_t* aResult)
+nsRange::ComparePoint(nsIDOMNode* aContainer, uint32_t aOffset,
+                      int16_t* aResult)
 {
   nsCOMPtr<nsINode> container = do_QueryInterface(aContainer);
   NS_ENSURE_TRUE(container, NS_ERROR_DOM_HIERARCHY_REQUEST_ERR);
 
   ErrorResult rv;
   *aResult = ComparePoint(*container, aOffset, rv);
   return rv.StealNSResult();
 }
@@ -830,25 +858,28 @@ nsRange::ComparePoint(nsINode& aContaine
     return 0;
   }
 
   if (aOffset > aContainer.Length()) {
     aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
     return 0;
   }
 
-  int32_t cmp;
-  if ((cmp = nsContentUtils::ComparePoints(&aContainer, aOffset,
-                                           mStartContainer,
-                                           mStartOffset)) <= 0) {
-
+  int32_t cmp =
+    nsContentUtils::ComparePoints(&aContainer,
+                                  static_cast<int32_t>(aOffset),
+                                  mStartContainer,
+                                  static_cast<int32_t>(mStartOffset));
+  if (cmp <= 0) {
     return cmp;
   }
-  if (nsContentUtils::ComparePoints(mEndContainer, mEndOffset,
-                                    &aContainer, aOffset) == -1) {
+  if (nsContentUtils::ComparePoints(mEndContainer,
+                                    static_cast<int32_t>(mEndOffset),
+                                    &aContainer,
+                                    static_cast<int32_t>(aOffset)) == -1) {
     return 1;
   }
 
   return 0;
 }
 
 NS_IMETHODIMP
 nsRange::IntersectsNode(nsIDOMNode* aNode, bool* aResult)
@@ -881,22 +912,25 @@ nsRange::IntersectsNode(nsINode& aNode, 
   }
 
   // Step 5.
   int32_t nodeIndex = parent->IndexOf(&aNode);
 
   // Steps 6-7.
   // Note: if disconnected is true, ComparePoints returns 1.
   bool disconnected = false;
-  bool result = nsContentUtils::ComparePoints(mStartContainer, mStartOffset,
-                                             parent, nodeIndex + 1,
-                                             &disconnected) < 0 &&
-               nsContentUtils::ComparePoints(parent, nodeIndex,
-                                             mEndContainer, mEndOffset,
-                                             &disconnected) < 0;
+  bool result =
+    nsContentUtils::ComparePoints(mStartContainer,
+                                  static_cast<int32_t>(mStartOffset),
+                                  parent, nodeIndex + 1,
+                                  &disconnected) < 0 &&
+    nsContentUtils::ComparePoints(parent, nodeIndex,
+                                  mEndContainer,
+                                  static_cast<int32_t>(mEndOffset),
+                                  &disconnected) < 0;
 
   // Step 2.
   if (disconnected) {
     result = false;
   }
   return result;
 }
 
@@ -905,18 +939,18 @@ nsRange::IntersectsNode(nsINode& aNode, 
  ******************************************************/
 
 // It's important that all setting of the range start/end points
 // go through this function, which will do all the right voodoo
 // for content notification of range ownership.
 // Calling DoSetRange with either parent argument null will collapse
 // the range to have both endpoints point to the other node
 void
-nsRange::DoSetRange(nsINode* aStartN, int32_t aStartOffset,
-                    nsINode* aEndN, int32_t aEndOffset,
+nsRange::DoSetRange(nsINode* aStartN, uint32_t aStartOffset,
+                    nsINode* aEndN, uint32_t aEndOffset,
                     nsINode* aRoot, bool aNotInsertedYet)
 {
   NS_PRECONDITION((aStartN && aEndN && aRoot) ||
                   (!aStartN && !aEndN && !aRoot),
                   "Set all or none");
   NS_PRECONDITION(!aRoot || aNotInsertedYet ||
                   (nsContentUtils::ContentIsDescendantOf(aStartN, aRoot) &&
                    nsContentUtils::ContentIsDescendantOf(aEndN, aRoot) &&
@@ -932,16 +966,18 @@ nsRange::DoSetRange(nsINode* aStartN, in
                     static_cast<nsIContent*>(aEndN)->GetBindingParent()) ||
                   (!aRoot->GetParentNode() &&
                    (aRoot->IsNodeOfType(nsINode::eDOCUMENT) ||
                     aRoot->IsNodeOfType(nsINode::eATTRIBUTE) ||
                     aRoot->IsNodeOfType(nsINode::eDOCUMENT_FRAGMENT) ||
                      /*For backward compatibility*/
                     aRoot->IsNodeOfType(nsINode::eCONTENT))),
                   "Bad root");
+  MOZ_ASSERT(IsValidOffset(aStartOffset));
+  MOZ_ASSERT(IsValidOffset(aEndOffset));
 
   if (mRoot != aRoot) {
     if (mRoot) {
       mRoot->RemoveMutationObserver(this);
     }
     if (aRoot) {
       aRoot->AddMutationObserver(this);
     }
@@ -1054,17 +1090,17 @@ nsRange::GetStartContainer(ErrorResult& 
     aRv.Throw(NS_ERROR_NOT_INITIALIZED);
     return nullptr;
   }
 
   return mStartContainer;
 }
 
 NS_IMETHODIMP
-nsRange::GetStartOffset(int32_t* aStartOffset)
+nsRange::GetStartOffset(uint32_t* aStartOffset)
 {
   if (!mIsPositioned)
     return NS_ERROR_NOT_INITIALIZED;
 
   *aStartOffset = mStartOffset;
 
   return NS_OK;
 }
@@ -1096,17 +1132,17 @@ nsRange::GetEndContainer(ErrorResult& aR
     aRv.Throw(NS_ERROR_NOT_INITIALIZED);
     return nullptr;
   }
 
   return mEndContainer;
 }
 
 NS_IMETHODIMP
-nsRange::GetEndOffset(int32_t* aEndOffset)
+nsRange::GetEndOffset(uint32_t* aEndOffset)
 {
   if (!mIsPositioned)
     return NS_ERROR_NOT_INITIALIZED;
 
   *aEndOffset = mEndOffset;
 
   return NS_OK;
 }
@@ -1155,20 +1191,20 @@ nsRange::GetCommonAncestorContainer(nsID
     *aCommonParent = nullptr;
   }
 
   return rv.StealNSResult();
 }
 
 /* static */
 bool
-nsRange::IsValidOffset(nsINode* aNode, int32_t aOffset)
+nsRange::IsValidOffset(nsINode* aNode, uint32_t aOffset)
 {
   return aNode &&
-         aOffset >= 0 &&
+         IsValidOffset(aOffset) &&
          static_cast<size_t>(aOffset) <= aNode->Length();
 }
 
 nsINode*
 nsRange::IsValidBoundary(nsINode* aNode)
 {
   if (!aNode) {
     return nullptr;
@@ -1230,45 +1266,47 @@ nsRange::SetStart(nsINode& aNode, uint32
     return;
   }
 
   AutoInvalidateSelection atEndOfBlock(this);
   aRv = SetStart(&aNode, aOffset);
 }
 
 NS_IMETHODIMP
-nsRange::SetStart(nsIDOMNode* aContainer, int32_t aOffset)
+nsRange::SetStart(nsIDOMNode* aContainer, uint32_t aOffset)
 {
   nsCOMPtr<nsINode> container = do_QueryInterface(aContainer);
   if (!container) {
     return NS_ERROR_DOM_NOT_OBJECT_ERR;
   }
 
   ErrorResult rv;
   SetStart(*container, aOffset, rv);
   return rv.StealNSResult();
 }
 
 /* virtual */ nsresult
-nsRange::SetStart(nsINode* aContainer, int32_t aOffset)
+nsRange::SetStart(nsINode* aContainer, uint32_t aOffset)
 {
   nsINode* newRoot = IsValidBoundary(aContainer);
   if (!newRoot) {
     return NS_ERROR_DOM_INVALID_NODE_TYPE_ERR;
   }
 
   if (!IsValidOffset(aContainer, aOffset)) {
     return NS_ERROR_DOM_INDEX_SIZE_ERR;
   }
 
   // Collapse if not positioned yet, if positioned in another doc or
   // if the new start is after end.
   if (!mIsPositioned || newRoot != mRoot ||
-      nsContentUtils::ComparePoints(aContainer, aOffset,
-                                    mEndContainer, mEndOffset) == 1) {
+      nsContentUtils::ComparePoints(aContainer,
+                                    static_cast<int32_t>(aOffset),
+                                    mEndContainer,
+                                    static_cast<int32_t>(mEndOffset)) == 1) {
     DoSetRange(aContainer, aOffset, aContainer, aOffset, newRoot);
 
     return NS_OK;
   }
 
   DoSetRange(aContainer, aOffset, mEndContainer, mEndOffset, mRoot);
 
   return NS_OK;
@@ -1287,17 +1325,20 @@ nsRange::SetStartBefore(nsINode& aNode, 
 {
   if (!nsContentUtils::LegacyIsCallerNativeCode() &&
       !nsContentUtils::CanCallerAccess(&aNode)) {
     aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
     return;
   }
 
   AutoInvalidateSelection atEndOfBlock(this);
-  int32_t offset = -1;
+  // If the node is being removed from its parent, GetContainerAndOffsetBefore()
+  // returns nullptr.  Then, SetStart() will throw
+  // NS_ERROR_DOM_INVALID_NODE_TYPE_ERR.
+  uint32_t offset = UINT32_MAX;
   nsINode* container = GetContainerAndOffsetBefore(&aNode, &offset);
   aRv = SetStart(container, offset);
 }
 
 NS_IMETHODIMP
 nsRange::SetStartBefore(nsIDOMNode* aSibling)
 {
   nsCOMPtr<nsINode> sibling = do_QueryInterface(aSibling);
@@ -1323,17 +1364,20 @@ nsRange::SetStartAfter(nsINode& aNode, E
 {
   if (!nsContentUtils::LegacyIsCallerNativeCode() &&
       !nsContentUtils::CanCallerAccess(&aNode)) {
     aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
     return;
   }
 
   AutoInvalidateSelection atEndOfBlock(this);
-  int32_t offset = -1;
+  // If the node is being removed from its parent, GetContainerAndOffsetAfter()
+  // returns nullptr.  Then, SetStart() will throw
+  // NS_ERROR_DOM_INVALID_NODE_TYPE_ERR.
+  uint32_t offset = UINT32_MAX;
   nsINode* container = GetContainerAndOffsetAfter(&aNode, &offset);
   aRv = SetStart(container, offset);
 }
 
 NS_IMETHODIMP
 nsRange::SetStartAfter(nsIDOMNode* aSibling)
 {
   nsCOMPtr<nsINode> sibling = do_QueryInterface(aSibling);
@@ -1362,58 +1406,60 @@ nsRange::SetEnd(nsINode& aNode, uint32_t
     aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
     return;
   }
   AutoInvalidateSelection atEndOfBlock(this);
   aRv = SetEnd(&aNode, aOffset);
 }
 
 NS_IMETHODIMP
-nsRange::SetEnd(nsIDOMNode* aContainer, int32_t aOffset)
+nsRange::SetEnd(nsIDOMNode* aContainer, uint32_t aOffset)
 {
   nsCOMPtr<nsINode> container = do_QueryInterface(aContainer);
   if (!container) {
     return NS_ERROR_DOM_NOT_OBJECT_ERR;
   }
 
   ErrorResult rv;
   SetEnd(*container, aOffset, rv);
   return rv.StealNSResult();
 }
 
 /* virtual */ nsresult
-nsRange::SetEnd(nsINode* aContainer, int32_t aOffset)
+nsRange::SetEnd(nsINode* aContainer, uint32_t aOffset)
 {
   nsINode* newRoot = IsValidBoundary(aContainer);
   if (!newRoot) {
     return NS_ERROR_DOM_INVALID_NODE_TYPE_ERR;
   }
 
   if (!IsValidOffset(aContainer, aOffset)) {
     return NS_ERROR_DOM_INDEX_SIZE_ERR;
   }
 
   // Collapse if not positioned yet, if positioned in another doc or
   // if the new end is before start.
   if (!mIsPositioned || newRoot != mRoot ||
-      nsContentUtils::ComparePoints(mStartContainer, mStartOffset,
-                                    aContainer, aOffset) == 1) {
+      nsContentUtils::ComparePoints(mStartContainer,
+                                    static_cast<int32_t>(mStartOffset),
+                                    aContainer,
+                                    static_cast<int32_t>(aOffset)) == 1) {
     DoSetRange(aContainer, aOffset, aContainer, aOffset, newRoot);
 
     return NS_OK;
   }
 
   DoSetRange(mStartContainer, mStartOffset, aContainer, aOffset, mRoot);
 
   return NS_OK;
 }
 
 nsresult
-nsRange::SetStartAndEnd(nsINode* aStartContainer, int32_t aStartOffset,
-                        nsINode* aEndContainer, int32_t aEndOffset)
+nsRange::SetStartAndEnd(nsINode* aStartContainer, uint32_t aStartOffset,
+                        nsINode* aEndContainer, uint32_t aEndOffset)
 {
   if (NS_WARN_IF(!aStartContainer) || NS_WARN_IF(!aEndContainer)) {
     return NS_ERROR_INVALID_ARG;
   }
 
   nsINode* newStartRoot = IsValidBoundary(aStartContainer);
   if (!newStartRoot) {
     return NS_ERROR_DOM_INVALID_NODE_TYPE_ERR;
@@ -1450,18 +1496,20 @@ nsRange::SetStartAndEnd(nsINode* aStartC
   if (newStartRoot != newEndRoot) {
     DoSetRange(aEndContainer, aEndOffset,
                aEndContainer, aEndOffset, newEndRoot);
     return NS_OK;
   }
 
   // If the end point is before the start point, this should be collapsed at
   // the end point.
-  if (nsContentUtils::ComparePoints(aStartContainer, aStartOffset,
-                                    aEndContainer, aEndOffset) == 1) {
+  if (nsContentUtils::ComparePoints(aStartContainer,
+                                    static_cast<int32_t>(aStartOffset),
+                                    aEndContainer,
+                                    static_cast<int32_t>(aEndOffset)) == 1) {
     DoSetRange(aEndContainer, aEndOffset,
                aEndContainer, aEndOffset, newEndRoot);
     return NS_OK;
   }
 
   // Otherwise, set the range as specified.
   DoSetRange(aStartContainer, aStartOffset,
              aEndContainer, aEndOffset, newStartRoot);
@@ -1481,17 +1529,20 @@ nsRange::SetEndBefore(nsINode& aNode, Er
 {
   if (!nsContentUtils::LegacyIsCallerNativeCode() &&
       !nsContentUtils::CanCallerAccess(&aNode)) {
     aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
     return;
   }
 
   AutoInvalidateSelection atEndOfBlock(this);
-  int32_t offset = -1;
+  // If the node is being removed from its parent, GetContainerAndOffsetBefore()
+  // returns nullptr.  Then, SetEnd() will throw
+  // NS_ERROR_DOM_INVALID_NODE_TYPE_ERR.
+  uint32_t offset = UINT32_MAX;
   nsINode* container = GetContainerAndOffsetBefore(&aNode, &offset);
   aRv = SetEnd(container, offset);
 }
 
 NS_IMETHODIMP
 nsRange::SetEndBefore(nsIDOMNode* aSibling)
 {
   nsCOMPtr<nsINode> sibling = do_QueryInterface(aSibling);
@@ -1517,17 +1568,20 @@ nsRange::SetEndAfter(nsINode& aNode, Err
 {
   if (!nsContentUtils::LegacyIsCallerNativeCode() &&
       !nsContentUtils::CanCallerAccess(&aNode)) {
     aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
     return;
   }
 
   AutoInvalidateSelection atEndOfBlock(this);
-  int32_t offset = -1;
+  // If the node is being removed from its parent, GetContainerAndOffsetAfter()
+  // returns nullptr.  Then, SetEnd() will throw
+  // NS_ERROR_DOM_INVALID_NODE_TYPE_ERR.
+  uint32_t offset = UINT32_MAX;
   nsINode* container = GetContainerAndOffsetAfter(&aNode, &offset);
   aRv = SetEnd(container, offset);
 }
 
 NS_IMETHODIMP
 nsRange::SetEndAfter(nsIDOMNode* aSibling)
 {
   nsCOMPtr<nsINode> sibling = do_QueryInterface(aSibling);
@@ -1597,17 +1651,19 @@ nsRange::SelectNode(nsINode& aNode, Erro
   nsINode* container = aNode.GetParentNode();
   nsINode* newRoot = IsValidBoundary(container);
   if (!newRoot) {
     aRv.Throw(NS_ERROR_DOM_INVALID_NODE_TYPE_ERR);
     return;
   }
 
   int32_t index = container->IndexOf(&aNode);
-  if (index < 0) {
+  if (NS_WARN_IF(index < 0) ||
+      !IsValidOffset(static_cast<uint32_t>(index)) ||
+      !IsValidOffset(static_cast<uint32_t>(index) + 1)) {
     aRv.Throw(NS_ERROR_DOM_INVALID_NODE_TYPE_ERR);
     return;
   }
 
   AutoInvalidateSelection atEndOfBlock(this);
   DoSetRange(container, index, container, index + 1, newRoot);
 }
 
@@ -2054,33 +2110,35 @@ nsRange::CutContents(DocumentFragment** 
 
   // Batch possible DOMSubtreeModified events.
   mozAutoSubtreeModified subtree(mRoot ? mRoot->OwnerDoc(): nullptr, nullptr);
 
   // Save the range end points locally to avoid interference
   // of Range gravity during our edits!
 
   nsCOMPtr<nsINode> startContainer = mStartContainer;
-  int32_t              startOffset = mStartOffset;
+  uint32_t startOffset = mStartOffset;
   nsCOMPtr<nsINode> endContainer = mEndContainer;
-  int32_t              endOffset = mEndOffset;
+  uint32_t endOffset = mEndOffset;
 
   if (retval) {
     // For extractContents(), abort early if there's a doctype (bug 719533).
     // This can happen only if the common ancestor is a document, in which case
     // we just need to find its doctype child and check if that's in the range.
     nsCOMPtr<nsIDocument> commonAncestorDocument = do_QueryInterface(commonAncestor);
     if (commonAncestorDocument) {
       RefPtr<DocumentType> doctype = commonAncestorDocument->GetDoctype();
 
       if (doctype &&
-          nsContentUtils::ComparePoints(startContainer, startOffset,
+          nsContentUtils::ComparePoints(startContainer,
+                                        static_cast<int32_t>(startOffset),
                                         doctype, 0) < 0 &&
           nsContentUtils::ComparePoints(doctype, 0,
-                                        endContainer, endOffset) < 0) {
+                                        endContainer,
+                                        static_cast<int32_t>(endOffset)) < 0) {
         return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
       }
     }
   }
 
   // Create and initialize a subtree iterator that will give
   // us all the subtrees within the range.
 
@@ -2165,60 +2223,53 @@ nsRange::CutContents(DocumentFragment** 
         }
         else
         {
           // Delete or extract everything after startOffset.
 
           rv = charData->GetLength(&dataLength);
           NS_ENSURE_SUCCESS(rv, rv);
 
-          if (dataLength >= (uint32_t)startOffset)
-          {
+          if (dataLength >= startOffset) {
             nsMutationGuard guard;
             nsCOMPtr<nsIDOMCharacterData> cutNode;
             rv = SplitDataNode(charData, startOffset, getter_AddRefs(cutNode));
             NS_ENSURE_SUCCESS(rv, rv);
             NS_ENSURE_STATE(!guard.Mutated(1) ||
                             ValidateCurrentNode(this, iter));
             nodeToResult = do_QueryInterface(cutNode);
           }
 
           handled = true;
         }
       }
       else if (node == endContainer)
       {
         // Delete or extract everything before endOffset.
-
-        if (endOffset >= 0)
-        {
-          nsMutationGuard guard;
-          nsCOMPtr<nsIDOMCharacterData> cutNode;
-          /* The Range spec clearly states clones get cut and original nodes
-             remain behind, so use false as the last parameter.
-          */
-          rv = SplitDataNode(charData, endOffset, getter_AddRefs(cutNode),
-                             false);
-          NS_ENSURE_SUCCESS(rv, rv);
-          NS_ENSURE_STATE(!guard.Mutated(1) ||
-                          ValidateCurrentNode(this, iter));
-          nodeToResult = do_QueryInterface(cutNode);
-        }
-
+        nsMutationGuard guard;
+        nsCOMPtr<nsIDOMCharacterData> cutNode;
+        /* The Range spec clearly states clones get cut and original nodes
+           remain behind, so use false as the last parameter.
+        */
+        rv = SplitDataNode(charData, endOffset, getter_AddRefs(cutNode),
+                           false);
+        NS_ENSURE_SUCCESS(rv, rv);
+        NS_ENSURE_STATE(!guard.Mutated(1) ||
+                        ValidateCurrentNode(this, iter));
+        nodeToResult = do_QueryInterface(cutNode);
         handled = true;
       }
     }
 
     if (!handled && (node == endContainer || node == startContainer))
     {
       if (node && node->IsElement() &&
           ((node == endContainer && endOffset == 0) ||
            (node == startContainer &&
-            int32_t(node->AsElement()->GetChildCount()) == startOffset)))
-      {
+            node->AsElement()->GetChildCount() == startOffset))) {
         if (retval) {
           ErrorResult rv;
           nodeToResult = node->CloneNode(false, rv);
           NS_ENSURE_TRUE(!rv.Failed(), rv.StealNSResult());
         }
         handled = true;
       }
     }
@@ -2353,17 +2404,17 @@ nsRange::CompareBoundaryPoints(uint16_t 
                                ErrorResult& rv)
 {
   if (!mIsPositioned || !aOtherRange.IsPositioned()) {
     rv.Throw(NS_ERROR_NOT_INITIALIZED);
     return 0;
   }
 
   nsINode *ourNode, *otherNode;
-  int32_t ourOffset, otherOffset;
+  uint32_t ourOffset, otherOffset;
 
   switch (aHow) {
     case nsIDOMRange::START_TO_START:
       ourNode = mStartContainer;
       ourOffset = mStartOffset;
       otherNode = aOtherRange.GetStartContainer();
       otherOffset = aOtherRange.StartOffset();
       break;
@@ -2391,18 +2442,20 @@ nsRange::CompareBoundaryPoints(uint16_t 
       return 0;
   }
 
   if (mRoot != aOtherRange.GetRoot()) {
     rv.Throw(NS_ERROR_DOM_WRONG_DOCUMENT_ERR);
     return 0;
   }
 
-  return nsContentUtils::ComparePoints(ourNode, ourOffset,
-                                       otherNode, otherOffset);
+  return nsContentUtils::ComparePoints(ourNode,
+                                       static_cast<int32_t>(ourOffset),
+                                       otherNode,
+                                       static_cast<int32_t>(otherOffset));
 }
 
 /* static */ nsresult
 nsRange::CloneParentsBetween(nsINode *aAncestor,
                              nsINode *aNode,
                              nsINode **aClosestAncestor,
                              nsINode **aFarthestAncestor)
 {
@@ -2509,18 +2562,17 @@ nsRange::CloneContents(ErrorResult& aRv)
   // correctly places this new subtree into the doc fragment.
 
   while (!iter.IsDone())
   {
     nsCOMPtr<nsINode> node = iter.GetCurrentNode();
     bool deepClone = !node->IsElement() ||
                        (!(node == mEndContainer && mEndOffset == 0) &&
                         !(node == mStartContainer &&
-                          mStartOffset ==
-                            int32_t(node->AsElement()->GetChildCount())));
+                          mStartOffset == node->AsElement()->GetChildCount()));
 
     // Clone the current subtree!
 
     nsCOMPtr<nsINode> clone = node->CloneNode(deepClone, aRv);
     if (aRv.Failed()) {
       return nullptr;
     }
 
@@ -2539,18 +2591,17 @@ nsRange::CloneContents(ErrorResult& aRv)
         // data after it.
 
         uint32_t dataLength = 0;
         aRv = charData->GetLength(&dataLength);
         if (aRv.Failed()) {
           return nullptr;
         }
 
-        if (dataLength > (uint32_t)mEndOffset)
-        {
+        if (dataLength > mEndOffset) {
           aRv = charData->DeleteData(mEndOffset, dataLength - mEndOffset);
           if (aRv.Failed()) {
             return nullptr;
           }
         }
       }
 
       if (node == mStartContainer) {
@@ -2697,17 +2748,17 @@ void
 nsRange::InsertNode(nsINode& aNode, ErrorResult& aRv)
 {
   if (!nsContentUtils::LegacyIsCallerNativeCode() &&
       !nsContentUtils::CanCallerAccess(&aNode)) {
     aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
     return;
   }
 
-  int32_t tStartOffset = StartOffset();
+  uint32_t tStartOffset = StartOffset();
 
   nsCOMPtr<nsINode> tStartContainer = GetStartContainer(aRv);
   if (aRv.Failed()) {
     return;
   }
 
   if (&aNode == tStartContainer) {
     aRv.Throw(NS_ERROR_DOM_HIERARCHY_REQUEST_ERR);
@@ -2758,28 +2809,30 @@ nsRange::InsertNode(nsINode& aNode, Erro
     if (aRv.Failed()) {
       return;
     }
   }
 
   // We might need to update the end to include the new node (bug 433662).
   // Ideally we'd only do this if needed, but it's tricky to know when it's
   // needed in advance (bug 765799).
-  int32_t newOffset;
+  uint32_t newOffset;
 
   if (referenceNode) {
-    newOffset = IndexOf(referenceNode);
+    int32_t indexInParent = IndexOf(referenceNode);
+    if (NS_WARN_IF(indexInParent < 0)) {
+      aRv.Throw(NS_ERROR_FAILURE);
+      return;
+    }
+    newOffset = static_cast<uint32_t>(indexInParent);
   } else {
-    uint32_t length;
-    aRv = tChildList->GetLength(&length);
+    aRv = tChildList->GetLength(&newOffset);
     if (aRv.Failed()) {
       return;
     }
-
-    newOffset = length;
   }
 
   if (aNode.NodeType() == nsIDOMNode::DOCUMENT_FRAGMENT_NODE) {
     newOffset += aNode.GetChildCount();
   } else {
     newOffset++;
   }
 
@@ -3115,21 +3168,26 @@ static nsresult GetPartialTextRect(nsLay
   return NS_OK;
 }
 
 /* static */ void
 nsRange::CollectClientRectsAndText(nsLayoutUtils::RectCallback* aCollector,
                                    Sequence<nsString>* aTextList,
                                    nsRange* aRange,
                                    nsINode* aStartContainer,
-                                   int32_t aStartOffset,
+                                   uint32_t aStartOffset,
                                    nsINode* aEndContainer,
-                                   int32_t aEndOffset,
+                                   uint32_t aEndOffset,
                                    bool aClampToEdge, bool aFlushLayout)
 {
+  // Currently, this method is called with start of end offset of nsRange.
+  // So, they must be between 0 - INT32_MAX.
+  MOZ_ASSERT(IsValidOffset(aStartOffset));
+  MOZ_ASSERT(IsValidOffset(aEndOffset));
+
   // Hold strong pointers across the flush
   nsCOMPtr<nsINode> startContainer = aStartContainer;
   nsCOMPtr<nsINode> endContainer = aEndContainer;
 
   // Flush out layout so our frames are up to date.
   if (!aStartContainer->IsInUncomposedDoc()) {
     return;
   }
@@ -3150,23 +3208,25 @@ nsRange::CollectClientRectsAndText(nsLay
   if (iter.IsDone()) {
     // the range is collapsed, only continue if the cursor is in a text node
     nsCOMPtr<nsIContent> content = do_QueryInterface(aStartContainer);
     if (content && content->IsNodeOfType(nsINode::eTEXT)) {
       nsTextFrame* textFrame = GetTextFrameForContent(content, aFlushLayout);
       if (textFrame) {
         int32_t outOffset;
         nsIFrame* outFrame;
-        textFrame->GetChildFrameContainingOffset(aStartOffset, false,
-          &outOffset, &outFrame);
+        textFrame->GetChildFrameContainingOffset(
+                     static_cast<int32_t>(aStartOffset), false,
+                     &outOffset, &outFrame);
         if (outFrame) {
            nsIFrame* relativeTo =
              nsLayoutUtils::GetContainingBlockForClientRect(outFrame);
            nsRect r = outFrame->GetRectRelativeToSelf();
-           ExtractRectFromOffset(outFrame, aStartOffset, &r, false, aClampToEdge);
+           ExtractRectFromOffset(outFrame, static_cast<int32_t>(aStartOffset),
+                                 &r, false, aClampToEdge);
            r.width = 0;
            r = nsLayoutUtils::TransformFrameRectToAncestor(outFrame, r, relativeTo);
            aCollector->AddRect(r);
         }
       }
     }
     return;
   }
@@ -3175,22 +3235,24 @@ nsRange::CollectClientRectsAndText(nsLay
     nsCOMPtr<nsINode> node = iter.GetCurrentNode();
     iter.Next();
     nsCOMPtr<nsIContent> content = do_QueryInterface(node);
     if (!content)
       continue;
     if (content->IsNodeOfType(nsINode::eTEXT)) {
        if (node == startContainer) {
          int32_t offset = startContainer == endContainer ?
-           aEndOffset : content->GetText()->GetLength();
-         GetPartialTextRect(aCollector, aTextList, content, aStartOffset, offset,
+           static_cast<int32_t>(aEndOffset) : content->GetText()->GetLength();
+         GetPartialTextRect(aCollector, aTextList, content,
+                            static_cast<int32_t>(aStartOffset), offset,
                             aClampToEdge, aFlushLayout);
          continue;
        } else if (node == endContainer) {
-         GetPartialTextRect(aCollector, aTextList, content, 0, aEndOffset,
+         GetPartialTextRect(aCollector, aTextList, content,
+                            0, static_cast<int32_t>(aEndOffset),
                             aClampToEdge, aFlushLayout);
          continue;
        }
     }
 
     nsIFrame* frame = content->GetPrimaryFrame();
     if (frame) {
       nsLayoutUtils::GetAllInFlowRectsAndTexts(frame,
@@ -3555,17 +3617,17 @@ ElementIsVisibleNoFlush(Element* aElemen
   RefPtr<nsStyleContext> sc =
     nsComputedDOMStyle::GetStyleContextNoFlush(aElement, nullptr, nullptr);
   return sc && sc->StyleVisibility()->IsVisible();
 }
 
 static void
 AppendTransformedText(InnerTextAccumulator& aResult,
                       nsGenericDOMDataNode* aTextNode,
-                      int32_t aStart, int32_t aEnd)
+                      uint32_t aStart, uint32_t aEnd)
 {
   nsIFrame* frame = aTextNode->GetPrimaryFrame();
   if (!IsVisibleAndNotInReplacedElement(frame)) {
     return;
   }
   nsIFrame::RenderedText text = frame->GetRenderedText(aStart, aEnd);
   aResult.Append(text.mString);
 }
@@ -3664,17 +3726,17 @@ nsRange::GetInnerTextNoFlush(DOMString& 
     }
   }
 
   nsIContent* endNode = aEndContainer;
   TreeTraversalState endState = AFTER_NODE;
   if (aEndContainer->IsNodeOfType(nsINode::eTEXT)) {
     endState = AT_NODE;
   } else {
-    if (uint32_t(aEndOffset) < aEndContainer->GetChildCount()) {
+    if (aEndOffset < aEndContainer->GetChildCount()) {
       endNode = aEndContainer->GetChildAt(aEndOffset);
       endState = AT_NODE;
     }
   }
 
   while (currentNode != endNode || currentState != endState) {
     nsIFrame* f = currentNode->GetPrimaryFrame();
     bool isVisibleAndNotReplaced = IsVisibleAndNotInReplacedElement(f);
--- a/dom/base/nsRange.h
+++ b/dom/base/nsRange.h
@@ -42,24 +42,30 @@ class nsRange final : public nsIDOMRange
   typedef mozilla::dom::DOMRect DOMRect;
   typedef mozilla::dom::DOMRectList DOMRectList;
 
   virtual ~nsRange();
 
 public:
   explicit nsRange(nsINode* aNode);
 
-  static nsresult CreateRange(nsIDOMNode* aStartContainer, int32_t aStartOffset,
-                              nsIDOMNode* aEndContainer, int32_t aEndOffset,
+  static nsresult CreateRange(nsIDOMNode* aStartContainer,
+                              uint32_t aStartOffset,
+                              nsIDOMNode* aEndContainer,
+                              uint32_t aEndOffset,
                               nsRange** aRange);
-  static nsresult CreateRange(nsIDOMNode* aStartContainer, int32_t aStartOffset,
-                              nsIDOMNode* aEndContainer, int32_t aEndOffset,
+  static nsresult CreateRange(nsIDOMNode* aStartContainer,
+                              uint32_t aStartOffset,
+                              nsIDOMNode* aEndContainer,
+                              uint32_t aEndOffset,
                               nsIDOMRange** aRange);
-  static nsresult CreateRange(nsINode* aStartContainer, int32_t aStartOffset,
-                              nsINode* aEndContainer, int32_t aEndOffset,
+  static nsresult CreateRange(nsINode* aStartContainer,
+                              uint32_t aStartOffset,
+                              nsINode* aEndContainer,
+                              uint32_t aEndOffset,
                               nsRange** aRange);
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsRange, nsIDOMRange)
 
   nsrefcnt GetRefCount() const
   {
     return mRefCnt;
@@ -78,22 +84,22 @@ public:
     return mStartContainer;
   }
 
   nsINode* GetEndContainer() const
   {
     return mEndContainer;
   }
 
-  int32_t StartOffset() const
+  uint32_t StartOffset() const
   {
     return mStartOffset;
   }
 
-  int32_t EndOffset() const
+  uint32_t EndOffset() const
   {
     return mEndOffset;
   }
 
   bool IsPositioned() const
   {
     return mIsPositioned;
   }
@@ -142,63 +148,76 @@ public:
   void Reset();
 
   /**
    * SetStart() and SetEnd() sets start point or end point separately.
    * However, this is expensive especially when it's a range of Selection.
    * When you set both start and end of a range, you should use
    * SetStartAndEnd() instead.
    */
-  nsresult SetStart(nsINode* aContainer, int32_t aOffset);
-  nsresult SetEnd(nsINode* aContainer, int32_t aOffset);
+  nsresult SetStart(nsINode* aContainer, uint32_t aOffset);
+  nsresult SetEnd(nsINode* aContainer, uint32_t aOffset);
 
   already_AddRefed<nsRange> CloneRange() const;
 
   /**
    * SetStartAndEnd() works similar to call both SetStart() and SetEnd().
    * Different from calls them separately, this does nothing if either
    * the start point or the end point is invalid point.
    * If the specified start point is after the end point, the range will be
    * collapsed at the end point.  Similarly, if they are in different root,
    * the range will be collapsed at the end point.
    */
-  nsresult SetStartAndEnd(nsINode* aStartContainer, int32_t aStartOffset,
-                          nsINode* aEndContainer, int32_t aEndOffset);
+  nsresult SetStartAndEnd(nsINode* aStartContainer, uint32_t aStartOffset,
+                          nsINode* aEndContainer, uint32_t aEndOffset);
 
   /**
    * CollapseTo() works similar to call both SetStart() and SetEnd() with
    * same node and offset.  This just calls SetStartAndParent() to set
    * collapsed range at aContainer and aOffset.
    */
-  nsresult CollapseTo(nsINode* aContainer, int32_t aOffset)
+  nsresult CollapseTo(nsINode* aContainer, uint32_t aOffset)
   {
     return SetStartAndEnd(aContainer, aOffset, aContainer, aOffset);
   }
 
   /**
    * Retrieves node and offset for setting start or end of a range to
    * before or after aNode.
    */
-  static nsINode* GetContainerAndOffsetAfter(nsINode* aNode, int32_t* aOffset)
+  static nsINode* GetContainerAndOffsetAfter(nsINode* aNode, uint32_t* aOffset)
   {
     MOZ_ASSERT(aNode);
     MOZ_ASSERT(aOffset);
+    *aOffset = 0;
     nsINode* parentNode = aNode->GetParentNode();
-    *aOffset = parentNode ? parentNode->IndexOf(aNode) : -1;
-    if (*aOffset >= 0) {
-      (*aOffset)++;
+    if (!parentNode) {
+      return nullptr;
     }
+    int32_t indexInParent = parentNode->IndexOf(aNode);
+    if (NS_WARN_IF(indexInParent < 0)) {
+      return nullptr;
+    }
+    *aOffset = static_cast<uint32_t>(indexInParent) + 1;
     return parentNode;
   }
-  static nsINode* GetContainerAndOffsetBefore(nsINode* aNode, int32_t* aOffset)
+  static nsINode* GetContainerAndOffsetBefore(nsINode* aNode, uint32_t* aOffset)
   {
     MOZ_ASSERT(aNode);
     MOZ_ASSERT(aOffset);
+    *aOffset = 0;
     nsINode* parentNode = aNode->GetParentNode();
-    *aOffset = parentNode ? parentNode->IndexOf(aNode) : -1;
+    if (!parentNode) {
+      return nullptr;
+    }
+    int32_t indexInParent = parentNode->IndexOf(aNode);
+    if (NS_WARN_IF(indexInParent < 0)) {
+      return nullptr;
+    }
+    *aOffset = static_cast<uint32_t>(indexInParent);
     return parentNode;
   }
 
   NS_IMETHOD GetUsedFontFaces(nsIDOMFontFaceList** aResult);
 
   // nsIMutationObserver methods
   NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATACHANGED
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
@@ -322,19 +341,19 @@ public:
   /**
    * This helper function gets rects and correlated text for the given range.
    * @param aTextList optional where nullptr = don't retrieve text
    */
   static void CollectClientRectsAndText(nsLayoutUtils::RectCallback* aCollector,
                                         mozilla::dom::Sequence<nsString>* aTextList,
                                         nsRange* aRange,
                                         nsINode* aStartContainer,
-                                        int32_t aStartOffset,
+                                        uint32_t aStartOffset,
                                         nsINode* aEndContainer,
-                                        int32_t aEndOffset,
+                                        uint32_t aEndOffset,
                                         bool aClampToEdge, bool aFlushLayout);
 
   /**
    * Scan this range for -moz-user-select:none nodes and split it up into
    * multiple ranges to exclude those nodes.  The resulting ranges are put
    * in aOutRanges.  If no -moz-user-select:none node is found in the range
    * then |this| is unmodified and is the only range in aOutRanges.
    * Otherwise, |this| will be modified so that it ends before the first
@@ -345,24 +364,35 @@ public:
    */
   void ExcludeNonSelectableNodes(nsTArray<RefPtr<nsRange>>* aOutRanges);
 
   typedef nsTHashtable<nsPtrHashKey<nsRange> > RangeHashTable;
 protected:
   void RegisterCommonAncestor(nsINode* aNode);
   void UnregisterCommonAncestor(nsINode* aNode);
   nsINode* IsValidBoundary(nsINode* aNode);
-  static bool IsValidOffset(nsINode* aNode, int32_t aOffset);
+
+  /**
+   * XXX nsRange should accept 0 - UINT32_MAX as offset.  However, users of
+   *     nsRange treat offset as int32_t.  Additionally, some other internal
+   *     APIs like nsINode::IndexOf() use int32_t.  Therefore, nsRange should
+   *     accept only 0 - INT32_MAX as valid offset for now.
+   */
+  static bool IsValidOffset(uint32_t aOffset)
+  {
+    return aOffset <= INT32_MAX;
+  }
+  static bool IsValidOffset(nsINode* aNode, uint32_t aOffset);
 
   // CharacterDataChanged set aNotInsertedYet to true to disable an assertion
   // and suppress re-registering a range common ancestor node since
   // the new text node of a splitText hasn't been inserted yet.
   // CharacterDataChanged does the re-registering when needed.
-  void DoSetRange(nsINode* aStartN, int32_t aStartOffset,
-                  nsINode* aEndN, int32_t aEndOffset,
+  void DoSetRange(nsINode* aStartN, uint32_t aStartOffset,
+                  nsINode* aEndN, uint32_t aEndOffset,
                   nsINode* aRoot, bool aNotInsertedYet = false);
 
   /**
    * For a range for which IsInSelection() is true, return the common
    * ancestor for the range.  This method uses the selection bits and
    * nsGkAtoms::range property on the nodes to quickly find the ancestor.
    * That is, it's a faster version of GetCommonAncestor that only works
    * for ranges in a Selection.  The method will assert and the behavior
@@ -425,18 +455,18 @@ protected:
     static bool mIsNested;
   };
 
   nsCOMPtr<nsIDocument> mOwner;
   nsCOMPtr<nsINode> mRoot;
   nsCOMPtr<nsINode> mStartContainer;
   nsCOMPtr<nsINode> mEndContainer;
   RefPtr<mozilla::dom::Selection> mSelection;
-  int32_t mStartOffset;
-  int32_t mEndOffset;
+  uint32_t mStartOffset;
+  uint32_t mEndOffset;
 
   bool mIsPositioned : 1;
   bool mMaySpanAnonymousSubtrees : 1;
   bool mIsGenerated : 1;
   bool mStartOffsetWasIncremented : 1;
   bool mEndOffsetWasIncremented : 1;
   bool mCalledByJS : 1;
 #ifdef DEBUG
--- a/dom/interfaces/range/nsIDOMRange.idl
+++ b/dom/interfaces/range/nsIDOMRange.idl
@@ -11,24 +11,24 @@
  * For more information on this interface please see
  * http://www.w3.org/TR/DOM-Level-2-Traversal-Range/
  */
 
 [builtinclass, uuid(1f94055c-42e7-4a30-96a1-6a804f1c2d1e)]
 interface nsIDOMRange : nsISupports
 {
   readonly attribute nsIDOMNode       startContainer;
-  readonly attribute long             startOffset;
+  readonly attribute unsigned long    startOffset;
   readonly attribute nsIDOMNode       endContainer;
-  readonly attribute long             endOffset;
+  readonly attribute unsigned long    endOffset;
   readonly attribute boolean          collapsed;
   readonly attribute nsIDOMNode       commonAncestorContainer;
 
-  void               setStart(in nsIDOMNode refNode, in long offset);
-  void               setEnd(in nsIDOMNode refNode, in long offset);
+  void               setStart(in nsIDOMNode refNode, in unsigned long offset);
+  void               setEnd(in nsIDOMNode refNode, in unsigned long offset);
   void               setStartBefore(in nsIDOMNode refNode);
   void               setStartAfter(in nsIDOMNode refNode);
   void               setEndBefore(in nsIDOMNode refNode);
   void               setEndAfter(in nsIDOMNode refNode);
   void               collapse(in boolean toStart);
   void               selectNode(in nsIDOMNode refNode);
   void               selectNodeContents(in nsIDOMNode refNode);
 
@@ -51,24 +51,24 @@ interface nsIDOMRange : nsISupports
   
   // This method comes from
   // http://html5.org/specs/dom-parsing.html#extensions-to-the-range-interface
   nsIDOMDocumentFragment    createContextualFragment(in DOMString fragment);
 
   // This returns true if parent+offset equals either
   // of the boundary points or is between them.
   boolean                   isPointInRange(in nsIDOMNode parent,
-                                           in long offset);
+                                           in unsigned long offset);
 
   // comparePoint returns
   //   -1 if point is before the start boundary point,
   //    0 if point is either of the boundary points or between them,
   //    1 if point is after the end boundary point.
   // Sort of a strcmp for ranges.
-  short                     comparePoint(in nsIDOMNode parent, in long offset);
+  short comparePoint(in nsIDOMNode parent, in unsigned long offset);
 
   /**
    * Returns whether the range intersects node.
    */
   boolean                   intersectsNode(in nsIDOMNode node);
 
   // These methods come from 
   // http://dev.w3.org/csswg/cssom-view/#extensions-to-the-range-interface
--- a/editor/libeditor/EditorBase.cpp
+++ b/editor/libeditor/EditorBase.cpp
@@ -5314,17 +5314,17 @@ EditorBase::GetIMESelectionStartOffsetIn
   MOZ_ASSERT(aTextNode, "aTextNode must not be nullptr");
 
   nsCOMPtr<nsISelectionController> selectionController =
     GetSelectionController();
   if (NS_WARN_IF(!selectionController)) {
     return -1;
   }
 
-  int32_t minOffset = INT32_MAX;
+  uint32_t minOffset = UINT32_MAX;
   static const SelectionType kIMESelectionTypes[] = {
     SelectionType::eIMERawClause,
     SelectionType::eIMESelectedRawClause,
     SelectionType::eIMEConvertedClause,
     SelectionType::eIMESelectedClause
   };
   for (auto selectionType : kIMESelectionTypes) {
     RefPtr<Selection> selection = GetSelection(selectionType);
@@ -5334,25 +5334,21 @@ EditorBase::GetIMESelectionStartOffsetIn
     for (uint32_t i = 0; i < selection->RangeCount(); i++) {
       RefPtr<nsRange> range = selection->GetRangeAt(i);
       if (NS_WARN_IF(!range)) {
         continue;
       }
       if (NS_WARN_IF(range->GetStartContainer() != aTextNode)) {
         // ignore the start offset...
       } else {
-        MOZ_ASSERT(range->StartOffset() >= 0,
-                   "start offset shouldn't be negative");
         minOffset = std::min(minOffset, range->StartOffset());
       }
       if (NS_WARN_IF(range->GetEndContainer() != aTextNode)) {
         // ignore the end offset...
       } else {
-        MOZ_ASSERT(range->EndOffset() >= 0,
-                   "start offset shouldn't be negative");
         minOffset = std::min(minOffset, range->EndOffset());
       }
     }
   }
   return minOffset < INT32_MAX ? minOffset : -1;
 }
 
 void
--- a/editor/libeditor/HTMLEditRules.cpp
+++ b/editor/libeditor/HTMLEditRules.cpp
@@ -453,17 +453,17 @@ HTMLEditRules::AfterEditInner(EditAction
     return NS_OK;
   }
 
   NS_ENSURE_STATE(mHTMLEditor);
   RefPtr<Selection> selection = mHTMLEditor->GetSelection();
   NS_ENSURE_STATE(selection);
 
   nsCOMPtr<nsIDOMNode> rangeStartContainer, rangeEndContainer;
-  int32_t rangeStartOffset = 0, rangeEndOffset = 0;
+  uint32_t rangeStartOffset = 0, rangeEndOffset = 0;
   // do we have a real range to act on?
   bool bDamagedRange = false;
   if (mDocChangeRange) {
     mDocChangeRange->GetStartContainer(getter_AddRefs(rangeStartContainer));
     mDocChangeRange->GetEndContainer(getter_AddRefs(rangeEndContainer));
     mDocChangeRange->GetStartOffset(&rangeStartOffset);
     mDocChangeRange->GetEndOffset(&rangeEndOffset);
     if (rangeStartContainer && rangeEndContainer) {
@@ -563,18 +563,18 @@ HTMLEditRules::AfterEditInner(EditAction
 
   NS_ENSURE_STATE(mHTMLEditor);
 
   nsresult rv =
     mHTMLEditor->HandleInlineSpellCheck(
                    action, selection,
                    GetAsDOMNode(mRangeItem->mStartContainer),
                    mRangeItem->mStartOffset,
-                   rangeStartContainer, rangeStartOffset,
-                   rangeEndContainer, rangeEndOffset);
+                   rangeStartContainer, static_cast<int32_t>(rangeStartOffset),
+                   rangeEndContainer, static_cast<int32_t>(rangeEndOffset));
   NS_ENSURE_SUCCESS(rv, rv);
 
   // detect empty doc
   rv = CreateBogusNodeIfNeeded(selection);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // adjust selection HINT if needed
   if (!mDidExplicitlySetInterline) {
@@ -5312,113 +5312,127 @@ HTMLEditRules::NormalizeSelection(Select
   // we don't need to mess with cell selections, and we assume multirange selections are those.
   if (rangeCount != 1) {
     return NS_OK;
   }
 
   RefPtr<nsRange> range = inSelection->GetRangeAt(0);
   NS_ENSURE_TRUE(range, NS_ERROR_NULL_POINTER);
   nsCOMPtr<nsIDOMNode> startNode, endNode;
-  int32_t startOffset, endOffset;
+  uint32_t startOffset, endOffset;
   nsCOMPtr<nsIDOMNode> newStartNode, newEndNode;
-  int32_t newStartOffset, newEndOffset;
 
   rv = range->GetStartContainer(getter_AddRefs(startNode));
   NS_ENSURE_SUCCESS(rv, rv);
   rv = range->GetStartOffset(&startOffset);
   NS_ENSURE_SUCCESS(rv, rv);
   rv = range->GetEndContainer(getter_AddRefs(endNode));
   NS_ENSURE_SUCCESS(rv, rv);
   rv = range->GetEndOffset(&endOffset);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // adjusted values default to original values
   newStartNode = startNode;
-  newStartOffset = startOffset;
+  uint32_t newStartOffset = startOffset;
   newEndNode = endNode;
-  newEndOffset = endOffset;
+  uint32_t newEndOffset = endOffset;
 
   // some locals we need for whitespace code
   nsCOMPtr<nsINode> unused;
-  int32_t offset;
+  int32_t offset = -1;
   WSType wsType;
 
   // let the whitespace code do the heavy lifting
-  WSRunObject wsEndObj(mHTMLEditor, endNode, endOffset);
+  WSRunObject wsEndObj(mHTMLEditor, endNode, static_cast<int32_t>(endOffset));
   // is there any intervening visible whitespace?  if so we can't push selection past that,
   // it would visibly change maening of users selection
   nsCOMPtr<nsINode> endNode_(do_QueryInterface(endNode));
-  wsEndObj.PriorVisibleNode(endNode_, endOffset, address_of(unused),
-                            &offset, &wsType);
+  wsEndObj.PriorVisibleNode(endNode_, static_cast<int32_t>(endOffset),
+                            address_of(unused), &offset, &wsType);
   if (wsType != WSType::text && wsType != WSType::normalWS) {
     // eThisBlock and eOtherBlock conveniently distinquish cases
     // of going "down" into a block and "up" out of a block.
     if (wsEndObj.mStartReason == WSType::otherBlock) {
       // endpoint is just after the close of a block.
       nsCOMPtr<nsIDOMNode> child =
         GetAsDOMNode(mHTMLEditor->GetRightmostChild(wsEndObj.mStartReasonNode,
                                                     true));
       if (child) {
-        newEndNode = EditorBase::GetNodeLocation(child, &newEndOffset);
-        ++newEndOffset; // offset *after* child
+        int32_t offset = -1;
+        newEndNode = EditorBase::GetNodeLocation(child, &offset);
+        // offset *after* child
+        newEndOffset = static_cast<uint32_t>(offset + 1);
       }
       // else block is empty - we can leave selection alone here, i think.
     } else if (wsEndObj.mStartReason == WSType::thisBlock) {
       // endpoint is just after start of this block
       nsCOMPtr<nsIDOMNode> child;
       NS_ENSURE_STATE(mHTMLEditor);
-      mHTMLEditor->GetPriorHTMLNode(endNode, endOffset, address_of(child));
+      mHTMLEditor->GetPriorHTMLNode(endNode, static_cast<int32_t>(endOffset),
+                                    address_of(child));
       if (child) {
-        newEndNode = EditorBase::GetNodeLocation(child, &newEndOffset);
-        ++newEndOffset; // offset *after* child
+        int32_t offset = -1;
+        newEndNode = EditorBase::GetNodeLocation(child, &offset);
+        // offset *after* child
+        newEndOffset = static_cast<uint32_t>(offset + 1);
       }
       // else block is empty - we can leave selection alone here, i think.
     } else if (wsEndObj.mStartReason == WSType::br) {
       // endpoint is just after break.  lets adjust it to before it.
+      int32_t offset = -1;
       newEndNode =
         EditorBase::GetNodeLocation(GetAsDOMNode(wsEndObj.mStartReasonNode),
-                                    &newEndOffset);
+                                    &offset);
+      newEndOffset = static_cast<uint32_t>(offset);;
     }
   }
 
 
   // similar dealio for start of range
-  WSRunObject wsStartObj(mHTMLEditor, startNode, startOffset);
+  WSRunObject wsStartObj(mHTMLEditor, startNode,
+                         static_cast<int32_t>(startOffset));
   // is there any intervening visible whitespace?  if so we can't push selection past that,
   // it would visibly change maening of users selection
   nsCOMPtr<nsINode> startNode_(do_QueryInterface(startNode));
-  wsStartObj.NextVisibleNode(startNode_, startOffset, address_of(unused),
-                             &offset, &wsType);
+  wsStartObj.NextVisibleNode(startNode_, static_cast<int32_t>(startOffset),
+                             address_of(unused), &offset, &wsType);
   if (wsType != WSType::text && wsType != WSType::normalWS) {
     // eThisBlock and eOtherBlock conveniently distinquish cases
     // of going "down" into a block and "up" out of a block.
     if (wsStartObj.mEndReason == WSType::otherBlock) {
       // startpoint is just before the start of a block.
       nsCOMPtr<nsIDOMNode> child =
         GetAsDOMNode(mHTMLEditor->GetLeftmostChild(wsStartObj.mEndReasonNode,
                                                    true));
       if (child) {
-        newStartNode = EditorBase::GetNodeLocation(child, &newStartOffset);
+        int32_t offset = -1;
+        newStartNode = EditorBase::GetNodeLocation(child, &offset);
+        newStartOffset = static_cast<uint32_t>(offset);
       }
       // else block is empty - we can leave selection alone here, i think.
     } else if (wsStartObj.mEndReason == WSType::thisBlock) {
       // startpoint is just before end of this block
       nsCOMPtr<nsIDOMNode> child;
       NS_ENSURE_STATE(mHTMLEditor);
-      mHTMLEditor->GetNextHTMLNode(startNode, startOffset, address_of(child));
+      mHTMLEditor->GetNextHTMLNode(startNode, static_cast<int32_t>(startOffset),
+                                   address_of(child));
       if (child) {
-        newStartNode = EditorBase::GetNodeLocation(child, &newStartOffset);
+        int32_t offset = -1;
+        newStartNode = EditorBase::GetNodeLocation(child, &offset);
+        newStartOffset = static_cast<uint32_t>(offset);
       }
       // else block is empty - we can leave selection alone here, i think.
     } else if (wsStartObj.mEndReason == WSType::br) {
       // startpoint is just before a break.  lets adjust it to after it.
+      int32_t offset = -1;
       newStartNode =
         EditorBase::GetNodeLocation(GetAsDOMNode(wsStartObj.mEndReasonNode),
-                                    &newStartOffset);
-      ++newStartOffset; // offset *after* break
+                                    &offset);
+      // offset *after* break
+      newStartOffset = static_cast<uint32_t>(offset + 1);
     }
   }
 
   // there is a demented possiblity we have to check for.  We might have a very strange selection
   // that is not collapsed and yet does not contain any editable content, and satisfies some of the
   // above conditions that cause tweaking.  In this case we don't want to tweak the selection into
   // a block it was never in, etc.  There are a variety of strategies one might use to try to
   // detect these cases, but I think the most straightforward is to see if the adjusted locations
@@ -8188,33 +8202,33 @@ HTMLEditRules::UpdateDocChangeRange(nsRa
       // The same test won't be needed further down since after we've set
       // the start the range will be collapsed to that point.
       result = 1;
       rv = NS_OK;
     }
     NS_ENSURE_SUCCESS(rv, rv);
     // Positive result means mDocChangeRange start is after aRange start.
     if (result > 0) {
-      int32_t startOffset;
+      uint32_t startOffset;
       rv = aRange->GetStartOffset(&startOffset);
       NS_ENSURE_SUCCESS(rv, rv);
       rv = mDocChangeRange->SetStart(startNode, startOffset);
       NS_ENSURE_SUCCESS(rv, rv);
     }
 
     // compare ends of ranges
     rv = mDocChangeRange->CompareBoundaryPoints(nsIDOMRange::END_TO_END,
                                                 aRange, &result);
     NS_ENSURE_SUCCESS(rv, rv);
     // Negative result means mDocChangeRange end is before aRange end.
     if (result < 0) {
       nsCOMPtr<nsIDOMNode> endNode;
-      int32_t endOffset;
       rv = aRange->GetEndContainer(getter_AddRefs(endNode));
       NS_ENSURE_SUCCESS(rv, rv);
+      uint32_t endOffset;
       rv = aRange->GetEndOffset(&endOffset);
       NS_ENSURE_SUCCESS(rv, rv);
       rv = mDocChangeRange->SetEnd(endNode, endOffset);
       NS_ENSURE_SUCCESS(rv, rv);
     }
   }
   return NS_OK;
 }
--- a/editor/libeditor/HTMLEditor.cpp
+++ b/editor/libeditor/HTMLEditor.cpp
@@ -2413,32 +2413,30 @@ HTMLEditor::GetSelectedElement(const nsA
   bool isLinkTag = IsLinkTag(TagName);
   bool isNamedAnchorTag = IsNamedAnchorTag(TagName);
 
   nsCOMPtr<nsIDOMElement> selectedElement;
   RefPtr<nsRange> range = selection->GetRangeAt(0);
   NS_ENSURE_STATE(range);
 
   nsCOMPtr<nsIDOMNode> startContainer;
-  int32_t startOffset, endOffset;
   nsresult rv = range->GetStartContainer(getter_AddRefs(startContainer));
   NS_ENSURE_SUCCESS(rv, rv);
-  rv = range->GetStartOffset(&startOffset);
-  NS_ENSURE_SUCCESS(rv, rv);
+  uint32_t startOffset = range->StartOffset();
 
   nsCOMPtr<nsIDOMNode> endContainer;
   rv = range->GetEndContainer(getter_AddRefs(endContainer));
   NS_ENSURE_SUCCESS(rv, rv);
-  rv = range->GetEndOffset(&endOffset);
-  NS_ENSURE_SUCCESS(rv, rv);
+  uint32_t endOffset = range->EndOffset();
 
   // Optimization for a single selected element
   if (startContainer && startContainer == endContainer &&
       endOffset - startOffset == 1) {
-    nsCOMPtr<nsIDOMNode> selectedNode = GetChildAt(startContainer, startOffset);
+    nsCOMPtr<nsIDOMNode> selectedNode =
+      GetChildAt(startContainer, static_cast<int32_t>(startOffset));
     NS_ENSURE_SUCCESS(rv, NS_OK);
     if (selectedNode) {
       selectedNode->GetNodeName(domTagName);
       ToLowerCase(domTagName);
 
       // Test for appropriate node type requested
       if (anyTag || (TagName == domTagName) ||
           (isLinkTag && HTMLEditUtils::IsLink(selectedNode)) ||
--- a/editor/libeditor/HTMLEditorDataTransfer.cpp
+++ b/editor/libeditor/HTMLEditorDataTransfer.cpp
@@ -136,24 +136,23 @@ HTMLEditor::LoadHTML(const nsAString& aI
     nsCOMPtr<nsIDOMDocumentFragment> docfrag;
     rv = range->CreateContextualFragment(aInputString, getter_AddRefs(docfrag));
     NS_ENSURE_SUCCESS(rv, rv);
     // put the fragment into the document
     nsCOMPtr<nsIDOMNode> parent;
     rv = range->GetStartContainer(getter_AddRefs(parent));
     NS_ENSURE_SUCCESS(rv, rv);
     NS_ENSURE_TRUE(parent, NS_ERROR_NULL_POINTER);
-    int32_t childOffset;
-    rv = range->GetStartOffset(&childOffset);
-    NS_ENSURE_SUCCESS(rv, rv);
+    uint32_t childOffset = range->StartOffset();
 
     nsCOMPtr<nsIDOMNode> nodeToInsert;
     docfrag->GetFirstChild(getter_AddRefs(nodeToInsert));
     while (nodeToInsert) {
-      rv = InsertNode(nodeToInsert, parent, childOffset++);
+      rv = InsertNode(nodeToInsert, parent,
+                      static_cast<int32_t>(childOffset++));
       NS_ENSURE_SUCCESS(rv, rv);
       docfrag->GetFirstChild(getter_AddRefs(nodeToInsert));
     }
   }
 
   return rules->DidDoAction(selection, &ruleInfo, rv);
 }
 
--- a/editor/libeditor/HTMLStyleEditor.cpp
+++ b/editor/libeditor/HTMLStyleEditor.cpp
@@ -1068,17 +1068,17 @@ HTMLEditor::GetInlinePropertyBase(nsIAto
       // just ignore any non-editable nodes
       if (content->GetAsText() && (!IsEditable(content) ||
                                    IsEmptyTextNode(this, content))) {
         continue;
       }
       if (content->GetAsText()) {
         if (!isCollapsed && first && firstNodeInRange) {
           firstNodeInRange = false;
-          if (range->StartOffset() == (int32_t)content->Length()) {
+          if (range->StartOffset() == content->Length()) {
             continue;
           }
         } else if (content == endNode && !endOffset) {
           continue;
         }
       } else if (content->IsElement()) {
         // handle non-text leaf nodes here
         continue;
--- a/editor/libeditor/HTMLTableEditor.cpp
+++ b/editor/libeditor/HTMLTableEditor.cpp
@@ -2922,40 +2922,35 @@ HTMLEditor::GetCellFromRange(nsRange* aR
 
   *aCell = nullptr;
 
   nsCOMPtr<nsIDOMNode> startContainer;
   nsresult rv = aRange->GetStartContainer(getter_AddRefs(startContainer));
   NS_ENSURE_SUCCESS(rv, rv);
   NS_ENSURE_TRUE(startContainer, NS_ERROR_FAILURE);
 
-  int32_t startOffset;
-  rv = aRange->GetStartOffset(&startOffset);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsCOMPtr<nsIDOMNode> childNode = GetChildAt(startContainer, startOffset);
+  uint32_t startOffset = aRange->StartOffset();
+
+  nsCOMPtr<nsIDOMNode> childNode =
+    GetChildAt(startContainer, static_cast<int32_t>(startOffset));
   // This means selection is probably at a text node (or end of doc?)
   if (!childNode) {
     return NS_ERROR_FAILURE;
   }
 
   nsCOMPtr<nsIDOMNode> endContainer;
   rv = aRange->GetEndContainer(getter_AddRefs(endContainer));
   NS_ENSURE_SUCCESS(rv, rv);
   NS_ENSURE_TRUE(startContainer, NS_ERROR_FAILURE);
 
-  int32_t endOffset;
-  rv = aRange->GetEndOffset(&endOffset);
-  NS_ENSURE_SUCCESS(rv, rv);
-
   // If a cell is deleted, the range is collapse
-  //   (startOffset == endOffset)
+  //   (startOffset == aRange->EndOffset())
   //   so tell caller the cell wasn't found
   if (startContainer == endContainer &&
-      endOffset == startOffset+1 &&
+      aRange->EndOffset() == startOffset+1 &&
       HTMLEditUtils::IsTableCell(childNode)) {
     // Should we also test if frame is selected? (Use GetCellDataAt())
     // (Let's not for now -- more efficient)
     nsCOMPtr<nsIDOMElement> cellElement = do_QueryInterface(childNode);
     *aCell = cellElement.get();
     NS_ADDREF(*aCell);
     return NS_OK;
   }
--- a/editor/txtsvc/nsFilteredContentIterator.cpp
+++ b/editor/txtsvc/nsFilteredContentIterator.cpp
@@ -236,23 +236,25 @@ ContentIsInTraversalRange(nsIContent *aC
 static bool
 ContentIsInTraversalRange(nsRange* aRange, nsIDOMNode* aNextNode, bool aIsPreMode)
 {
   nsCOMPtr<nsIContent> content(do_QueryInterface(aNextNode));
   NS_ENSURE_TRUE(content && aRange, false);
 
   nsCOMPtr<nsIDOMNode> sNode;
   nsCOMPtr<nsIDOMNode> eNode;
-  int32_t sOffset;
-  int32_t eOffset;
+  uint32_t sOffset;
+  uint32_t eOffset;
   aRange->GetStartContainer(getter_AddRefs(sNode));
   aRange->GetStartOffset(&sOffset);
   aRange->GetEndContainer(getter_AddRefs(eNode));
   aRange->GetEndOffset(&eOffset);
-  return ContentIsInTraversalRange(content, aIsPreMode, sNode, sOffset, eNode, eOffset);
+  return ContentIsInTraversalRange(content, aIsPreMode,
+                                   sNode, static_cast<int32_t>(sOffset),
+                                   eNode, static_cast<int32_t>(eOffset));
 }
 
 //------------------------------------------------------------
 // Helper function to advance to the next or previous node
 nsresult
 nsFilteredContentIterator::AdvanceNode(nsIDOMNode* aNode, nsIDOMNode*& aNewNode, eDirectionType aDir)
 {
   nsCOMPtr<nsIDOMNode> nextNode;
--- a/editor/txtsvc/nsTextServicesDocument.cpp
+++ b/editor/txtsvc/nsTextServicesDocument.cpp
@@ -505,17 +505,16 @@ nsTextServicesDocument::LastSelectedBloc
 
   RefPtr<Selection> selection = domSelection->AsSelection();
 
   bool isCollapsed = selection->IsCollapsed();
 
   nsCOMPtr<nsIContentIterator> iter;
   RefPtr<nsRange> range;
   nsCOMPtr<nsIDOMNode>         parent;
-  int32_t rangeCount, offset;
 
   if (isCollapsed) {
     // We have a caret. Check if the caret is in a text node.
     // If it is, make the text node's block the current block.
     // If the caret isn't in a text node, search forwards in
     // the document, till we find a text node.
 
     range = selection->GetRangeAt(0);
@@ -532,16 +531,17 @@ nsTextServicesDocument::LastSelectedBloc
       return rv;
     }
 
     if (!parent) {
       UNLOCK_DOC(this);
       return NS_ERROR_FAILURE;
     }
 
+    uint32_t offset;
     rv = range->GetStartOffset(&offset);
 
     if (NS_FAILED(rv)) {
       UNLOCK_DOC(this);
       return rv;
     }
 
     if (IsTextNode(parent)) {
@@ -591,18 +591,19 @@ nsTextServicesDocument::LastSelectedBloc
         rv = SetSelectionInternal(*aSelOffset, *aSelLength, false);
       }
     } else {
       // The caret isn't in a text node. Create an iterator
       // based on a range that extends from the current caret
       // position to the end of the document, then walk forwards
       // till you find a text node, then find the beginning of it's block.
 
-      rv = CreateDocumentContentRootToNodeOffsetRange(parent, offset, false,
-                                                      getter_AddRefs(range));
+      rv = CreateDocumentContentRootToNodeOffsetRange(
+             parent, static_cast<int32_t>(offset), false,
+             getter_AddRefs(range));
 
       if (NS_FAILED(rv)) {
         UNLOCK_DOC(this);
         return rv;
       }
 
       rv = range->GetCollapsed(&isCollapsed);
 
@@ -685,16 +686,17 @@ nsTextServicesDocument::LastSelectedBloc
   }
 
   // If we get here, we have an uncollapsed selection!
   // Look backwards through each range in the selection till you
   // find the first text node. If you find one, find the
   // beginning of its text block, and make it the current
   // block.
 
+  int32_t rangeCount;
   rv = selection->GetRangeCount(&rangeCount);
 
   if (NS_FAILED(rv)) {
     UNLOCK_DOC(this);
     return rv;
   }
 
   NS_ASSERTION(rangeCount > 0, "Unexpected range count!");
@@ -792,25 +794,26 @@ nsTextServicesDocument::LastSelectedBloc
     return rv;
   }
 
   if (!parent) {
     UNLOCK_DOC(this);
     return NS_ERROR_FAILURE;
   }
 
+  uint32_t offset;
   rv = range->GetEndOffset(&offset);
 
   if (NS_FAILED(rv)) {
     UNLOCK_DOC(this);
     return rv;
   }
 
-  rv = CreateDocumentContentRootToNodeOffsetRange(parent, offset, false,
-                                                  getter_AddRefs(range));
+  rv = CreateDocumentContentRootToNodeOffsetRange(
+         parent, static_cast<int32_t>(offset), false, getter_AddRefs(range));
 
   if (NS_FAILED(rv)) {
     UNLOCK_DOC(this);
     return rv;
   }
 
   rv = range->GetCollapsed(&isCollapsed);
 
@@ -2372,42 +2375,44 @@ nsTextServicesDocument::GetCollapsedSele
 
   nsCOMPtr<nsIDOMNode> domParent;
   rv = range->GetStartContainer(getter_AddRefs(domParent));
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsINode> parent = do_QueryInterface(domParent);
   MOZ_ASSERT(parent);
 
-  int32_t offset;
+  uint32_t offset;
   rv = range->GetStartOffset(&offset);
   NS_ENSURE_SUCCESS(rv, rv);
 
   int32_t e1s1 = nsContentUtils::ComparePoints(eStart->mNode, eStartOffset,
-                                               domParent, offset);
+                                               domParent,
+                                               static_cast<int32_t>(offset));
   int32_t e2s1 = nsContentUtils::ComparePoints(eEnd->mNode, eEndOffset,
-                                               domParent, offset);
+                                               domParent,
+                                               static_cast<int32_t>(offset));
 
   if (e1s1 > 0 || e2s1 < 0) {
     // We're done if the caret is outside the current text block.
     return NS_OK;
   }
 
   if (parent->NodeType() == nsIDOMNode::TEXT_NODE) {
     // Good news, the caret is in a text node. Look
     // through the offset table for the entry that
     // matches its parent and offset.
 
     for (int32_t i = 0; i < tableCount; i++) {
       OffsetEntry* entry = mOffsetTable[i];
       NS_ENSURE_TRUE(entry, NS_ERROR_FAILURE);
 
       if (entry->mNode == domParent.get() &&
-          entry->mNodeOffset <= offset &&
-          offset <= entry->mNodeOffset + entry->mLength) {
+          entry->mNodeOffset <= static_cast<int32_t>(offset) &&
+          static_cast<int32_t>(offset) <= entry->mNodeOffset + entry->mLength) {
         *aSelStatus = nsITextServicesDocument::eBlockContains;
         *aSelOffset = entry->mStrOffset + (offset - entry->mNodeOffset);
         *aSelLength = 0;
 
         return NS_OK;
       }
     }
 
@@ -2435,17 +2440,17 @@ nsTextServicesDocument::GetCollapsedSele
   nsIContent* saveNode;
   if (parent->HasChildren()) {
     // XXX: We need to make sure that all of parent's
     //      children are in the text block.
 
     // If the parent has children, position the iterator
     // on the child that is to the left of the offset.
 
-    uint32_t childIndex = (uint32_t)offset;
+    uint32_t childIndex = offset;
 
     if (childIndex > 0) {
       uint32_t numChildren = parent->GetChildCount();
       NS_ASSERTION(childIndex <= numChildren, "Invalid selection offset!");
 
       if (childIndex > numChildren) {
         childIndex = numChildren;
       }
@@ -2521,18 +2526,18 @@ nsTextServicesDocument::GetCollapsedSele
     offset = 0;
   }
 
   for (int32_t i = 0; i < tableCount; i++) {
     OffsetEntry* entry = mOffsetTable[i];
     NS_ENSURE_TRUE(entry, NS_ERROR_FAILURE);
 
     if (entry->mNode == node->AsDOMNode() &&
-        entry->mNodeOffset <= offset &&
-        offset <= entry->mNodeOffset + entry->mLength) {
+        entry->mNodeOffset <= static_cast<int32_t>(offset) &&
+        static_cast<int32_t>(offset) <= entry->mNodeOffset + entry->mLength) {
       *aSelStatus = nsITextServicesDocument::eBlockContains;
       *aSelOffset = entry->mStrOffset + (offset - entry->mNodeOffset);
       *aSelLength = 0;
 
       // Now move the caret so that it is actually in the text node.
       // We do this to keep things in sync.
       //
       // In most cases, the user shouldn't see any movement in the caret
@@ -2815,27 +2820,35 @@ nsTextServicesDocument::GetRangeEndPoint
                  aEndContainer && aEndOffset, NS_ERROR_NULL_POINTER);
 
   nsresult rv = aRange->GetStartContainer(aStartContainer);
 
   NS_ENSURE_SUCCESS(rv, rv);
 
   NS_ENSURE_TRUE(aStartContainer, NS_ERROR_FAILURE);
 
-  rv = aRange->GetStartOffset(aStartOffset);
-
-  NS_ENSURE_SUCCESS(rv, rv);
+  uint32_t offset;
+  rv = aRange->GetStartOffset(&offset);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+  *aStartOffset = static_cast<int32_t>(offset);
 
   rv = aRange->GetEndContainer(aEndContainer);
 
   NS_ENSURE_SUCCESS(rv, rv);
 
   NS_ENSURE_TRUE(aEndContainer, NS_ERROR_FAILURE);
 
-  return aRange->GetEndOffset(aEndOffset);
+  rv = aRange->GetEndOffset(&offset);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+  *aEndOffset = static_cast<int32_t>(offset);
+  return NS_OK;
 }
 
 nsresult
 nsTextServicesDocument::CreateRange(nsIDOMNode* aStartContainer,
                                     int32_t aStartOffset,
                                     nsIDOMNode* aEndContainer,
                                     int32_t aEndOffset,
                                     nsRange** aRange)
--- a/extensions/spellcheck/src/mozInlineSpellChecker.cpp
+++ b/extensions/spellcheck/src/mozInlineSpellChecker.cpp
@@ -347,49 +347,49 @@ nsresult
 mozInlineSpellStatus::FinishNavigationEvent(mozInlineSpellWordUtil& aWordUtil)
 {
   nsCOMPtr<nsIEditor> editor = do_QueryReferent(mSpellChecker->mEditor);
   if (! editor)
     return NS_ERROR_FAILURE; // editor is gone
 
   NS_ASSERTION(mAnchorRange, "No anchor for navigation!");
   nsCOMPtr<nsIDOMNode> newAnchorNode, oldAnchorNode;
-  int32_t newAnchorOffset, oldAnchorOffset;
 
   // get the DOM position of the old caret, the range should be collapsed
   nsresult rv = mOldNavigationAnchorRange->GetStartContainer(
       getter_AddRefs(oldAnchorNode));
   NS_ENSURE_SUCCESS(rv, rv);
-  rv = mOldNavigationAnchorRange->GetStartOffset(&oldAnchorOffset);
-  NS_ENSURE_SUCCESS(rv, rv);
+  uint32_t oldAnchorOffset = mOldNavigationAnchorRange->StartOffset();
 
   // find the word on the old caret position, this is the one that we MAY need
   // to check
   RefPtr<nsRange> oldWord;
-  rv = aWordUtil.GetRangeForWord(oldAnchorNode, oldAnchorOffset,
+  rv = aWordUtil.GetRangeForWord(oldAnchorNode,
+                                 static_cast<int32_t>(oldAnchorOffset),
                                  getter_AddRefs(oldWord));
   NS_ENSURE_SUCCESS(rv, rv);
 
   // aWordUtil.GetRangeForWord flushes pending notifications, check editor again.
   editor = do_QueryReferent(mSpellChecker->mEditor);
   if (! editor)
     return NS_ERROR_FAILURE; // editor is gone
 
   // get the DOM position of the new caret, the range should be collapsed
   rv = mAnchorRange->GetStartContainer(getter_AddRefs(newAnchorNode));
   NS_ENSURE_SUCCESS(rv, rv);
-  rv = mAnchorRange->GetStartOffset(&newAnchorOffset);
-  NS_ENSURE_SUCCESS(rv, rv);
+  uint32_t newAnchorOffset = mAnchorRange->StartOffset();
 
   // see if the new cursor position is in the word of the old cursor position
   bool isInRange = false;
   if (! mForceNavigationWordCheck) {
-    rv = oldWord->IsPointInRange(newAnchorNode,
-                                 newAnchorOffset + mNewNavigationPositionOffset,
-                                 &isInRange);
+    rv = oldWord->IsPointInRange(
+                    newAnchorNode,
+                    static_cast<int32_t>(
+                      newAnchorOffset + mNewNavigationPositionOffset),
+                    &isInRange);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   if (isInRange) {
     // caller should give up
     mRange = nullptr;
   } else {
     // check the old word
@@ -412,21 +412,19 @@ mozInlineSpellStatus::FinishNavigationEv
 nsresult
 mozInlineSpellStatus::FillNoCheckRangeFromAnchor(
     mozInlineSpellWordUtil& aWordUtil)
 {
   nsCOMPtr<nsIDOMNode> anchorNode;
   nsresult rv = mAnchorRange->GetStartContainer(getter_AddRefs(anchorNode));
   NS_ENSURE_SUCCESS(rv, rv);
 
-  int32_t anchorOffset;
-  rv = mAnchorRange->GetStartOffset(&anchorOffset);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  return aWordUtil.GetRangeForWord(anchorNode, anchorOffset,
+  uint32_t anchorOffset = mAnchorRange->StartOffset();
+  return aWordUtil.GetRangeForWord(anchorNode,
+                                   static_cast<int32_t>(anchorOffset),
                                    getter_AddRefs(mNoCheckRange));
 }
 
 // mozInlineSpellStatus::GetDocument
 //
 //    Returns the nsIDOMDocument object for the document for the
 //    current spellchecker.
 
@@ -1211,17 +1209,17 @@ mozInlineSpellChecker::MakeSpellCheckRan
   nsCOMPtr<nsINode> startNode = do_QueryInterface(aStartNode);
   nsCOMPtr<nsINode> endNode = do_QueryInterface(aEndNode);
   if (aEndOffset) {
     rv = range->SetStartAndEnd(startNode, aStartOffset, endNode, aEndOffset);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
   } else {
-    int32_t endOffset = -1;
+    uint32_t endOffset;
     endNode = nsRange::GetContainerAndOffsetAfter(endNode, &endOffset);
     rv = range->SetStartAndEnd(startNode, aStartOffset, endNode, endOffset);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
   }
 
   range.swap(*aRange);
--- a/layout/base/PresShell.cpp
+++ b/layout/base/PresShell.cpp
@@ -4790,19 +4790,21 @@ PresShell::ClipListToRange(nsDisplayList
     if (content) {
       bool atStart = (content == aRange->GetStartContainer());
       bool atEnd = (content == aRange->GetEndContainer());
       if ((atStart || atEnd) && frame->IsTextFrame()) {
         int32_t frameStartOffset, frameEndOffset;
         frame->GetOffsets(frameStartOffset, frameEndOffset);
 
         int32_t hilightStart =
-          atStart ? std::max(aRange->StartOffset(), frameStartOffset) : frameStartOffset;
+          atStart ? std::max(static_cast<int32_t>(aRange->StartOffset()),
+                             frameStartOffset) : frameStartOffset;
         int32_t hilightEnd =
-          atEnd ? std::min(aRange->EndOffset(), frameEndOffset) : frameEndOffset;
+          atEnd ? std::min(static_cast<int32_t>(aRange->EndOffset()),
+                           frameEndOffset) : frameEndOffset;
         if (hilightStart < hilightEnd) {
           // determine the location of the start and end edges of the range.
           nsPoint startPoint, endPoint;
           frame->GetPointFromOffset(hilightStart, &startPoint);
           frame->GetPointFromOffset(hilightEnd, &endPoint);
 
           // The clip rectangle is determined by taking the the start and
           // end points of the range, offset from the reference frame.
--- a/layout/generic/nsImageFrame.cpp
+++ b/layout/generic/nsImageFrame.cpp
@@ -1891,30 +1891,34 @@ nsImageFrame::ShouldDisplaySelection()
         if (rangeCount == 1) //if not one then let code drop to nsFrame::Paint
         {
           nsCOMPtr<nsIContent> parentContent = mContent->GetParent();
           if (parentContent)
           {
             int32_t thisOffset = parentContent->IndexOf(mContent);
             nsCOMPtr<nsIDOMNode> parentNode = do_QueryInterface(parentContent);
             nsCOMPtr<nsIDOMNode> rangeNode;
-            int32_t rangeOffset;
+            uint32_t rangeOffset;
             nsCOMPtr<nsIDOMRange> range;
             selection->GetRangeAt(0,getter_AddRefs(range));
             if (range)
             {
               range->GetStartContainer(getter_AddRefs(rangeNode));
               range->GetStartOffset(&rangeOffset);
 
-              if (parentNode && rangeNode && (rangeNode == parentNode) && rangeOffset == thisOffset)
-              {
+              if (parentNode && rangeNode && rangeNode == parentNode &&
+                  static_cast<int32_t>(rangeOffset) == thisOffset) {
                 range->GetEndContainer(getter_AddRefs(rangeNode));
                 range->GetEndOffset(&rangeOffset);
-                if ((rangeNode == parentNode) && (rangeOffset == (thisOffset +1))) //+1 since that would mean this whole content is selected only
-                  return false; //do not allow nsFrame do draw any further selection
+                // +1 since that would mean this whole content is selected only
+                if (rangeNode == parentNode &&
+                    static_cast<int32_t>(rangeOffset) == thisOffset + 1) {
+                  // Do not allow nsFrame do draw any further selection
+                  return false;
+                }
               }
             }
           }
         }
       }
     }
   }
 #endif
--- a/toolkit/components/find/nsFind.cpp
+++ b/toolkit/components/find/nsFind.cpp
@@ -596,17 +596,17 @@ nsFind::NextNode(nsIDOMRange* aSearchRan
   nsCOMPtr<nsIContent> content;
 
   if (!mIterator || aContinueOk) {
     // If we are continuing, that means we have a match in progress. In that
     // case, we want to continue from the end point (where we are now) to the
     // beginning/end of the search range.
     nsCOMPtr<nsIDOMNode> startNode;
     nsCOMPtr<nsIDOMNode> endNode;
-    int32_t startOffset, endOffset;
+    uint32_t startOffset, endOffset;
     if (aContinueOk) {
 #ifdef DEBUG_FIND
       printf("Match in progress: continuing past endpoint\n");
 #endif
       if (mFindBackward) {
         aSearchRange->GetStartContainer(getter_AddRefs(startNode));
         aSearchRange->GetStartOffset(&startOffset);
         aEndPoint->GetStartContainer(getter_AddRefs(endNode));
@@ -632,17 +632,18 @@ nsFind::NextNode(nsIDOMRange* aSearchRan
       } else { // forward
         aStartPoint->GetStartContainer(getter_AddRefs(startNode));
         aStartPoint->GetStartOffset(&startOffset);
         aEndPoint->GetEndContainer(getter_AddRefs(endNode));
         aEndPoint->GetEndOffset(&endOffset);
       }
     }
 
-    rv = InitIterator(startNode, startOffset, endNode, endOffset);
+    rv = InitIterator(startNode, static_cast<int32_t>(startOffset),
+                      endNode, static_cast<int32_t>(endOffset));
     NS_ENSURE_SUCCESS(rv, rv);
     if (!aStartPoint) {
       aStartPoint = aSearchRange;
     }
 
     content = do_QueryInterface(mIterator->GetCurrentNode());
 #ifdef DEBUG_FIND
     nsCOMPtr<nsIDOMNode> dnode(do_QueryInterface(content));
@@ -652,24 +653,28 @@ nsFind::NextNode(nsIDOMRange* aSearchRan
     if (content && content->IsNodeOfType(nsINode::eTEXT) &&
         !SkipNode(content)) {
       mIterNode = do_QueryInterface(content);
       // Also set mIterOffset if appropriate:
       nsCOMPtr<nsIDOMNode> node;
       if (mFindBackward) {
         aStartPoint->GetEndContainer(getter_AddRefs(node));
         if (mIterNode.get() == node.get()) {
-          aStartPoint->GetEndOffset(&mIterOffset);
+          uint32_t endOffset;
+          aStartPoint->GetEndOffset(&endOffset);
+          mIterOffset = static_cast<int32_t>(endOffset);
         } else {
           mIterOffset = -1; // sign to start from end
         }
       } else {
         aStartPoint->GetStartContainer(getter_AddRefs(node));
         if (mIterNode.get() == node.get()) {
-          aStartPoint->GetStartOffset(&mIterOffset);
+          uint32_t startOffset;
+          aStartPoint->GetStartOffset(&startOffset);
+          mIterOffset = static_cast<int32_t>(startOffset);
         } else {
           mIterOffset = 0;
         }
       }
 #ifdef DEBUG_FIND
       printf("Setting initial offset to %d\n", mIterOffset);
 #endif
       return NS_OK;
@@ -983,17 +988,17 @@ nsFind::Find(const char16_t* aPatText, n
   bool wordBreakPrev = false;
 
   // Place to save the range start point in case we find a match:
   nsCOMPtr<nsIDOMNode> matchAnchorNode;
   int32_t matchAnchorOffset = 0;
 
   // Get the end point, so we know when to end searches:
   nsCOMPtr<nsIDOMNode> endNode;
-  int32_t endOffset;
+  uint32_t endOffset;
   aEndPoint->GetEndContainer(getter_AddRefs(endNode));
   aEndPoint->GetEndOffset(&endOffset);
 
   char16_t c = 0;
   char16_t patc = 0;
   char16_t prevChar = 0;
   char16_t prevCharInMatch = 0;
   while (1) {
@@ -1118,18 +1123,18 @@ nsFind::Find(const char16_t* aPatText, n
         frag = nullptr;
         continue;
       }
     }
 
     // Have we gone past the endpoint yet? If we have, and we're not in the
     // middle of a match, return.
     if (mIterNode == endNode &&
-        ((mFindBackward && findex < endOffset) ||
-         (!mFindBackward && findex > endOffset))) {
+        ((mFindBackward && findex < static_cast<int32_t>(endOffset)) ||
+         (!mFindBackward && findex > static_cast<int32_t>(endOffset)))) {
       ResetAll();
       return NS_OK;
     }
 
     // Save the previous character for word boundary detection
     prevChar = c;
     // The two characters we'll be comparing:
     c = (t2b ? t2b[findex] : CHAR_TO_UNICHAR(t1b[findex]));
--- a/toolkit/components/find/nsWebBrowserFind.cpp
+++ b/toolkit/components/find/nsWebBrowserFind.cpp
@@ -511,17 +511,17 @@ nsWebBrowserFind::GetSearchLimits(nsIDOM
 
   uint32_t childCount = bodyContent->GetChildCount();
 
   // There are four possible range endpoints we might use:
   // DocumentStart, SelectionStart, SelectionEnd, DocumentEnd.
 
   nsCOMPtr<nsIDOMRange> range;
   nsCOMPtr<nsIDOMNode> node;
-  int32_t offset;
+  uint32_t offset;
 
   // Forward, not wrapping: SelEnd to DocEnd
   if (!mFindBackwards && !aWrap) {
     // This isn't quite right, since the selection's ranges aren't
     // necessarily in order; but they usually will be.
     aSel->GetRangeAt(count - 1, getter_AddRefs(range));
     if (!range) {
       return NS_ERROR_UNEXPECTED;
--- a/toolkit/components/typeaheadfind/nsTypeAheadFind.cpp
+++ b/toolkit/components/typeaheadfind/nsTypeAheadFind.cpp
@@ -843,17 +843,17 @@ nsTypeAheadFind::GetSearchContainers(nsI
     // Ensure visible range, move forward if necessary
     // This uses ignores the return value, but usese the side effect of
     // IsRangeVisible. It returns the first visible range after searchRange
     IsRangeVisible(presShell, presContext, mSearchRange,
                    aIsFirstVisiblePreferred, true,
                    getter_AddRefs(mStartPointRange), nullptr);
   }
   else {
-    int32_t startOffset;
+    uint32_t startOffset;
     nsCOMPtr<nsIDOMNode> startNode;
     if (aFindPrev) {
       currentSelectionRange->GetStartContainer(getter_AddRefs(startNode));
       currentSelectionRange->GetStartOffset(&startOffset);
     } else {
       currentSelectionRange->GetEndContainer(getter_AddRefs(startNode));
       currentSelectionRange->GetEndOffset(&startOffset);
     }
@@ -881,17 +881,17 @@ nsTypeAheadFind::RangeStartsInsideLink(n
 {
   *aIsInsideLink = false;
   *aIsStartingLink = true;
 
   // ------- Get nsIContent to test -------
   nsCOMPtr<nsIDOMNode> startNode;
   nsCOMPtr<nsIContent> startContent, origContent;
   aRange->GetStartContainer(getter_AddRefs(startNode));
-  int32_t startOffset;
+  uint32_t startOffset;
   aRange->GetStartOffset(&startOffset);
 
   startContent = do_QueryInterface(startNode);
   if (!startContent) {
     NS_NOTREACHED("startContent should never be null");
     return;
   }
   origContent = startContent;
@@ -901,19 +901,20 @@ nsTypeAheadFind::RangeStartsInsideLink(n
     if (childContent) {
       startContent = childContent;
     }
   }
   else if (startOffset > 0) {
     const nsTextFragment *textFrag = startContent->GetText();
     if (textFrag) {
       // look for non whitespace character before start offset
-      for (int32_t index = 0; index < startOffset; index++) {
+      for (uint32_t index = 0; index < startOffset; index++) {
         // FIXME: take content language into account when deciding whitespace.
-        if (!mozilla::dom::IsSpaceCharacter(textFrag->CharAt(index))) {
+        if (!mozilla::dom::IsSpaceCharacter(
+                             textFrag->CharAt(static_cast<int32_t>(index)))) {
           *aIsStartingLink = false;  // not at start of a node
 
           break;
         }
       }
     }
   }
 
@@ -1230,22 +1231,24 @@ nsTypeAheadFind::IsRangeVisible(nsIPresS
       (frame->GetStateBits() & NS_FRAME_INDEPENDENT_SELECTION);
   }
 
   // ---- We have a frame ----
   if (!aMustBeInViewPort)
     return true; //  Don't need it to be on screen, just in rendering tree
 
   // Get the next in flow frame that contains the range start
-  int32_t startRangeOffset, startFrameOffset, endFrameOffset;
+  int32_t startFrameOffset, endFrameOffset;
+  uint32_t startRangeOffset;
   aRange->GetStartOffset(&startRangeOffset);
   while (true) {
     frame->GetOffsets(startFrameOffset, endFrameOffset);
-    if (startRangeOffset < endFrameOffset)
+    if (static_cast<int32_t>(startRangeOffset) < endFrameOffset) {
       break;
+    }
 
     nsIFrame *nextContinuationFrame = frame->GetNextContinuation();
     if (nextContinuationFrame)
       frame = nextContinuationFrame;
     else
       break;
   }