diff --git a/src/java.base/share/classes/java/net/InMemoryCookieStore.java b/src/java.base/share/classes/java/net/InMemoryCookieStore.java index 0ce3dc5b68c4e..1c72549e37d5c 100644 --- a/src/java.base/share/classes/java/net/InMemoryCookieStore.java +++ b/src/java.base/share/classes/java/net/InMemoryCookieStore.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,10 +25,6 @@ package java.net; -import java.net.URI; -import java.net.CookieStore; -import java.net.HttpCookie; -import java.net.URISyntaxException; import java.util.List; import java.util.Map; import java.util.ArrayList; @@ -72,6 +68,7 @@ public InMemoryCookieStore() { /** * Add one cookie into cookie store. */ + @Override public void add(URI uri, HttpCookie cookie) { // pre-condition : argument can't be null if (cookie == null) { @@ -109,6 +106,7 @@ public void add(URI uri, HttpCookie cookie) { * 3) not expired. * See RFC 2965 sec. 3.3.4 for more detail. */ + @Override public List get(URI uri) { // argument can't be null if (uri == null) { @@ -127,12 +125,13 @@ public List get(URI uri) { lock.unlock(); } - return cookies; + return Collections.unmodifiableList(cookies); } /** * Get all cookies in cookie store, except those have expired */ + @Override public List getCookies() { List rt; @@ -156,6 +155,7 @@ public List getCookies() { * Get all URIs, which are associated with at least one cookie * of this cookie store. */ + @Override public List getURIs() { List uris = new ArrayList<>(); @@ -165,7 +165,7 @@ public List getURIs() { while (it.hasNext()) { URI uri = it.next(); List cookies = uriIndex.get(uri); - if (cookies == null || cookies.size() == 0) { + if (cookies == null || cookies.isEmpty()) { // no cookies list or an empty list associated with // this uri entry, delete it it.remove(); @@ -176,13 +176,14 @@ public List getURIs() { lock.unlock(); } - return uris; + return Collections.unmodifiableList(uris); } /** * Remove a cookie from store */ + @Override public boolean remove(URI uri, HttpCookie ck) { // argument can't be null if (ck == null) { @@ -204,6 +205,7 @@ public boolean remove(URI uri, HttpCookie ck) { /** * Remove all cookies in this cookie store. */ + @Override public boolean removeAll() { lock.lock(); try { diff --git a/test/jdk/java/net/CookieStoreTest.java b/test/jdk/java/net/CookieStoreTest.java new file mode 100644 index 0000000000000..50a5ab3fac1a5 --- /dev/null +++ b/test/jdk/java/net/CookieStoreTest.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.net.CookieManager; +import java.net.CookieStore; +import java.net.HttpCookie; +import java.net.URI; +import java.util.ArrayList; +import java.util.List; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; + +/* + * @test + * @bug 8365086 + * @summary verify that the implementation of java.net.CookieStore works + * as expected + * @run junit CookieStoreTest + */ +class CookieStoreTest { + + // neither the scheme, host nor the port matters in this test + private static final URI COOKIE_TEST_URI = URI.create("https://127.0.0.1:12345"); + + static List cookieStores() { + final List params = new ArrayList<>(); + // empty CookieStore + params.add(Arguments.of(new CookieManager().getCookieStore(), true)); + + final CookieStore cookieStore = new CookieManager().getCookieStore(); + cookieStore.add(COOKIE_TEST_URI, new HttpCookie("foo", "bar")); + // non-empty CookieStore + params.add(Arguments.of(cookieStore, false)); + + return params; + } + + /* + * Verify that the List returned by CookieStore.getURIs() is immutable. + */ + @ParameterizedTest + @MethodSource("cookieStores") + void testImmutableGetURIs(final CookieStore cookieStore, final boolean expectEmpty) { + final List uris = cookieStore.getURIs(); + assertNotNull(uris, "CookieStore.getURIs() returned null"); + assertEquals(expectEmpty, uris.isEmpty(), "CookieStore.getURIs() returned: " + uris); + assertImmutableList(uris, COOKIE_TEST_URI); + } + + /* + * Verify that the List returned by CookieStore.getCookies() is immutable. + */ + @ParameterizedTest + @MethodSource("cookieStores") + void testImmutableGetCookies(final CookieStore cookieStore, final boolean expectEmpty) { + final List cookies = cookieStore.getCookies(); + assertNotNull(cookies, "CookieStore.getCookies() returned null"); + assertEquals(expectEmpty, cookies.isEmpty(), "CookieStore.getCookies() returned: " + cookies); + assertImmutableList(cookies, new HttpCookie("hello", "world")); + } + + /* + * Verify that the List returned by CookieStore.get(URI) is immutable. + */ + @ParameterizedTest + @MethodSource("cookieStores") + void testImmutableGetCookiesForURI(final CookieStore cookieStore, final boolean expectEmpty) { + final List cookies = cookieStore.get(COOKIE_TEST_URI); + assertNotNull(cookies, "CookieStore.get(URI) returned null"); + assertEquals(expectEmpty, cookies.isEmpty(), "CookieStore.get(URI) returned: " + cookies); + assertImmutableList(cookies, new HttpCookie("hello", "world")); + } + + /* + * Verifies that the attempt to modify the contents of the list will fail + * due to the list being immutable. + */ + private static void assertImmutableList(final List list, T elementToAddOrRemove) { + // the list is expected to be immutable, so each of these operations must fail + assertThrows(UnsupportedOperationException.class, () -> list.add(elementToAddOrRemove)); + assertThrows(UnsupportedOperationException.class, () -> list.remove(elementToAddOrRemove)); + assertThrows(UnsupportedOperationException.class, list::clear); + // even try the replace operation when the list isn't empty + if (!list.isEmpty()) { + assertThrows(UnsupportedOperationException.class, () -> list.set(0, elementToAddOrRemove)); + } + } +}