Fix validation for session cookie config

Signed-off-by: Arjan Tijms <arjan.tijms@gmail.com>
diff --git a/appserver/web/web-core/src/main/java/org/apache/catalina/core/SessionCookieConfigImpl.java b/appserver/web/web-core/src/main/java/org/apache/catalina/core/SessionCookieConfigImpl.java
index 5a6f8a9..6aa6b39 100644
--- a/appserver/web/web-core/src/main/java/org/apache/catalina/core/SessionCookieConfigImpl.java
+++ b/appserver/web/web-core/src/main/java/org/apache/catalina/core/SessionCookieConfigImpl.java
@@ -17,22 +17,31 @@
 
 package org.apache.catalina.core;
 
-import org.apache.catalina.LogFacade;
+import static java.lang.String.CASE_INSENSITIVE_ORDER;
+import static java.util.Collections.unmodifiableMap;
+import static org.apache.catalina.LogFacade.SESSION_COOKIE_CONFIG_ALREADY_INIT;
+import static org.apache.catalina.core.Constants.COOKIE_DOMAIN_ATTR;
+import static org.apache.catalina.core.Constants.COOKIE_HTTP_ONLY_ATTR;
+import static org.apache.catalina.core.Constants.COOKIE_MAX_AGE_ATTR;
+import static org.apache.catalina.core.Constants.COOKIE_PATH_ATTR;
+import static org.apache.catalina.core.Constants.COOKIE_SECURE_ATTR;
 
 import java.text.MessageFormat;
-import java.util.Collections;
 import java.util.Map;
 import java.util.ResourceBundle;
 import java.util.TreeMap;
 
+import org.apache.catalina.LogFacade;
+
 import jakarta.servlet.SessionCookieConfig;
 
 /**
- * Class that may be used to configure various properties of cookies
- * used for session tracking purposes.
+ * Class that may be used to configure various properties of cookies used for session tracking purposes.
  */
 public class SessionCookieConfigImpl implements SessionCookieConfig {
 
+    private static final ResourceBundle rb = LogFacade.getLogger().getResourceBundle();
+
     private static final int DEFAULT_MAX_AGE = -1;
     private static final boolean DEFAULT_HTTP_ONLY = false;
     private static final boolean DEFAULT_SECURE = false;
@@ -40,12 +49,9 @@
 
     private String name = DEFAULT_NAME;
 
-    private final Map<String,String> attributes = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
+    private final Map<String, String> attributes = new TreeMap<>(CASE_INSENSITIVE_ORDER);
     private final StandardContext ctx;
 
-    private static final ResourceBundle rb = LogFacade.getLogger().getResourceBundle();
-
-
     /**
      * Constructor
      */
@@ -53,215 +59,156 @@
         this.ctx = ctx;
     }
 
-
     /**
      * @param name the cookie name to use
      *
-     * @throws IllegalStateException if the <tt>ServletContext</tt>
-     * from which this <tt>SessionCookieConfig</tt> was acquired has
-     * already been initialized
+     * @throws IllegalStateException if the <tt>ServletContext</tt> from which this <tt>SessionCookieConfig</tt> was
+     * acquired has already been initialized
      */
     @Override
     public void setName(String name) {
-        if (ctx.isContextInitializedCalled()) {
-            String msg = MessageFormat.format(rb.getString(LogFacade.SESSION_COOKIE_CONFIG_ALREADY_INIT),
-                                              new Object[] {"name", ctx.getName()});
-            throw new IllegalStateException(msg);
-        }
+        checkContextInitialized("name");
 
         this.name = name;
         ctx.setSessionCookieName(name);
     }
 
-
     /**
-     * @return the cookie name set via {@link #setName}, or
-     * <tt>JSESSIONID</tt> if {@link #setName} was never called
+     * @return the cookie name set via {@link #setName}, or <tt>JSESSIONID</tt> if {@link #setName} was never called
      */
     @Override
     public String getName() {
         return name;
     }
 
-
     /**
      * @param domain the cookie domain to use
      *
-     * @throws IllegalStateException if the <tt>ServletContext</tt>
-     * from which this <tt>SessionCookieConfig</tt> was acquired has
-     * already been initialized
+     * @throws IllegalStateException if the <tt>ServletContext</tt> from which this <tt>SessionCookieConfig</tt> was
+     * acquired has already been initialized
      */
     @Override
     public void setDomain(String domain) {
-        if (ctx.isContextInitializedCalled()) {
-            String msg = MessageFormat.format(rb.getString(LogFacade.SESSION_COOKIE_CONFIG_ALREADY_INIT),
-                                              new Object[] {"dnmain", ctx.getName()});
-            throw new IllegalStateException(msg);
-        }
-        setAttribute(Constants.COOKIE_DOMAIN_ATTR, domain);
+        checkContextInitialized("domain");
+        setAttribute(COOKIE_DOMAIN_ATTR, domain);
     }
 
-
     /**
-     * @return the cookie domain set via {@link #setDomain}, or
-     * <tt>null</tt> if {@link #setDomain} was never called
+     * @return the cookie domain set via {@link #setDomain}, or <tt>null</tt> if {@link #setDomain} was never called
      */
     @Override
     public String getDomain() {
-        return getAttribute(Constants.COOKIE_DOMAIN_ATTR);
+        return getAttribute(COOKIE_DOMAIN_ATTR);
     }
 
-
     /**
      * @param path the cookie path to use
      *
-     * @throws IllegalStateException if the <tt>ServletContext</tt>
-     * from which this <tt>SessionCookieConfig</tt> was acquired has
-     * already been initialized
+     * @throws IllegalStateException if the <tt>ServletContext</tt> from which this <tt>SessionCookieConfig</tt> was
+     * acquired has already been initialized
      */
     @Override
     public void setPath(String path) {
-        if (ctx.isContextInitializedCalled()) {
-            String msg = MessageFormat.format(rb.getString(LogFacade.SESSION_COOKIE_CONFIG_ALREADY_INIT),
-                                              new Object[] {"path", ctx.getName()});
-            throw new IllegalStateException(msg);
-        }
-        setAttribute(Constants.COOKIE_PATH_ATTR, path);
+        checkContextInitialized("path");
+        setAttribute(COOKIE_PATH_ATTR, path);
     }
 
-
     /**
-     * @return the cookie path set via {@link #setPath}, or the context
-     * path of the <tt>ServletContext</tt> from which this
-     * <tt>SessionCookieConfig</tt> was acquired if {@link #setPath}
-     * was never called
+     * @return the cookie path set via {@link #setPath}, or the context path of the <tt>ServletContext</tt> from which this
+     * <tt>SessionCookieConfig</tt> was acquired if {@link #setPath} was never called
      */
     @Override
     public String getPath() {
-        return getAttribute(Constants.COOKIE_PATH_ATTR);
+        return getAttribute(COOKIE_PATH_ATTR);
     }
 
-
     /**
      * @param comment the cookie comment to use
      *
-     * @throws IllegalStateException if the <tt>ServletContext</tt>
-     * from which this <tt>SessionCookieConfig</tt> was acquired has
-     * already been initialized
+     * @throws IllegalStateException if the <tt>ServletContext</tt> from which this <tt>SessionCookieConfig</tt> was
+     * acquired has already been initialized
      */
     @Override
     public void setComment(String comment) {
-        if (ctx.isContextInitializedCalled()) {
-            String msg = MessageFormat.format(rb.getString(LogFacade.SESSION_COOKIE_CONFIG_ALREADY_INIT),
-                                              new Object[] {"comment", ctx.getName()});
-            throw new IllegalStateException(msg);
-        }
+        checkContextInitialized("comment");
         setAttribute(Constants.COOKIE_COMMENT_ATTR, comment);
     }
 
-
     /**
-     * @return the cookie comment set via {@link #setComment}, or
-     * <tt>null</tt> if {@link #setComment} was never called
+     * @return the cookie comment set via {@link #setComment}, or <tt>null</tt> if {@link #setComment} was never called
      */
     @Override
     public String getComment() {
         return getAttribute(Constants.COOKIE_COMMENT_ATTR);
     }
 
-
     /**
-     * @param httpOnly true if the session tracking cookies created
-     * on behalf of the <tt>ServletContext</tt> from which this
-     * <tt>SessionCookieConfig</tt> was acquired shall be marked as
-     * <i>HttpOnly</i>, false otherwise
+     * @param httpOnly true if the session tracking cookies created on behalf of the <tt>ServletContext</tt> from which this
+     * <tt>SessionCookieConfig</tt> was acquired shall be marked as <i>HttpOnly</i>, false otherwise
      *
-     * @throws IllegalStateException if the <tt>ServletContext</tt>
-     * from which this <tt>SessionCookieConfig</tt> was acquired has
-     * already been initialized
+     * @throws IllegalStateException if the <tt>ServletContext</tt> from which this <tt>SessionCookieConfig</tt> was
+     * acquired has already been initialized
      */
     @Override
     public void setHttpOnly(boolean httpOnly) {
-        if (ctx.isContextInitializedCalled()) {
-            String msg = MessageFormat.format(rb.getString(LogFacade.SESSION_COOKIE_CONFIG_ALREADY_INIT),
-                                              new Object[] {"httpOnly", ctx.getName()});
-            throw new IllegalStateException(msg);
-        }
-        setAttribute(Constants.COOKIE_HTTP_ONLY_ATTR, String.valueOf(httpOnly));
+        checkContextInitialized("httpOnly");
+        setAttribute(COOKIE_HTTP_ONLY_ATTR, String.valueOf(httpOnly));
     }
 
-
     /**
-     * @return true if the session tracking cookies created on behalf of the
-     * <tt>ServletContext</tt> from which this <tt>SessionCookieConfig</tt>
-     * was acquired will be marked as <i>HttpOnly</i>, false otherwise
+     * @return true if the session tracking cookies created on behalf of the <tt>ServletContext</tt> from which this
+     * <tt>SessionCookieConfig</tt> was acquired will be marked as <i>HttpOnly</i>, false otherwise
      */
     @Override
     public boolean isHttpOnly() {
-        String value = getAttribute(Constants.COOKIE_HTTP_ONLY_ATTR);
+        String value = getAttribute(COOKIE_HTTP_ONLY_ATTR);
         return value == null ? DEFAULT_HTTP_ONLY : Boolean.parseBoolean(value);
     }
 
-
     /**
-     * @param secure true if the session tracking cookies created on
-     * behalf of the <tt>ServletContext</tt> from which this
-     * <tt>SessionCookieConfig</tt> was acquired shall be marked as
-     * <i>secure</i> even if the request that initiated the corresponding
-     * session is using plain HTTP instead of HTTPS, and false if they
-     * shall be marked as <i>secure</i> only if the request that initiated
-     * the corresponding session was also secure
+     * @param secure true if the session tracking cookies created on behalf of the <tt>ServletContext</tt> from which this
+     * <tt>SessionCookieConfig</tt> was acquired shall be marked as <i>secure</i> even if the request that initiated the
+     * corresponding session is using plain HTTP instead of HTTPS, and false if they shall be marked as <i>secure</i> only
+     * if the request that initiated the corresponding session was also secure
      *
-     * @throws IllegalStateException if the <tt>ServletContext</tt>
-     * from which this <tt>SessionCookieConfig</tt> was acquired has
-     * already been initialized
+     * @throws IllegalStateException if the <tt>ServletContext</tt> from which this <tt>SessionCookieConfig</tt> was
+     * acquired has already been initialized
      */
     @Override
     public void setSecure(boolean secure) {
-        if (ctx.isContextInitializedCalled()) {
-            String msg = MessageFormat.format(rb.getString(LogFacade.SESSION_COOKIE_CONFIG_ALREADY_INIT),
-                                              new Object[] {"secure", ctx.getName()});
-            throw new IllegalStateException(msg);
-        }
-        setAttribute(Constants.COOKIE_SECURE_ATTR, String.valueOf(secure));
+        checkContextInitialized("secure");
+        setAttribute(COOKIE_SECURE_ATTR, String.valueOf(secure));
     }
 
-
     /**
-     * @return true if the session tracking cookies created on behalf of the
-     * <tt>ServletContext</tt> from which this <tt>SessionCookieConfig</tt>
-     * was acquired will be marked as <i>secure</i> even if the request
-     * that initiated the corresponding session is using plain HTTP
-     * instead of HTTPS, and false if they will be marked as <i>secure</i>
-     * only if the request that initiated the corresponding session was
-     * also secure
+     * @return true if the session tracking cookies created on behalf of the <tt>ServletContext</tt> from which this
+     * <tt>SessionCookieConfig</tt> was acquired will be marked as <i>secure</i> even if the request that initiated the
+     * corresponding session is using plain HTTP instead of HTTPS, and false if they will be marked as <i>secure</i> only if
+     * the request that initiated the corresponding session was also secure
      */
     @Override
     public boolean isSecure() {
-        String value = getAttribute(Constants.COOKIE_SECURE_ATTR);
+        String value = getAttribute(COOKIE_SECURE_ATTR);
         return value == null ? DEFAULT_SECURE : Boolean.parseBoolean(value);
     }
 
-
     @Override
     public void setMaxAge(int maxAge) {
-        if (ctx.isContextInitializedCalled()) {
-            String msg = MessageFormat.format(rb.getString(LogFacade.SESSION_COOKIE_CONFIG_ALREADY_INIT),
-                                              new Object[] {"maxAge", ctx.getName()});
-            throw new IllegalStateException(msg);
-        }
-        setAttribute(Constants.COOKIE_MAX_AGE_ATTR, String.valueOf(maxAge));
+        checkContextInitialized("maxAge");
+        setAttribute(COOKIE_MAX_AGE_ATTR, String.valueOf(maxAge));
     }
 
-
     @Override
     public int getMaxAge() {
-        String value = getAttribute(Constants.COOKIE_MAX_AGE_ATTR);
+        String value = getAttribute(COOKIE_MAX_AGE_ATTR);
         return value == null ? DEFAULT_MAX_AGE : Integer.parseInt(value);
     }
 
     @Override
     public void setAttribute(String name, String value) {
+        checkContextInitialized("attribute");
+        checkValid(name, value);
+
         this.attributes.put(name, value);
     }
 
@@ -272,6 +219,23 @@
 
     @Override
     public Map<String, String> getAttributes() {
-        return Collections.unmodifiableMap(this.attributes);
+        return unmodifiableMap(this.attributes);
+    }
+
+    private void checkContextInitialized(String parameter) {
+        if (ctx.isContextInitializedCalled()) {
+            throw new IllegalStateException(MessageFormat.format(rb.getString(SESSION_COOKIE_CONFIG_ALREADY_INIT),
+                new Object[] { parameter, ctx.getName() }));
+        }
+    }
+
+    private void checkValid(String name, String value) {
+        if (name == null) {
+            throw new IllegalArgumentException(name + " cannot be null");
+        }
+
+        if (name.equals("DEFAULT_MAX_AGE")) {
+            Integer.parseInt(value);
+        }
     }
 }