<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[209857] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/209857">209857</a></dd>
<dt>Author</dt> <dd>achristensen@apple.com</dd>
<dt>Date</dt> <dd>2016-12-15 00:19:47 -0800 (Thu, 15 Dec 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>REGRESSION (<a href="http://trac.webkit.org/projects/webkit/changeset/208902">r208902</a>) Null pointer dereference in wkIsPublicSuffix
https://bugs.webkit.org/show_bug.cgi?id=165885
&lt;rdar://problem/29476917&gt;

Reviewed by Darin Adler.

Source/WebCore:

wkIsPublicSuffix crashes if you give it a nil NSString*.
This was possible before IDN2008 adoption, but it's more common now
because domains like &quot;<a href="http://trac.webkit.org/projects/webkit/changeset/4">r4</a>---asdf.example.com&quot; fail in uidna_nameToASCII but not in uidna_IDNToASCII.
decodeHostName can return a nil NSString.  We can't use it unchecked, so instead we use an algorithm that allows
for decoding failures while still finding top privately controlled domains correctly.

Tested by new API tests which crash before this change and verify the behavior matches behavior before <a href="http://trac.webkit.org/projects/webkit/changeset/208902">r208902</a>.

* platform/mac/PublicSuffixMac.mm:
(WebCore::isPublicSuffix):
(WebCore::topPrivatelyControlledDomain):

Tools:

* TestWebKitAPI/Tests/WebCore/URLParser.cpp:
(TestWebKitAPI::utf16String): Deleted.
* TestWebKitAPI/Tests/mac/PublicSuffix.mm:
(TestWebKitAPI::TEST_F):
* TestWebKitAPI/WTFStringUtilities.h:
(utf16String):
Moved from URLParser to share with other tests.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreplatformmacPublicSuffixMacmm">trunk/Source/WebCore/platform/mac/PublicSuffixMac.mm</a></li>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsTestWebKitAPITestsWebCoreURLParsercpp">trunk/Tools/TestWebKitAPI/Tests/WebCore/URLParser.cpp</a></li>
<li><a href="#trunkToolsTestWebKitAPITestsmacPublicSuffixmm">trunk/Tools/TestWebKitAPI/Tests/mac/PublicSuffix.mm</a></li>
<li><a href="#trunkToolsTestWebKitAPIWTFStringUtilitiesh">trunk/Tools/TestWebKitAPI/WTFStringUtilities.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (209856 => 209857)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-12-15 08:17:17 UTC (rev 209856)
+++ trunk/Source/WebCore/ChangeLog        2016-12-15 08:19:47 UTC (rev 209857)
</span><span class="lines">@@ -1,5 +1,25 @@
</span><span class="cx"> 2016-12-15  Alex Christensen  &lt;achristensen@webkit.org&gt;
</span><span class="cx"> 
</span><ins>+        REGRESSION (r208902) Null pointer dereference in wkIsPublicSuffix
+        https://bugs.webkit.org/show_bug.cgi?id=165885
+        &lt;rdar://problem/29476917&gt;
+
+        Reviewed by Darin Adler.
+
+        wkIsPublicSuffix crashes if you give it a nil NSString*.
+        This was possible before IDN2008 adoption, but it's more common now
+        because domains like &quot;r4---asdf.example.com&quot; fail in uidna_nameToASCII but not in uidna_IDNToASCII.
+        decodeHostName can return a nil NSString.  We can't use it unchecked, so instead we use an algorithm that allows
+        for decoding failures while still finding top privately controlled domains correctly.
+
+        Tested by new API tests which crash before this change and verify the behavior matches behavior before r208902.
+
+        * platform/mac/PublicSuffixMac.mm:
+        (WebCore::isPublicSuffix):
+        (WebCore::topPrivatelyControlledDomain):
+
+2016-12-15  Alex Christensen  &lt;achristensen@webkit.org&gt;
+
</ins><span class="cx">         Fix Windows WebGL build after r209832
</span><span class="cx"> 
</span><span class="cx">         * CMakeLists.txt:
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmacPublicSuffixMacmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mac/PublicSuffixMac.mm (209856 => 209857)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mac/PublicSuffixMac.mm        2016-12-15 08:17:17 UTC (rev 209856)
+++ trunk/Source/WebCore/platform/mac/PublicSuffixMac.mm        2016-12-15 08:19:47 UTC (rev 209857)
</span><span class="lines">@@ -39,39 +39,21 @@
</span><span class="cx"> 
</span><span class="cx"> bool isPublicSuffix(const String&amp; domain)
</span><span class="cx"> {
</span><del>-    return wkIsPublicSuffix(decodeHostName(domain));
</del><ins>+    NSString *host = decodeHostName(domain);
+    return host &amp;&amp; wkIsPublicSuffix(host);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> String topPrivatelyControlledDomain(const String&amp; domain)
</span><span class="cx"> {
</span><del>-    if (domain.isNull() || domain.isEmpty())
-        return String();
-
-    NSString *host = decodeHostName(domain);
-
-    if ([host _web_looksLikeIPAddress])
</del><ins>+    if ([domain _web_looksLikeIPAddress])
</ins><span class="cx">         return domain;
</span><span class="cx"> 
</span><del>-    // Match the longest possible suffix.
-    bool hasTopLevelDomain = false;
-    NSCharacterSet *dot = [[NSCharacterSet characterSetWithCharactersInString:@&quot;.&quot;] retain];
-    NSRange nextDot = NSMakeRange(0, [host length]);
-    for (NSRange previousDot = [host rangeOfCharacterFromSet:dot]; previousDot.location != NSNotFound; nextDot = previousDot, previousDot = [host rangeOfCharacterFromSet:dot options:0 range:NSMakeRange(previousDot.location + previousDot.length, [host length] - (previousDot.location + previousDot.length))]) {
-        NSString *substring = [host substringFromIndex:previousDot.location + previousDot.length];
-        if (wkIsPublicSuffix(substring)) {
-            hasTopLevelDomain = true;
-            break;
-        }
</del><ins>+    size_t separatorPosition;
+    for (unsigned labelStart = 0; (separatorPosition = domain.find('.', labelStart)) != notFound; labelStart = separatorPosition + 1) {
+        if (isPublicSuffix(domain.substring(separatorPosition + 1)))
+            return domain.substring(labelStart);
</ins><span class="cx">     }
</span><del>-
-    [dot release];
-    if (!hasTopLevelDomain)
-        return String();
-
-    if (!nextDot.location)
-        return domain;
-
-    return encodeHostName([host substringFromIndex:nextDot.location + nextDot.length]);
</del><ins>+    return String();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (209856 => 209857)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog        2016-12-15 08:17:17 UTC (rev 209856)
+++ trunk/Tools/ChangeLog        2016-12-15 08:19:47 UTC (rev 209857)
</span><span class="lines">@@ -1,3 +1,19 @@
</span><ins>+2016-12-15  Alex Christensen  &lt;achristensen@webkit.org&gt;
+
+        REGRESSION (r208902) Null pointer dereference in wkIsPublicSuffix
+        https://bugs.webkit.org/show_bug.cgi?id=165885
+        &lt;rdar://problem/29476917&gt;
+
+        Reviewed by Darin Adler.
+
+        * TestWebKitAPI/Tests/WebCore/URLParser.cpp:
+        (TestWebKitAPI::utf16String): Deleted.
+        * TestWebKitAPI/Tests/mac/PublicSuffix.mm:
+        (TestWebKitAPI::TEST_F):
+        * TestWebKitAPI/WTFStringUtilities.h:
+        (utf16String):
+        Moved from URLParser to share with other tests.
+
</ins><span class="cx"> 2016-12-14  Ryosuke Niwa  &lt;rniwa@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         iOS: An element with tabindex is not focusable unless there is no mouse event handler
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPITestsWebCoreURLParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Tools/TestWebKitAPI/Tests/WebCore/URLParser.cpp (209856 => 209857)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/Tests/WebCore/URLParser.cpp        2016-12-15 08:17:17 UTC (rev 209856)
+++ trunk/Tools/TestWebKitAPI/Tests/WebCore/URLParser.cpp        2016-12-15 08:19:47 UTC (rev 209857)
</span><span class="lines">@@ -24,6 +24,7 @@
</span><span class="cx">  */
</span><span class="cx"> 
</span><span class="cx"> #include &quot;config.h&quot;
</span><ins>+#include &quot;WTFStringUtilities.h&quot;
</ins><span class="cx"> #include &lt;WebCore/URLParser.h&gt;
</span><span class="cx"> #include &lt;wtf/MainThread.h&gt;
</span><span class="cx"> #include &lt;wtf/text/StringBuilder.h&gt;
</span><span class="lines">@@ -325,16 +326,6 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-template&lt;size_t length&gt;
-static String utf16String(const char16_t (&amp;url)[length])
-{
-    StringBuilder builder;
-    builder.reserveCapacity(length - 1);
-    for (size_t i = 0; i &lt; length - 1; ++i)
-        builder.append(static_cast&lt;UChar&gt;(url[i]));
-    return builder.toString();
-}
-
</del><span class="cx"> TEST_F(URLParserTest, Basic)
</span><span class="cx"> {
</span><span class="cx">     checkURL(&quot;http://user:pass@webkit.org:123/path?query#fragment&quot;, {&quot;http&quot;, &quot;user&quot;, &quot;pass&quot;, &quot;webkit.org&quot;, 123, &quot;/path&quot;, &quot;query&quot;, &quot;fragment&quot;, &quot;http://user:pass@webkit.org:123/path?query#fragment&quot;});
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPITestsmacPublicSuffixmm"></a>
<div class="modfile"><h4>Modified: trunk/Tools/TestWebKitAPI/Tests/mac/PublicSuffix.mm (209856 => 209857)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/Tests/mac/PublicSuffix.mm        2016-12-15 08:17:17 UTC (rev 209856)
+++ trunk/Tools/TestWebKitAPI/Tests/mac/PublicSuffix.mm        2016-12-15 08:19:47 UTC (rev 209857)
</span><span class="lines">@@ -44,6 +44,8 @@
</span><span class="cx">     }
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+const char16_t bidirectionalDomain[28] = u&quot;bidirectional\u0786\u07AE\u0782\u07B0\u0795\u07A9\u0793\u07A6\u0783\u07AA.com&quot;;
+
</ins><span class="cx"> TEST_F(PublicSuffix, IsPublicSuffix)
</span><span class="cx"> {
</span><span class="cx">     EXPECT_TRUE(isPublicSuffix(&quot;com&quot;));
</span><span class="lines">@@ -55,10 +57,17 @@
</span><span class="cx">     EXPECT_FALSE(isPublicSuffix(&quot;bl.uk&quot;));
</span><span class="cx">     EXPECT_FALSE(isPublicSuffix(&quot;test.co.uk&quot;));
</span><span class="cx">     EXPECT_TRUE(isPublicSuffix(&quot;xn--zf0ao64a.tw&quot;));
</span><ins>+    EXPECT_FALSE(isPublicSuffix(&quot;r4---asdf.test.com&quot;));
+    EXPECT_FALSE(isPublicSuffix(utf16String(bidirectionalDomain)));
+    EXPECT_TRUE(isPublicSuffix(utf16String(u&quot;\u6803\u6728.jp&quot;)));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> TEST_F(PublicSuffix, TopPrivatelyControlledDomain)
</span><span class="cx"> {
</span><ins>+    EXPECT_EQ(utf16String(u&quot;\u6803\u6728.jp&quot;), topPrivatelyControlledDomain(utf16String(u&quot;\u6803\u6728.jp&quot;)));
+    EXPECT_EQ(String(utf16String(u&quot;example.\u6803\u6728.jp&quot;)), topPrivatelyControlledDomain(utf16String(u&quot;example.\u6803\u6728.jp&quot;)));
+    EXPECT_EQ(String(), topPrivatelyControlledDomain(String()));
+    EXPECT_EQ(String(), topPrivatelyControlledDomain(&quot;&quot;));
</ins><span class="cx">     EXPECT_EQ(String(&quot;test.com&quot;), topPrivatelyControlledDomain(&quot;test.com&quot;));
</span><span class="cx">     EXPECT_EQ(String(&quot;test.com&quot;), topPrivatelyControlledDomain(&quot;com.test.com&quot;));
</span><span class="cx">     EXPECT_EQ(String(&quot;test.com&quot;), topPrivatelyControlledDomain(&quot;subdomain.test.com&quot;));
</span><span class="lines">@@ -72,6 +81,11 @@
</span><span class="cx">     EXPECT_EQ(String(&quot;127.0.0.1&quot;), topPrivatelyControlledDomain(&quot;127.0.0.1&quot;));
</span><span class="cx">     EXPECT_EQ(String(), topPrivatelyControlledDomain(&quot;1&quot;));
</span><span class="cx">     EXPECT_EQ(String(), topPrivatelyControlledDomain(&quot;com&quot;));
</span><ins>+    EXPECT_EQ(String(&quot;test.com&quot;), topPrivatelyControlledDomain(&quot;r4---asdf.test.com&quot;));
+    EXPECT_EQ(String(&quot;r4---asdf.com&quot;), topPrivatelyControlledDomain(&quot;r4---asdf.com&quot;));
+    EXPECT_EQ(String(), topPrivatelyControlledDomain(&quot;r4---asdf&quot;));
+    EXPECT_EQ(utf16String(bidirectionalDomain), utf16String(bidirectionalDomain));
+    
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPIWTFStringUtilitiesh"></a>
<div class="modfile"><h4>Modified: trunk/Tools/TestWebKitAPI/WTFStringUtilities.h (209856 => 209857)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/WTFStringUtilities.h        2016-12-15 08:17:17 UTC (rev 209856)
+++ trunk/Tools/TestWebKitAPI/WTFStringUtilities.h        2016-12-15 08:19:47 UTC (rev 209857)
</span><span class="lines">@@ -28,8 +28,7 @@
</span><span class="cx">  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
</span><span class="cx">  */
</span><span class="cx"> 
</span><del>-#ifndef WTFStringUtilities_h
-#define WTFStringUtilities_h
</del><ins>+#pragma once
</ins><span class="cx"> 
</span><span class="cx"> #include &lt;wtf/Assertions.h&gt;
</span><span class="cx"> #include &lt;wtf/text/CString.h&gt;
</span><span class="lines">@@ -45,4 +44,12 @@
</span><span class="cx"> 
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-#endif // WTFStringUtilities_h
</del><ins>+template&lt;size_t length&gt;
+static String utf16String(const char16_t (&amp;url)[length])
+{
+    StringBuilder builder;
+    builder.reserveCapacity(length - 1);
+    for (size_t i = 0; i &lt; length - 1; ++i)
+        builder.append(static_cast&lt;UChar&gt;(url[i]));
+    return builder.toString();
+}
</ins></span></pre>
</div>
</div>

</body>
</html>