WebCore:
authordarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 5 Jan 2009 19:50:37 +0000 (19:50 +0000)
committerdarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 5 Jan 2009 19:50:37 +0000 (19:50 +0000)
2009-01-05  Darin Adler  <darin@apple.com>

        Reviewed by Dan Bernstein.

        Bug 23109: REGRESSION: Backwards search in a long document matches incorrectly
        https://bugs.webkit.org/show_bug.cgi?id=23109

        Test: fast/text/find-backwards.html

        * editing/TextIterator.cpp:
        (WebCore::SearchBuffer::append): Fix incorrect size passed to memcpy.
        (WebCore::SearchBuffer::search): Handle case where we have an empty buffer but
        we're at a break; must not try to search because ICU will give us an error.
        Fix incorrect size passed to memcpy and memmove.
        (WebCore::findPlainText): Fix case where we found a match and need to search
        again because we want to find the last match. We need to try again without
        adding any more text or handling the break before moving on.

LayoutTests:

2009-01-05  Darin Adler  <darin@apple.com>

        Reviewed by Dan Bernstein.

        Bug 23109: REGRESSION: Backwards search in a long document matches incorrectly
        https://bugs.webkit.org/show_bug.cgi?id=23109

        * fast/text/find-backwards-expected.txt: Added.
        * fast/text/find-backwards.html: Added.
        * fast/text/resources/TEMPLATE.html: Copied from fast/js/resources/TEMPLATE.html.
        * fast/text/resources/find-backwards.js: Added.

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

LayoutTests/ChangeLog
LayoutTests/fast/text/find-backwards-expected.txt [new file with mode: 0644]
LayoutTests/fast/text/find-backwards.html [new file with mode: 0644]
LayoutTests/fast/text/resources/TEMPLATE.html [new file with mode: 0644]
LayoutTests/fast/text/resources/find-backwards.js [new file with mode: 0644]
WebCore/ChangeLog
WebCore/editing/TextIterator.cpp

index 450a5f4..976b1ac 100644 (file)
@@ -1,5 +1,17 @@
 2009-01-05  Darin Adler  <darin@apple.com>
 
+        Reviewed by Dan Bernstein.
+
+        Bug 23109: REGRESSION: Backwards search in a long document matches incorrectly
+        https://bugs.webkit.org/show_bug.cgi?id=23109
+
+        * fast/text/find-backwards-expected.txt: Added.
+        * fast/text/find-backwards.html: Added.
+        * fast/text/resources/TEMPLATE.html: Copied from fast/js/resources/TEMPLATE.html.
+        * fast/text/resources/find-backwards.js: Added.
+
+2009-01-05  Darin Adler  <darin@apple.com>
+
         Reviewed by Anders Carlsson.
 
         Bug 23104: minor mistakes in init functions for animation and transition events
diff --git a/LayoutTests/fast/text/find-backwards-expected.txt b/LayoutTests/fast/text/find-backwards-expected.txt
new file mode 100644 (file)
index 0000000..370c55f
--- /dev/null
@@ -0,0 +1,33 @@
+Tests find going both forward and backwards in small and large documents.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS testFind('abc', 'a', forward) is '0, 1'
+PASS testFind('abc', 'b', forward) is '1, 2'
+PASS testFind('abc', 'c', forward) is '2, 3'
+PASS testFind('abc', 'a', backward) is '0, 1'
+PASS testFind('abc', 'b', backward) is '1, 2'
+PASS testFind('abc', 'c', backward) is '2, 3'
+PASS testFind(tenThousandCharacters + 'abc' + tenThousandCharacters, 'a', forward) is '10000, 10001'
+PASS testFind(tenThousandCharacters + 'abc' + tenThousandCharacters, 'b', forward) is '10001, 10002'
+PASS testFind(tenThousandCharacters + 'abc' + tenThousandCharacters, 'c', forward) is '10002, 10003'
+PASS testFind(tenThousandCharacters + 'abc' + tenThousandCharacters, 'a', backward) is '10000, 10001'
+PASS testFind(tenThousandCharacters + 'abc' + tenThousandCharacters, 'b', backward) is '10001, 10002'
+PASS testFind(tenThousandCharacters + 'abc' + tenThousandCharacters, 'c', backward) is '10002, 10003'
+PASS testFind('abcabc', 'a', forward) is '0, 1'
+PASS testFind('abcabc', 'b', forward) is '1, 2'
+PASS testFind('abcabc', 'c', forward) is '2, 3'
+PASS testFind('abcabc', 'a', backward) is '3, 4'
+PASS testFind('abcabc', 'b', backward) is '4, 5'
+PASS testFind('abcabc', 'c', backward) is '5, 6'
+PASS testFind(tenThousandCharacters + 'abcabc' + tenThousandCharacters, 'a', forward) is '10000, 10001'
+PASS testFind(tenThousandCharacters + 'abcabc' + tenThousandCharacters, 'b', forward) is '10001, 10002'
+PASS testFind(tenThousandCharacters + 'abcabc' + tenThousandCharacters, 'c', forward) is '10002, 10003'
+PASS testFind(tenThousandCharacters + 'abcabc' + tenThousandCharacters, 'a', backward) is '10003, 10004'
+PASS testFind(tenThousandCharacters + 'abcabc' + tenThousandCharacters, 'b', backward) is '10004, 10005'
+PASS testFind(tenThousandCharacters + 'abcabc' + tenThousandCharacters, 'c', backward) is '10005, 10006'
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/text/find-backwards.html b/LayoutTests/fast/text/find-backwards.html
new file mode 100644 (file)
index 0000000..06089c8
--- /dev/null
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href="../js/resources/js-test-style.css">
+<script src="../js/resources/js-test-pre.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script src="resources/find-backwards.js"></script>
+<script src="../js/resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/fast/text/resources/TEMPLATE.html b/LayoutTests/fast/text/resources/TEMPLATE.html
new file mode 100644 (file)
index 0000000..1936e0d
--- /dev/null
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href="../js/resources/js-test-style.css">
+<script src="../js/resources/js-test-pre.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script src="YOUR_JS_FILE_HERE"></script>
+<script src="../js/resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/fast/text/resources/find-backwards.js b/LayoutTests/fast/text/resources/find-backwards.js
new file mode 100644 (file)
index 0000000..54963c0
--- /dev/null
@@ -0,0 +1,70 @@
+description("Tests find going both forward and backwards in small and large documents.");
+
+var selection = getSelection();
+
+function testFind(subjectString, pattern, backwards)
+{
+    var textNode = document.createTextNode(subjectString);
+    document.body.appendChild(textNode);
+    selection.removeAllRanges();
+    if (backwards) {
+        var afterTextNodeRange = document.createRange();
+        afterTextNodeRange.setStartAfter(textNode);
+        afterTextNodeRange.setEndAfter(textNode);
+        selection.addRange(afterTextNodeRange);
+    } else {
+        var beforeTextNodeRange = document.createRange();
+        beforeTextNodeRange.setStartBefore(textNode);
+        beforeTextNodeRange.setEndBefore(textNode);
+        selection.addRange(beforeTextNodeRange);
+    }
+    var result;
+    if (!find(pattern, false, backwards))
+        result = "not found"
+    else if (selection.rangeCount != 1)
+        result = "internal inconsistency";
+    else {
+        var resultRange = selection.getRangeAt(0);
+        if (resultRange.startContainer !== textNode || resultRange.endContainer !== textNode)
+            result = "not found";
+        else
+            result = resultRange.startOffset + ", " + resultRange.endOffset;
+    }
+    document.body.removeChild(textNode);
+    return result;
+}
+
+var forward = false;
+var backward = true;
+
+var manyCharacters = "1234567890"
+for (i = 0; i < 10; ++i)
+    manyCharacters += manyCharacters;
+var tenThousandCharacters = manyCharacters.substring(0, 10000);
+
+shouldBe("testFind('abc', 'a', forward)", "'0, 1'");
+shouldBe("testFind('abc', 'b', forward)", "'1, 2'");
+shouldBe("testFind('abc', 'c', forward)", "'2, 3'");
+shouldBe("testFind('abc', 'a', backward)", "'0, 1'");
+shouldBe("testFind('abc', 'b', backward)", "'1, 2'");
+shouldBe("testFind('abc', 'c', backward)", "'2, 3'");
+shouldBe("testFind(tenThousandCharacters + 'abc' + tenThousandCharacters, 'a', forward)", "'10000, 10001'");
+shouldBe("testFind(tenThousandCharacters + 'abc' + tenThousandCharacters, 'b', forward)", "'10001, 10002'");
+shouldBe("testFind(tenThousandCharacters + 'abc' + tenThousandCharacters, 'c', forward)", "'10002, 10003'");
+shouldBe("testFind(tenThousandCharacters + 'abc' + tenThousandCharacters, 'a', backward)", "'10000, 10001'");
+shouldBe("testFind(tenThousandCharacters + 'abc' + tenThousandCharacters, 'b', backward)", "'10001, 10002'");
+shouldBe("testFind(tenThousandCharacters + 'abc' + tenThousandCharacters, 'c', backward)", "'10002, 10003'");
+shouldBe("testFind('abcabc', 'a', forward)", "'0, 1'");
+shouldBe("testFind('abcabc', 'b', forward)", "'1, 2'");
+shouldBe("testFind('abcabc', 'c', forward)", "'2, 3'");
+shouldBe("testFind('abcabc', 'a', backward)", "'3, 4'");
+shouldBe("testFind('abcabc', 'b', backward)", "'4, 5'");
+shouldBe("testFind('abcabc', 'c', backward)", "'5, 6'");
+shouldBe("testFind(tenThousandCharacters + 'abcabc' + tenThousandCharacters, 'a', forward)", "'10000, 10001'");
+shouldBe("testFind(tenThousandCharacters + 'abcabc' + tenThousandCharacters, 'b', forward)", "'10001, 10002'");
+shouldBe("testFind(tenThousandCharacters + 'abcabc' + tenThousandCharacters, 'c', forward)", "'10002, 10003'");
+shouldBe("testFind(tenThousandCharacters + 'abcabc' + tenThousandCharacters, 'a', backward)", "'10003, 10004'");
+shouldBe("testFind(tenThousandCharacters + 'abcabc' + tenThousandCharacters, 'b', backward)", "'10004, 10005'");
+shouldBe("testFind(tenThousandCharacters + 'abcabc' + tenThousandCharacters, 'c', backward)", "'10005, 10006'");
+
+var successfullyParsed = true;
index 245ac49..ff150de 100644 (file)
@@ -1,3 +1,21 @@
+2009-01-05  Darin Adler  <darin@apple.com>
+
+        Reviewed by Dan Bernstein.
+
+        Bug 23109: REGRESSION: Backwards search in a long document matches incorrectly
+        https://bugs.webkit.org/show_bug.cgi?id=23109
+
+        Test: fast/text/find-backwards.html
+
+        * editing/TextIterator.cpp:
+        (WebCore::SearchBuffer::append): Fix incorrect size passed to memcpy.
+        (WebCore::SearchBuffer::search): Handle case where we have an empty buffer but
+        we're at a break; must not try to search because ICU will give us an error.
+        Fix incorrect size passed to memcpy and memmove.
+        (WebCore::findPlainText): Fix case where we found a match and need to search
+        again because we want to find the last match. We need to try again without
+        adding any more text or handling the break before moving on.
+
 2009-01-05  Adam Treat  <treat@kde.org>
 
         Fix the Qt build
index fe38c40..c14c455 100644 (file)
@@ -1259,7 +1259,7 @@ inline size_t SearchBuffer::append(const UChar* characters, size_t length)
         m_buffer.shrink(0);
         m_atBreak = false;
     } else if (m_buffer.size() == m_buffer.capacity()) {
-        memcpy(m_buffer.data(), m_buffer.data() + m_buffer.size() - m_overlap, m_overlap);
+        memcpy(m_buffer.data(), m_buffer.data() + m_buffer.size() - m_overlap, m_overlap * sizeof(UChar));
         m_buffer.shrink(m_overlap);
     }
 
@@ -1282,8 +1282,13 @@ inline void SearchBuffer::reachedBreak()
 inline size_t SearchBuffer::search(size_t& start)
 {
     size_t size = m_buffer.size();
-    if (!m_atBreak && size < m_buffer.capacity())
-        return 0;
+    if (m_atBreak) {
+        if (!size)
+            return 0;
+    } else {
+        if (size != m_buffer.capacity())
+            return 0;
+    }
 
     UStringSearch* searcher = WebCore::searcher();
 
@@ -1302,13 +1307,13 @@ inline size_t SearchBuffer::search(size_t& start)
     // The same match may appear later, matching more characters,
     // possibly including a combining character that's not yet in the buffer.
     if (!m_atBreak && static_cast<size_t>(matchStart) >= size - m_overlap) {
-        memcpy(m_buffer.data(), m_buffer.data() + size - m_overlap, m_overlap);
+        memcpy(m_buffer.data(), m_buffer.data() + size - m_overlap, m_overlap * sizeof(UChar));
         m_buffer.shrink(m_overlap);
         return 0;
     }
 
     size_t newSize = size - (matchStart + 1);
-    memmove(m_buffer.data(), m_buffer.data() + matchStart + 1, newSize);
+    memmove(m_buffer.data(), m_buffer.data() + matchStart + 1, newSize * sizeof(UChar));
     m_buffer.shrink(newSize);
 
     start = size - matchStart;
@@ -1628,6 +1633,7 @@ tryAgain:
             // If searching backward, don't stop, so we end up with the last match.
             if (forward)
                 break;
+            goto tryAgain;
         }
         if (it.atBreak() && !buffer.atBreak()) {
             buffer.reachedBreak();