REGRESSION (r165385): Crash when applying autocorrection exceeds maximum text area...
authorenrica@apple.com <enrica@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 15 Jan 2015 00:18:39 +0000 (00:18 +0000)
committerenrica@apple.com <enrica@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 15 Jan 2015 00:18:39 +0000 (00:18 +0000)
https://bugs.webkit.org/show_bug.cgi?id=137902
rdar://problem/18568864

Reviewed by Darin Adler.

Source/WebCore:

Test: editing/text-iterator/invalid-subrange.html

characterSubrange should check the iterator position after each advance.
This changed adds a new method to the Internals object to be able to test this.

* editing/TextIterator.cpp:
(WebCore::characterSubrange):
(WebCore::TextIterator::subrange):
(WebCore::findPlainText):
* testing/Internals.cpp:
(WebCore::Internals::subrange):
* testing/Internals.h:
* testing/Internals.idl:

LayoutTests:

* editing/text-iterator/invalid-subrange-expected.txt: Added.
* editing/text-iterator/invalid-subrange.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@178462 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/editing/text-iterator/invalid-subrange-expected.txt [new file with mode: 0644]
LayoutTests/editing/text-iterator/invalid-subrange.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/editing/TextIterator.cpp
Source/WebCore/testing/Internals.cpp
Source/WebCore/testing/Internals.h
Source/WebCore/testing/Internals.idl

index 3f4871f..30225f1 100644 (file)
@@ -1,3 +1,14 @@
+2015-01-14  Enrica Casucci  <enrica@apple.com>
+
+        REGRESSION (r165385): Crash when applying autocorrection exceeds maximum text area length.
+        https://bugs.webkit.org/show_bug.cgi?id=137902
+        rdar://problem/18568864
+
+        Reviewed by Darin Adler.
+
+        * editing/text-iterator/invalid-subrange-expected.txt: Added.
+        * editing/text-iterator/invalid-subrange.html: Added.
+
 2015-01-14  Said Abou-Hallawa  <sabouhallawa@apple.com>
 
         REGRESSION (r154769): Wrong <title> taken as a tooltip for SVG element.
diff --git a/LayoutTests/editing/text-iterator/invalid-subrange-expected.txt b/LayoutTests/editing/text-iterator/invalid-subrange-expected.txt
new file mode 100644 (file)
index 0000000..bf44229
--- /dev/null
@@ -0,0 +1,6 @@
+PASS internals.lengthFromRange(container, subrange) is 0
+PASS internals.lengthFromRange(container, subrange) is 0
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/editing/text-iterator/invalid-subrange.html b/LayoutTests/editing/text-iterator/invalid-subrange.html
new file mode 100644 (file)
index 0000000..af6fdd3
--- /dev/null
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../resources/js-test-pre.js"></script>
+</head>
+<body>
+<div id="test" contenteditable>
+<p>hello world.</p>
+</div>
+<div id="console"></div>
+<script>
+
+if (!window.internals)
+    testFailed('This test requires internals object');
+else {
+    var container = document.getElementById('test');
+
+    var p = document.querySelector('#test p');
+    var r = internals.rangeFromLocationAndLength(container, 0, 1);
+    // This offset is valid, the length is past the end of the range
+    var subrange = internals.subrange(r, 5, 100);
+    shouldBe('internals.lengthFromRange(container, subrange)', '0');
+    // This offset is past the end of the range
+    subrange = internals.subrange(r, 100, 1);
+    shouldBe('internals.lengthFromRange(container, subrange)', '0');
+    container.style.display = 'none';
+}
+
+
+</script>
+<script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
index be39889..1f6fe8b 100644 (file)
@@ -1,3 +1,25 @@
+2015-01-14  Enrica Casucci  <enrica@apple.com>
+
+        REGRESSION (r165385): Crash when applying autocorrection exceeds maximum text area length.
+        https://bugs.webkit.org/show_bug.cgi?id=137902
+        rdar://problem/18568864
+
+        Reviewed by Darin Adler.
+
+        Test: editing/text-iterator/invalid-subrange.html
+
+        characterSubrange should check the iterator position after each advance.
+        This changed adds a new method to the Internals object to be able to test this.
+
+        * editing/TextIterator.cpp:
+        (WebCore::characterSubrange):
+        (WebCore::TextIterator::subrange):
+        (WebCore::findPlainText):
+        * testing/Internals.cpp:
+        (WebCore::Internals::subrange):
+        * testing/Internals.h:
+        * testing/Internals.idl:
+
 2015-01-14  Said Abou-Hallawa  <sabouhallawa@apple.com>
 
         REGRESSION (r154769): Wrong <title> taken as a tooltip for SVG element.
index 8a415c8..33f5723 100644 (file)
@@ -1463,16 +1463,22 @@ void CharacterIterator::advance(int count)
     m_runOffset = 0;
 }
 
-static Ref<Range> characterSubrange(CharacterIterator& it, int offset, int length)
+static Ref<Range> characterSubrange(Document& document, CharacterIterator& it, int offset, int length)
 {
     it.advance(offset);
+    if (it.atEnd())
+        return Range::create(document);
+
     Ref<Range> start = it.range();
 
     if (length > 1)
         it.advance(length - 1);
+    if (it.atEnd())
+        return Range::create(document);
+
     Ref<Range> end = it.range();
 
-    return Range::create(start->startContainer()->document(),
+    return Range::create(document,
         start->startContainer(), start->startOffset(), 
         end->endContainer(), end->endOffset());
 }
@@ -2382,7 +2388,7 @@ int TextIterator::rangeLength(const Range* range, bool forSelectionPreservation)
 Ref<Range> TextIterator::subrange(Range* entireRange, int characterOffset, int characterCount)
 {
     CharacterIterator entireRangeIterator(*entireRange);
-    return characterSubrange(entireRangeIterator, characterOffset, characterCount);
+    return characterSubrange(entireRange->ownerDocument(), entireRangeIterator, characterOffset, characterCount);
 }
 
 static inline bool isInsideReplacedElement(TextIterator& iterator)
@@ -2602,7 +2608,7 @@ Ref<Range> findPlainText(const Range& range, const String& target, FindOptions o
 
     // Then, find the document position of the start and the end of the text.
     CharacterIterator computeRangeIterator(range, TextIteratorEntersTextControls);
-    return characterSubrange(computeRangeIterator, matchStart, matchLength);
+    return characterSubrange(range.ownerDocument(), computeRangeIterator, matchStart, matchLength);
 }
 
 }
index db10370..98bffe6 100644 (file)
@@ -1078,6 +1078,16 @@ String Internals::rangeAsText(const Range* range, ExceptionCode& ec)
     return range->text();
 }
 
+PassRefPtr<Range> Internals::subrange(Range* range, int rangeLocation, int rangeLength, ExceptionCode& ec)
+{
+    if (!range) {
+        ec = INVALID_ACCESS_ERR;
+        return 0;
+    }
+
+    return TextIterator::subrange(range, rangeLocation, rangeLength);
+}
+
 void Internals::setDelegatesScrolling(bool enabled, ExceptionCode& ec)
 {
     Document* document = contextDocument();
index f100bf3..478d265 100644 (file)
@@ -158,6 +158,7 @@ public:
     unsigned locationFromRange(Element* scope, const Range*, ExceptionCode&);
     unsigned lengthFromRange(Element* scope, const Range*, ExceptionCode&);
     String rangeAsText(const Range*, ExceptionCode&);
+    PassRefPtr<Range> subrange(Range* range, int rangeLocation, int rangeLength, ExceptionCode&);
 
     void setDelegatesScrolling(bool enabled, ExceptionCode&);
 
index 433044a..1672fbe 100644 (file)
@@ -121,6 +121,7 @@ enum PageOverlayType {
     [RaisesException] unsigned long locationFromRange(Element scope, Range range);
     [RaisesException] unsigned long lengthFromRange(Element scope, Range range);
     [RaisesException] DOMString rangeAsText(Range range);
+    [RaisesException] Range subrange(Range range, long rangeLocation, long rangeLength);
 
     [RaisesException] void setDelegatesScrolling(boolean enabled);