[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc

darin at apple.com darin at apple.com
Wed Dec 22 13:24:59 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit ee07de264af0df5331135587f653c2634ad4127b
Author: darin at apple.com <darin at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Tue Sep 14 21:10:18 2010 +0000

    2010-09-14  Darin Adler  <darin at apple.com>
    
            Reviewed by Geoffrey Garen.
    
            Hang processing href attribute containing a million slashes
            https://bugs.webkit.org/show_bug.cgi?id=45767
    
            Test: fast/css/visited-link-hang.html
    
            * platform/LinkHash.cpp:
            (WebCore::findSlashDotDotSlash): Added a start position argument and
            changed types to use size_t consistently instead of a mix.
            (WebCore::findSlashSlash): Ditto.
            (WebCore::findSlashDotSlash): Ditto.
            (WebCore::squeezeOutNullCharacters): Added.
            (WebCore::cleanSlashDotDotSlashes): Added. Factored out part
            of cleanPath (see below).
            (WebCore::mergeDoubleSlashes): Ditto.
            (WebCore::cleanSlashDotSlashes): Ditto.
            (WebCore::cleanPath): Changed algorithm to not remove as we go to
            avoid N^2 behavior; instead replace with null characters and then
            do a squeeze operation after the fact. Also moved the body of the
            function out of line since we normally don't have to do any cleaning.
            This whole thing should go at some point -- it's not the right
            algorithm -- but this should eliminate the performance problems
            without changing behavior.
    2010-09-14  Darin Adler  <darin at apple.com>
    
            Reviewed by Geoffrey Garen.
    
            Hang processing href attribute containing a million slashes
            https://bugs.webkit.org/show_bug.cgi?id=45767
    
            * fast/css/visited-link-hang-expected.txt: Added.
            * fast/css/visited-link-hang.html: Added.
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@67496 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index ae87476..330d0e2 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -2,6 +2,16 @@
 
         Reviewed by Geoffrey Garen.
 
+        Hang processing href attribute containing a million slashes
+        https://bugs.webkit.org/show_bug.cgi?id=45767
+
+        * fast/css/visited-link-hang-expected.txt: Added.
+        * fast/css/visited-link-hang.html: Added.
+
+2010-09-14  Darin Adler  <darin at apple.com>
+
+        Reviewed by Geoffrey Garen.
+
         Sort with non-numeric custom sort function fails on array with length but no values
         https://bugs.webkit.org/show_bug.cgi?id=45781
 
diff --git a/LayoutTests/fast/css/visited-link-hang-expected.txt b/LayoutTests/fast/css/visited-link-hang-expected.txt
new file mode 100644
index 0000000..27c7a7f
--- /dev/null
+++ b/LayoutTests/fast/css/visited-link-hang-expected.txt
@@ -0,0 +1,3 @@
+The URL of this link has a ton of slashes.
+
+If this test runs without hanging, then it passes. The visited link hash algorithm was N^2 at one point and would hang.
diff --git a/LayoutTests/fast/css/visited-link-hang.html b/LayoutTests/fast/css/visited-link-hang.html
new file mode 100644
index 0000000..f311f70
--- /dev/null
+++ b/LayoutTests/fast/css/visited-link-hang.html
@@ -0,0 +1,30 @@
+<p>If this test runs without hanging, then it has passed. The visited link hash algorithm was N^2 at one point and would hang.</p>
+<p id="test1"></p>
+<p id="test2"></p>
+<p id="test3"></p>
+<p id="result">TEST DID NOT RUN YET</p>
+
+<script>
+
+if (window.layoutTestController)
+    layoutTestController.dumpAsText();
+
+var oneMillionSlashes = "";
+for (i = 0; i < 1000000; ++i)
+    oneMillionSlashes += "/";
+
+var oneMillionSlashesAndDots = "";
+for (i = 0; i < 333334; ++i)
+    oneMillionSlashesAndDots += "/./";
+
+var oneMillionSlashesAndDoubleDots = "";
+for (i = 0; i < 250000; ++i)
+    oneMillionSlashesAndDoubleDots += "/../";
+
+document.getElementById("test1").innerHTML = '<a href="about:test?slashes' + oneMillionSlashes + '">Link with tons of slashes</a>';
+document.getElementById("test2").innerHTML = '<a href="about:test?slashes' + oneMillionSlashesAndDots + '">Link with tons of slashes with dots</a>';
+document.getElementById("test3").innerHTML = '<a href="about:test?slashes' + oneMillionSlashesAndDoubleDots + '">Link with tons of slashes with double dots</a>';
+
+document.getElementById("result").firstChild.data = "TEST PASSED";
+
+</script>
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 1dff5d6..73063aa 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,30 @@
+2010-09-14  Darin Adler  <darin at apple.com>
+
+        Reviewed by Geoffrey Garen.
+
+        Hang processing href attribute containing a million slashes
+        https://bugs.webkit.org/show_bug.cgi?id=45767
+
+        Test: fast/css/visited-link-hang.html
+
+        * platform/LinkHash.cpp:
+        (WebCore::findSlashDotDotSlash): Added a start position argument and
+        changed types to use size_t consistently instead of a mix.
+        (WebCore::findSlashSlash): Ditto.
+        (WebCore::findSlashDotSlash): Ditto.
+        (WebCore::squeezeOutNullCharacters): Added.
+        (WebCore::cleanSlashDotDotSlashes): Added. Factored out part
+        of cleanPath (see below).
+        (WebCore::mergeDoubleSlashes): Ditto.
+        (WebCore::cleanSlashDotSlashes): Ditto.
+        (WebCore::cleanPath): Changed algorithm to not remove as we go to
+        avoid N^2 behavior; instead replace with null characters and then
+        do a squeeze operation after the fact. Also moved the body of the
+        function out of line since we normally don't have to do any cleaning.
+        This whole thing should go at some point -- it's not the right
+        algorithm -- but this should eliminate the performance problems
+        without changing behavior.
+
 2010-09-14  Nico Weber  <thakis at chromium.org>
 
         Reviewed by Kenneth Russell.
diff --git a/WebCore/platform/LinkHash.cpp b/WebCore/platform/LinkHash.cpp
index 86b4c8a..ac3aa3c 100644
--- a/WebCore/platform/LinkHash.cpp
+++ b/WebCore/platform/LinkHash.cpp
@@ -31,36 +31,36 @@
 
 namespace WebCore {
 
-static inline size_t findSlashDotDotSlash(const UChar* characters, size_t length)
+static inline size_t findSlashDotDotSlash(const UChar* characters, size_t length, size_t position)
 {
     if (length < 4)
         return notFound;
-    unsigned loopLimit = length - 3;
-    for (unsigned i = 0; i < loopLimit; ++i) {
+    size_t loopLimit = length - 3;
+    for (size_t i = position; i < loopLimit; ++i) {
         if (characters[i] == '/' && characters[i + 1] == '.' && characters[i + 2] == '.' && characters[i + 3] == '/')
             return i;
     }
     return notFound;
 }
 
-static inline size_t findSlashSlash(const UChar* characters, size_t length, int position)
+static inline size_t findSlashSlash(const UChar* characters, size_t length, size_t position)
 {
     if (length < 2)
         return notFound;
-    unsigned loopLimit = length - 1;
-    for (unsigned i = position; i < loopLimit; ++i) {
+    size_t loopLimit = length - 1;
+    for (size_t i = position; i < loopLimit; ++i) {
         if (characters[i] == '/' && characters[i + 1] == '/')
             return i;
     }
     return notFound;
 }
 
-static inline size_t findSlashDotSlash(const UChar* characters, size_t length)
+static inline size_t findSlashDotSlash(const UChar* characters, size_t length, size_t position)
 {
     if (length < 3)
         return notFound;
-    unsigned loopLimit = length - 2;
-    for (unsigned i = 0; i < loopLimit; ++i) {
+    size_t loopLimit = length - 2;
+    for (size_t i = position; i < loopLimit; ++i) {
         if (characters[i] == '/' && characters[i + 1] == '.' && characters[i + 2] == '/')
             return i;
     }
@@ -79,38 +79,90 @@ static inline bool containsColonSlashSlash(const UChar* characters, unsigned len
     return false;
 }
 
-static inline void cleanPath(Vector<UChar, 512>& path)
+static inline void squeezeOutNullCharacters(Vector<UChar, 512>& string)
 {
-    // FIXME: Should not do this in the query or anchor part.
-    size_t pos;
-    while ((pos = findSlashDotDotSlash(path.data(), path.size())) != notFound) {
-        size_t prev = reverseFind(path.data(), path.size(), '/', pos - 1);
-        // don't remove the host, i.e. http://foo.org/../foo.html
-        if (prev == notFound || (prev > 3 && path[prev - 2] == ':' && path[prev - 1] == '/'))
-            path.remove(pos, 3);
-        else
-            path.remove(prev, pos - prev + 3);
+    size_t size = string.size();
+    size_t i = 0;
+    for (i = 0; i < size; ++i) {
+        if (!string[i])
+            break;
     }
+    if (i == size)
+        return;
+    size_t j = i;
+    for (++i; i < size; ++i) {
+        if (UChar character = string[i])
+            string[j++] = character;
+    }
+    ASSERT(j < size);
+    string.shrink(j);
+}
 
-    // FIXME: Should not do this in the query part.
-    pos = 0;
-    if ((pos = findSlashSlash(path.data(), path.size(), pos)) != notFound) {
-        size_t refPos = find(path.data(), path.size(), '#');
-        while (refPos == 0 || refPos == notFound || pos < refPos) {
-            if (pos == 0 || path[pos - 1] != ':')
-                path.remove(pos);
-            else
-                pos += 2;
-            if ((pos = findSlashSlash(path.data(), path.size(), pos)) == notFound)
-                break;
+static void cleanSlashDotDotSlashes(Vector<UChar, 512>& path, size_t firstSlash)
+{
+    size_t slash = firstSlash;
+    do {
+        size_t previousSlash = slash ? reverseFind(path.data(), path.size(), '/', slash - 1) : notFound;
+        // Don't remove the host, i.e. http://foo.org/../foo.html
+        if (previousSlash == notFound || (previousSlash > 3 && path[previousSlash - 2] == ':' && path[previousSlash - 1] == '/')) {
+            path[slash] = 0;
+            path[slash + 1] = 0;
+            path[slash + 2] = 0;
+        } else {
+            for (size_t i = previousSlash; i < slash + 3; ++i)
+                path[i] = 0;
         }
+        slash += 3;
+    } while ((slash = findSlashDotDotSlash(path.data(), path.size(), slash)) != notFound);
+    squeezeOutNullCharacters(path);
+}
+
+static void mergeDoubleSlashes(Vector<UChar, 512>& path, size_t firstSlash)
+{
+    size_t refPos = find(path.data(), path.size(), '#');
+    if (!refPos || refPos == notFound)
+        refPos = path.size();
+
+    size_t slash = firstSlash;
+    while (slash < refPos) {
+        if (!slash || path[slash - 1] != ':')
+            path[slash++] = 0;
+        else
+            slash += 2;
+        if ((slash = findSlashSlash(path.data(), path.size(), slash)) == notFound)
+            break;
     }
+    squeezeOutNullCharacters(path);
+}
 
-    // FIXME: Should not do this in the query or anchor part.
-    while ((pos = findSlashDotSlash(path.data(), path.size())) != notFound)
-        path.remove(pos, 2);
+static void cleanSlashDotSlashes(Vector<UChar, 512>& path, size_t firstSlash)
+{
+    size_t slash = firstSlash;
+    do {
+        path[slash] = 0;
+        path[slash + 1] = 0;
+        slash += 2;
+    } while ((slash = findSlashDotSlash(path.data(), path.size(), slash)) != notFound);
+    squeezeOutNullCharacters(path);
 }
 
+static inline void cleanPath(Vector<UChar, 512>& path)
+{
+    // FIXME: Should not do this in the query or anchor part of the URL.
+    size_t firstSlash = findSlashDotDotSlash(path.data(), path.size(), 0);
+    if (firstSlash != notFound)
+        cleanSlashDotDotSlashes(path, firstSlash);
+
+    // FIXME: Should not do this in the query part.
+    firstSlash = findSlashSlash(path.data(), path.size(), 0);
+    if (firstSlash != notFound)
+        mergeDoubleSlashes(path, firstSlash);
+
+    // FIXME: Should not do this in the query or anchor part.
+    firstSlash = findSlashDotSlash(path.data(), path.size(), 0);
+    if (firstSlash != notFound)
+        cleanSlashDotSlashes(path, firstSlash);
+}
 
 static inline bool matchLetter(UChar c, UChar lowercaseLetter)
 {

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list