From e7174910523adeaeaa5778768baad1da5aa6ec3a Mon Sep 17 00:00:00 2001 From: Chris Povirk Date: Wed, 18 Dec 2024 09:40:09 -0500 Subject: [PATCH] Annotate some `java.net` classes, mostly related to cookies. (#108) Prompted by https://github.com/google/xplat/commit/18fd514cbb143dd75837b9a92d97b8c9cb91c960. Co-authored-by: Werner Dietl --- .../share/classes/java/net/CookieHandler.java | 8 +++-- .../share/classes/java/net/CookieManager.java | 9 +++-- .../share/classes/java/net/CookiePolicy.java | 3 ++ .../share/classes/java/net/HttpCookie.java | 35 +++++++++++++------ .../classes/java/net/URISyntaxException.java | 3 +- 5 files changed, 41 insertions(+), 17 deletions(-) diff --git a/src/java.base/share/classes/java/net/CookieHandler.java b/src/java.base/share/classes/java/net/CookieHandler.java index ec20c860591..27d879e54bd 100644 --- a/src/java.base/share/classes/java/net/CookieHandler.java +++ b/src/java.base/share/classes/java/net/CookieHandler.java @@ -29,6 +29,9 @@ import java.util.List; import java.io.IOException; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; + /** * A CookieHandler object provides a callback mechanism to hook up a * HTTP state management policy implementation into the HTTP protocol @@ -49,6 +52,7 @@ * @author Yingxian Wang * @since 1.5 */ +@NullMarked public abstract class CookieHandler { /** * Constructor for subclasses to call. @@ -71,7 +75,7 @@ public CookieHandler() {} * there is no system-wide cookie handler currently set. * @see #setDefault(CookieHandler) */ - public static synchronized CookieHandler getDefault() { + public static synchronized @Nullable CookieHandler getDefault() { return cookieHandler; } @@ -84,7 +88,7 @@ public static synchronized CookieHandler getDefault() { * {@code null} to unset. * @see #getDefault() */ - public static synchronized void setDefault(CookieHandler cHandler) { + public static synchronized void setDefault(@Nullable CookieHandler cHandler) { cookieHandler = cHandler; } diff --git a/src/java.base/share/classes/java/net/CookieManager.java b/src/java.base/share/classes/java/net/CookieManager.java index 9cb69b80493..eda8a01e72c 100644 --- a/src/java.base/share/classes/java/net/CookieManager.java +++ b/src/java.base/share/classes/java/net/CookieManager.java @@ -30,6 +30,8 @@ import java.util.Comparator; import java.io.IOException; import sun.util.logging.PlatformLogger; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; /** * CookieManager provides a concrete implementation of {@link CookieHandler}, @@ -114,6 +116,7 @@ * @author Edward Wang * @since 1.6 */ +@NullMarked public class CookieManager extends CookieHandler { /* ---------------- Fields -------------- */ @@ -149,8 +152,8 @@ public CookieManager() { * if {@code null}, ACCEPT_ORIGINAL_SERVER will * be used. */ - public CookieManager(CookieStore store, - CookiePolicy cookiePolicy) + public CookieManager(@Nullable CookieStore store, + @Nullable CookiePolicy cookiePolicy) { // use default cookie policy if not specify one policyCallback = (cookiePolicy == null) ? CookiePolicy.ACCEPT_ORIGINAL_SERVER @@ -177,7 +180,7 @@ public CookieManager(CookieStore store, * @param cookiePolicy the cookie policy. Can be {@code null}, which * has no effects on current cookie policy. */ - public void setCookiePolicy(CookiePolicy cookiePolicy) { + public void setCookiePolicy(@Nullable CookiePolicy cookiePolicy) { if (cookiePolicy != null) policyCallback = cookiePolicy; } diff --git a/src/java.base/share/classes/java/net/CookiePolicy.java b/src/java.base/share/classes/java/net/CookiePolicy.java index 80948359153..215bb11472b 100644 --- a/src/java.base/share/classes/java/net/CookiePolicy.java +++ b/src/java.base/share/classes/java/net/CookiePolicy.java @@ -25,6 +25,8 @@ package java.net; +import org.jspecify.annotations.NullMarked; + /** * CookiePolicy implementations decide which cookies should be accepted * and which should be rejected. Three pre-defined policy implementations @@ -35,6 +37,7 @@ * @author Edward Wang * @since 1.6 */ +@NullMarked public interface CookiePolicy { /** * One pre-defined policy which accepts all cookies. diff --git a/src/java.base/share/classes/java/net/HttpCookie.java b/src/java.base/share/classes/java/net/HttpCookie.java index 6115b3a31a7..89928419bb8 100644 --- a/src/java.base/share/classes/java/net/HttpCookie.java +++ b/src/java.base/share/classes/java/net/HttpCookie.java @@ -25,6 +25,8 @@ package java.net; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.NullUnmarked; import org.jspecify.annotations.Nullable; import java.util.List; @@ -60,6 +62,7 @@ * @author Edward Wang * @since 1.6 */ +@NullMarked public final class HttpCookie implements Cloneable { // ---------------- Fields -------------- @@ -140,6 +143,7 @@ public final class HttpCookie implements Cloneable { * @see #setValue * @see #setVersion */ + @NullUnmarked // TODO(cpovirk): Should `value` be @Nullable? public HttpCookie(String name, String value) { this(name, value, null /*header*/); } @@ -262,7 +266,7 @@ public boolean hasExpired() { * * @see #getComment */ - public void setComment(String purpose) { + public void setComment(@Nullable String purpose) { comment = purpose; } @@ -274,7 +278,7 @@ public void setComment(String purpose) { * * @see #setComment */ - public String getComment() { + public @Nullable String getComment() { return comment; } @@ -288,7 +292,7 @@ public String getComment() { * * @see #getCommentURL */ - public void setCommentURL(String purpose) { + public void setCommentURL(@Nullable String purpose) { commentURL = purpose; } @@ -301,7 +305,7 @@ public void setCommentURL(String purpose) { * * @see #setCommentURL */ - public String getCommentURL() { + public @Nullable String getCommentURL() { return commentURL; } @@ -339,7 +343,7 @@ public boolean getDiscard() { * * @see #getPortlist */ - public void setPortlist(String ports) { + public void setPortlist(@Nullable String ports) { portlist = ports; } @@ -350,7 +354,7 @@ public void setPortlist(String ports) { * * @see #setPortlist */ - public String getPortlist() { + public @Nullable String getPortlist() { return portlist; } @@ -370,7 +374,7 @@ public String getPortlist() { * * @see #getDomain */ - public void setDomain(String pattern) { + public void setDomain(@Nullable String pattern) { if (pattern != null) domain = pattern.toLowerCase(Locale.ROOT); else @@ -385,7 +389,7 @@ public void setDomain(String pattern) { * * @see #setDomain */ - public String getDomain() { + public @Nullable String getDomain() { return domain; } @@ -442,7 +446,7 @@ public long getMaxAge() { * * @see #getPath */ - public void setPath(String uri) { + public void setPath(@Nullable String uri) { path = uri; } @@ -455,7 +459,7 @@ public void setPath(String uri) { * * @see #setPath */ - public String getPath() { + public @Nullable String getPath() { return path; } @@ -514,6 +518,7 @@ public String getName() { * * @see #getValue */ + @NullUnmarked // TODO(cpovirk): Should `newValue` be @Nullable? public void setValue(String newValue) { value = newValue; } @@ -525,6 +530,7 @@ public void setValue(String newValue) { * * @see #setValue */ + @NullUnmarked // TODO(cpovirk): Should the return type be @Nullable? public String getValue() { return value; } @@ -644,7 +650,14 @@ public void setHttpOnly(boolean httpOnly) { * * @return {@code true} if they domain-matches; {@code false} if not */ - public static boolean domainMatches(String domain, String host) { + /* + * JSpecify: Passing null for either parameter seems likely to be at least suspicious. However, + * if we make the types non-null, we would change the null behavior under Kotlin from "return + * false" to "throw NullPointerException." And it's not clear whether any callers pass null in + * practice, even the one caller in the JDK, which passes cookie.getDomain() and uri.getHost(), + * both of which have nullable types. + */ + public static boolean domainMatches(@Nullable String domain, @Nullable String host) { if (domain == null || host == null) return false; diff --git a/src/java.base/share/classes/java/net/URISyntaxException.java b/src/java.base/share/classes/java/net/URISyntaxException.java index 3b9889cd1b4..b767f8d29ff 100644 --- a/src/java.base/share/classes/java/net/URISyntaxException.java +++ b/src/java.base/share/classes/java/net/URISyntaxException.java @@ -25,6 +25,7 @@ package java.net; +import org.jspecify.annotations.NullMarked; /** * Checked exception thrown to indicate that a string could not be parsed as a @@ -34,7 +35,7 @@ * @see URI * @since 1.4 */ - +@NullMarked public class URISyntaxException extends Exception {