<!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>[231067] 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/231067">231067</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2018-04-26 13:39:47 -0700 (Thu, 26 Apr 2018)</dd>
</dl>

<h3>Log Message</h3>
<pre>-[WKHTTPCookieStore deleteCookie:completionHandler:] doesn't delete cookies
https://bugs.webkit.org/show_bug.cgi?id=184938
<rdar://problem/34737395>

Patch by Sihui Liu <sihui_liu@apple.com> on 2018-04-26
Reviewed by Geoffrey Garen.

Source/WebCore:

When a Cookie object was converted to NSHTTPCookie object, the HTTPOnly property information
was lost so the delete function cannot find the proper cookie to delete.
This patch implements a workaround that compares Cookie object instead of NSHTTPCookie
object. We might want to add the ability to set HTTPOnly header during conversion if there
is an easy way to do it later.

New API test: WebKit.WKHTTPCookieStoreHttpOnly

* platform/network/cocoa/CookieCocoa.mm:
(WebCore::Cookie::operator== const):
* platform/network/cocoa/NetworkStorageSessionCocoa.mm:
(WebCore::NetworkStorageSession::deleteCookie):

Tools:

Add API test coverage.

* TestWebKitAPI/Tests/WebKitCocoa/WKHTTPCookieStore.mm:
(TEST):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreplatformnetworkcocoaCookieCocoamm">trunk/Source/WebCore/platform/network/cocoa/CookieCocoa.mm</a></li>
<li><a href="#trunkSourceWebCoreplatformnetworkcocoaNetworkStorageSessionCocoamm">trunk/Source/WebCore/platform/network/cocoa/NetworkStorageSessionCocoa.mm</a></li>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsTestWebKitAPITestsWebKitCocoaWKHTTPCookieStoremm">trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKHTTPCookieStore.mm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (231066 => 231067)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog   2018-04-26 20:36:48 UTC (rev 231066)
+++ trunk/Source/WebCore/ChangeLog      2018-04-26 20:39:47 UTC (rev 231067)
</span><span class="lines">@@ -1,3 +1,24 @@
</span><ins>+2018-04-26  Sihui Liu  <sihui_liu@apple.com>
+
+        -[WKHTTPCookieStore deleteCookie:completionHandler:] doesn't delete cookies
+        https://bugs.webkit.org/show_bug.cgi?id=184938
+        <rdar://problem/34737395>
+
+        Reviewed by Geoffrey Garen.
+
+        When a Cookie object was converted to NSHTTPCookie object, the HTTPOnly property information
+        was lost so the delete function cannot find the proper cookie to delete.
+        This patch implements a workaround that compares Cookie object instead of NSHTTPCookie 
+        object. We might want to add the ability to set HTTPOnly header during conversion if there
+        is an easy way to do it later.
+        
+        New API test: WebKit.WKHTTPCookieStoreHttpOnly
+
+        * platform/network/cocoa/CookieCocoa.mm:
+        (WebCore::Cookie::operator== const):
+        * platform/network/cocoa/NetworkStorageSessionCocoa.mm:
+        (WebCore::NetworkStorageSession::deleteCookie):
+
</ins><span class="cx"> 2018-04-26  Commit Queue  <commit-queue@webkit.org>
</span><span class="cx"> 
</span><span class="cx">         Unreviewed, rolling out r231052.
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkcocoaCookieCocoamm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/cocoa/CookieCocoa.mm (231066 => 231067)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/cocoa/CookieCocoa.mm       2018-04-26 20:36:48 UTC (rev 231066)
+++ trunk/Source/WebCore/platform/network/cocoa/CookieCocoa.mm  2018-04-26 20:39:47 UTC (rev 231067)
</span><span class="lines">@@ -132,8 +132,18 @@
</span><span class="cx">     if (thisNull || otherNull)
</span><span class="cx">         return thisNull == otherNull;
</span><span class="cx">     
</span><del>-    NSHTTPCookie *nsCookie(*this);
-    return [nsCookie isEqual:other];
</del><ins>+    return name == other.name
+    && value == other.value
+    && domain == other.domain
+    && path == other.path
+    && created == other.created
+    && expires == other.expires
+    && httpOnly == other.httpOnly
+    && secure == other.secure
+    && session == other.session
+    && comment == other.comment
+    && commentURL == other.commentURL
+    && ports == other.ports;
</ins><span class="cx"> }
</span><span class="cx">     
</span><span class="cx"> unsigned Cookie::hash() const
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkcocoaNetworkStorageSessionCocoamm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/cocoa/NetworkStorageSessionCocoa.mm (231066 => 231067)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/cocoa/NetworkStorageSessionCocoa.mm        2018-04-26 20:36:48 UTC (rev 231066)
+++ trunk/Source/WebCore/platform/network/cocoa/NetworkStorageSessionCocoa.mm   2018-04-26 20:39:47 UTC (rev 231067)
</span><span class="lines">@@ -60,8 +60,14 @@
</span><span class="cx"> void NetworkStorageSession::deleteCookie(const Cookie& cookie)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(hasProcessPrivilege(ProcessPrivilege::CanAccessRawCookies));
</span><del>-
-    [nsCookieStorage() deleteCookie:(NSHTTPCookie *)cookie];
</del><ins>+    
+    NSArray *nsCookies = [nsCookieStorage() cookies];
+    for (NSHTTPCookie *nsCookie in nsCookies) {
+        if (Cookie(nsCookie) == cookie) {
+            [nsCookieStorage() deleteCookie:nsCookie];
+            break;
+        }
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static Vector<Cookie> nsCookiesToCookieVector(NSArray<NSHTTPCookie *> *nsCookies)
</span></span></pre></div>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (231066 => 231067)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog    2018-04-26 20:36:48 UTC (rev 231066)
+++ trunk/Tools/ChangeLog       2018-04-26 20:39:47 UTC (rev 231067)
</span><span class="lines">@@ -1,3 +1,16 @@
</span><ins>+2018-04-26  Sihui Liu  <sihui_liu@apple.com>
+
+        -[WKHTTPCookieStore deleteCookie:completionHandler:] doesn't delete cookies
+        https://bugs.webkit.org/show_bug.cgi?id=184938
+        <rdar://problem/34737395>
+
+        Reviewed by Geoffrey Garen.
+
+        Add API test coverage.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/WKHTTPCookieStore.mm:
+        (TEST):
+
</ins><span class="cx"> 2018-04-26  Ross Kirsling  <ross.kirsling@sony.com>
</span><span class="cx"> 
</span><span class="cx">         WinCairo test bots should run JSC tests with options for Windows command prompt.
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPITestsWebKitCocoaWKHTTPCookieStoremm"></a>
<div class="modfile"><h4>Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKHTTPCookieStore.mm (231066 => 231067)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKHTTPCookieStore.mm 2018-04-26 20:36:48 UTC (rev 231066)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKHTTPCookieStore.mm    2018-04-26 20:39:47 UTC (rev 231067)
</span><span class="lines">@@ -192,6 +192,90 @@
</span><span class="cx">     runTestWithWebsiteDataStore([WKWebsiteDataStore defaultDataStore]);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+TEST(WebKit, WKHTTPCookieStoreHttpOnly) 
+{
+    WKWebsiteDataStore* dataStore = [WKWebsiteDataStore defaultDataStore];
+
+    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+    configuration.get().websiteDataStore = dataStore;
+    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
+
+    [webView loadHTMLString:@"WebKit Test" baseURL:[NSURL URLWithString:@"http://webkit.org"]];
+    [webView _test_waitForDidFinishNavigation];
+
+    [dataStore removeDataOfTypes:[WKWebsiteDataStore allWebsiteDataTypes] modifiedSince:[NSDate distantPast] completionHandler:[] {
+        gotFlag = true;
+    }];
+
+    TestWebKitAPI::Util::run(&gotFlag);
+    gotFlag = false;
+
+    id pool = [WKProcessPool _sharedProcessPool];
+    EXPECT_EQ([pool _pluginProcessCount], static_cast<size_t>(0));
+
+    globalCookieStore = dataStore.httpCookieStore;
+
+    NSArray<NSHTTPCookie *> *cookies = nil;
+    [globalCookieStore getAllCookies:[cookiesPtr = &cookies](NSArray<NSHTTPCookie *> *nsCookies) {
+        *cookiesPtr = [nsCookies retain];
+        gotFlag = true;
+    }];
+
+    TestWebKitAPI::Util::run(&gotFlag);
+    gotFlag = false;
+
+    ASSERT_EQ(cookies.count, 0u);
+    [cookies release];
+
+    CFMutableDictionaryRef cookieProperties = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+    CFDictionarySetValue(cookieProperties, CFSTR("Name"), CFSTR("httpCookie"));
+    CFDictionarySetValue(cookieProperties, CFSTR("Value"), CFSTR("httpCookieValue"));
+    CFDictionarySetValue(cookieProperties, CFSTR("Domain"), CFSTR(".www.webkit.org"));
+    CFDictionarySetValue(cookieProperties, CFSTR("Path"), CFSTR("/httpPath"));
+    CFDictionarySetValue(cookieProperties, CFSTR("HttpOnly"), kCFBooleanTrue);
+    RetainPtr<NSHTTPCookie> httpOnlyCookie = [NSHTTPCookie cookieWithProperties:(NSDictionary*) cookieProperties];
+    CFDictionaryRemoveValue(cookieProperties, CFSTR("HttpOnly"));
+    RetainPtr<NSHTTPCookie> notHttpOnlyCookie = [NSHTTPCookie cookieWithProperties:(NSDictionary*) cookieProperties];
+    EXPECT_TRUE(httpOnlyCookie.get().HTTPOnly);
+    EXPECT_FALSE(notHttpOnlyCookie.get().HTTPOnly);
+
+    [globalCookieStore setCookie:notHttpOnlyCookie.get() completionHandler:[]() {
+        gotFlag = true;
+    }];
+
+    TestWebKitAPI::Util::run(&gotFlag);
+    gotFlag = false;
+
+    [globalCookieStore getAllCookies:[cookiesPtr = &cookies](NSArray<NSHTTPCookie *> *nsCookies) {
+        *cookiesPtr = [nsCookies retain];
+        gotFlag = true;
+    }];
+
+    TestWebKitAPI::Util::run(&gotFlag);
+    gotFlag = false;
+
+    ASSERT_EQ(cookies.count, 1u);
+    [cookies release];
+
+    [globalCookieStore deleteCookie:httpOnlyCookie.get() completionHandler:[]() {
+        gotFlag = true;
+    }];
+
+    TestWebKitAPI::Util::run(&gotFlag);
+    gotFlag = false;
+    [globalCookieStore getAllCookies:[cookiesPtr = &cookies](NSArray<NSHTTPCookie *> *nsCookies) {
+        *cookiesPtr = [nsCookies retain];
+        gotFlag = true;
+    }];
+
+    TestWebKitAPI::Util::run(&gotFlag);
+    gotFlag = false;
+
+    // Delete httpOnlyCookie should fail because it is different from notHttpOnlyCookie. 
+    ASSERT_EQ(cookies.count, 1u);
+    [cookies release];
+}
+
</ins><span class="cx"> // FIXME: This should be removed once <rdar://problem/35344202> is resolved and bots are updated.
</span><span class="cx"> #if (PLATFORM(MAC) && __MAC_OS_X_VERSION_MAX_ALLOWED <= 101301) || (PLATFORM(IOS) && __IPHONE_OS_VERSION_MAX_ALLOWED <= 110102)
</span><span class="cx"> TEST(WebKit, WKHTTPCookieStoreNonPersistent)
</span></span></pre>
</div>
</div>

</body>
</html>