Bug 1509989 - Factor out nsRange security checks. r=mats
authorEmilio Cobos Álvarez <emilio@crisal.io>
Tue, 27 Nov 2018 16:54:34 +0000
changeset 448355 ab61114ae332c44234176d2181a897ff5e89d6d6
parent 448354 33930dc85090600ba8c1ab269b9854ac4f1c0ebb
child 448356 76cda4d85a5a55f75afdd932b782ab02d01b6d5d
push id73815
push userealvarez@mozilla.com
push dateTue, 27 Nov 2018 18:03:28 +0000
treeherderautoland@49adeee1a194 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmats
bugs1509989
milestone65.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 1509989 - Factor out nsRange security checks. r=mats Differential Revision: https://phabricator.services.mozilla.com/D13069
dom/base/nsRange.cpp
dom/base/nsRange.h
--- a/dom/base/nsRange.cpp
+++ b/dom/base/nsRange.cpp
@@ -1246,21 +1246,29 @@ nsRange::IsValidPoints(nsINode* aStartCo
 void
 nsRange::SetStartJS(nsINode& aNode, uint32_t aOffset, ErrorResult& aErr)
 {
   AutoCalledByJSRestore calledByJSRestorer(*this);
   mCalledByJS = true;
   SetStart(aNode, aOffset, aErr);
 }
 
+bool
+nsRange::CanAccess(const nsINode& aNode) const
+{
+  if (nsContentUtils::LegacyIsCallerNativeCode()) {
+    return true;
+  }
+  return nsContentUtils::CanCallerAccess(&aNode);
+}
+
 void
 nsRange::SetStart(nsINode& aNode, uint32_t aOffset, ErrorResult& aRv)
 {
- if (!nsContentUtils::LegacyIsCallerNativeCode() &&
-     !nsContentUtils::CanCallerAccess(&aNode)) {
+ if (!CanAccess(aNode)) {
     aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
     return;
   }
 
   AutoInvalidateSelection atEndOfBlock(this);
   SetStart(RawRangeBoundary(&aNode, aOffset), aRv);
 }
 
@@ -1295,18 +1303,17 @@ nsRange::SetStartBeforeJS(nsINode& aNode
   AutoCalledByJSRestore calledByJSRestorer(*this);
   mCalledByJS = true;
   SetStartBefore(aNode, aErr);
 }
 
 void
 nsRange::SetStartBefore(nsINode& aNode, ErrorResult& aRv)
 {
-  if (!nsContentUtils::LegacyIsCallerNativeCode() &&
-      !nsContentUtils::CanCallerAccess(&aNode)) {
+  if (!CanAccess(aNode)) {
     aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
     return;
   }
 
   AutoInvalidateSelection atEndOfBlock(this);
   // If the node is being removed from its parent, GetContainerAndOffsetBefore()
   // returns nullptr.  Then, SetStart() will throw
   // NS_ERROR_DOM_INVALID_NODE_TYPE_ERR.
@@ -1321,18 +1328,17 @@ nsRange::SetStartAfterJS(nsINode& aNode,
   AutoCalledByJSRestore calledByJSRestorer(*this);
   mCalledByJS = true;
   SetStartAfter(aNode, aErr);
 }
 
 void
 nsRange::SetStartAfter(nsINode& aNode, ErrorResult& aRv)
 {
-  if (!nsContentUtils::LegacyIsCallerNativeCode() &&
-      !nsContentUtils::CanCallerAccess(&aNode)) {
+  if (!CanAccess(aNode)) {
     aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
     return;
   }
 
   AutoInvalidateSelection atEndOfBlock(this);
   // If the node is being removed from its parent, GetContainerAndOffsetAfter()
   // returns nullptr.  Then, SetStart() will throw
   // NS_ERROR_DOM_INVALID_NODE_TYPE_ERR.
@@ -1347,18 +1353,17 @@ nsRange::SetEndJS(nsINode& aNode, uint32
   AutoCalledByJSRestore calledByJSRestorer(*this);
   mCalledByJS = true;
   SetEnd(aNode, aOffset, aErr);
 }
 
 void
 nsRange::SetEnd(nsINode& aNode, uint32_t aOffset, ErrorResult& aRv)
 {
- if (!nsContentUtils::LegacyIsCallerNativeCode() &&
-     !nsContentUtils::CanCallerAccess(&aNode)) {
+ if (!CanAccess(aNode)) {
     aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
     return;
   }
   AutoInvalidateSelection atEndOfBlock(this);
   SetEnd(RawRangeBoundary(&aNode, aOffset), aRv);
 }
 
 void
@@ -1471,18 +1476,17 @@ nsRange::SetEndBeforeJS(nsINode& aNode, 
   AutoCalledByJSRestore calledByJSRestorer(*this);
   mCalledByJS = true;
   SetEndBefore(aNode, aErr);
 }
 
 void
 nsRange::SetEndBefore(nsINode& aNode, ErrorResult& aRv)
 {
-  if (!nsContentUtils::LegacyIsCallerNativeCode() &&
-      !nsContentUtils::CanCallerAccess(&aNode)) {
+  if (!CanAccess(aNode)) {
     aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
     return;
   }
 
   AutoInvalidateSelection atEndOfBlock(this);
   // If the node is being removed from its parent, GetContainerAndOffsetBefore()
   // returns nullptr.  Then, SetEnd() will throw
   // NS_ERROR_DOM_INVALID_NODE_TYPE_ERR.
@@ -1497,18 +1501,17 @@ nsRange::SetEndAfterJS(nsINode& aNode, E
   AutoCalledByJSRestore calledByJSRestorer(*this);
   mCalledByJS = true;
   SetEndAfter(aNode, aErr);
 }
 
 void
 nsRange::SetEndAfter(nsINode& aNode, ErrorResult& aRv)
 {
-  if (!nsContentUtils::LegacyIsCallerNativeCode() &&
-      !nsContentUtils::CanCallerAccess(&aNode)) {
+  if (!CanAccess(aNode)) {
     aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
     return;
   }
 
   AutoInvalidateSelection atEndOfBlock(this);
   // If the node is being removed from its parent, GetContainerAndOffsetAfter()
   // returns nullptr.  Then, SetEnd() will throw
   // NS_ERROR_DOM_INVALID_NODE_TYPE_ERR.
@@ -1545,18 +1548,17 @@ nsRange::SelectNodeJS(nsINode& aNode, Er
   AutoCalledByJSRestore calledByJSRestorer(*this);
   mCalledByJS = true;
   SelectNode(aNode, aErr);
 }
 
 void
 nsRange::SelectNode(nsINode& aNode, ErrorResult& aRv)
 {
-  if (!nsContentUtils::LegacyIsCallerNativeCode() &&
-      !nsContentUtils::CanCallerAccess(&aNode)) {
+  if (!CanAccess(aNode)) {
     aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
     return;
   }
 
   nsINode* container = aNode.GetParentNode();
   nsINode* newRoot = IsValidBoundary(container);
   if (!newRoot) {
     aRv.Throw(NS_ERROR_DOM_INVALID_NODE_TYPE_ERR);
@@ -1586,18 +1588,17 @@ nsRange::SelectNodeContentsJS(nsINode& a
   AutoCalledByJSRestore calledByJSRestorer(*this);
   mCalledByJS = true;
   SelectNodeContents(aNode, aErr);
 }
 
 void
 nsRange::SelectNodeContents(nsINode& aNode, ErrorResult& aRv)
 {
-  if (!nsContentUtils::LegacyIsCallerNativeCode() &&
-      !nsContentUtils::CanCallerAccess(&aNode)) {
+  if (!CanAccess(aNode)) {
     aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
     return;
   }
 
   nsINode* newRoot = IsValidBoundary(&aNode);
   if (!newRoot) {
     aRv.Throw(NS_ERROR_DOM_INVALID_NODE_TYPE_ERR);
     return;
@@ -2606,18 +2607,17 @@ nsRange::CloneRange() const
   range->DoSetRange(mStart.AsRaw(), mEnd.AsRaw(), mRoot);
 
   return range.forget();
 }
 
 void
 nsRange::InsertNode(nsINode& aNode, ErrorResult& aRv)
 {
-  if (!nsContentUtils::LegacyIsCallerNativeCode() &&
-      !nsContentUtils::CanCallerAccess(&aNode)) {
+  if (!CanAccess(aNode)) {
     aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
     return;
   }
 
   uint32_t tStartOffset = StartOffset();
 
   nsCOMPtr<nsINode> tStartContainer = GetStartContainer(aRv);
   if (aRv.Failed()) {
@@ -2699,18 +2699,17 @@ nsRange::InsertNode(nsINode& aNode, Erro
   if (Collapsed()) {
     aRv = SetEnd(referenceParentNode, newOffset);
   }
 }
 
 void
 nsRange::SurroundContents(nsINode& aNewParent, ErrorResult& aRv)
 {
-  if (!nsContentUtils::LegacyIsCallerNativeCode() &&
-      !nsContentUtils::CanCallerAccess(&aNewParent)) {
+  if (!CanAccess(aNewParent)) {
     aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
     return;
   }
 
   if (!mRoot) {
     aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
     return;
   }
--- a/dom/base/nsRange.h
+++ b/dom/base/nsRange.h
@@ -387,16 +387,21 @@ private:
    */
   nsresult CutContents(mozilla::dom::DocumentFragment** frag);
 
   static nsresult CloneParentsBetween(nsINode* aAncestor,
                                       nsINode* aNode,
                                       nsINode** aClosestAncestor,
                                       nsINode** aFarthestAncestor);
 
+  /**
+   * Returns whether a node is safe to be accessed by the current caller.
+   */
+  bool CanAccess(const nsINode&) const;
+
 public:
   /**
    * Compute the root node of aNode for initializing range classes.
    * When aNode is in an anonymous subtree, this returns the shadow root or
    * binding parent.  Otherwise, the root node of the document or document
    * fragment.  If this returns nullptr, that means aNode can be neither the
    * start container nor end container of any range.
    */