Bug 1315146 - Avoid using the Web-facing Range methods in nsTextControlFrame::SetSelectionInternal(); r=baku
authorEhsan Akhgari <ehsan@mozilla.com>
Wed, 16 Nov 2016 17:34:43 -0500
changeset 323056 5e51ba71c958fbec2b6774c2d39e22d9e3f9c5fb
parent 323055 eb0e39566b63239abd2b71cba08c5775e48ac1fd
child 323057 45f214b73596d7d1b194822e7e5a85ee606c372d
push id30967
push userphilringnalda@gmail.com
push dateFri, 18 Nov 2016 03:21:38 +0000
treeherdermozilla-central@8e476f8bd52d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbaku
bugs1315146
milestone53.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 1315146 - Avoid using the Web-facing Range methods in nsTextControlFrame::SetSelectionInternal(); r=baku The Web-facing methods perform access checks which blow up when the stars are aligned such that we run this code under a subject principal that doesn't have access to the anchor node of the selection.
dom/html/test/bug1315146-iframe.html
dom/html/test/bug1315146-main.html
dom/html/test/mochitest.ini
dom/html/test/test_bug1315146.html
layout/forms/nsTextControlFrame.cpp
new file mode 100644
--- /dev/null
+++ b/dom/html/test/bug1315146-iframe.html
@@ -0,0 +1,4 @@
+<!DOCTYPE html>
+<script>
+document.domain = "example.org";
+</script>
new file mode 100644
--- /dev/null
+++ b/dom/html/test/bug1315146-main.html
@@ -0,0 +1,15 @@
+<!DOCTYPE HTML>
+<iframe src="http://example.org/tests/dom/html/test/bug1315146-iframe.html"></iframe>
+<input value="test">
+<script>
+document.domain = "example.org";
+onload = function() {
+  let iframe = document.querySelector("iframe");
+  let input = document.querySelector("input");
+  input.selectionStart = input.selectionEnd = 2;
+  document.body.style.overflow = "scroll";
+  iframe.contentDocument.body.offsetWidth;
+  opener.postMessage({start: input.selectionStart,
+                      end: input.selectionEnd}, "*");
+}
+</script>
--- a/dom/html/test/mochitest.ini
+++ b/dom/html/test/mochitest.ini
@@ -35,16 +35,18 @@ support-files =
   bug448564-submit.js
   bug499092.html
   bug499092.xml
   bug514856_iframe.html
   bug1260704_iframe.html
   bug1260704_iframe_empty.html
   bug1292522_iframe.html
   bug1292522_page.html
+  bug1315146-iframe.html
+  bug1315146-main.html
   ../../plugins/test/mochitest/plugin-utils.js
   test_non-ascii-cookie.html^headers^
   file_bug209275_1.html
   file_bug209275_2.html
   file_bug209275_3.html
   file_bug297761.html
   file_bug417760.png
   file_bug893537.html
@@ -598,8 +600,9 @@ skip-if = (os == 'android' || os == 'mac
 skip-if = (os == 'android' || os == 'mac')
 [test_bug1260704.html]
 [test_allowMedia.html]
 [test_bug1292522_same_domain_with_different_port_number.html]
 [test_bug1295719_event_sequence_for_arrow_keys.html]
 skip-if = os == "android" # up/down arrow keys not supported on android
 [test_bug1295719_event_sequence_for_number_keys.html]
 [test_bug1310865.html]
+[test_bug1315146.html]
new file mode 100644
--- /dev/null
+++ b/dom/html/test/test_bug1315146.html
@@ -0,0 +1,33 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1315146
+-->
+<head>
+  <title>Test for Bug 1315146</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1315146">Mozilla Bug 1315146</a>
+<p id="display"></p>
+<div id="content">
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 1315146 **/
+
+SimpleTest.waitForExplicitFinish();
+onmessage = function(e) {
+  win.close();
+  is(e.data.start, 2, "Correct start offset expected");
+  is(e.data.end, 2, "Correct end offset expected");
+  SimpleTest.finish();
+};
+let win = window.open("http://test1.example.org/tests/dom/html/test/bug1315146-main.html", "_blank");
+
+</script>
+</pre>
+</body>
+</html>
--- a/layout/forms/nsTextControlFrame.cpp
+++ b/layout/forms/nsTextControlFrame.cpp
@@ -764,20 +764,21 @@ nsTextControlFrame::SetSelectionInternal
                                          int32_t aEndOffset,
                                          nsITextControlFrame::SelectionDirection aDirection)
 {
   // Create a new range to represent the new selection.
   // Note that we use a new range to avoid having to do
   // isIncreasing checks to avoid possible errors.
 
   RefPtr<nsRange> range = new nsRange(mContent);
-  nsresult rv = range->SetStart(aStartNode, aStartOffset);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  rv = range->SetEnd(aEndNode, aEndOffset);
+  // Be careful to use internal nsRange methods which do not check to make sure
+  // we have access to the node.
+  nsCOMPtr<nsINode> start = do_QueryInterface(aStartNode);
+  nsCOMPtr<nsINode> end = do_QueryInterface(aEndNode);
+  nsresult rv = range->Set(start, aStartOffset, end, aEndOffset);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Get the selection, clear it and add the new range to it!
   nsCOMPtr<nsITextControlElement> txtCtrl = do_QueryInterface(GetContent());
   NS_ASSERTION(txtCtrl, "Content not a text control element");
   nsISelectionController* selCon = txtCtrl->GetSelectionController();
   NS_ENSURE_TRUE(selCon, NS_ERROR_FAILURE);