⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 246264 in webkit


Ignore:
Timestamp:
Jun 10, 2019, 9:16:52 AM (7 years ago)
Author:
sihui_liu@apple.com
Message:

[WKHTTPCookieStore getAllCookies:] may return duplicate cookies
https://bugs.webkit.org/show_bug.cgi?id=198635
<rdar://problem/46010232>

Reviewed by Ryosuke Niwa.

Source/WebCore:

Test: WebKit.WKHTTPCookieStoreWithoutProcessPoolDuplicates

  • platform/Cookie.h:

(WebCore::Cookie::isKeyEqual const):
(WTF::HashTraits<WebCore::Cookie>::isEmptyValue):

Source/WebKit:

When there is no process pool, we store cookies set in memory with HashSet m_pendingCookies of WebsiteDataStore.

HashSet does not contain duplicate Cookies that are completely identical, but it may contain Cookies that have
all the other properties identical other than value. This is not correct because Cookies with same name, domain
and path should be treated as the same cookie. When a cookie is set via API, we should either insert the
cookie into m_pendingCookies if the cookie does not exist, or update the cookie value if it already exists.

Note that we still use HashSet with CookieHash for m_pendingCookies because in cookie deletion, we only delete
cookie when there is a complete match. If some cookie from m_pendingCookies has all other properties the same as
the cookie specified in the deletion function, but the value is different, it will not be removed.

  • UIProcess/WebsiteData/WebsiteDataStore.cpp:

(WebKit::WebsiteDataStore::addPendingCookie):

Tools:

  • TestWebKitAPI/Tests/WebKitCocoa/WKHTTPCookieStore.mm:

(areCookiesEqual):
(TEST):

Location:
trunk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r246238 r246264  
     12019-06-10  Sihui Liu  <sihui_liu@apple.com>
     2
     3        [WKHTTPCookieStore getAllCookies:] may return duplicate cookies
     4        https://bugs.webkit.org/show_bug.cgi?id=198635
     5        <rdar://problem/46010232>
     6
     7        Reviewed by Ryosuke Niwa.
     8
     9        Test: WebKit.WKHTTPCookieStoreWithoutProcessPoolDuplicates
     10
     11        * platform/Cookie.h:
     12        (WebCore::Cookie::isKeyEqual const):
     13        (WTF::HashTraits<WebCore::Cookie>::isEmptyValue):
     14
    1152019-06-09  Rob Buis  <rbuis@igalia.com>
    216
  • trunk/Source/WebCore/platform/Cookie.h

    r239427 r246264  
    7777    }
    7878   
     79    bool isKeyEqual(const Cookie& otherCookie) const
     80    {
     81        return name == otherCookie.name
     82            && domain == otherCookie.domain
     83            && path == otherCookie.path;
     84    }
     85
    7986    String name;
    8087    String value;
     
    170177        static void constructDeletedValue(WebCore::Cookie& slot) { slot = WebCore::Cookie(WTF::HashTableDeletedValue); }
    171178        static bool isDeletedValue(const WebCore::Cookie& slot) { return slot.name.isHashTableDeletedValue(); }
     179
     180        static const bool hasIsEmptyValueFunction = true;
     181        static bool isEmptyValue(const WebCore::Cookie& slot) { return slot.isNull(); }
    172182    };
    173183    template<> struct EnumTraits<WebCore::Cookie::SameSitePolicy> {
  • trunk/Source/WebKit/ChangeLog

    r246257 r246264  
     12019-06-10  Sihui Liu  <sihui_liu@apple.com>
     2
     3        [WKHTTPCookieStore getAllCookies:] may return duplicate cookies
     4        https://bugs.webkit.org/show_bug.cgi?id=198635
     5        <rdar://problem/46010232>
     6
     7        Reviewed by Ryosuke Niwa.
     8
     9        When there is no process pool, we store cookies set in memory with HashSet m_pendingCookies of WebsiteDataStore.
     10
     11        HashSet does not contain duplicate Cookies that are completely identical, but it may contain Cookies that have
     12        all the other properties identical other than value. This is not correct because Cookies with same name, domain
     13        and path should be treated as the same cookie. When a cookie is set via API, we should either insert the
     14        cookie into m_pendingCookies if the cookie does not exist, or update the cookie value if it already exists.
     15
     16        Note that we still use HashSet with CookieHash for m_pendingCookies because in cookie deletion, we only delete
     17        cookie when there is a complete match. If some cookie from m_pendingCookies has all other properties the same as
     18        the cookie specified in the deletion function, but the value is different, it will not be removed.
     19
     20        * UIProcess/WebsiteData/WebsiteDataStore.cpp:
     21        (WebKit::WebsiteDataStore::addPendingCookie):
     22
    1232019-06-10  Philippe Normand  <pnormand@igalia.com>
    224
  • trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp

    r246110 r246264  
    19421942void WebsiteDataStore::addPendingCookie(const WebCore::Cookie& cookie)
    19431943{
     1944    m_pendingCookies.removeIf([&cookie](auto& pendingCookie) {
     1945        return pendingCookie.isKeyEqual(cookie);
     1946    });
    19441947    m_pendingCookies.add(cookie);
    19451948}
  • trunk/Tools/ChangeLog

    r246262 r246264  
     12019-06-10  Sihui Liu  <sihui_liu@apple.com>
     2
     3        [WKHTTPCookieStore getAllCookies:] may return duplicate cookies
     4        https://bugs.webkit.org/show_bug.cgi?id=198635
     5        <rdar://problem/46010232>
     6
     7        Reviewed by Ryosuke Niwa.
     8
     9        * TestWebKitAPI/Tests/WebKitCocoa/WKHTTPCookieStore.mm:
     10        (areCookiesEqual):
     11        (TEST):
     12
    1132019-06-10  Adrian Perez de Castro  <aperez@igalia.com>
    214
  • trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKHTTPCookieStore.mm

    r246097 r246264  
    628628    TestWebKitAPI::Util::run(&finished);
    629629}
     630
     631static bool areCookiesEqual(NSHTTPCookie *first, NSHTTPCookie *second)
     632{
     633    return [first.name isEqual:second.name] && [first.domain isEqual:second.domain] && [first.path isEqual:second.path] && [first.value isEqual:second.value];
     634}
     635
     636TEST(WebKit, WKHTTPCookieStoreWithoutProcessPoolDuplicates)
     637{
     638    RetainPtr<WKHTTPCookieStore> httpCookieStore = [WKWebsiteDataStore defaultDataStore].httpCookieStore;
     639    RetainPtr<NSHTTPCookie> sessionCookie = [NSHTTPCookie cookieWithProperties:@{
     640        NSHTTPCookiePath: @"/",
     641        NSHTTPCookieName: @"SessionCookieName",
     642        NSHTTPCookieValue: @"CookieValue",
     643        NSHTTPCookieDomain: @"127.0.0.1",
     644    }];
     645
     646    auto properties = adoptNS([sessionCookie.get().properties mutableCopy]);
     647    properties.get()[NSHTTPCookieDomain] = @"localhost";
     648    RetainPtr<NSHTTPCookie> sessionCookieDifferentDomain = [NSHTTPCookie cookieWithProperties:properties.get()];
     649    properties.get()[NSHTTPCookieValue] = @"OtherCookieValue";
     650    RetainPtr<NSHTTPCookie> sessionCookieDifferentValue = [NSHTTPCookie cookieWithProperties:properties.get()];
     651    finished = false;
     652   
     653    [httpCookieStore.get() setCookie:sessionCookie.get() completionHandler:^{
     654        finished = true;
     655    }];
     656    TestWebKitAPI::Util::run(&finished);
     657    finished = false;
     658
     659    [httpCookieStore.get() setCookie:sessionCookieDifferentDomain.get() completionHandler:^{
     660        finished = true;
     661    }];
     662    TestWebKitAPI::Util::run(&finished);
     663    finished = false;
     664
     665    [httpCookieStore.get() setCookie:sessionCookieDifferentValue.get() completionHandler:^{
     666        finished = true;
     667    }];
     668    TestWebKitAPI::Util::run(&finished);
     669    finished = false;
     670
     671    [httpCookieStore.get() getAllCookies:^(NSArray<NSHTTPCookie *> *cookies) {
     672        EXPECT_EQ(2u, cookies.count);
     673        bool sessionCookieExists = false, otherSessionCookieExists = false;
     674        for (NSHTTPCookie* cookie in cookies) {
     675            if (areCookiesEqual(cookie, sessionCookie.get()))
     676                sessionCookieExists = true;
     677            else if (areCookiesEqual(cookie, sessionCookieDifferentValue.get()))
     678                otherSessionCookieExists = true;
     679        }
     680        EXPECT_TRUE(sessionCookieExists && otherSessionCookieExists);
     681        finished = true;
     682    }];
     683    TestWebKitAPI::Util::run(&finished);
     684}
Note: See TracChangeset for help on using the changeset viewer.