* This resolver is always read-only since {@link Record}s are always read-only.
*
- * {@code ELResolver}s are combined using {@link CompositeELResolver}s to define rich semantics for evaluating
- * an expression. See the javadocs for {@link ELResolver} for details.
+ * {@code ELResolver}s are combined using {@link CompositeELResolver}s to define rich semantics for evaluating an
+ * expression. See the javadocs for {@link ELResolver} for details.
*
* @since EL 6.0
*/
diff -Nru tomcat11-11.0.6/java/jakarta/el/Util.java tomcat11-11.0.15/java/jakarta/el/Util.java
--- tomcat11-11.0.6/java/jakarta/el/Util.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/jakarta/el/Util.java 2025-12-02 16:54:08.000000000 +0000
@@ -106,7 +106,7 @@
try {
Method method = clazz.getMethod(methodName, paramTypes);
return getMethod(clazz, base, method);
- } catch (NoSuchMethodException | SecurityException e) {
+ } catch (NoSuchMethodException | SecurityException ignore) {
// Fall through to broader, slower logic
}
}
@@ -631,8 +631,8 @@
/*
* This class duplicates code in org.apache.el.util.ReflectionUtil. When making changes keep the code in sync.
*/
- private record MatchResult(boolean varArgs, int exactCount, int assignableCount, int coercibleCount, int varArgsCount,
- boolean bridge) implements Comparable {
+ private record MatchResult(boolean varArgs, int exactCount, int assignableCount, int coercibleCount,
+ int varArgsCount, boolean bridge) implements Comparable {
public boolean isVarArgs() {
return varArgs;
diff -Nru tomcat11-11.0.6/java/jakarta/security/auth/message/ClientAuth.java tomcat11-11.0.15/java/jakarta/security/auth/message/ClientAuth.java
--- tomcat11-11.0.6/java/jakarta/security/auth/message/ClientAuth.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/jakarta/security/auth/message/ClientAuth.java 2025-12-02 16:54:08.000000000 +0000
@@ -28,8 +28,8 @@
*
* @return An AuthStatus instance that represents the result of the authentication
*
- * @throws AuthException If a failure occurred in a manner that prevented the failure from being communicated
- * via messageInfo
+ * @throws AuthException If a failure occurred in a manner that prevented the failure from being communicated via
+ * messageInfo
*/
AuthStatus secureRequest(MessageInfo messageInfo, Subject clientSubject) throws AuthException;
@@ -42,8 +42,8 @@
*
* @return An AuthStatus instance that represents the result of the validation
*
- * @throws AuthException If a failure occurred in a manner that prevented the failure from being communicated
- * via messageInfo
+ * @throws AuthException If a failure occurred in a manner that prevented the failure from being communicated via
+ * messageInfo
*/
default AuthStatus validateResponse(MessageInfo messageInfo, Subject clientSubject, Subject serviceSubject)
throws AuthException {
diff -Nru tomcat11-11.0.6/java/jakarta/security/auth/message/ServerAuth.java tomcat11-11.0.15/java/jakarta/security/auth/message/ServerAuth.java
--- tomcat11-11.0.6/java/jakarta/security/auth/message/ServerAuth.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/jakarta/security/auth/message/ServerAuth.java 2025-12-02 16:54:08.000000000 +0000
@@ -29,8 +29,8 @@
*
* @return An AuthStatus instance that represents the result of the validation
*
- * @throws AuthException If a failure occurred in a manner that prevented the failure from being communicated
- * via messageInfo
+ * @throws AuthException If a failure occurred in a manner that prevented the failure from being communicated via
+ * messageInfo
*/
AuthStatus validateRequest(MessageInfo messageInfo, Subject clientSubject, Subject serviceSubject)
throws AuthException;
@@ -43,8 +43,8 @@
*
* @return An AuthStatus instance that represents the result of the authentication
*
- * @throws AuthException If a failure occurred in a manner that prevented the failure from being communicated
- * via messageInfo
+ * @throws AuthException If a failure occurred in a manner that prevented the failure from being communicated via
+ * messageInfo
*/
default AuthStatus secureResponse(MessageInfo messageInfo, Subject serviceSubject) throws AuthException {
return AuthStatus.SUCCESS;
diff -Nru tomcat11-11.0.6/java/jakarta/security/auth/message/callback/PasswordValidationCallback.java tomcat11-11.0.15/java/jakarta/security/auth/message/callback/PasswordValidationCallback.java
--- tomcat11-11.0.6/java/jakarta/security/auth/message/callback/PasswordValidationCallback.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/jakarta/security/auth/message/callback/PasswordValidationCallback.java 2025-12-02 16:54:08.000000000 +0000
@@ -22,8 +22,8 @@
import javax.security.auth.callback.Callback;
/**
- * Callback that enables an authentication module to supply a username and password (to a runtime?) and determine if
- * the result of validation.
+ * Callback that enables an authentication module to supply a username and password (to a runtime?) and determine if the
+ * result of validation.
*/
public class PasswordValidationCallback implements Callback {
diff -Nru tomcat11-11.0.6/java/jakarta/servlet/GenericFilter.java tomcat11-11.0.15/java/jakarta/servlet/GenericFilter.java
--- tomcat11-11.0.6/java/jakarta/servlet/GenericFilter.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/jakarta/servlet/GenericFilter.java 2025-12-02 16:54:08.000000000 +0000
@@ -76,8 +76,8 @@
/**
- * Convenience method for subclasses to save them having to call super.init(config). This is a NO-OP
- * by default.
+ * Convenience method for subclasses to save them having to call super.init(config). This is a NO-OP by
+ * default.
*
* @throws ServletException If an exception occurs that interrupts the Filter's normal operation
*/
diff -Nru tomcat11-11.0.6/java/jakarta/servlet/LocalStrings_ru.properties tomcat11-11.0.15/java/jakarta/servlet/LocalStrings_ru.properties
--- tomcat11-11.0.6/java/jakarta/servlet/LocalStrings_ru.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/jakarta/servlet/LocalStrings_ru.properties 2025-12-02 16:54:08.000000000 +0000
@@ -17,3 +17,9 @@
# To edit translations see: https://tomcat.apache.org/getinvolved.html#Translations
httpMethodConstraintElement.invalidMethod=Ошибочный HTTP метод
+
+value.false=ложный
+value.true=истина
+
+wrapper.nullRequest=запрос не может быть null
+wrapper.nullResponse=Ответ не может быть null
diff -Nru tomcat11-11.0.6/java/jakarta/servlet/ServletConnection.java tomcat11-11.0.15/java/jakarta/servlet/ServletConnection.java
--- tomcat11-11.0.6/java/jakarta/servlet/ServletConnection.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/jakarta/servlet/ServletConnection.java 2025-12-02 16:54:08.000000000 +0000
@@ -73,9 +73,9 @@
String getProtocolConnectionId();
/**
- * Determine whether the incoming network connection to the server used encryption or not. Note that where a
- * reverse proxy is used, the application may have a different view as to whether encryption is being used due to
- * the use of headers like {@code X-Forwarded-Proto}.
+ * Determine whether the incoming network connection to the server used encryption or not. Note that where a reverse
+ * proxy is used, the application may have a different view as to whether encryption is being used due to the use of
+ * headers like {@code X-Forwarded-Proto}.
*
* @return {@code true} if the incoming network connection used encryption, otherwise {@code false}
*/
diff -Nru tomcat11-11.0.6/java/jakarta/servlet/ServletContext.java tomcat11-11.0.15/java/jakarta/servlet/ServletContext.java
--- tomcat11-11.0.6/java/jakarta/servlet/ServletContext.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/jakarta/servlet/ServletContext.java 2025-12-02 16:54:08.000000000 +0000
@@ -72,9 +72,9 @@
* Returns a ServletContext object that corresponds to a specified URL on the server.
*
* This method allows servlets to gain access to the context for various parts of the server, and as needed obtain
- * {@link RequestDispatcher} objects from the context. The given path must begin with "/", is interpreted
- * relative to the server's document root and is matched against the context roots of other web applications hosted
- * on this container.
+ * {@link RequestDispatcher} objects from the context. The given path must begin with "/", is interpreted relative
+ * to the server's document root and is matched against the context roots of other web applications hosted on this
+ * container.
*
* In a security conscious environment, the servlet container may return null for a given URL.
*
diff -Nru tomcat11-11.0.6/java/jakarta/servlet/ServletRequest.java tomcat11-11.0.15/java/jakarta/servlet/ServletRequest.java
--- tomcat11-11.0.6/java/jakarta/servlet/ServletRequest.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/jakarta/servlet/ServletRequest.java 2025-12-02 16:54:08.000000000 +0000
@@ -105,7 +105,7 @@
default void setCharacterEncoding(Charset encoding) {
try {
setCharacterEncoding(encoding.name());
- } catch (UnsupportedEncodingException e) {
+ } catch (UnsupportedEncodingException ignore) {
// Unreachable code
}
}
diff -Nru tomcat11-11.0.6/java/jakarta/servlet/ServletResponse.java tomcat11-11.0.15/java/jakarta/servlet/ServletResponse.java
--- tomcat11-11.0.6/java/jakarta/servlet/ServletResponse.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/jakarta/servlet/ServletResponse.java 2025-12-02 16:54:08.000000000 +0000
@@ -66,7 +66,8 @@
* getWriter has been called or after the response has been committed have no effect on the character
* encoding. If no character encoding has been specified, ISO-8859-1 is returned.
*
- * See RFC 2047 for more information about character encoding and MIME.
+ * See RFC 2047 for more information about character encoding and
+ * MIME.
*
* @return a String specifying the name of the character encoding, for example, UTF-8
*/
diff -Nru tomcat11-11.0.6/java/jakarta/servlet/http/HttpServlet.java tomcat11-11.0.15/java/jakarta/servlet/http/HttpServlet.java
--- tomcat11-11.0.6/java/jakarta/servlet/http/HttpServlet.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/jakarta/servlet/http/HttpServlet.java 2025-12-02 16:54:08.000000000 +0000
@@ -735,9 +735,8 @@
if (REQUEST_FACADE_CLAZZ.isAssignableFrom(req.getClass())) {
try {
return ((Boolean) GET_ALLOW_TRACE.invoke(req, (Object[]) null)).booleanValue();
- } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
+ } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ignore) {
// Should never happen given the checks in place.
- // Ignore
}
}
}
@@ -944,11 +943,11 @@
Writer osw = null;
try {
osw = new OutputStreamWriter(out, encoding);
- } catch (UnsupportedEncodingException e) {
- // Impossible.
- // The same values were used in the constructor. If this method
- // gets called then the constructor must have succeeded so the
- // above call must also succeed.
+ } catch (UnsupportedEncodingException ignore) {
+ /*
+ * Impossible. The same values were used in the constructor. If this method gets called then the
+ * constructor must have succeeded so the above call must also succeed.
+ */
}
pw = new PrintWriter(osw);
}
diff -Nru tomcat11-11.0.6/java/jakarta/servlet/http/HttpServletRequest.java tomcat11-11.0.15/java/jakarta/servlet/http/HttpServletRequest.java
--- tomcat11-11.0.6/java/jakarta/servlet/http/HttpServletRequest.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/jakarta/servlet/http/HttpServletRequest.java 2025-12-02 16:54:08.000000000 +0000
@@ -77,8 +77,8 @@
* Date object. Use this method with headers that contain dates, such as
* If-Modified-Since.
*
- * The date is returned as the number of milliseconds since January 1, 1970 GMT. The header name
- * is case-insensitive.
+ * The date is returned as the number of milliseconds since January 1, 1970 GMT. The header name is
+ * case-insensitive.
*
* If the request did not have a header of the specified name, this method returns -1. If the header can't be
* converted to a date, the method throws an IllegalArgumentException.
@@ -297,8 +297,8 @@
String getRequestedSessionId();
/**
- * Returns the part of this request's URL from the protocol name up to the query string in the first line of the
- * HTTP request. The web container does not decode this String. For example:
+ * Returns the URI path part of this request's URL which starts after the authority (if any) and ends before the
+ * query string delimiter ({@code ?}), if any. The web container does not decode this String. For example:
*
*
Examples of Returned Values
*
@@ -320,7 +320,8 @@
*
* To reconstruct a URL with a scheme and host, use {@link #getRequestURL}.
*
- * @return a String containing the part of the URL from the protocol name up to the query string
+ * @return a String containing the path part of the URL from after the authority to before the query
+ * string
*
* @see #getRequestURL
*/
diff -Nru tomcat11-11.0.6/java/jakarta/servlet/http/LocalStrings_ja.properties tomcat11-11.0.15/java/jakarta/servlet/http/LocalStrings_ja.properties
--- tomcat11-11.0.6/java/jakarta/servlet/http/LocalStrings_ja.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/jakarta/servlet/http/LocalStrings_ja.properties 2025-12-02 16:54:08.000000000 +0000
@@ -28,7 +28,7 @@
http.method_delete_not_supported=HTTPのDELETEメソッドは、このURLではサポートされていません。
http.method_get_not_supported=HTTPのGETメソッドは、このURLではサポートされていません。
-http.method_not_implemented=メソッド [{0}] は RFC 2068 には定義されておらず、サーブレット API ではサポートされません
+http.method_not_implemented=メソッド [{0}] はこの URI のこのサーブレットでは実装されていません
http.method_patch_not_supported=HTTPのPATCHメソッドは、このURLではサポートされていません。
http.method_post_not_supported=HTTPのPOSTメソッドは、このURLではサポートされていません。
http.method_put_not_supported=HTTPのPUTメソッドは、このURLではサポートされていません。
diff -Nru tomcat11-11.0.6/java/jakarta/servlet/http/LocalStrings_ru.properties tomcat11-11.0.15/java/jakarta/servlet/http/LocalStrings_ru.properties
--- tomcat11-11.0.6/java/jakarta/servlet/http/LocalStrings_ru.properties 1970-01-01 00:00:00.000000000 +0000
+++ tomcat11-11.0.15/java/jakarta/servlet/http/LocalStrings_ru.properties 2025-12-02 16:54:08.000000000 +0000
@@ -0,0 +1,22 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Do not edit this file directly.
+# To edit translations see: https://tomcat.apache.org/getinvolved.html#Translations
+
+http.method_get_not_supported=HTTP метод GET не поддерживается этим URL
+http.method_patch_not_supported=HTTP метод PATCH не поддерживается этим URL
+http.method_post_not_supported=HTTP метод POST не поддерживается этим URL
+http.method_put_not_supported=HTTP метод PUT не поддерживается этим URL
diff -Nru tomcat11-11.0.6/java/jakarta/servlet/http/Part.java tomcat11-11.0.15/java/jakarta/servlet/http/Part.java
--- tomcat11-11.0.6/java/jakarta/servlet/http/Part.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/jakarta/servlet/http/Part.java 2025-12-02 16:54:08.000000000 +0000
@@ -69,11 +69,11 @@
long getSize();
/**
- * A convenience method to write an uploaded part to disk. The client code is not concerned with whether the
- * part is stored in memory, or on disk in a temporary location. They just want to write the uploaded part to a
- * file. This method is not guaranteed to succeed if called more than once for the same part. This allows a
- * particular implementation to use, for example, file renaming, where possible, rather than copying all of the
- * underlying data, thus gaining a significant performance benefit.
+ * A convenience method to write an uploaded part to disk. The client code is not concerned with whether the part is
+ * stored in memory, or on disk in a temporary location. They just want to write the uploaded part to a file. This
+ * method is not guaranteed to succeed if called more than once for the same part. This allows a particular
+ * implementation to use, for example, file renaming, where possible, rather than copying all of the underlying
+ * data, thus gaining a significant performance benefit.
*
* @param fileName The location into which the uploaded part should be stored. Relative locations are relative to
* {@link jakarta.servlet.MultipartConfigElement#getLocation()}
diff -Nru tomcat11-11.0.6/java/jakarta/servlet/jsp/LocalStrings_ru.properties tomcat11-11.0.15/java/jakarta/servlet/jsp/LocalStrings_ru.properties
--- tomcat11-11.0.6/java/jakarta/servlet/jsp/LocalStrings_ru.properties 1970-01-01 00:00:00.000000000 +0000
+++ tomcat11-11.0.15/java/jakarta/servlet/jsp/LocalStrings_ru.properties 2025-12-02 16:54:08.000000000 +0000
@@ -0,0 +1,19 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Do not edit this file directly.
+# To edit translations see: https://tomcat.apache.org/getinvolved.html#Translations
+
+el.unknown.identifier=Неизвестный идентификатор
diff -Nru tomcat11-11.0.6/java/jakarta/servlet/jsp/tagext/BodyContent.java tomcat11-11.0.15/java/jakarta/servlet/jsp/tagext/BodyContent.java
--- tomcat11-11.0.6/java/jakarta/servlet/jsp/tagext/BodyContent.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/jakarta/servlet/jsp/tagext/BodyContent.java 2025-12-02 16:54:08.000000000 +0000
@@ -71,7 +71,7 @@
public void clearBody() {
try {
this.clear();
- } catch (IOException ex) {
+ } catch (IOException ioe) {
// TODO -- clean this one up.
throw new Error("internal error!;");
}
diff -Nru tomcat11-11.0.6/java/jakarta/servlet/jsp/tagext/TagAttributeInfo.java tomcat11-11.0.15/java/jakarta/servlet/jsp/tagext/TagAttributeInfo.java
--- tomcat11-11.0.6/java/jakarta/servlet/jsp/tagext/TagAttributeInfo.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/jakarta/servlet/jsp/tagext/TagAttributeInfo.java 2025-12-02 16:54:08.000000000 +0000
@@ -165,14 +165,9 @@
*/
@Override
public String toString() {
- return "name = " + name + " " +
- "type = " + type + " " +
- "reqTime = " + reqTime + " " +
- "required = " + required + " " +
- "fragment = " + fragment + " " +
- "deferredValue = " + deferredValue + " " +
- "expectedTypeName = " + expectedTypeName + " " +
- "deferredMethod = " + deferredMethod + " " +
+ return "name = " + name + " " + "type = " + type + " " + "reqTime = " + reqTime + " " + "required = " +
+ required + " " + "fragment = " + fragment + " " + "deferredValue = " + deferredValue + " " +
+ "expectedTypeName = " + expectedTypeName + " " + "deferredMethod = " + deferredMethod + " " +
"methodSignature = " + methodSignature;
}
diff -Nru tomcat11-11.0.6/java/jakarta/websocket/ContainerProvider.java tomcat11-11.0.15/java/jakarta/websocket/ContainerProvider.java
--- tomcat11-11.0.6/java/jakarta/websocket/ContainerProvider.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/jakarta/websocket/ContainerProvider.java 2025-12-02 16:54:08.000000000 +0000
@@ -47,7 +47,7 @@
Class clazz =
(Class) Class.forName(DEFAULT_PROVIDER_CLASS_NAME);
result = clazz.getConstructor().newInstance();
- } catch (ReflectiveOperationException | IllegalArgumentException | SecurityException e) {
+ } catch (ReflectiveOperationException | IllegalArgumentException | SecurityException ignore) {
// No options left. Just return null.
}
}
diff -Nru tomcat11-11.0.6/java/jakarta/websocket/server/ServerEndpointConfig.java tomcat11-11.0.15/java/jakarta/websocket/server/ServerEndpointConfig.java
--- tomcat11-11.0.6/java/jakarta/websocket/server/ServerEndpointConfig.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/jakarta/websocket/server/ServerEndpointConfig.java 2025-12-02 16:54:08.000000000 +0000
@@ -176,7 +176,7 @@
@SuppressWarnings("unchecked")
Class clazz = (Class) Class.forName(DEFAULT_IMPL_CLASSNAME);
result = clazz.getConstructor().newInstance();
- } catch (ReflectiveOperationException | IllegalArgumentException | SecurityException e) {
+ } catch (ReflectiveOperationException | IllegalArgumentException | SecurityException ignore) {
// No options left. Just return null.
}
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/Authenticator.java tomcat11-11.0.15/java/org/apache/catalina/Authenticator.java
--- tomcat11-11.0.6/java/org/apache/catalina/Authenticator.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/Authenticator.java 2025-12-02 16:54:08.000000000 +0000
@@ -27,8 +27,6 @@
/**
* An Authenticator is a component (usually a Valve or Container) that provides some sort of authentication
* service.
- *
- * @author Craig R. McClanahan
*/
public interface Authenticator {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/Cluster.java tomcat11-11.0.15/java/org/apache/catalina/Cluster.java
--- tomcat11-11.0.6/java/org/apache/catalina/Cluster.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/Cluster.java 2025-12-02 16:54:08.000000000 +0000
@@ -21,9 +21,6 @@
* support different ways to communicate within the Cluster. A Cluster implementation is responsible for setting up a
* way to communicate within the Cluster and also supply "ClientApplications" with ClusterSender used when
* sending information in the Cluster and ClusterInfo used for receiving information in the Cluster.
- *
- * @author Bip Thelin
- * @author Remy Maucherat
*/
public interface Cluster extends Contained {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/Contained.java tomcat11-11.0.15/java/org/apache/catalina/Contained.java
--- tomcat11-11.0.6/java/org/apache/catalina/Contained.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/Contained.java 2025-12-02 16:54:08.000000000 +0000
@@ -17,13 +17,8 @@
package org.apache.catalina;
/**
- *
* Decoupling interface which specifies that an implementing class is associated with at most one
* Container instance.
- *
- *
- * @author Craig R. McClanahan
- * @author Peter Donald
*/
public interface Contained {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/Container.java tomcat11-11.0.15/java/org/apache/catalina/Container.java
--- tomcat11-11.0.6/java/org/apache/catalina/Container.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/Container.java 2025-12-02 16:54:08.000000000 +0000
@@ -60,9 +60,6 @@
*
Resources - JNDI directory context enabling access to static resources, enabling custom linkages to
* existing server components when Catalina is embedded in a larger server.
*
- *
- * @author Craig R. McClanahan
- * @author Remy Maucherat
*/
public interface Container extends Lifecycle {
@@ -429,7 +426,7 @@
*
* @param request Request (associated with the response) to log
* @param response Response (associated with the request) to log
- * @param time Time taken to process the request/response in milliseconds (use 0 if not known)
+ * @param time Time taken to process the request/response in nanoseconds (use 0 if not known)
* @param useDefault Flag that indicates that the request/response should be logged in the engine's default access
* log
*/
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/ContainerEvent.java tomcat11-11.0.15/java/org/apache/catalina/ContainerEvent.java
--- tomcat11-11.0.6/java/org/apache/catalina/ContainerEvent.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/ContainerEvent.java 2025-12-02 16:54:08.000000000 +0000
@@ -21,8 +21,6 @@
/**
* General event for notifying listeners of significant changes on a Container.
- *
- * @author Craig R. McClanahan
*/
public final class ContainerEvent extends EventObject {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/ContainerListener.java tomcat11-11.0.15/java/org/apache/catalina/ContainerListener.java
--- tomcat11-11.0.6/java/org/apache/catalina/ContainerListener.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/ContainerListener.java 2025-12-02 16:54:08.000000000 +0000
@@ -20,8 +20,6 @@
/**
* Interface defining a listener for significant Container generated events. Note that "container start" and "container
* stop" events are normally LifecycleEvents, not ContainerEvents.
- *
- * @author Craig R. McClanahan
*/
public interface ContainerListener {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/ContainerServlet.java tomcat11-11.0.15/java/org/apache/catalina/ContainerServlet.java
--- tomcat11-11.0.6/java/org/apache/catalina/ContainerServlet.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/ContainerServlet.java 2025-12-02 16:54:08.000000000 +0000
@@ -20,8 +20,6 @@
* A ContainerServlet is a servlet that has access to Catalina internal functionality, and is loaded from the
* Catalina class loader instead of the web application class loader. The property setter methods must be called by the
* container whenever a new instance of this servlet is put into service.
- *
- * @author Craig R. McClanahan
*/
public interface ContainerServlet {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/Context.java tomcat11-11.0.15/java/org/apache/catalina/Context.java
--- tomcat11-11.0.6/java/org/apache/catalina/Context.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/Context.java 2025-12-02 16:54:08.000000000 +0000
@@ -61,8 +61,6 @@
* The child containers attached to a Context are generally implementations of Wrapper (representing individual servlet
* definitions).
*
- *
- * @author Craig R. McClanahan
*/
public interface Context extends Container, ContextBind {
@@ -1105,7 +1103,7 @@
/**
* @return the array of watched resources for this Context. If none are defined, a zero length array will be
- * returned.
+ * returned.
*/
String[] findWatchedResources();
@@ -1121,7 +1119,7 @@
/**
* @return the array of welcome files defined for this Context. If none are defined, a zero-length array is
- * returned.
+ * returned.
*/
String[] findWelcomeFiles();
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/Engine.java tomcat11-11.0.15/java/org/apache/catalina/Engine.java
--- tomcat11-11.0.6/java/org/apache/catalina/Engine.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/Engine.java 2025-12-02 16:54:08.000000000 +0000
@@ -32,8 +32,6 @@
*
* If used, an Engine is always the top level Container in a Catalina hierarchy. Therefore, the implementation's
* setParent() method should throw IllegalArgumentException.
- *
- * @author Craig R. McClanahan
*/
public interface Engine extends Container {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/Globals.java tomcat11-11.0.15/java/org/apache/catalina/Globals.java
--- tomcat11-11.0.6/java/org/apache/catalina/Globals.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/Globals.java 2025-12-02 16:54:08.000000000 +0000
@@ -18,8 +18,6 @@
/**
* Global constants that are applicable to multiple packages within Catalina.
- *
- * @author Craig R. McClanahan
*/
public final class Globals {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/Group.java tomcat11-11.0.15/java/org/apache/catalina/Group.java
--- tomcat11-11.0.6/java/org/apache/catalina/Group.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/Group.java 2025-12-02 16:54:08.000000000 +0000
@@ -25,8 +25,6 @@
* group inherits the {@link Role}s assigned to the group.
*
*
- * @author Craig R. McClanahan
- *
* @since 4.1
*/
public interface Group extends Principal {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/Host.java tomcat11-11.0.15/java/org/apache/catalina/Host.java
--- tomcat11-11.0.6/java/org/apache/catalina/Host.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/Host.java 2025-12-02 16:54:08.000000000 +0000
@@ -37,8 +37,6 @@
*
* The child containers attached to a Host are generally implementations of Context (representing an individual servlet
* context).
- *
- * @author Craig R. McClanahan
*/
public interface Host extends Container {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/Lifecycle.java tomcat11-11.0.15/java/org/apache/catalina/Lifecycle.java
--- tomcat11-11.0.6/java/org/apache/catalina/Lifecycle.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/Lifecycle.java 2025-12-02 16:54:08.000000000 +0000
@@ -75,8 +75,6 @@
*
* The {@link LifecycleEvent}s fired during state changes are defined in the methods that trigger the changed. No
* {@link LifecycleEvent}s are fired if the attempted transition is not valid.
- *
- * @author Craig R. McClanahan
*/
public interface Lifecycle {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/LifecycleEvent.java tomcat11-11.0.15/java/org/apache/catalina/LifecycleEvent.java
--- tomcat11-11.0.6/java/org/apache/catalina/LifecycleEvent.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/LifecycleEvent.java 2025-12-02 16:54:08.000000000 +0000
@@ -21,8 +21,6 @@
/**
* General event for notifying listeners of significant changes on a component that implements the Lifecycle interface.
- *
- * @author Craig R. McClanahan
*/
public final class LifecycleEvent extends EventObject {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/LifecycleException.java tomcat11-11.0.15/java/org/apache/catalina/LifecycleException.java
--- tomcat11-11.0.6/java/org/apache/catalina/LifecycleException.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/LifecycleException.java 2025-12-02 16:54:08.000000000 +0000
@@ -22,8 +22,6 @@
/**
* General purpose exception that is thrown to indicate a lifecycle related problem. Such exceptions should generally be
* considered fatal to the operation of the application containing this component.
- *
- * @author Craig R. McClanahan
*/
public final class LifecycleException extends Exception {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/LifecycleListener.java tomcat11-11.0.15/java/org/apache/catalina/LifecycleListener.java
--- tomcat11-11.0.6/java/org/apache/catalina/LifecycleListener.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/LifecycleListener.java 2025-12-02 16:54:08.000000000 +0000
@@ -18,11 +18,9 @@
/**
- * Interface defining a listener for significant events (including "component start" and "component stop") generated by a
- * component that implements the Lifecycle interface. The listener will be fired after the associated state change has
+ * Interface defining a listener for significant events (including "component start" and "component stop") generated by
+ * a component that implements the Lifecycle interface. The listener will be fired after the associated state change has
* taken place.
- *
- * @author Craig R. McClanahan
*/
public interface LifecycleListener {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/Loader.java tomcat11-11.0.15/java/org/apache/catalina/Loader.java
--- tomcat11-11.0.6/java/org/apache/catalina/Loader.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/Loader.java 2025-12-02 16:54:08.000000000 +0000
@@ -35,8 +35,6 @@
*
Based on a policy chosen by the implementation, must call the Context.reload() method on the owning
* Context when a change to one or more of the class files loaded by this class loader is detected.
*
- *
- * @author Craig R. McClanahan
*/
public interface Loader {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/Manager.java tomcat11-11.0.15/java/org/apache/catalina/Manager.java
--- tomcat11-11.0.6/java/org/apache/catalina/Manager.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/Manager.java 2025-12-02 16:54:08.000000000 +0000
@@ -31,8 +31,6 @@
*
Must allow a call to stop() to be followed by a call to start() on the same
* Manager instance.
*
- *
- * @author Craig R. McClanahan
*/
public interface Manager {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/Pipeline.java tomcat11-11.0.15/java/org/apache/catalina/Pipeline.java
--- tomcat11-11.0.6/java/org/apache/catalina/Pipeline.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/Pipeline.java 2025-12-02 16:54:08.000000000 +0000
@@ -19,21 +19,15 @@
import java.util.Set;
/**
- *
* Interface describing a collection of Valves that should be executed in sequence when the invoke() method
* is invoked. It is required that a Valve somewhere in the pipeline (usually the last one) must process the request and
* create the corresponding response, rather than trying to pass the request on.
- *
*
* There is generally a single Pipeline instance associated with each Container. The container's normal request
* processing functionality is generally encapsulated in a container-specific Valve, which should always be executed at
* the end of a pipeline. To facilitate this, the setBasic() method is provided to set the Valve instance
* that will always be executed last. Other Valves will be executed in the order that they were added, before the basic
* Valve is executed.
- *
- *
- * @author Craig R. McClanahan
- * @author Peter Donald
*/
public interface Pipeline extends Contained {
@@ -81,7 +75,7 @@
/**
* @return the array of Valves in the pipeline associated with this Container, including the basic Valve (if any).
- * If there are no such Valves, a zero-length array is returned.
+ * If there are no such Valves, a zero-length array is returned.
*/
Valve[] getValves();
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/Realm.java tomcat11-11.0.15/java/org/apache/catalina/Realm.java
--- tomcat11-11.0.6/java/org/apache/catalina/Realm.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/Realm.java 2025-12-02 16:54:08.000000000 +0000
@@ -32,8 +32,6 @@
* A Realm is a read-only facade for an underlying security realm used to authenticate individual users, and
* identify the security roles associated with those users. Realms can be attached at any Container level, but will
* typically only be attached to a Context, or higher level, Container.
- *
- * @author Craig R. McClanahan
*/
public interface Realm extends Contained {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/Role.java tomcat11-11.0.15/java/org/apache/catalina/Role.java
--- tomcat11-11.0.6/java/org/apache/catalina/Role.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/Role.java 2025-12-02 16:54:08.000000000 +0000
@@ -26,8 +26,6 @@
* Principals.
*
*
- * @author Craig R. McClanahan
- *
* @since 4.1
*/
public interface Role extends Principal {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/Server.java tomcat11-11.0.15/java/org/apache/catalina/Server.java
--- tomcat11-11.0.6/java/org/apache/catalina/Server.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/Server.java 2025-12-02 16:54:08.000000000 +0000
@@ -34,8 +34,6 @@
* In between, the implementation must open a server socket on the port number specified by the port
* property. When a connection is accepted, the first line is read and compared with the specified shutdown command. If
* the command matches, shutdown of the server is initiated.
- *
- * @author Craig R. McClanahan
*/
public interface Server extends Lifecycle {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/Service.java tomcat11-11.0.15/java/org/apache/catalina/Service.java
--- tomcat11-11.0.6/java/org/apache/catalina/Service.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/Service.java 2025-12-02 16:54:08.000000000 +0000
@@ -26,8 +26,6 @@
*
* A given JVM can contain any number of Service instances; however, they are completely independent of each other and
* share only the basic JVM facilities and classes on the system class path.
- *
- * @author Craig R. McClanahan
*/
public interface Service extends Lifecycle {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/Session.java tomcat11-11.0.15/java/org/apache/catalina/Session.java
--- tomcat11-11.0.6/java/org/apache/catalina/Session.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/Session.java 2025-12-02 16:54:08.000000000 +0000
@@ -26,8 +26,6 @@
/**
* A Session is the Catalina-internal facade for an HttpSession that is used to maintain state
* information between requests for a particular user of a web application.
- *
- * @author Craig R. McClanahan
*/
public interface Session {
@@ -58,6 +56,10 @@
*/
String SESSION_PASSIVATED_EVENT = "passivateSession";
+ /**
+ * The SessionEvent event type when a session changes its sessionId.
+ */
+ String SESSION_CHANGED_ID_EVENT = "changeSessionId";
// ------------------------------------------------------------- Properties
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/SessionEvent.java tomcat11-11.0.15/java/org/apache/catalina/SessionEvent.java
--- tomcat11-11.0.6/java/org/apache/catalina/SessionEvent.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/SessionEvent.java 2025-12-02 16:54:08.000000000 +0000
@@ -23,8 +23,6 @@
/**
* General event for notifying listeners of significant changes on a Session.
- *
- * @author Craig R. McClanahan
*/
public final class SessionEvent extends EventObject {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/SessionListener.java tomcat11-11.0.15/java/org/apache/catalina/SessionListener.java
--- tomcat11-11.0.6/java/org/apache/catalina/SessionListener.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/SessionListener.java 2025-12-02 16:54:08.000000000 +0000
@@ -21,8 +21,6 @@
/**
* Interface defining a listener for significant Session generated events.
- *
- * @author Craig R. McClanahan
*/
public interface SessionListener extends EventListener {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/Store.java tomcat11-11.0.15/java/org/apache/catalina/Store.java
--- tomcat11-11.0.6/java/org/apache/catalina/Store.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/Store.java 2025-12-02 16:54:08.000000000 +0000
@@ -25,13 +25,9 @@
* A Store is the abstraction of a Catalina component that provides persistent storage and loading of Sessions
* and their associated user data. Implementations are free to save and load the Sessions to any media they wish, but it
* is assumed that saved Sessions are persistent across server or context restarts.
- *
- * @author Craig R. McClanahan
*/
public interface Store {
- // ------------------------------------------------------------- Properties
-
/**
* @return the Manager instance associated with this Store.
*/
@@ -54,9 +50,6 @@
int getSize() throws IOException;
- // --------------------------------------------------------- Public Methods
-
-
/**
* Add a property change listener to this component.
*
@@ -77,6 +70,11 @@
/**
* Load and return the Session associated with the specified session identifier from this Store, without removing
* it. If there is no such stored Session, return null.
+ *
+ * Implementations should expect, and correctly handle, concurrent calls to any method but in particular calls to
+ * {@code #load(String)}, {@code #save(Session)} and {@code #remove(String)} for the same session.
+ *
+ * The session ID is user provided so stores must treat it as untrusted data.
*
* @param id Session identifier of the session to load
*
@@ -91,6 +89,11 @@
/**
* Remove the Session with the specified session identifier from this Store, if present. If no such Session is
* present, this method takes no action.
+ *
+ * Implementations should expect, and correctly handle, concurrent calls to any method but in particular calls to
+ * {@code #load(String)}, {@code #save(Session)} and {@code #remove(String)} for the same session.
+ *
+ * The session ID is user provided so stores must treat it as untrusted data.
*
* @param id Session identifier of the Session to be removed
*
@@ -118,12 +121,13 @@
/**
* Save the specified Session into this Store. Any previously saved information for the associated session
* identifier is replaced.
+ *
+ * Implementations should expect, and correctly handle, concurrent calls to any method but in particular calls to
+ * {@code #load(String)}, {@code #save(Session)} and {@code #remove(String)} for the same session.
*
* @param session Session to be saved
*
* @exception IOException if an input/output error occurs
*/
void save(Session session) throws IOException;
-
-
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/User.java tomcat11-11.0.15/java/org/apache/catalina/User.java
--- tomcat11-11.0.6/java/org/apache/catalina/User.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/User.java 2025-12-02 16:54:08.000000000 +0000
@@ -26,8 +26,6 @@
* {@link Group}s through which they inherit additional security roles, and is optionally assigned a set of specific
* {@link Role}s.
*
- * @author Craig R. McClanahan
- *
* @since 4.1
*/
public interface User extends Principal {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/UserDatabase.java tomcat11-11.0.15/java/org/apache/catalina/UserDatabase.java
--- tomcat11-11.0.6/java/org/apache/catalina/UserDatabase.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/UserDatabase.java 2025-12-02 16:54:08.000000000 +0000
@@ -23,8 +23,6 @@
* along with definitions of corresponding {@link Role}s, and referenced by a {@link Realm} for authentication and
* access control.
*
- * @author Craig R. McClanahan
- *
* @since 4.1
*/
public interface UserDatabase {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/Valve.java tomcat11-11.0.15/java/org/apache/catalina/Valve.java
--- tomcat11-11.0.6/java/org/apache/catalina/Valve.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/Valve.java 2025-12-02 16:54:08.000000000 +0000
@@ -24,17 +24,12 @@
import org.apache.catalina.connector.Response;
/**
- *
* A Valve is a request processing component associated with a particular Container. A series of Valves are
* generally associated with each other into a Pipeline. The detailed contract for a Valve is included in the
* description of the invoke() method below.
- *
+ *
* HISTORICAL NOTE: The "Valve" name was assigned to this concept because a valve is what you use in a real world
* pipeline to control and/or modify flows through it.
- *
- * @author Craig R. McClanahan
- * @author Gunnar Rjnning
- * @author Peter Donald
*/
public interface Valve {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/WebResourceLockSet.java tomcat11-11.0.15/java/org/apache/catalina/WebResourceLockSet.java
--- tomcat11-11.0.6/java/org/apache/catalina/WebResourceLockSet.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/WebResourceLockSet.java 2025-12-02 16:54:08.000000000 +0000
@@ -17,6 +17,7 @@
package org.apache.catalina;
import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
@@ -25,13 +26,27 @@
public interface WebResourceLockSet {
/**
+ * Obtain a reentrant read/write lock for the resource at the provided path. The resource is not required to exist.
+ * Multiple calls to this method with the same path will return the same lock provided that at least one instance of
+ * the lock remains in use between the calls.
+ *
+ * @param path The path for which the lock should be obtained
+ *
+ * @return A reentrant read/write lock for the given resource.
+ */
+ ReadWriteLock getLock(String path);
+
+ /**
* Lock the resource at the provided path for reading. The resource is not required to exist. Read locks are not
* exclusive.
*
* @param path The path to the resource to be locked for reading
*
* @return The {@link ResourceLock} that must be passed to {@link #unlockForRead(ResourceLock)} to release the lock
+ *
+ * @deprecated Unused. Will be removed in Tomcat 12 onwards. Use {@code #getLock(String)} instead.
*/
+ @Deprecated
ResourceLock lockForRead(String path);
/**
@@ -39,7 +54,10 @@
*
* @param resourceLock The {@link ResourceLock} associated with the resource for which a read lock should be
* released
+ *
+ * @deprecated Unused. Will be removed in Tomcat 12 onwards. Use {@code #getLock(String)} instead.
*/
+ @Deprecated
void unlockForRead(ResourceLock resourceLock);
/**
@@ -49,7 +67,10 @@
* @param path The path to the resource to be locked for writing
*
* @return The {@link ResourceLock} that must be passed to {@link #unlockForWrite(ResourceLock)} to release the lock
+ *
+ * @deprecated Unused. Will be removed in Tomcat 12 onwards. Use {@code #getLock(String)} instead.
*/
+ @Deprecated
ResourceLock lockForWrite(String path);
/**
@@ -57,10 +78,19 @@
*
* @param resourceLock The {@link ResourceLock} associated with the resource for which the write lock should be
* released
+ *
+ * @deprecated Unused. Will be removed in Tomcat 12 onwards. Use {@code #getLock(String)} instead.
*/
+ @Deprecated
void unlockForWrite(ResourceLock resourceLock);
+ /**
+ * Represents a lock on a resource.
+ *
+ * @deprecated Unused. Will be removed in Tomcat 12 onwards.
+ */
+ @Deprecated
class ResourceLock {
public final AtomicInteger count = new AtomicInteger(0);
public final ReentrantReadWriteLock reentrantLock = new ReentrantReadWriteLock();
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/WebResourceRoot.java tomcat11-11.0.15/java/org/apache/catalina/WebResourceRoot.java
--- tomcat11-11.0.6/java/org/apache/catalina/WebResourceRoot.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/WebResourceRoot.java 2025-12-02 16:54:08.000000000 +0000
@@ -21,6 +21,8 @@
import java.util.List;
import java.util.Set;
+import org.apache.catalina.util.ResourceSet;
+
/**
* Represents the complete set of resources for a web application. The resources for a web application consist of
* multiple ResourceSets and when looking for a Resource, the ResourceSets are processed in the following order:
@@ -95,8 +97,8 @@
* calls to this method until the web application is reloaded. No guarantee is made as to what the search order for
* JAR files may be.
*
- * @param path The path of the class loader resource of interest relative to the root of class loader resources
- * for this web application.
+ * @param path The path of the class loader resource of interest relative to the root of class loader resources for
+ * this web application.
*
* @return The object that represents the class loader resource at the given path
*/
@@ -246,14 +248,16 @@
void setContext(Context context);
/**
- * Configure if this resources allow the use of symbolic links.
+ * Configure if this web application allows the use of symbolic links by default. Individual {@link ResourceSet}s
+ * may override this setting.
*
* @param allowLinking true if symbolic links are allowed.
*/
void setAllowLinking(boolean allowLinking);
/**
- * Determine if this resources allow the use of symbolic links.
+ * Determine if this web application allows the use of symbolic links by default. Individual {@link ResourceSet}s
+ * may override this setting.
*
* @return true if symbolic links are allowed
*/
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/WebResourceSet.java tomcat11-11.0.15/java/org/apache/catalina/WebResourceSet.java
--- tomcat11-11.0.6/java/org/apache/catalina/WebResourceSet.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/WebResourceSet.java 2025-12-02 16:54:08.000000000 +0000
@@ -135,4 +135,19 @@
* resources.
*/
void gc();
+
+ /**
+ * Configure if this {@code ResourceSet} allows the use of symbolic links.
+ *
+ * @param allowLinking true if symbolic links are allowed.
+ */
+ void setAllowLinking(boolean allowLinking);
+
+ /**
+ * Determine if this {@code ResourceSet} allows the use of symbolic links. If {@link #setAllowLinking(boolean)} has
+ * not been called for this instance, the value of {@link WebResourceRoot#getAllowLinking()} is returned.
+ *
+ * @return true if symbolic links are allowed
+ */
+ boolean getAllowLinking();
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/Wrapper.java tomcat11-11.0.15/java/org/apache/catalina/Wrapper.java
--- tomcat11-11.0.6/java/org/apache/catalina/Wrapper.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/Wrapper.java 2025-12-02 16:54:08.000000000 +0000
@@ -36,8 +36,6 @@
*
* Child Containers are not allowed on Wrapper implementations, so the addChild() method should throw an
* IllegalArgumentException.
- *
- * @author Craig R. McClanahan
*/
public interface Wrapper extends Container {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/ant/AbstractCatalinaTask.java tomcat11-11.0.15/java/org/apache/catalina/ant/AbstractCatalinaTask.java
--- tomcat11-11.0.6/java/org/apache/catalina/ant/AbstractCatalinaTask.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/ant/AbstractCatalinaTask.java 2025-12-02 16:54:08.000000000 +0000
@@ -28,6 +28,7 @@
import java.net.URLConnection;
import org.apache.catalina.util.IOTools;
+import org.apache.tomcat.util.http.Method;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
@@ -35,8 +36,6 @@
* Abstract base class for Ant tasks that interact with the Manager web application for dynamically deploying
* and undeploying applications. These tasks require Ant 1.4 or later.
*
- * @author Craig R. McClanahan
- *
* @since 4.1
*/
public abstract class AbstractCatalinaTask extends BaseRedirectorHelperTask {
@@ -187,7 +186,7 @@
preAuthenticate();
hconn.setDoOutput(true);
- hconn.setRequestMethod("PUT");
+ hconn.setRequestMethod(Method.PUT);
if (contentType != null) {
hconn.setRequestProperty("Content-Type", contentType);
}
@@ -198,7 +197,7 @@
}
} else {
hconn.setDoOutput(false);
- hconn.setRequestMethod("GET");
+ hconn.setRequestMethod(Method.GET);
}
hconn.setRequestProperty("User-Agent", "Catalina-Ant-Task/1.0");
@@ -297,7 +296,7 @@
hconn.setDoInput(true);
hconn.setUseCaches(false);
hconn.setDoOutput(false);
- hconn.setRequestMethod("OPTIONS");
+ hconn.setRequestMethod(Method.OPTIONS);
hconn.setRequestProperty("User-Agent", "Catalina-Ant-Task/1.0");
// Establish the connection with the server
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/ant/BaseRedirectorHelperTask.java tomcat11-11.0.15/java/org/apache/catalina/ant/BaseRedirectorHelperTask.java
--- tomcat11-11.0.6/java/org/apache/catalina/ant/BaseRedirectorHelperTask.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/ant/BaseRedirectorHelperTask.java 2025-12-02 16:54:08.000000000 +0000
@@ -30,14 +30,12 @@
/**
* Abstract base class to add output redirection support for Catalina Ant tasks. These tasks require Ant 1.5 or later.
*
- * WARNING: due to dependency chain, Ant could call a Task more than once and this can affect the output
- * redirection when configured. If you are collecting the output in a property, it will collect the output of only the
- * first run, since Ant properties are immutable and once created they cannot be changed.
+ * WARNING: due to dependency chain, Ant could call a Task more than once and this can affect the
+ * output redirection when configured. If you are collecting the output in a property, it will collect the output of
+ * only the first run, since Ant properties are immutable and once created they cannot be changed.
* If you are collecting output in a file the file will be overwritten with the output of the last run, unless you set
* append="true", in which case each run will append it's output to the file.
*
- * @author Gabriele Garuglieri
- *
* @since 5.5
*/
public abstract class BaseRedirectorHelperTask extends Task {
@@ -218,8 +216,8 @@
redirectOutput = true;
}
/*
- * Due to dependency chain, Ant could call the Task more than once, this is to prevent that we attempt to configure
- * uselessly more than once the Redirector.
+ * Due to dependency chain, Ant could call the Task more than once, this is to prevent that we attempt to
+ * configure uselessly more than once the Redirector.
*/
redirectorConfigured = true;
}
@@ -256,8 +254,8 @@
log("Error closing redirector: " + ioe.getMessage(), Project.MSG_ERR);
}
/*
- * Due to dependency chain, Ant could call the Task more than once, this is to prevent that we attempt to reuse the
- * previously closed Streams.
+ * Due to dependency chain, Ant could call the Task more than once, this is to prevent that we attempt to reuse
+ * the previously closed Streams.
*/
redirectOutStream = null;
redirectOutPrintStream = null;
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/ant/DeployTask.java tomcat11-11.0.15/java/org/apache/catalina/ant/DeployTask.java
--- tomcat11-11.0.6/java/org/apache/catalina/ant/DeployTask.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/ant/DeployTask.java 2025-12-02 16:54:08.000000000 +0000
@@ -32,8 +32,6 @@
/**
* Ant task that implements the /deploy command, supported by the Tomcat manager application.
*
- * @author Craig R. McClanahan
- *
* @since 4.1
*/
public class DeployTask extends AbstractCatalinaCommandTask {
@@ -145,15 +143,15 @@
FileChannel fsChannel = fsInput.getChannel();
contentLength = fsChannel.size();
stream = new BufferedInputStream(fsInput, 1024);
- } catch (IOException e) {
+ } catch (IOException ioe) {
if (fsInput != null) {
try {
fsInput.close();
- } catch (IOException ioe) {
+ } catch (IOException ignore) {
// Ignore
}
}
- throw new BuildException(e);
+ throw new BuildException(ioe);
}
}
contentType = "application/octet-stream";
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/ant/JKStatusUpdateTask.java tomcat11-11.0.15/java/org/apache/catalina/ant/JKStatusUpdateTask.java
--- tomcat11-11.0.6/java/org/apache/catalina/ant/JKStatusUpdateTask.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/ant/JKStatusUpdateTask.java 2025-12-02 16:54:08.000000000 +0000
@@ -24,8 +24,6 @@
/**
* Ant task that implements the /status command, supported by the mod_jk status (1.2.9) application.
*
- * @author Peter Rossbach
- *
* @since 5.5.9
*/
public class JKStatusUpdateTask extends AbstractCatalinaTask {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/ant/JMXGetTask.java tomcat11-11.0.15/java/org/apache/catalina/ant/JMXGetTask.java
--- tomcat11-11.0.6/java/org/apache/catalina/ant/JMXGetTask.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/ant/JMXGetTask.java 2025-12-02 16:54:08.000000000 +0000
@@ -26,8 +26,6 @@
/**
* Ant task that implements the JMX Get command (/jmxproxy/?get) supported by the Tomcat manager
* application.
- *
- * @author Peter Rossbach
*/
public class JMXGetTask extends AbstractCatalinaTask {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/ant/JMXQueryTask.java tomcat11-11.0.15/java/org/apache/catalina/ant/JMXQueryTask.java
--- tomcat11-11.0.6/java/org/apache/catalina/ant/JMXQueryTask.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/ant/JMXQueryTask.java 2025-12-02 16:54:08.000000000 +0000
@@ -26,8 +26,6 @@
/**
* Ant task that implements the JMX Query command (/jmxproxy/?qry) supported by the Tomcat manager
* application.
- *
- * @author Vivek Chopra
*/
public class JMXQueryTask extends AbstractCatalinaTask {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/ant/JMXSetTask.java tomcat11-11.0.15/java/org/apache/catalina/ant/JMXSetTask.java
--- tomcat11-11.0.6/java/org/apache/catalina/ant/JMXSetTask.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/ant/JMXSetTask.java 2025-12-02 16:54:08.000000000 +0000
@@ -26,8 +26,6 @@
/**
* Ant task that implements the JMX Set command (/jmxproxy/?set) supported by the Tomcat manager
* application.
- *
- * @author Vivek Chopra
*/
public class JMXSetTask extends AbstractCatalinaTask {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/ant/ListTask.java tomcat11-11.0.15/java/org/apache/catalina/ant/ListTask.java
--- tomcat11-11.0.6/java/org/apache/catalina/ant/ListTask.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/ant/ListTask.java 2025-12-02 16:54:08.000000000 +0000
@@ -23,8 +23,6 @@
/**
* Ant task that implements the /list command, supported by the Tomcat manager application.
*
- * @author Craig R. McClanahan
- *
* @since 4.1
*/
public class ListTask extends AbstractCatalinaTask {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/ant/ReloadTask.java tomcat11-11.0.15/java/org/apache/catalina/ant/ReloadTask.java
--- tomcat11-11.0.6/java/org/apache/catalina/ant/ReloadTask.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/ant/ReloadTask.java 2025-12-02 16:54:08.000000000 +0000
@@ -23,8 +23,6 @@
/**
* Ant task that implements the /reload command, supported by the Tomcat manager application.
*
- * @author Craig R. McClanahan
- *
* @since 4.1
*/
public class ReloadTask extends AbstractCatalinaCommandTask {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/ant/ResourcesTask.java tomcat11-11.0.15/java/org/apache/catalina/ant/ResourcesTask.java
--- tomcat11-11.0.6/java/org/apache/catalina/ant/ResourcesTask.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/ant/ResourcesTask.java 2025-12-02 16:54:08.000000000 +0000
@@ -26,8 +26,6 @@
/**
* Ant task that implements the /resources command, supported by the Tomcat manager application.
*
- * @author Craig R. McClanahan
- *
* @since 4.1
*/
public class ResourcesTask extends AbstractCatalinaTask {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/ant/ServerinfoTask.java tomcat11-11.0.15/java/org/apache/catalina/ant/ServerinfoTask.java
--- tomcat11-11.0.6/java/org/apache/catalina/ant/ServerinfoTask.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/ant/ServerinfoTask.java 2025-12-02 16:54:08.000000000 +0000
@@ -16,19 +16,13 @@
*/
package org.apache.catalina.ant;
-
import org.apache.tools.ant.BuildException;
-
/**
* Ant task that implements the /serverinfo command supported by the Tomcat manager application.
- *
- * @author Vivek Chopra
*/
public class ServerinfoTask extends AbstractCatalinaTask {
- // Public Methods
-
/**
* Execute the requested operation.
*
@@ -36,9 +30,7 @@
*/
@Override
public void execute() throws BuildException {
-
super.execute();
execute("/serverinfo");
-
}
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/ant/SessionsTask.java tomcat11-11.0.15/java/org/apache/catalina/ant/SessionsTask.java
--- tomcat11-11.0.6/java/org/apache/catalina/ant/SessionsTask.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/ant/SessionsTask.java 2025-12-02 16:54:08.000000000 +0000
@@ -16,18 +16,13 @@
*/
package org.apache.catalina.ant;
-
import org.apache.tools.ant.BuildException;
-
/**
* Ant task that implements the /sessions command supported by the Tomcat manager application.
- *
- * @author Vivek Chopra
*/
public class SessionsTask extends AbstractCatalinaCommandTask {
-
protected String idle = null;
public String getIdle() {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/ant/StartTask.java tomcat11-11.0.15/java/org/apache/catalina/ant/StartTask.java
--- tomcat11-11.0.6/java/org/apache/catalina/ant/StartTask.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/ant/StartTask.java 2025-12-02 16:54:08.000000000 +0000
@@ -23,8 +23,6 @@
/**
* Ant task that implements the /start command, supported by the Tomcat manager application.
*
- * @author Craig R. McClanahan
- *
* @since 4.1
*/
public class StartTask extends AbstractCatalinaCommandTask {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/ant/StopTask.java tomcat11-11.0.15/java/org/apache/catalina/ant/StopTask.java
--- tomcat11-11.0.6/java/org/apache/catalina/ant/StopTask.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/ant/StopTask.java 2025-12-02 16:54:08.000000000 +0000
@@ -23,8 +23,6 @@
/**
* Ant task that implements the /stop command, supported by the Tomcat manager application.
*
- * @author Craig R. McClanahan
- *
* @since 4.1
*/
public class StopTask extends AbstractCatalinaCommandTask {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/ant/UndeployTask.java tomcat11-11.0.15/java/org/apache/catalina/ant/UndeployTask.java
--- tomcat11-11.0.6/java/org/apache/catalina/ant/UndeployTask.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/ant/UndeployTask.java 2025-12-02 16:54:08.000000000 +0000
@@ -23,8 +23,6 @@
/**
* Ant task that implements the /undeploy command, supported by the Tomcat manager application.
*
- * @author Craig R. McClanahan
- *
* @since 4.1
*/
public class UndeployTask extends AbstractCatalinaCommandTask {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/ant/ValidatorTask.java tomcat11-11.0.15/java/org/apache/catalina/ant/ValidatorTask.java
--- tomcat11-11.0.6/java/org/apache/catalina/ant/ValidatorTask.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/ant/ValidatorTask.java 2025-12-02 16:54:08.000000000 +0000
@@ -31,8 +31,6 @@
/**
* Task for validating a web application deployment descriptor, using XML schema validation.
*
- * @author Remy Maucherat
- *
* @since 5.0
*/
public class ValidatorTask extends BaseRedirectorHelperTask {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/ant/jmx/JMXAccessorCondition.java tomcat11-11.0.15/java/org/apache/catalina/ant/jmx/JMXAccessorCondition.java
--- tomcat11-11.0.6/java/org/apache/catalina/ant/jmx/JMXAccessorCondition.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/ant/jmx/JMXAccessorCondition.java 2025-12-02 16:54:08.000000000 +0000
@@ -77,8 +77,6 @@
* NOTE: For numeric expressions the type must be set and use xml entities as operations.
* As type we currently support long and double.
*
- * @author Peter Rossbach
- *
* @since 5.5.10
*/
public class JMXAccessorCondition extends JMXAccessorConditionBase {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/ant/jmx/JMXAccessorCreateTask.java tomcat11-11.0.15/java/org/apache/catalina/ant/jmx/JMXAccessorCreateTask.java
--- tomcat11-11.0.6/java/org/apache/catalina/ant/jmx/JMXAccessorCreateTask.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/ant/jmx/JMXAccessorCreateTask.java 2025-12-02 16:54:08.000000000 +0000
@@ -46,16 +46,14 @@
* </jmxCreate/>
*
*
- * WARNINGNot all Tomcat MBeans can create remotely and auto register by its parents! Please, use the MBeanFactory
- * operation to generate valves and realms.
+ * WARNINGNot all Tomcat MBeans can create remotely and auto register by its parents! Please, use the
+ * MBeanFactory operation to generate valves and realms.
*
*
* First call to a remote MBean server save the JMXConnection a reference jmx.server
*
* These tasks require Ant 1.6 or later interface.
*
- * @author Peter Rossbach
- *
* @since 5.5.12
*/
public class JMXAccessorCreateTask extends JMXAccessorTask {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/ant/jmx/JMXAccessorEqualsCondition.java tomcat11-11.0.15/java/org/apache/catalina/ant/jmx/JMXAccessorEqualsCondition.java
--- tomcat11-11.0.6/java/org/apache/catalina/ant/jmx/JMXAccessorEqualsCondition.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/ant/jmx/JMXAccessorEqualsCondition.java 2025-12-02 16:54:08.000000000 +0000
@@ -54,8 +54,6 @@
* </target>
*
*
- * @author Peter Rossbach
- *
* @since 5.5.10
*/
public class JMXAccessorEqualsCondition extends JMXAccessorConditionBase {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/ant/jmx/JMXAccessorGetTask.java tomcat11-11.0.15/java/org/apache/catalina/ant/jmx/JMXAccessorGetTask.java
--- tomcat11-11.0.6/java/org/apache/catalina/ant/jmx/JMXAccessorGetTask.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/ant/jmx/JMXAccessorGetTask.java 2025-12-02 16:54:08.000000000 +0000
@@ -49,8 +49,6 @@
*
* These tasks require Ant 1.6 or later interface.
*
- * @author Peter Rossbach
- *
* @since 5.5.10
*/
public class JMXAccessorGetTask extends JMXAccessorTask {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/ant/jmx/JMXAccessorInvokeTask.java tomcat11-11.0.15/java/org/apache/catalina/ant/jmx/JMXAccessorInvokeTask.java
--- tomcat11-11.0.6/java/org/apache/catalina/ant/jmx/JMXAccessorInvokeTask.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/ant/jmx/JMXAccessorInvokeTask.java 2025-12-02 16:54:08.000000000 +0000
@@ -54,6 +54,7 @@
*
*
*
* First call to a remote MBeanserver save the JMXConnection a referenz jmx.server
*
* These tasks require Ant 1.6 or later interface.
*
- * @author Peter Rossbach
- *
* @since 5.5.10
*/
public class JMXAccessorInvokeTask extends JMXAccessorTask {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/ant/jmx/JMXAccessorQueryTask.java tomcat11-11.0.15/java/org/apache/catalina/ant/jmx/JMXAccessorQueryTask.java
--- tomcat11-11.0.6/java/org/apache/catalina/ant/jmx/JMXAccessorQueryTask.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/ant/jmx/JMXAccessorQueryTask.java 2025-12-02 16:54:08.000000000 +0000
@@ -51,8 +51,6 @@
* The property manager.length show the size of the result and with manager.[0..length].name the resulted ObjectNames
* are saved. These tasks require Ant 1.6 or later interface.
*
- * @author Peter Rossbach
- *
* @since 5.5.10
*/
public class JMXAccessorQueryTask extends JMXAccessorTask {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/ant/jmx/JMXAccessorSetTask.java tomcat11-11.0.15/java/org/apache/catalina/ant/jmx/JMXAccessorSetTask.java
--- tomcat11-11.0.6/java/org/apache/catalina/ant/jmx/JMXAccessorSetTask.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/ant/jmx/JMXAccessorSetTask.java 2025-12-02 16:54:08.000000000 +0000
@@ -55,8 +55,6 @@
*
* These tasks require Ant 1.6 or later interface.
*
- * @author Peter Rossbach
- *
* @since 5.5.10
*/
public class JMXAccessorSetTask extends JMXAccessorTask {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/ant/jmx/JMXAccessorTask.java tomcat11-11.0.15/java/org/apache/catalina/ant/jmx/JMXAccessorTask.java
--- tomcat11-11.0.6/java/org/apache/catalina/ant/jmx/JMXAccessorTask.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/ant/jmx/JMXAccessorTask.java 2025-12-02 16:54:08.000000000 +0000
@@ -77,8 +77,6 @@
* execute when property exist and with unless when property not exists.
* NOTE : These tasks require Ant 1.6 or later interface.
*
- * @author Peter Rossbach
- *
* @since 5.5.10
*/
public class JMXAccessorTask extends BaseRedirectorHelperTask {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/ant/jmx/JMXAccessorUnregisterTask.java tomcat11-11.0.15/java/org/apache/catalina/ant/jmx/JMXAccessorUnregisterTask.java
--- tomcat11-11.0.6/java/org/apache/catalina/ant/jmx/JMXAccessorUnregisterTask.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/ant/jmx/JMXAccessorUnregisterTask.java 2025-12-02 16:54:08.000000000 +0000
@@ -45,8 +45,6 @@
*
* These tasks require Ant 1.6 or later interface.
*
- * @author Peter Rossbach
- *
* @since 5.5.12
*/
public class JMXAccessorUnregisterTask extends JMXAccessorTask {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/authenticator/AuthenticatorBase.java tomcat11-11.0.15/java/org/apache/catalina/authenticator/AuthenticatorBase.java
--- tomcat11-11.0.6/java/org/apache/catalina/authenticator/AuthenticatorBase.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/authenticator/AuthenticatorBase.java 2025-12-02 16:54:08.000000000 +0000
@@ -70,6 +70,7 @@
import org.apache.tomcat.util.descriptor.web.LoginConfig;
import org.apache.tomcat.util.descriptor.web.SecurityConstraint;
import org.apache.tomcat.util.http.FastHttpDateFormat;
+import org.apache.tomcat.util.http.Method;
import org.apache.tomcat.util.http.RequestUtil;
import org.apache.tomcat.util.res.StringManager;
@@ -85,8 +86,6 @@
*
* USAGE CONSTRAINT: This Valve is only useful when processing HTTP requests. Requests of any other type will
* simply be passed through.
- *
- * @author Craig R. McClanahan
*/
public abstract class AuthenticatorBase extends ValveBase implements Authenticator, RegistrationListener {
@@ -486,7 +485,7 @@
// Make sure that constrained resources are not cached by web proxies
// or browsers as caching can provide a security hole
- if (constraints != null && disableProxyCaching && !"POST".equalsIgnoreCase(request.getMethod())) {
+ if (constraints != null && disableProxyCaching && !Method.POST.equals(request.getMethod())) {
if (securePagesWithPragma) {
// Note: These can cause problems with downloading files with IE
response.setHeader("Pragma", "No-cache");
@@ -609,7 +608,7 @@
if (allowCorsPreflight != AllowCorsPreflight.NEVER) {
// First check to see if this is a CORS Preflight request
// This is a subset of the tests in CorsFilter.checkRequestType
- if ("OPTIONS".equals(request.getMethod())) {
+ if (Method.OPTIONS.equals(request.getMethod())) {
String originHeader = request.getHeader(CorsFilter.REQUEST_HEADER_ORIGIN);
if (originHeader != null && !originHeader.isEmpty() && RequestUtil.isValidOrigin(originHeader) &&
!RequestUtil.isSameOrigin(request, originHeader)) {
@@ -726,12 +725,13 @@
Class> clazz = null;
try {
clazz = Class.forName(jaspicCallbackHandlerClass, true, Thread.currentThread().getContextClassLoader());
- } catch (ClassNotFoundException e) {
- // Proceed with the retry below
+ } catch (ClassNotFoundException ignore) {
+ // Not found in the context class loader (web application class loader). Re-try below.
}
try {
if (clazz == null) {
+ // Look in the same class loader that loaded this class - usually Tomcat's common loader.
clazz = Class.forName(jaspicCallbackHandlerClass);
}
callbackHandler = (CallbackHandler) clazz.getConstructor().newInstance();
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/authenticator/BasicAuthenticator.java tomcat11-11.0.15/java/org/apache/catalina/authenticator/BasicAuthenticator.java
--- tomcat11-11.0.6/java/org/apache/catalina/authenticator/BasicAuthenticator.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/authenticator/BasicAuthenticator.java 2025-12-02 16:54:08.000000000 +0000
@@ -34,8 +34,6 @@
/**
* An Authenticator and Valve implementation of HTTP BASIC Authentication, as outlined in RFC 7617: "The
* 'Basic' HTTP Authentication Scheme"
- *
- * @author Craig R. McClanahan
*/
public class BasicAuthenticator extends AuthenticatorBase {
@@ -89,7 +87,7 @@
}
} catch (IllegalArgumentException iae) {
if (log.isDebugEnabled()) {
- log.debug(sm.getString("basicAuthenticator.invalidAuthorization", iae.getMessage()));
+ log.debug(sm.getString("basicAuthenticator.invalidAuthorization"), iae);
}
}
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/authenticator/DigestAuthenticator.java tomcat11-11.0.15/java/org/apache/catalina/authenticator/DigestAuthenticator.java
--- tomcat11-11.0.6/java/org/apache/catalina/authenticator/DigestAuthenticator.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/authenticator/DigestAuthenticator.java 2025-12-02 16:54:08.000000000 +0000
@@ -48,9 +48,6 @@
/**
* An Authenticator and Valve implementation of HTTP DIGEST Authentication, as outlined in RFC 7616: "HTTP
* Digest Authentication"
- *
- * @author Craig R. McClanahan
- * @author Remy Maucherat
*/
public class DigestAuthenticator extends AuthenticatorBase {
@@ -267,14 +264,18 @@
@Override
protected boolean doAuthenticate(Request request, HttpServletResponse response) throws IOException {
- // NOTE: We don't try to reauthenticate using any existing SSO session,
- // because that will only work if the original authentication was
- // BASIC or FORM, which are less secure than the DIGEST auth-type
- // specified for this webapp
- //
- // Change to true below to allow previous FORM or BASIC authentications
- // to authenticate users for this webapp
- // TODO make this a configurable attribute (in SingleSignOn??)
+ /*
+ * Reauthentication using the cached user name and password (if any) is not enabled for DIGEST authentication.
+ * This was an historical design decision made because DIGEST authentication is viewed as more secure than
+ * BASIC/FORM.
+ *
+ * However, reauthentication was introduced to handle the case where the Realm took additional actions on
+ * authentication. Reauthenticating with the cached user name and password should be sufficient for DIGEST in
+ * that scenario. However, the original behaviour to reauthenticate has been retained in case of any (very
+ * unlikely) backwards compatibility issues.
+ *
+ * TODO: Make the reauthentication behaviour configurable per authenticator.
+ */
if (checkForCachedAuthentication(request, response, false)) {
return true;
}
@@ -505,7 +506,7 @@
Map directives;
try {
directives = Authorization.parseAuthorizationDigest(new StringReader(authorization));
- } catch (IOException e) {
+ } catch (IOException ioe) {
return false;
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/authenticator/FormAuthenticator.java tomcat11-11.0.15/java/org/apache/catalina/authenticator/FormAuthenticator.java
--- tomcat11-11.0.6/java/org/apache/catalina/authenticator/FormAuthenticator.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/authenticator/FormAuthenticator.java 2025-12-02 16:54:08.000000000 +0000
@@ -40,14 +40,12 @@
import org.apache.tomcat.util.buf.ByteChunk;
import org.apache.tomcat.util.buf.MessageBytes;
import org.apache.tomcat.util.descriptor.web.LoginConfig;
+import org.apache.tomcat.util.http.Method;
import org.apache.tomcat.util.http.MimeHeaders;
/**
* An Authenticator and Valve implementation of FORM BASED Authentication, as described in the Servlet API
* Specification.
- *
- * @author Craig R. McClanahan
- * @author Remy Maucherat
*/
public class FormAuthenticator extends AuthenticatorBase {
@@ -245,7 +243,7 @@
try {
saveRequest(request, session);
} catch (IOException ioe) {
- log.debug(sm.getString("authenticator.requestBodyTooBig"));
+ log.debug(sm.getString("authenticator.requestBodyTooBig"), ioe);
response.sendError(HttpServletResponse.SC_FORBIDDEN, sm.getString("authenticator.requestBodyTooBig"));
return false;
}
@@ -301,7 +299,7 @@
// the landing page
String uri = request.getContextPath() + landingPage;
SavedRequest saved = new SavedRequest();
- saved.setMethod("GET");
+ saved.setMethod(Method.GET);
saved.setRequestURI(uri);
saved.setDecodedRequestURI(uri);
request.getSessionInternal(true).setNote(Constants.FORM_REQUEST_NOTE, saved);
@@ -326,7 +324,7 @@
// the landing page
String uri = request.getContextPath() + landingPage;
SavedRequest saved = new SavedRequest();
- saved.setMethod("GET");
+ saved.setMethod(Method.GET);
saved.setRequestURI(uri);
saved.setDecodedRequestURI(uri);
session.setNote(Constants.FORM_REQUEST_NOTE, saved);
@@ -443,7 +441,7 @@
// Always use GET for the login page, regardless of the method used
String oldMethod = request.getMethod();
- request.getCoyoteRequest().method().setString("GET");
+ request.getCoyoteRequest().setMethod(Method.GET);
RequestDispatcher disp = context.getServletContext().getRequestDispatcher(loginPage);
try {
@@ -459,7 +457,7 @@
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, msg);
} finally {
// Restore original method so that it is written into access log
- request.getCoyoteRequest().method().setString(oldMethod);
+ request.getCoyoteRequest().setMethod(oldMethod);
}
}
@@ -585,7 +583,7 @@
String method = saved.getMethod();
MimeHeaders rmh = request.getCoyoteRequest().getMimeHeaders();
rmh.recycle();
- boolean cacheable = "GET".equalsIgnoreCase(method) || "HEAD".equalsIgnoreCase(method);
+ boolean cacheable = Method.GET.equals(method) || Method.HEAD.equals(method);
Iterator names = saved.getHeaderNames();
while (names.hasNext()) {
String name = names.next();
@@ -619,7 +617,7 @@
// If no content type specified, use default for POST
String savedContentType = saved.getContentType();
- if (savedContentType == null && "POST".equalsIgnoreCase(method)) {
+ if (savedContentType == null && Method.POST.equals(method)) {
savedContentType = Globals.CONTENT_TYPE_FORM_URL_ENCODING;
}
@@ -627,7 +625,7 @@
request.getCoyoteRequest().setContentType(contentType);
}
- request.getCoyoteRequest().method().setString(method);
+ request.getCoyoteRequest().setMethod(method);
// The method, URI, queryString and protocol are normally stored as
// bytes in the HttpInputBuffer and converted lazily to String. At this
// point, the method has already been set as String in the line above
@@ -641,8 +639,8 @@
request.getCoyoteRequest().queryString().toStringType();
request.getCoyoteRequest().protocol().toStringType();
- if (saved.getOriginalMaxInactiveInterval() > 0) {
- session.setMaxInactiveInterval(saved.getOriginalMaxInactiveInterval());
+ if (saved.getOriginalMaxInactiveIntervalOptional() != null) {
+ session.setMaxInactiveInterval(saved.getOriginalMaxInactiveIntervalOptional().intValue());
}
return true;
@@ -713,17 +711,19 @@
SavedRequest previousSavedRequest = (SavedRequest) session.getNote(Constants.FORM_REQUEST_NOTE);
if (session.isNew()) {
int originalMaxInactiveInterval = session.getMaxInactiveInterval();
- if (originalMaxInactiveInterval > getAuthenticationSessionTimeout()) {
+ if (originalMaxInactiveInterval > getAuthenticationSessionTimeout() || originalMaxInactiveInterval <= 0) {
saved.setOriginalMaxInactiveInterval(originalMaxInactiveInterval);
session.setMaxInactiveInterval(getAuthenticationSessionTimeout());
}
- } else if (previousSavedRequest != null && previousSavedRequest.getOriginalMaxInactiveInterval() > 0) {
+ } else if (previousSavedRequest != null &&
+ previousSavedRequest.getOriginalMaxInactiveIntervalOptional() != null) {
/*
* The user may have refreshed the browser page during authentication. Transfer the original max inactive
* interval from previous saved request to current one else, once authentication is completed, the session
* will retain the shorter authentication session timeout
*/
- saved.setOriginalMaxInactiveInterval(previousSavedRequest.getOriginalMaxInactiveInterval());
+ saved.setOriginalMaxInactiveInterval(
+ previousSavedRequest.getOriginalMaxInactiveIntervalOptional().intValue());
}
// Stash the SavedRequest in our session for later use
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/authenticator/LocalStrings.properties tomcat11-11.0.15/java/org/apache/catalina/authenticator/LocalStrings.properties
--- tomcat11-11.0.6/java/org/apache/catalina/authenticator/LocalStrings.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/authenticator/LocalStrings.properties 2025-12-02 16:54:08.000000000 +0000
@@ -42,7 +42,7 @@
authenticator.userDataPermissionFail=User data does not comply with the constraints of the resource
authenticator.userPermissionFail=User [{0}] does not have authorization to access the resource
-basicAuthenticator.invalidAuthorization=Invalid Authorization: [{0}]
+basicAuthenticator.invalidAuthorization=Invalid Authorization header
basicAuthenticator.invalidCharset=The only permitted values are null, the empty string or UTF-8
basicAuthenticator.notBase64=Basic Authorization credentials are not Base64
basicAuthenticator.notBasic=Authorization header method is not ''Basic''
@@ -76,9 +76,12 @@
singleSignOn.debug.principalNotFound=SSO did not find a cached Principal. Erasing SSO cookie for session [{0}]
singleSignOn.debug.register=SSO registering SSO session [{0}] for user [{1}] with authentication type [{2}]
singleSignOn.debug.removeSession=SSO removing application session [{0}] from SSO session [{1}]
+singleSignOn.debug.sessionChangedId=SSO changing sessionID in session [{0}, oldSessionId {1}] from SSO session [{2}]
singleSignOn.debug.sessionLogout=SSO processing a log out for SSO session [{0}] and application session [{1}]
singleSignOn.debug.sessionTimeout=SSO processing a time out for SSO session [{0}] and application session [{1}]
singleSignOn.debug.update=SSO updating SSO session [{0}] to authentication type [{1}]
+singleSignOn.duplicateRealm=SSO found a realm defined on context [{0}], this will conflict with principals defined in the main realm
+singleSignOn.noRealm=This SSO [{0}] has no realm associated with it
singleSignOn.sessionExpire.contextNotFound=SSO unable to expire session [{0}] because the Context could not be found
singleSignOn.sessionExpire.engineNull=SSO unable to expire session [{0}] because the Engine was null
singleSignOn.sessionExpire.hostNotFound=SSO unable to expire session [{0}] because the Host could not be found
@@ -92,6 +95,6 @@
spnegoAuthenticator.ticketValidateFail=Failed to validate client supplied ticket
sslAuthenticatorValve.authFailed=Authentication with the provided certificates failed
-sslAuthenticatorValve.http2=The context [{0}] in virtual host [{1}] is configured to use CLIENT-CERT authentication and [{2}] is configured to support HTTP/2. Use of CLIENT-CERT authentication is not compatible with the use of HTTP/2.
+sslAuthenticatorValve.http2=The context [{0}] in virtual host [{1}] is configured to use CLIENT-CERT authentication and [{2}] is configured to support HTTP/2. Use of CLIENT-CERT authentication is not compatible with the use of HTTP/2 unless certificateVerification is set to required.
sslAuthenticatorValve.noCertificates=No certificates are included with this request
-sslAuthenticatorValve.tls13=The context [{0}] in virtual host [{1}] is configured to use CLIENT-CERT authentication and [{2}] is configured to support TLS 1.3 using JSSE. Use of CLIENT-CERT authentication is not compatible with the use of TLS 1.3 and JSSE.
+sslAuthenticatorValve.tls13=The context [{0}] in virtual host [{1}] is configured to use CLIENT-CERT authentication and [{2}] is configured to support TLS 1.3 using JSSE. Use of CLIENT-CERT authentication is not compatible with the use of TLS 1.3 and JSSE unless certificateVerification is set to required.
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/authenticator/LocalStrings_fr.properties tomcat11-11.0.15/java/org/apache/catalina/authenticator/LocalStrings_fr.properties
--- tomcat11-11.0.6/java/org/apache/catalina/authenticator/LocalStrings_fr.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/authenticator/LocalStrings_fr.properties 2025-12-02 16:54:08.000000000 +0000
@@ -42,7 +42,7 @@
authenticator.userDataPermissionFail=Les données envoyées par l'utilisateur ne répondent pas aux contraintes définies pour la ressource
authenticator.userPermissionFail=L''utilisateur [{0}] n''a pas l''autorisation d''accéder à la ressource
-basicAuthenticator.invalidAuthorization=L''autorisation est invalide: [{0}]
+basicAuthenticator.invalidAuthorization=L'autorisation est invalide
basicAuthenticator.invalidCharset=Les seules valeurs permises sont null, la chaîne vide, ou des caractères UTF-8
basicAuthenticator.notBase64=Les informations d'identification Basic ne sont pas encodées en Base64
basicAuthenticator.notBasic=La méthode d'authentification n'est pas ''Basic''
@@ -76,9 +76,12 @@
singleSignOn.debug.principalNotFound=Le SSO n''a pas trouvé de principal en cache, le cookie SSO de la session [{0}] est effacé
singleSignOn.debug.register=Enregistrement de la session SSO [{0}] pour l''utilisateur [{1}] avec le type d''authentification [{2}]
singleSignOn.debug.removeSession=Le SSO retire la session applicative [{0}] de la session SSO [{1}]
+singleSignOn.debug.sessionChangedId=Changement de l''id de session [{0}, ancien id {1}] dans la session SSO [{2}]
singleSignOn.debug.sessionLogout=Le SSO effectue une déconnection pour la session SSO [{0}] et la session [{1}] de l''application
singleSignOn.debug.sessionTimeout=Le SSO traite un timeout pour la session SSO [{0}] et la session [{1}] de l''application
singleSignOn.debug.update=Le SSO met à jour la session SSO [{0}] avec le type d''authentification [{1}]
+singleSignOn.duplicateRealm=Le SSO a trouvé un royaume défini sur le contexte [{0}] qui va entrer en conflit avec les principals définis dans le royaume du SSO
+singleSignOn.noRealm=Ce SSO [{0}] n''a aucun royaume associé avec lui
singleSignOn.sessionExpire.contextNotFound=Le SSO n''a pu faire expirer la session [{0}] parce que le contexte n''a pas été trouvé
singleSignOn.sessionExpire.engineNull=Le SSO n''a pu faire expirer la session [{0}] parce que le moteur est null
singleSignOn.sessionExpire.hostNotFound=SSO ne peut pas faire expirer le session [{0}] parce que l''hôte ("Host") n''a pas été trouvé
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/authenticator/LocalStrings_ja.properties tomcat11-11.0.15/java/org/apache/catalina/authenticator/LocalStrings_ja.properties
--- tomcat11-11.0.6/java/org/apache/catalina/authenticator/LocalStrings_ja.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/authenticator/LocalStrings_ja.properties 2025-12-02 16:54:08.000000000 +0000
@@ -42,7 +42,7 @@
authenticator.userDataPermissionFail=ユーザデータがリソースの制約に従っていません
authenticator.userPermissionFail=ユーザ [{0}] にはリソースへのアクセス権限がありません
-basicAuthenticator.invalidAuthorization=無効な認証: [{0}]
+basicAuthenticator.invalidAuthorization=無効な認証
basicAuthenticator.invalidCharset=指定できる値は、null、空の文字列またはUTF-8です。
basicAuthenticator.notBase64=Basic認証の資格情報がBase64ではありません
basicAuthenticator.notBasic=認証ヘッダメソッドが ''Basic'' ではありません
@@ -76,9 +76,12 @@
singleSignOn.debug.principalNotFound=SSO はキャッシュされたプリンシパルを検出しませんでした。セッション [{0}] の SSO Cookie を消去しています
singleSignOn.debug.register=SSO は認証タイプ [{2}] のユーザー [{1}] の SSO セッション [{0}] を登録しています
singleSignOn.debug.removeSession=SSOはSSOセッション [{1}] からアプリケーションセッション [{0}] を削除しています
+singleSignOn.debug.sessionChangedId=SSO は SSO セッション [{2}] からセッション [{0}、oldSessionId {1}] のセッション ID を変更しています
singleSignOn.debug.sessionLogout=SSOはSSOセッション[{0}]とアプリケーションセッション[{1}]をログアウト処理しています
singleSignOn.debug.sessionTimeout=SSOはSSOセッション[{0}]とアプリケーションセッション[{1}]のタイムアウトを処理しています
singleSignOn.debug.update=SSOはSSOセッション [{0}] を認証タイプ [{1}] に更新します
+singleSignOn.duplicateRealm=SSO はコンテキスト [{0}] で定義されたレルムを検出しました。これはメインレルムで定義されたプリンシパルと競合します
+singleSignOn.noRealm=このSSO [{0}]にはレルムが関連付けられていません
singleSignOn.sessionExpire.contextNotFound=Context が見つからないため、SSO はセッション [{0}] を破棄できません
singleSignOn.sessionExpire.engineNull=Engine が null だったため、SSO はセッション [{0}] を破棄できません
singleSignOn.sessionExpire.hostNotFound=ホストが見つからないため SSO セッション [{0}] を破棄できません
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/authenticator/LocalStrings_ru.properties tomcat11-11.0.15/java/org/apache/catalina/authenticator/LocalStrings_ru.properties
--- tomcat11-11.0.6/java/org/apache/catalina/authenticator/LocalStrings_ru.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/authenticator/LocalStrings_ru.properties 2025-12-02 16:54:08.000000000 +0000
@@ -16,4 +16,7 @@
# Do not edit this file directly.
# To edit translations see: https://tomcat.apache.org/getinvolved.html#Translations
+authenticator.check.found=Уже аутентифицирован [{0}]
authenticator.noAuthHeader=Заголовок авторизации не был отправлен клиентом
+
+basicAuthenticator.invalidCharset=Единственные разрешенные значения это null, пустая строка или UTF-8
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/authenticator/NonLoginAuthenticator.java tomcat11-11.0.15/java/org/apache/catalina/authenticator/NonLoginAuthenticator.java
--- tomcat11-11.0.6/java/org/apache/catalina/authenticator/NonLoginAuthenticator.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/authenticator/NonLoginAuthenticator.java 2025-12-02 16:54:08.000000000 +0000
@@ -25,8 +25,6 @@
/**
* An Authenticator and Valve implementation that checks only security constraints not involving user
* authentication.
- *
- * @author Craig R. McClanahan
*/
public final class NonLoginAuthenticator extends AuthenticatorBase {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/authenticator/SSLAuthenticator.java tomcat11-11.0.15/java/org/apache/catalina/authenticator/SSLAuthenticator.java
--- tomcat11-11.0.6/java/org/apache/catalina/authenticator/SSLAuthenticator.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/authenticator/SSLAuthenticator.java 2025-12-02 16:54:08.000000000 +0000
@@ -37,12 +37,11 @@
import org.apache.juli.logging.LogFactory;
import org.apache.tomcat.util.net.Constants;
import org.apache.tomcat.util.net.SSLHostConfig;
+import org.apache.tomcat.util.net.SSLHostConfig.CertificateVerification;
/**
* An Authenticator and Valve implementation of authentication that utilizes SSL certificates to identify
* client users.
- *
- * @author Craig R. McClanahan
*/
public class SSLAuthenticator extends AuthenticatorBase {
@@ -60,14 +59,19 @@
@Override
protected boolean doAuthenticate(Request request, HttpServletResponse response) throws IOException {
- // NOTE: We don't try to reauthenticate using any existing SSO session,
- // because that will only work if the original authentication was
- // BASIC or FORM, which are less secure than the CLIENT-CERT auth-type
- // specified for this webapp
- //
- // Change to true below to allow previous FORM or BASIC authentications
- // to authenticate users for this webapp
- // TODO make this a configurable attribute (in SingleSignOn??)
+ /*
+ * Reauthentication using the cached user name and password (if any) is not enabled for CLIENT-CERT
+ * authentication. This was an historical design decision made because CLIENT-CERT authentication is viewed as
+ * more secure than BASIC/FORM.
+ *
+ * However, reauthentication was introduced to handle the case where the Realm took additional actions on
+ * authentication. Reauthenticating with the cached user name and password may not be sufficient for CLIENT-CERT
+ * since it will not make any TLS information (client certificate etc) available that a web application may
+ * depend on. Therefore, the reauthentication behaviour for CLIENT-CERT is to perform a normal CLIENT-CERT
+ * authentication.
+ *
+ * TODO: Make the reauthentication behaviour configurable per authenticator.
+ */
if (checkForCachedAuthentication(request, response, false)) {
return true;
}
@@ -154,10 +158,10 @@
* and an Engine but test at each stage to be safe.
*/
Container container = getContainer();
- if (!(container instanceof Context context2)) {
+ if (!(container instanceof Context context)) {
return;
}
- container = context2.getParent();
+ container = context.getParent();
if (!(container instanceof Host host)) {
return;
}
@@ -169,28 +173,52 @@
Connector[] connectors = engine.getService().findConnectors();
for (Connector connector : connectors) {
- // First check for upgrade
- UpgradeProtocol[] upgradeProtocols = connector.findUpgradeProtocols();
- for (UpgradeProtocol upgradeProtocol : upgradeProtocols) {
- if ("h2".equals(upgradeProtocol.getAlpnName())) {
- log.warn(sm.getString("sslAuthenticatorValve.http2", context2.getName(), host.getName(), connector));
+ /*
+ * There are two underlying issues here.
+ *
+ * 1. JSSE does not implement post-handshake authentication (PHA) for TLS 1.3. That means CLIENT-CERT
+ * authentication will only work if the virtual host requires a certificate OR the client never requests a
+ * protected resource.
+ *
+ * 2. HTTP/2 does not permit re-negotiation nor PHA. That means CLIENT-CERT authentication will only work if
+ * the virtual host requires a certificate OR the client never requests a protected resource.
+ *
+ * We can't rely on the client never requesting a protected resource but we can check if all the virtual
+ * hosts are configured to require a certificate.
+ */
+ boolean allHostsRequireCertificate = true;
+ for (SSLHostConfig sslHostConfig : connector.findSslHostConfigs()) {
+ if (sslHostConfig.getCertificateVerification() != CertificateVerification.REQUIRED) {
+ allHostsRequireCertificate = false;
break;
}
}
- // Then check for TLS 1.3
- SSLHostConfig[] sslHostConfigs = connector.findSslHostConfigs();
- for (SSLHostConfig sslHostConfig : sslHostConfigs) {
- if (!sslHostConfig.isTls13RenegotiationAvailable()) {
- String[] enabledProtocols = sslHostConfig.getEnabledProtocols();
- if (enabledProtocols == null) {
- // Possibly boundOnInit is used, so use the less accurate protocols
- enabledProtocols = sslHostConfig.getProtocols().toArray(new String[0]);
+ // Only need to check for use of HTTP/2 or TLS 1.3 if one or more hosts doesn't require a certificate
+ if (!allHostsRequireCertificate) {
+ // Check if the Connector is configured to support upgrade to HTTP/2
+ UpgradeProtocol[] upgradeProtocols = connector.findUpgradeProtocols();
+ for (UpgradeProtocol upgradeProtocol : upgradeProtocols) {
+ if ("h2".equals(upgradeProtocol.getAlpnName())) {
+ log.warn(sm.getString("sslAuthenticatorValve.http2", context.getName(), host.getName(),
+ connector));
+ break;
}
- for (String enabledProtocol : enabledProtocols) {
- if (Constants.SSL_PROTO_TLSv1_3.equals(enabledProtocol)) {
- log.warn(sm.getString("sslAuthenticatorValve.tls13", context2.getName(), host.getName(),
- connector));
+ }
+
+ // Check if any of the virtual hosts support TLS 1.3 without supporting PHA
+ for (SSLHostConfig sslHostConfig : connector.findSslHostConfigs()) {
+ if (!sslHostConfig.isTls13RenegotiationAvailable()) {
+ String[] enabledProtocols = sslHostConfig.getEnabledProtocols();
+ if (enabledProtocols == null) {
+ // Possibly boundOnInit is used, so use the less accurate protocols
+ enabledProtocols = sslHostConfig.getProtocols().toArray(new String[0]);
+ }
+ for (String enabledProtocol : enabledProtocols) {
+ if (Constants.SSL_PROTO_TLSv1_3.equals(enabledProtocol)) {
+ log.warn(sm.getString("sslAuthenticatorValve.tls13", context.getName(), host.getName(),
+ connector));
+ }
}
}
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/authenticator/SavedRequest.java tomcat11-11.0.15/java/org/apache/catalina/authenticator/SavedRequest.java
--- tomcat11-11.0.6/java/org/apache/catalina/authenticator/SavedRequest.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/authenticator/SavedRequest.java 2025-12-02 16:54:08.000000000 +0000
@@ -36,8 +36,6 @@
*
* IMPLEMENTATION NOTE - It is assumed that this object is accessed only from the context of a single thread, so
* no synchronization around internal collection classes is performed.
- *
- * @author Craig R. McClanahan
*/
public final class SavedRequest implements Serializable {
@@ -183,13 +181,26 @@
/**
* The original maxInactiveInterval for the session.
*/
- private int originalMaxInactiveInterval = -1;
+ private Integer originalMaxInactiveInterval = null;
- public int getOriginalMaxInactiveInterval() {
+ public Integer getOriginalMaxInactiveIntervalOptional() {
return originalMaxInactiveInterval;
}
+ /**
+ * Obtain the original session maxInactiveInterval.
+ *
+ * @return the original session maxInactiveInterval
+ *
+ * @deprecated This method will be removed in Tomcat 12.0.x onwards. Use
+ * {@link SavedRequest#getOriginalMaxInactiveIntervalOptional()}
+ */
+ @Deprecated
+ public int getOriginalMaxInactiveInterval() {
+ return (originalMaxInactiveInterval == null) ? -1 : originalMaxInactiveInterval.intValue();
+ }
+
public void setOriginalMaxInactiveInterval(int originalMaxInactiveInterval) {
- this.originalMaxInactiveInterval = originalMaxInactiveInterval;
+ this.originalMaxInactiveInterval = Integer.valueOf(originalMaxInactiveInterval);
}
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/authenticator/SingleSignOn.java tomcat11-11.0.15/java/org/apache/catalina/authenticator/SingleSignOn.java
--- tomcat11-11.0.6/java/org/apache/catalina/authenticator/SingleSignOn.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/authenticator/SingleSignOn.java 2025-12-02 16:54:08.000000000 +0000
@@ -28,6 +28,7 @@
import org.apache.catalina.Container;
import org.apache.catalina.Context;
import org.apache.catalina.Engine;
+import org.apache.catalina.Host;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.Manager;
import org.apache.catalina.Realm;
@@ -50,8 +51,33 @@
*
The web applications themselves must use one of the standard Authenticators found in the
* org.apache.catalina.authenticator package.
*
- *
- * @author Craig R. McClanahan
+ *
+ * On first authentication to any web application, an SSO session is created and the authenticated Principal, the
+ * authentication type and the plain text user name and password used to authenticate (if available) are cached using a
+ * key based on the SSO session. On subsequent requests to a web application on the Host where this Valve is configured,
+ * the cached authenticated Principal and the authentication type are added to the request by the SSO Valve and no
+ * further authentication takes place.
+ *
+ * In some scenarios, adding the authenticated Principal and the authentication type is insufficient. This usually
+ * occurs when the web application depends on additional actions the Realm takes on authentication which are bypassed by
+ * the SSO Valve. Examples of this include the Realm setting security credentials on the request thread to support EJB
+ * access or the CLIENT-CERT authenticator providing the client certificate and other TLS attributes. To address this,
+ * the {@code requireReauthentication} flag can be set to {@code true} which will cause the SSO Valve not to set the
+ * cached Principal and authentication type on the request and the web application authenticator will authenticate the
+ * request. By default this reauthentication will occur in the following ways:
+ *
+ *
BASIC - call the realm using the plain text user name and password cached by the SSO Valve if available. If not
+ * cached, obtain those values from the request. If not present in the request, request them from the user agent.
+ *
FORM - call the realm using the plain text user name and password cached by the SSO Valve if available. If not
+ * cached, request them from the user agent.
+ *
DIGEST - call the realm using the credentials present in the request. If not present in the request, request them
+ * from the user agent.
+ *
CLIENT-CERT - call the realm using the credentials present in the TLS connection. If not present in the TLS
+ * connection, request them from the user agent.
+ *
SPNEGO - request authentication credentials from the user agent.
+ *
+ * Note that this means that enabling reauthentication only makes sense if there are two or more web applications in the
+ * Host that use BASIC or FORM. If that is not the case, the SSO Valve will just add processing overhead.
*/
public class SingleSignOn extends ValveBase {
@@ -426,8 +452,8 @@
Session session;
try {
session = manager.findSession(key.getSessionId());
- } catch (IOException e) {
- containerLog.warn(sm.getString("singleSignOn.sessionExpire.managerError", key), e);
+ } catch (IOException ioe) {
+ containerLog.warn(sm.getString("singleSignOn.sessionExpire.managerError", key), ioe);
return;
}
if (session == null) {
@@ -439,8 +465,8 @@
/**
- * Attempts reauthentication to the given Realm using the credentials associated with the single
- * sign-on session identified by argument ssoId.
+ * Attempts reauthentication to the given Realm using the cached plain text credentials associated with
+ * the single sign-on session identified by argument ssoId.
*
* If reauthentication is successful, the Principal and authorization type associated with the SSO
* session will be bound to the given Request object via calls to {@link Request#setAuthType
@@ -571,12 +597,39 @@
@Override
protected void startInternal() throws LifecycleException {
- Container c = getContainer();
- while (c != null && !(c instanceof Engine)) {
- c = c.getParent();
- }
- if (c != null) {
- engine = (Engine) c;
+ Container container = getContainer();
+ while (container != null && !(container instanceof Engine)) {
+ container = container.getParent();
+ }
+ if (container != null) {
+ engine = (Engine) container;
+ }
+ // Starting with the associated container, verify it has a realm associated,
+ // and that no child container returns a different realm
+ container = getContainer();
+ Realm containerRealm = container.getRealm();
+ if (containerRealm == null) {
+ containerLog.warn(sm.getString("singleSignOn.noRealm", container.getName()));
+ } else {
+ if (container instanceof Engine) {
+ for (Container host : engine.findChildren()) {
+ if (host.getRealm() != containerRealm) {
+ containerLog.warn(sm.getString("singleSignOn.duplicateRealm", host.getName()));
+ } else {
+ for (Container context : host.findChildren()) {
+ if (context.getRealm() != containerRealm) {
+ containerLog.warn(sm.getString("singleSignOn.duplicateRealm", context.getName()));
+ }
+ }
+ }
+ }
+ } else if (container instanceof Host) {
+ for (Container context : container.findChildren()) {
+ if (context.getRealm() != containerRealm) {
+ containerLog.warn(sm.getString("singleSignOn.duplicateRealm", context.getName()));
+ }
+ }
+ }
}
super.startInternal();
}
@@ -587,4 +640,27 @@
super.stopInternal();
engine = null;
}
+
+ protected void sessionChangedId(String ssoId, Session session, String oldSessionId) {
+ if (containerLog.isDebugEnabled()) {
+ containerLog.debug(sm.getString("singleSignOn.debug.sessionChangedId", session, oldSessionId, ssoId));
+ }
+
+ SingleSignOnEntry entry = cache.get(ssoId);
+ if (entry == null) {
+ return;
+ }
+
+ /*
+ * Associate the new sessionId with this SingleSignOnEntry. A SessionListener will be registered for the new
+ * sessionID. If not, then we would not notice any subsequent Session.SESSION_DESTROYED_EVENT for the session.
+ */
+ entry.addSession(this, ssoId, session);
+
+ /*
+ * Remove the obsolete sessionId from the SingleSignOnEntry. The sessionId part of the SingleSignOnSessionKey is
+ * final.
+ */
+ entry.removeSession(session, oldSessionId);
+ }
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/authenticator/SingleSignOnEntry.java tomcat11-11.0.15/java/org/apache/catalina/authenticator/SingleSignOnEntry.java
--- tomcat11-11.0.6/java/org/apache/catalina/authenticator/SingleSignOnEntry.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/authenticator/SingleSignOnEntry.java 2025-12-02 16:54:08.000000000 +0000
@@ -35,8 +35,6 @@
* AuthenticatorBase subclasses that need it in order to perform reauthentications when SingleSignOn is in
* use.
*
- * @author B Stansberry, based on work by Craig R. McClanahan
- *
* @see SingleSignOn
* @see AuthenticatorBase#reauthenticateFromSSO
*/
@@ -103,6 +101,18 @@
sessionKeys.remove(key);
}
+ /**
+ * Removes the given Session from the list of those associated with this SSO, using the previous
+ * sessionId
+ *
+ * @param session the Session to remove.
+ * @param oldSessionId the previous sessionId of the Session to remove.
+ */
+ public void removeSession(Session session, String oldSessionId) {
+ SingleSignOnSessionKey key = new SingleSignOnSessionKey(session, oldSessionId);
+ sessionKeys.remove(key);
+ }
+
/**
* Returns the HTTP Session identifiers associated with this SSO.
*
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/authenticator/SingleSignOnListener.java tomcat11-11.0.15/java/org/apache/catalina/authenticator/SingleSignOnListener.java
--- tomcat11-11.0.6/java/org/apache/catalina/authenticator/SingleSignOnListener.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/authenticator/SingleSignOnListener.java 2025-12-02 16:54:08.000000000 +0000
@@ -40,7 +40,8 @@
@Override
public void sessionEvent(SessionEvent event) {
- if (!Session.SESSION_DESTROYED_EVENT.equals(event.getType())) {
+ final String type = event.getType();
+ if (!(Session.SESSION_DESTROYED_EVENT.equals(type) || Session.SESSION_CHANGED_ID_EVENT.equals(type))) {
return;
}
@@ -58,6 +59,15 @@
if (sso == null) {
return;
}
- sso.sessionDestroyed(ssoId, session);
+
+ switch (type) {
+ case Session.SESSION_CHANGED_ID_EVENT:
+ sso.sessionChangedId(ssoId, session, (String) event.getData());
+ break;
+
+ case Session.SESSION_DESTROYED_EVENT:
+ sso.sessionDestroyed(ssoId, session);
+ break;
+ }
}
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/authenticator/SingleSignOnSessionKey.java tomcat11-11.0.15/java/org/apache/catalina/authenticator/SingleSignOnSessionKey.java
--- tomcat11-11.0.6/java/org/apache/catalina/authenticator/SingleSignOnSessionKey.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/authenticator/SingleSignOnSessionKey.java 2025-12-02 16:54:08.000000000 +0000
@@ -43,6 +43,13 @@
this.hostName = context.getParent().getName();
}
+ public SingleSignOnSessionKey(Session session, String sessionId) {
+ this.sessionId = sessionId;
+ Context context = session.getManager().getContext();
+ this.contextName = context.getName();
+ this.hostName = context.getParent().getName();
+ }
+
public String getSessionId() {
return sessionId;
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/authenticator/SpnegoAuthenticator.java tomcat11-11.0.15/java/org/apache/catalina/authenticator/SpnegoAuthenticator.java
--- tomcat11-11.0.6/java/org/apache/catalina/authenticator/SpnegoAuthenticator.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/authenticator/SpnegoAuthenticator.java 2025-12-02 16:54:08.000000000 +0000
@@ -135,7 +135,19 @@
@Override
protected boolean doAuthenticate(Request request, HttpServletResponse response) throws IOException {
- if (checkForCachedAuthentication(request, response, true)) {
+ /*
+ * Reauthentication using the cached user name and password (if any) is not enabled for SPNEGO authentication.
+ * This is because the delegated credentials will nto be available unless a normal SPNEGO authentication takes
+ * place.
+ *
+ * Reauthentication was introduced to handle the case where the Realm took additional actions on authentication.
+ * Reauthenticating with the cached user name and password may not be sufficient for SPNEGO since it will not
+ * make the delegated credentials available that a web application may depend on. Therefore, the
+ * reauthentication behaviour for SPNEGO is to perform a normal SPNEGO authentication.
+ *
+ * TODO: Make the reauthentication behaviour configurable per authenticator.
+ */
+ if (checkForCachedAuthentication(request, response, false)) {
return true;
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/authenticator/jaspic/AuthConfigFactoryImpl.java tomcat11-11.0.15/java/org/apache/catalina/authenticator/jaspic/AuthConfigFactoryImpl.java
--- tomcat11-11.0.6/java/org/apache/catalina/authenticator/jaspic/AuthConfigFactoryImpl.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/authenticator/jaspic/AuthConfigFactoryImpl.java 2025-12-02 16:54:08.000000000 +0000
@@ -521,7 +521,7 @@
private record SingleModuleServerAuthContext(ServerAuthModule module) implements ServerAuthContext {
@Override
public AuthStatus validateRequest(MessageInfo messageInfo, Subject clientSubject, Subject serviceSubject)
- throws AuthException {
+ throws AuthException {
return module.validateRequest(messageInfo, clientSubject, serviceSubject);
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/authenticator/jaspic/LocalStrings_ru.properties tomcat11-11.0.15/java/org/apache/catalina/authenticator/jaspic/LocalStrings_ru.properties
--- tomcat11-11.0.6/java/org/apache/catalina/authenticator/jaspic/LocalStrings_ru.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/authenticator/jaspic/LocalStrings_ru.properties 2025-12-02 16:54:08.000000000 +0000
@@ -18,4 +18,6 @@
authConfigFactoryImpl.zeroLengthAppContext=Название контекста приложения нулевой длины является недействительным
+persistentProviderRegistrations.deleteFail=Временный файл [{0}] не может быть удален
persistentProviderRegistrations.existsDeleteFail=Временный файл [{0}] уже существует и не может быть удалён
+persistentProviderRegistrations.moveFail=Невозможно переместить [{0}] в [{1}]
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/authenticator/jaspic/PersistentProviderRegistrations.java tomcat11-11.0.15/java/org/apache/catalina/authenticator/jaspic/PersistentProviderRegistrations.java
--- tomcat11-11.0.6/java/org/apache/catalina/authenticator/jaspic/PersistentProviderRegistrations.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/authenticator/jaspic/PersistentProviderRegistrations.java 2025-12-02 16:54:08.000000000 +0000
@@ -144,12 +144,12 @@
writer.write(" \n");
}
writer.write("\n");
- } catch (IOException e) {
+ } catch (IOException ioe) {
if (!configFileNew.delete()) {
Log log = LogFactory.getLog(PersistentProviderRegistrations.class);
log.warn(sm.getString("persistentProviderRegistrations.deleteFail", configFileNew.getAbsolutePath()));
}
- throw new SecurityException(e);
+ throw new SecurityException(ioe);
}
// Move the current file out of the way
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/connector/ClientAbortException.java tomcat11-11.0.15/java/org/apache/catalina/connector/ClientAbortException.java
--- tomcat11-11.0.6/java/org/apache/catalina/connector/ClientAbortException.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/connector/ClientAbortException.java 2025-12-02 16:54:08.000000000 +0000
@@ -22,8 +22,6 @@
/**
* Extend IOException to identify it as being caused by an abort of a request by a remote client.
- *
- * @author Glenn L. Nielsen
*/
public final class ClientAbortException extends BadRequestException {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/connector/Connector.java tomcat11-11.0.15/java/org/apache/catalina/connector/Connector.java
--- tomcat11-11.0.6/java/org/apache/catalina/connector/Connector.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/connector/Connector.java 2025-12-02 16:54:08.000000000 +0000
@@ -28,7 +28,6 @@
import org.apache.catalina.LifecycleException;
import org.apache.catalina.LifecycleState;
import org.apache.catalina.Service;
-import org.apache.catalina.core.AprStatus;
import org.apache.catalina.util.LifecycleMBeanBase;
import org.apache.coyote.AbstractProtocol;
import org.apache.coyote.Adapter;
@@ -37,12 +36,14 @@
import org.apache.coyote.http11.AbstractHttp11Protocol;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
+import org.apache.tomcat.jni.AprStatus;
import org.apache.tomcat.util.IntrospectionUtils;
import org.apache.tomcat.util.buf.B2CConverter;
import org.apache.tomcat.util.buf.CharsetUtil;
import org.apache.tomcat.util.buf.EncodedSolidusHandling;
import org.apache.tomcat.util.buf.StringUtils;
import org.apache.tomcat.util.compat.JreCompat;
+import org.apache.tomcat.util.http.Method;
import org.apache.tomcat.util.net.SSLHostConfig;
import org.apache.tomcat.util.net.openssl.OpenSSLImplementation;
import org.apache.tomcat.util.net.openssl.OpenSSLStatus;
@@ -51,9 +52,6 @@
/**
* Implementation of a Coyote connector.
- *
- * @author Craig R. McClanahan
- * @author Remy Maucherat
*/
public class Connector extends LifecycleMBeanBase {
@@ -62,6 +60,22 @@
public static final String INTERNAL_EXECUTOR_NAME = "Internal";
+ private static final boolean aprStatusPresent;
+
+ static {
+ /*
+ * The AprStatus class has to be in the org.apache.tomcat.jni package so it can be referenced by the OpenSSL
+ * clean-up code to avoid a race condition on shutdown between the AprLifecycleListener shutting down the Tomcat
+ * Native library along with any remaining open connections and the OpenSSL clean-up code shutting down an
+ * individual connection that can trigger a JVM crash.
+ *
+ * In some deployment scenarios AprStatus is not present - e.g. because tomcat-jni.jar is not present. To avoid
+ * a CNFE in this class on Connector initialisation when AprStatus is not present - and ugly work-arounds that
+ * try loading the class and catching the exception - use getResource() to see if AprStatus is present.
+ */
+ aprStatusPresent =
+ (Connector.class.getClassLoader().getResource("org/apache/tomcat/jni/AprStatus.class") != null);
+ }
// ------------------------------------------------------------ Constructor
@@ -210,6 +224,10 @@
*/
protected int maxParameterCount = 1000;
+ private int maxPartCount = 50;
+
+ private int maxPartHeaderSize = 512;
+
/**
* Maximum size of a POST which will be automatically parsed by the container. 2 MiB by default.
*/
@@ -225,7 +243,7 @@
* Comma-separated list of HTTP methods that will be parsed according to POST-style rules for
* application/x-www-form-urlencoded request bodies.
*/
- protected String parseBodyMethods = "POST";
+ protected String parseBodyMethods = Method.POST;
/**
* A Set of methods determined by {@link #parseBodyMethods}.
@@ -479,6 +497,26 @@
}
+ public int getMaxPartCount() {
+ return maxPartCount;
+ }
+
+
+ public void setMaxPartCount(int maxPartCount) {
+ this.maxPartCount = maxPartCount;
+ }
+
+
+ public int getMaxPartHeaderSize() {
+ return maxPartHeaderSize;
+ }
+
+
+ public void setMaxPartHeaderSize(int maxPartHeaderSize) {
+ this.maxPartHeaderSize = maxPartHeaderSize;
+ }
+
+
/**
* @return the maximum size of a POST which will be automatically parsed by the container.
*/
@@ -538,7 +576,7 @@
methodSet.addAll(Arrays.asList(StringUtils.splitCommaSeparated(methods)));
}
- if (methodSet.contains("TRACE")) {
+ if (methodSet.contains(Method.TRACE)) {
throw new IllegalArgumentException(sm.getString("coyoteConnector.parseBodyMethodNoTrace"));
}
@@ -1030,23 +1068,19 @@
setParseBodyMethods(getParseBodyMethods());
}
- if (JreCompat.isJre22Available() && OpenSSLStatus.getUseOpenSSL() && OpenSSLStatus.isAvailable() &&
- protocolHandler instanceof AbstractHttp11Protocol> jsseProtocolHandler) {
- // Use FFM and OpenSSL if available
- if (jsseProtocolHandler.isSSLEnabled() && jsseProtocolHandler.getSslImplementationName() == null) {
- // OpenSSL is compatible with the JSSE configuration, so use it if it is available
+ if (protocolHandler instanceof AbstractHttp11Protocol> jsseProtocolHandler &&
+ jsseProtocolHandler.isSSLEnabled() && jsseProtocolHandler.getSslImplementationName() == null) {
+ // If SSL is enabled and a specific implementation isn't specified, select the correct default.
+ if (JreCompat.isJre22Available() && OpenSSLStatus.getUseOpenSSL() && OpenSSLStatus.isAvailable()) {
+ // Use FFM and OpenSSL if available
jsseProtocolHandler
.setSslImplementationName("org.apache.tomcat.util.net.openssl.panama.OpenSSLImplementation");
- }
- } else if (AprStatus.isAprAvailable() && AprStatus.getUseOpenSSL() &&
- protocolHandler instanceof AbstractHttp11Protocol> jsseProtocolHandler) {
- // Use tomcat-native and OpenSSL otherwise, if available
- if (jsseProtocolHandler.isSSLEnabled() && jsseProtocolHandler.getSslImplementationName() == null) {
- // OpenSSL is compatible with the JSSE configuration, so use it if APR is available
+ } else if (aprStatusPresent && AprStatus.isAprAvailable() && AprStatus.getUseOpenSSL()) {
+ // Use tomcat-native and OpenSSL otherwise, if available
jsseProtocolHandler.setSslImplementationName(OpenSSLImplementation.class.getName());
}
+ // Otherwise the default JSSE will be used
}
- // Otherwise the default JSSE will be used
try {
protocolHandler.init();
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/connector/CoyoteAdapter.java tomcat11-11.0.15/java/org/apache/catalina/connector/CoyoteAdapter.java
--- tomcat11-11.0.6/java/org/apache/catalina/connector/CoyoteAdapter.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/connector/CoyoteAdapter.java 2025-12-02 16:54:08.000000000 +0000
@@ -49,6 +49,7 @@
import org.apache.tomcat.util.buf.CharChunk;
import org.apache.tomcat.util.buf.HexUtils;
import org.apache.tomcat.util.buf.MessageBytes;
+import org.apache.tomcat.util.http.Method;
import org.apache.tomcat.util.http.ServerCookie;
import org.apache.tomcat.util.http.ServerCookies;
import org.apache.tomcat.util.net.SSLSupport;
@@ -58,9 +59,6 @@
/**
* Implementation of a request processor which delegates the processing to a Coyote processor.
- *
- * @author Craig R. McClanahan
- * @author Remy Maucherat
*/
public class CoyoteAdapter implements Adapter {
@@ -261,9 +259,9 @@
}
success = false;
}
- } catch (IOException e) {
+ } catch (IOException ioe) {
+ // Issues that should be logged will have already been logged
success = false;
- // Ignore
} catch (Throwable t) {
ExceptionUtils.handleThrowable(t);
success = false;
@@ -372,8 +370,8 @@
response.finishResponse();
}
- } catch (IOException e) {
- // Ignore
+ } catch (IOException ignore) {
+ // Issues that should be logged will have already been logged
} finally {
AtomicBoolean error = new AtomicBoolean(false);
res.action(ActionCode.IS_ERROR, error);
@@ -592,7 +590,7 @@
// Check for ping OPTIONS * request
if (undecodedURI.equals("*")) {
- if (req.method().equals("OPTIONS")) {
+ if (Method.OPTIONS.equals(req.getMethod())) {
StringBuilder allow = new StringBuilder();
allow.append("GET, HEAD, POST, PUT, DELETE, OPTIONS");
// Trace if allowed
@@ -611,7 +609,7 @@
MessageBytes decodedURI = req.decodedURI();
// Filter CONNECT method
- if (req.method().equals("CONNECT")) {
+ if (Method.CONNECT.equals(req.getMethod())) {
response.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, sm.getString("coyoteAdapter.connect"));
} else {
// No URI for CONNECT requests
@@ -779,8 +777,8 @@
// point.
try {
Thread.sleep(1000);
- } catch (InterruptedException e) {
- // Should never happen
+ } catch (InterruptedException ignore) {
+ // Should never happen but, if it does, just continue looping
}
// Reset mapping
request.getMappingData().recycle();
@@ -810,14 +808,14 @@
}
// Filter TRACE method
- if (!connector.getAllowTrace() && req.method().equals("TRACE")) {
+ if (!connector.getAllowTrace() && Method.TRACE.equals(req.getMethod())) {
Wrapper wrapper = request.getWrapper();
StringBuilder header = null;
if (wrapper != null) {
String[] methods = wrapper.getServletMethods();
if (methods != null) {
for (String method : methods) {
- if ("TRACE".equals(method)) {
+ if (Method.TRACE.equals(method)) {
continue;
}
if (header == null) {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/connector/CoyoteInputStream.java tomcat11-11.0.15/java/org/apache/catalina/connector/CoyoteInputStream.java
--- tomcat11-11.0.6/java/org/apache/catalina/connector/CoyoteInputStream.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/connector/CoyoteInputStream.java 2025-12-02 16:54:08.000000000 +0000
@@ -27,8 +27,6 @@
/**
* This class handles reading bytes.
- *
- * @author Remy Maucherat
*/
public class CoyoteInputStream extends ServletInputStream {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/connector/CoyoteOutputStream.java tomcat11-11.0.15/java/org/apache/catalina/connector/CoyoteOutputStream.java
--- tomcat11-11.0.6/java/org/apache/catalina/connector/CoyoteOutputStream.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/connector/CoyoteOutputStream.java 2025-12-02 16:54:08.000000000 +0000
@@ -27,9 +27,6 @@
/**
* Coyote implementation of the servlet output stream.
- *
- * @author Costin Manolache
- * @author Remy Maucherat
*/
public class CoyoteOutputStream extends ServletOutputStream {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/connector/CoyotePrincipal.java tomcat11-11.0.15/java/org/apache/catalina/connector/CoyotePrincipal.java
--- tomcat11-11.0.6/java/org/apache/catalina/connector/CoyotePrincipal.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/connector/CoyotePrincipal.java 2025-12-02 16:54:08.000000000 +0000
@@ -23,8 +23,6 @@
/**
* Generic implementation of java.security.Principal that is used to represent principals authenticated
* at the protocol handler level.
- *
- * @author Remy Maucherat
*/
public class CoyotePrincipal implements Principal, Serializable {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/connector/CoyoteReader.java tomcat11-11.0.15/java/org/apache/catalina/connector/CoyoteReader.java
--- tomcat11-11.0.6/java/org/apache/catalina/connector/CoyoteReader.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/connector/CoyoteReader.java 2025-12-02 16:54:08.000000000 +0000
@@ -22,8 +22,6 @@
/**
* Coyote implementation of the buffered reader.
- *
- * @author Remy Maucherat
*/
public class CoyoteReader extends BufferedReader {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/connector/CoyoteWriter.java tomcat11-11.0.15/java/org/apache/catalina/connector/CoyoteWriter.java
--- tomcat11-11.0.6/java/org/apache/catalina/connector/CoyoteWriter.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/connector/CoyoteWriter.java 2025-12-02 16:54:08.000000000 +0000
@@ -21,8 +21,6 @@
/**
* Coyote implementation of the servlet writer.
- *
- * @author Remy Maucherat
*/
public class CoyoteWriter extends PrintWriter {
@@ -91,8 +89,8 @@
try {
ob.flush();
- } catch (IOException e) {
- setErrorException(e);
+ } catch (IOException ioe) {
+ setErrorException(ioe);
}
}
@@ -105,7 +103,7 @@
// so the stream can be reused. We close ob.
try {
ob.close();
- } catch (IOException ex) {
+ } catch (IOException ignore) {
// Ignore
}
error = false;
@@ -129,8 +127,8 @@
try {
ob.write(c);
- } catch (IOException e) {
- setErrorException(e);
+ } catch (IOException ioe) {
+ setErrorException(ioe);
}
}
@@ -145,8 +143,8 @@
try {
ob.write(buf, off, len);
- } catch (IOException e) {
- setErrorException(e);
+ } catch (IOException ioe) {
+ setErrorException(ioe);
}
}
@@ -167,8 +165,8 @@
try {
ob.write(s, off, len);
- } catch (IOException e) {
- setErrorException(e);
+ } catch (IOException ioe) {
+ setErrorException(ioe);
}
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/connector/InputBuffer.java tomcat11-11.0.15/java/org/apache/catalina/connector/InputBuffer.java
--- tomcat11-11.0.6/java/org/apache/catalina/connector/InputBuffer.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/connector/InputBuffer.java 2025-12-02 16:54:08.000000000 +0000
@@ -44,8 +44,6 @@
* The buffer used by Tomcat request. This is a derivative of the Tomcat 3.3 OutputBuffer, adapted to handle input
* instead of output. This allows complete recycling of the facade objects (the ServletInputStream and the
* BufferedReader).
- *
- * @author Remy Maucherat
*/
public class InputBuffer extends Reader implements ByteChunk.ByteInputChannel, ApplicationBufferHandler {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/connector/LocalStrings.properties tomcat11-11.0.15/java/org/apache/catalina/connector/LocalStrings.properties
--- tomcat11-11.0.6/java/org/apache/catalina/connector/LocalStrings.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/connector/LocalStrings.properties 2025-12-02 16:54:08.000000000 +0000
@@ -62,7 +62,9 @@
coyoteRequest.maxPostSizeExceeded=The multi-part request contained parameter data (excluding uploaded files) that exceeded the limit for maxPostSize set on the associated connector
coyoteRequest.noAsync=Unable to start async because the following classes in the processing chain do not support async [{0}]
coyoteRequest.noMultipartConfig=Unable to process parts as no multi-part configuration has been provided
+coyoteRequest.parametersParseException=Exception [{0}] occurred parsing parameters and will be thrown
coyoteRequest.parseParameters=Exception thrown whilst processing POSTed parameters
+coyoteRequest.partsParseException=Exception [{0}] occurred parsing parts and will be thrown
coyoteRequest.postTooLarge=Parameters were not parsed because the size of the posted data was too big. Use the maxPostSize attribute of the connector to resolve this if the application should accept large POSTs.
coyoteRequest.sendfileNotCanonical=Unable to determine canonical name of file [{0}] specified for use with sendfile
coyoteRequest.sessionCreateCommitted=Cannot create a session after the response has been committed
@@ -93,6 +95,7 @@
request.fragmentInDispatchPath=The fragment in dispatch path [{0}] has been removed
request.illegalWrap=The request wrapper must wrap the request obtained from getRequest()
request.notAsync=It is illegal to call this method if the current request is not in asynchronous mode (i.e. isAsyncStarted() returns false)
+request.partCleanup.failed=Unable to delete temporary file for uploaded part after multi-part processing failed
request.session.failed=Failed to load session [{0}] due to [{1}]
requestFacade.nullRequest=The request object has been recycled and is no longer associated with this facade
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/connector/LocalStrings_es.properties tomcat11-11.0.15/java/org/apache/catalina/connector/LocalStrings_es.properties
--- tomcat11-11.0.6/java/org/apache/catalina/connector/LocalStrings_es.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/connector/LocalStrings_es.properties 2025-12-02 16:54:08.000000000 +0000
@@ -38,7 +38,7 @@
coyoteRequest.attributeEvent=Excepción lanzada mediante el escuchador de eventos de atributos
coyoteRequest.authenticate.ise=No puedo llamar a authenticate() tras haberse acometido la respuesta
coyoteRequest.changeSessionId=No se puede cambiar el ID de sesión. No hay sesión asociada con esta solicitud
-coyoteRequest.chunkedPostTooLarge=No se han analizado los parámetros porque la medida de los datos enviados meiante "post" era demasiado grande. Debido a que este requerimiento es una parte del original, no puede ser procesado. Utiliza el atributo "maxPostSize" del conector para resolver esta situación, en caso de que la aplicación deba de aceptar POSTs mayores.
+coyoteRequest.chunkedPostTooLarge=No se han analizado los parámetros porque la medida de los datos enviados meiante POST era demasiado grande. Debido a que este requerimiento es una parte del original, no puede ser procesado. Utiliza el atributo "maxPostSize" del conector para resolver esta situación, en caso de que la aplicación deba de aceptar POSTs mayores.
coyoteRequest.filterAsyncSupportUnknown=Imposible determinar si algún filtro no soporta procesamiento asincrónico
coyoteRequest.getInputStream.ise=getReader() ya ha sido llamado para este requerimiento
coyoteRequest.getReader.ise=getInputStream() ya ha sido llamado para este requerimiento
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/connector/LocalStrings_fr.properties tomcat11-11.0.15/java/org/apache/catalina/connector/LocalStrings_fr.properties
--- tomcat11-11.0.6/java/org/apache/catalina/connector/LocalStrings_fr.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/connector/LocalStrings_fr.properties 2025-12-02 16:54:08.000000000 +0000
@@ -62,7 +62,9 @@
coyoteRequest.maxPostSizeExceeded=La requête multi part contenait des données de paramètres (en excluant les fichiers envoyés) dont la taille a excédé la limite maxPostSize fixée sur le connecteur associé
coyoteRequest.noAsync=Impossible de démarrer le mode asynchrone car les classes [{0}] de la chaîne de traitement ne le supportent pas
coyoteRequest.noMultipartConfig=Impossible de traiter des parties, parce qu'aucune configuration multi-parties n'a été fournie
+coyoteRequest.parametersParseException=Une exception [{0}] s''est produite lors du traitement des paramètres et sera lancée
coyoteRequest.parseParameters=Exception lors du traitement des paramètres envoyés par POST
+coyoteRequest.partsParseException=Une exception [{0}] s''est produite lors du traitement des portions du message et sera lancée
coyoteRequest.postTooLarge=Les paramètres n'ont pas été évalués car la taille des données postées est trop important. Utilisez l'attribut maxPostSize du connecteur pour corriger ce problème si votre application doit accepter des POSTs importants.
coyoteRequest.sendfileNotCanonical=Impossible d''obtenir le nom canonique du fichier [{0}] qui a été donné pour le sendfile
coyoteRequest.sessionCreateCommitted=Impossible de créer une session après que la réponse ait été envoyée
@@ -93,6 +95,7 @@
request.fragmentInDispatchPath=Le fragment dans le chemin de dispatch [{0}] a été enlevé
request.illegalWrap=L'enrobeur de la réponse doit enrober la requête obtenue à partir de getRequest()
request.notAsync=Il est interdit d'appeler cette méthode si la requête actuelle n'est pas en mode asynchrone (isAsyncStarted() a renvoyé false)
+request.partCleanup.failed=Impossible d'effacer le fichier temporaire pour la partie envoyée après l'échec de traitement du multi partie
request.session.failed=Erreur de chargement de la session [{0}] à cause de [{1}]
requestFacade.nullRequest=L'objet requête a été recyclé et n'est plus associé à cette façade
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/connector/LocalStrings_ja.properties tomcat11-11.0.15/java/org/apache/catalina/connector/LocalStrings_ja.properties
--- tomcat11-11.0.6/java/org/apache/catalina/connector/LocalStrings_ja.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/connector/LocalStrings_ja.properties 2025-12-02 16:54:08.000000000 +0000
@@ -62,9 +62,11 @@
coyoteRequest.maxPostSizeExceeded=マルチパートリクエストには、関連付けられたコネクタで設定されたmaxPostSizeの制限を超えたパラメータデータ(アップロードされたファイルを除く)が含まれていました。
coyoteRequest.noAsync=処理チェーン内の次のクラスが非同期をサポートしていないため、非同期を開始できません [{0}]
coyoteRequest.noMultipartConfig=multi-part 構成が提供されていないため、partを処理できません
+coyoteRequest.parametersParseException=パラメータの解析中に例外 [{0}] が発生しました
coyoteRequest.parseParameters=POST パラメーターの処理中に例外を投げました。
+coyoteRequest.partsParseException=パートの解析中に例外 [{0}] が発生しました
coyoteRequest.postTooLarge=POSTされたデータが大きすぎたので、パラメータが構文解析できませんでした。そのアプリケーションが巨大なPOSTを受け付けねばならない場合には、これを解決するためにコネクタのmaxPostSize属性を使用してください。
-coyoteRequest.sendfileNotCanonical=sendfile に指定されたファイル [{0}] の正式名を取得できません
+coyoteRequest.sendfileNotCanonical=sendfile に指定されたファイル [{0}] の正規名を取得できません
coyoteRequest.sessionCreateCommitted=レスポンスをコミットした後でセッションを作成できません
coyoteRequest.sessionEndAccessFail=リクエストの再利用中に行ったセッションへのアクセス終了処理で例外が送出されました。
coyoteRequest.setAttribute.namenull=setAttributeを名前を指定せずに呼び出すことはできません
@@ -93,6 +95,7 @@
request.fragmentInDispatchPath=ディスパッチパス [{0}] 中のフラグメントは除去されました
request.illegalWrap=リクエストラッパーは getRequest() で取得したリクエストをラップしなければなりません。
request.notAsync=非同期モードではないリクエストでこのメソッドを呼び出すことはできません。(例えば isAsyncStarted() が false を返す場合)
+request.partCleanup.failed=マルチパート処理が失敗した後、アップロードされたパートのテンポラリファイルを削除できませんでした
request.session.failed=[{1}]が原因で、セッション[{0}]の読み込みに失敗しました
requestFacade.nullRequest=リクエストオブジェクトは回収されこのファサードに関連付けられなくなりました。
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/connector/LocalStrings_ru.properties tomcat11-11.0.15/java/org/apache/catalina/connector/LocalStrings_ru.properties
--- tomcat11-11.0.6/java/org/apache/catalina/connector/LocalStrings_ru.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/connector/LocalStrings_ru.properties 2025-12-02 16:54:08.000000000 +0000
@@ -25,5 +25,6 @@
coyoteInputStream.nbNotready=В неблокирующем режиме невозможно читать из ServletInputStream до тех пор пока не завершится предыдущее чтение и IsReady() не вернёт true
+coyoteRequest.changeSessionId=Невозможно изменить ID сессии. Нет сессии связаной с этим запросом.
coyoteRequest.sendfileNotCanonical=Невозможно определить каноническое имя файла [{0}] указанное для использования с sendfile
coyoteRequest.sessionEndAccessFail=Исключение вызвало прекращение доступа к сессии при очистке запроса
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/connector/OutputBuffer.java tomcat11-11.0.15/java/org/apache/catalina/connector/OutputBuffer.java
--- tomcat11-11.0.6/java/org/apache/catalina/connector/OutputBuffer.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/connector/OutputBuffer.java 2025-12-02 16:54:08.000000000 +0000
@@ -33,14 +33,12 @@
import org.apache.coyote.Response;
import org.apache.tomcat.util.buf.C2BConverter;
import org.apache.tomcat.util.buf.CharsetHolder;
+import org.apache.tomcat.util.http.Method;
import org.apache.tomcat.util.res.StringManager;
/**
* The buffer used by Tomcat response. This is a derivative of the Tomcat 3.3 OutputBuffer, with the removal of some of
* the state handling (which in Coyote is mostly the Processor's responsibility).
- *
- * @author Costin Manolache
- * @author Remy Maucherat
*/
public class OutputBuffer extends Writer {
@@ -226,8 +224,8 @@
// - the content length has not been explicitly set
// AND
// - some content has been written OR this is NOT a HEAD request
- if ((!coyoteResponse.isCommitted()) && (coyoteResponse.getContentLengthLong() == -1) &&
- ((bb.remaining() > 0 || !coyoteResponse.getRequest().method().equals("HEAD")))) {
+ if (!coyoteResponse.isCommitted() && coyoteResponse.getContentLengthLong() == -1 &&
+ (bb.remaining() > 0 || !Method.HEAD.equals(coyoteResponse.getRequest().getMethod()))) {
coyoteResponse.setContentLength(bb.remaining());
}
@@ -323,11 +321,11 @@
// Prevent further output for this response
closed = true;
throw e;
- } catch (IOException e) {
+ } catch (IOException ioe) {
// An IOException on a write is almost always due to
// the remote client aborting the request. Wrap this
// so that it can be handled better by the error dispatcher.
- throw new ClientAbortException(e);
+ throw new ClientAbortException(ioe);
}
}
@@ -419,8 +417,8 @@
/*
* Handle the requirements of section 5.7 of the Servlet specification - Closure of the Response Object.
*
- * Currently, this just handles the simple case. There is work in progress to better define what should happen if
- * an attempt is made to write > content-length bytes. When that work is complete, this is likely where the
+ * Currently, this just handles the simple case. There is work in progress to better define what should happen
+ * if an attempt is made to write > content-length bytes. When that work is complete, this is likely where the
* implementation will end up.
*/
if (contentLength != -1 && bytesWritten >= contentLength) {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/connector/Request.java tomcat11-11.0.15/java/org/apache/catalina/connector/Request.java
--- tomcat11-11.0.6/java/org/apache/catalina/connector/Request.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/connector/Request.java 2025-12-02 16:54:08.000000000 +0000
@@ -111,6 +111,7 @@
import org.apache.tomcat.util.http.fileupload.FileItem;
import org.apache.tomcat.util.http.fileupload.FileUpload;
import org.apache.tomcat.util.http.fileupload.disk.DiskFileItemFactory;
+import org.apache.tomcat.util.http.fileupload.impl.FileCountLimitExceededException;
import org.apache.tomcat.util.http.fileupload.impl.InvalidContentTypeException;
import org.apache.tomcat.util.http.fileupload.impl.SizeException;
import org.apache.tomcat.util.http.fileupload.servlet.ServletRequestContext;
@@ -124,9 +125,6 @@
/**
* Wrapper object for the Coyote request.
- *
- * @author Remy Maucherat
- * @author Craig R. McClanahan
*/
public class Request implements HttpServletRequest {
@@ -147,7 +145,9 @@
public Request(Connector connector, org.apache.coyote.Request coyoteRequest) {
this.connector = connector;
if (connector != null) {
- this.maxParameterCount = connector.getMaxParameterCount();
+ maxParameterCount = connector.getMaxParameterCount();
+ maxPartCount = connector.getMaxPartCount();
+ maxPartHeaderSize = connector.getMaxPartHeaderSize();
}
this.coyoteRequest = coyoteRequest;
inputBuffer = new InputBuffer(coyoteRequest);
@@ -420,13 +420,17 @@
*/
private int maxParameterCount = -1;
+ private int maxPartCount = -1;
+
+ private int maxPartHeaderSize = -1;
+
// --------------------------------------------------------- Public Methods
- protected void addPathParameter(String name, String value) {
+ public void addPathParameter(String name, String value) {
coyoteRequest.addPathParameter(name, value);
}
- protected String getPathParameter(String name) {
+ public String getPathParameter(String name) {
return coyoteRequest.getPathParameter(name);
}
@@ -451,8 +455,12 @@
parametersParsed = false;
if (connector != null) {
maxParameterCount = connector.getMaxParameterCount();
+ maxPartCount = connector.getMaxPartCount();
+ maxPartHeaderSize = connector.getMaxPartHeaderSize();
} else {
maxParameterCount = -1;
+ maxPartCount = -1;
+ maxPartHeaderSize = -1;
}
if (parts != null) {
for (Part part : parts) {
@@ -519,7 +527,7 @@
}
- protected void recycleSessionInfo() {
+ public void recycleSessionInfo() {
if (session != null) {
try {
session.endAccess();
@@ -842,8 +850,9 @@
coyoteRequest.setServerPort(port);
}
+
/**
- * Set the maximum number of request parameters (GET plus POST) for a single request
+ * Set the maximum number of request parameters (GET plus POST including multipart) for a single request.
*
* @param maxParameterCount The maximum number of request parameters
*/
@@ -851,6 +860,27 @@
this.maxParameterCount = maxParameterCount;
}
+
+ /**
+ * Set the maximum number of parts for a single multipart request.
+ *
+ * @param maxPartCount The maximum number of request parts
+ */
+ public void setMaxPartCount(int maxPartCount) {
+ this.maxPartCount = maxPartCount;
+ }
+
+
+ /**
+ * Set the maximum header size per part for a single multipart request.
+ *
+ * @param maxPartHeaderSize The maximum size of the headers for one part
+ */
+ public void setMaxPartHeaderSize(int maxPartHeaderSize) {
+ this.maxPartHeaderSize = maxPartHeaderSize;
+ }
+
+
// ------------------------------------------------- ServletRequest Methods
@SuppressWarnings("deprecation")
@@ -924,8 +954,8 @@
* {@inheritDoc}
*
* The attribute names returned will only be those for the attributes set via {@link #setAttribute(String, Object)}.
- * Tomcat internal attributes will not be included even though they are accessible via {@link #getAttribute(String)}.
- * The Tomcat internal attributes include:
+ * Tomcat internal attributes will not be included even though they are accessible via
+ * {@link #getAttribute(String)}. The Tomcat internal attributes include:
*
*
{@link Globals#DISPATCHER_TYPE_ATTR}
*
{@link Globals#DISPATCHER_REQUEST_PATH_ATTR}
@@ -2035,7 +2065,7 @@
@Override
public String getMethod() {
- return coyoteRequest.method().toStringType();
+ return coyoteRequest.getMethod();
}
@@ -2177,8 +2207,8 @@
Session session = null;
try {
session = manager.findSession(requestedSessionId);
- } catch (IOException e) {
- // Can't find the session
+ } catch (IOException ignore) {
+ // Error looking up session. Treat it as not found.
}
if ((session == null) || !session.isValid()) {
@@ -2190,8 +2220,8 @@
if (ctxt.getManager().findSession(requestedSessionId) != null) {
return true;
}
- } catch (IOException e) {
- // Ignore
+ } catch (IOException ignore) {
+ // Error looking up session. Treat it as not found.
}
}
}
@@ -2406,9 +2436,14 @@
@Override
public Collection getParts() throws IOException, IllegalStateException, ServletException {
- parseParts();
+ parseParts(true);
if (partsParseException != null) {
+ Context context = getContext();
+ if (context != null && context.getLogger().isDebugEnabled()) {
+ context.getLogger()
+ .debug(sm.getString("coyoteRequest.partsParseException", partsParseException.getMessage()));
+ }
if (partsParseException instanceof IOException) {
throw (IOException) partsParseException;
} else if (partsParseException instanceof IllegalStateException) {
@@ -2422,7 +2457,7 @@
}
- private void parseParts() {
+ private void parseParts(boolean explicit) {
// Return immediately if the parts have already been parsed
if (parts != null || partsParseException != null) {
@@ -2437,11 +2472,35 @@
mce = new MultipartConfigElement(null, connector.getMaxPostSize(), connector.getMaxPostSize(),
connector.getMaxPostSize());
} else {
- partsParseException = new IllegalStateException(sm.getString("coyoteRequest.noMultipartConfig"));
+ if (explicit) {
+ partsParseException = new IllegalStateException(sm.getString("coyoteRequest.noMultipartConfig"));
+ } else {
+ parts = Collections.emptyList();
+ }
return;
}
}
+ /*
+ * When the request body is multipart/form-data, both the parts and the query string count towards
+ * maxParameterCount. If parseParts() is called before getParameterXXX() then the parts will be parsed before
+ * the query string. Otherwise, the query string will be parsed first.
+ *
+ * maxParameterCount must be respected regardless of which is parsed first.
+ *
+ * maxParameterCount is reset from the Connector at the start of every request.
+ *
+ * If parts are parsed first, non-file parts will be added to the parameter map and any files will reduce
+ * maxParameterCount by 1 so that when the query string is parsed the difference between the size of the
+ * parameter map and maxParameterCount will be the original maxParameterCount less the number of parts. i.e. the
+ * maxParameterCount applied to the query string will be the original maxParameterCount less the number of
+ * parts.
+ *
+ * If the query string is parsed first, all parameters will be added to the parameter map and, ignoring
+ * maxPartCount, the part limit will be set to the original maxParameterCount less the size of the parameter
+ * map. i.e. the maxParameterCount applied to the parts will be the original maxParameterCount less the number
+ * of query parameters.
+ */
Parameters parameters = coyoteRequest.getParameters();
parameters.setLimit(maxParameterCount);
@@ -2486,35 +2545,53 @@
upload.setFileItemFactory(factory);
upload.setFileSizeMax(mce.getMaxFileSize());
upload.setSizeMax(mce.getMaxRequestSize());
- if (maxParameterCount > -1) {
- // There is a limit. The limit for parts needs to be reduced by
- // the number of parameters we have already parsed.
- // Must be under the limit else parsing parameters would have
- // triggered an exception.
- upload.setFileCountMax(maxParameterCount - parameters.size());
+ upload.setPartHeaderSizeMax(maxPartHeaderSize);
+ /*
+ * There are two independent limits on the number of parts.
+ *
+ * 1. The limit based on parameters. This is maxParameterCount less the number of parameters already processed.
+ *
+ * 2. The limit based on parts. This is maxPartCount.
+ *
+ * The lower of these two limits will be applied to this request.
+ *
+ * Note: Either of both limits may be set to -1 (unlimited).
+ */
+ int partLimit = maxParameterCount;
+ if (partLimit > -1) {
+ partLimit = partLimit - parameters.size();
+ }
+ int maxPartCount = this.maxPartCount;
+ if (maxPartCount > -1) {
+ if (partLimit < 0 || partLimit > maxPartCount) {
+ partLimit = maxPartCount;
+ }
}
+ upload.setFileCountMax(partLimit);
parts = new ArrayList<>();
+ List items = null;
+ boolean success = false;
try {
- List items = upload.parseRequest(new ServletRequestContext(this));
+ items = upload.parseRequest(new ServletRequestContext(this));
int maxPostSize = getConnector().getMaxPostSize();
- int postSize = 0;
+ long postSize = 0;
Charset charset = getCharset();
for (FileItem item : items) {
ApplicationPart part = new ApplicationPart(item, location);
- parts.add(part);
if (part.getSubmittedFileName() == null) {
String name = part.getName();
if (maxPostSize >= 0) {
// Have to calculate equivalent size. Not completely
// accurate but close enough.
- postSize += name.getBytes(charset).length;
+ // Name
+ postSize = Math.addExact(postSize, name.getBytes(charset).length);
// Equals sign
- postSize++;
+ postSize = Math.addExact(postSize, 1);
// Value length
- postSize += (int) part.getSize();
+ postSize = Math.addExact(postSize, part.getSize());
// Value separator
- postSize++;
+ postSize = Math.addExact(postSize, 1);
if (postSize > maxPostSize) {
throw new IllegalStateException(sm.getString("coyoteRequest.maxPostSizeExceeded"));
}
@@ -2526,18 +2603,41 @@
// Not possible
}
parameters.addParameter(name, value);
+ } else {
+ // Adjust the limit to account for a file part which is not added to the parameter map.
+ maxParameterCount--;
}
+ parts.add(part);
}
+ success = true;
} catch (InvalidContentTypeException e) {
partsParseException = new ServletException(e);
- } catch (SizeException e) {
+ } catch (SizeException | FileCountLimitExceededException e) {
checkSwallowInput();
partsParseException = new InvalidParameterException(e, HttpServletResponse.SC_REQUEST_ENTITY_TOO_LARGE);
- } catch (IOException e) {
- partsParseException = e;
+ } catch (IOException ioe) {
+ partsParseException = ioe;
} catch (IllegalStateException e) {
checkSwallowInput();
partsParseException = e;
+ } finally {
+ /*
+ * GC will delete any temporary copies of uploaded files left in the work directory but if we know that the
+ * upload has failed then explicitly clean up now.
+ */
+ if (!success) {
+ parts.clear();
+ if (items != null) {
+ for (FileItem item : items) {
+ try {
+ item.delete();
+ } catch (Throwable t) {
+ ExceptionUtils.handleThrowable(t);
+ log.warn(sm.getString("request.partCleanup.failed"), t);
+ }
+ }
+ }
+ }
}
}
@@ -2579,11 +2679,11 @@
if (requestedSessionId != null) {
try {
session = manager.findSession(requestedSessionId);
- } catch (IOException e) {
+ } catch (IOException ioe) {
if (log.isDebugEnabled()) {
- log.debug(sm.getString("request.session.failed", requestedSessionId, e.getMessage()), e);
+ log.debug(sm.getString("request.session.failed", requestedSessionId, ioe.getMessage()), ioe);
} else {
- log.info(sm.getString("request.session.failed", requestedSessionId, e.getMessage()));
+ log.info(sm.getString("request.session.failed", requestedSessionId, ioe.getMessage()));
}
session = null;
}
@@ -2592,6 +2692,8 @@
}
if (session != null) {
session.access();
+ // The client has chosen to join the session
+ session.setNew(false);
return session;
}
}
@@ -2632,9 +2734,8 @@
found = true;
break;
}
- } catch (IOException e) {
- // Ignore. Problems with this manager will be
- // handled elsewhere.
+ } catch (IOException ignore) {
+ // Error looking up session. Treat it as not found.
}
}
}
@@ -2744,7 +2845,7 @@
scookie.getValue().getByteChunk().setCharset(getCookieProcessor().getCharset());
cookie.setValue(unescape(scookie.getValue().toString()));
cookies[idx++] = cookie;
- } catch (IllegalArgumentException e) {
+ } catch (IllegalArgumentException ignore) {
// Ignore bad cookie
}
}
@@ -2763,6 +2864,11 @@
doParseParameters();
if (parametersParseException != null) {
+ Context context = getContext();
+ if (context != null && context.getLogger().isDebugEnabled()) {
+ context.getLogger().debug(
+ sm.getString("coyoteRequest.parametersParseException", parametersParseException.getMessage()));
+ }
throw parametersParseException;
}
}
@@ -2774,11 +2880,27 @@
}
parametersParsed = true;
+ /*
+ * When the request body is multipart/form-data, both the parts and the query string count towards
+ * maxParameterCount. If parseParts() is called before getParameterXXX() then the parts will be parsed before
+ * the query string. Otherwise, the query string will be parsed first.
+ *
+ * maxParameterCount must be respected regardless of which is parsed first.
+ *
+ * maxParameterCount is reset from the Connector at the start of every request.
+ *
+ * If parts are parsed first, non-file parts will be added to the parameter map and any files will reduce
+ * maxParameterCount by 1 so that when the query string is parsed the difference between the size of the
+ * parameter map and maxParameterCount will be the original maxParameterCount less the number of parts. i.e. the
+ * maxParameterCount applied to the query string will be the original maxParameterCount less the number of
+ * parts.
+ *
+ * If the query string is parsed first, all parameters will be added to the parameter map and, ignoring
+ * maxPartCount, the part limit will be set to the original maxParameterCount less the size of the parameter
+ * map. i.e. the maxParameterCount applied to the parts will be the original maxParameterCount less the number
+ * of query parameters.
+ */
Parameters parameters = coyoteRequest.getParameters();
-
- if (parts != null && maxParameterCount > 0) {
- maxParameterCount -= parts.size();
- }
parameters.setLimit(maxParameterCount);
// getCharacterEncoding() may have been overridden to search for
@@ -2802,7 +2924,7 @@
String mediaType = MediaType.parseMediaTypeOnly(getContentType());
if ("multipart/form-data".equals(mediaType)) {
- parseParts();
+ parseParts(false);
if (partsParseException instanceof IllegalStateException) {
parametersParseException = (IllegalStateException) partsParseException;
} else if (partsParseException != null) {
@@ -2845,19 +2967,19 @@
}
try {
readPostBodyFully(formData, len);
- } catch (IOException e) {
+ } catch (IOException ioe) {
Context context = getContext();
if (context != null && context.getLogger().isDebugEnabled()) {
- context.getLogger().debug(sm.getString("coyoteRequest.parseParameters"), e);
+ context.getLogger().debug(sm.getString("coyoteRequest.parseParameters"), ioe);
}
- if (e instanceof ClientAbortException) {
+ if (ioe instanceof ClientAbortException) {
// Client has disconnected. Close immediately.
response.getCoyoteResponse().action(ActionCode.CLOSE_NOW, null);
}
- if (e instanceof BadRequestException) {
- parametersParseException = new InvalidParameterException(e);
+ if (ioe instanceof BadRequestException) {
+ parametersParseException = new InvalidParameterException(ioe);
} else {
- parametersParseException = new InvalidParameterException(new BadRequestException(e));
+ parametersParseException = new InvalidParameterException(new BadRequestException(ioe));
}
return;
}
@@ -2868,19 +2990,19 @@
formData = readChunkedPostBody();
} catch (IllegalStateException ise) {
parametersParseException = ise;
- } catch (IOException e) {
+ } catch (IOException ioe) {
Context context = getContext();
if (context != null && context.getLogger().isDebugEnabled()) {
- context.getLogger().debug(sm.getString("coyoteRequest.parseParameters"), e);
+ context.getLogger().debug(sm.getString("coyoteRequest.parseParameters"), ioe);
}
- if (e instanceof ClientAbortException) {
+ if (ioe instanceof ClientAbortException) {
// Client has disconnected. Close immediately.
response.getCoyoteResponse().action(ActionCode.CLOSE_NOW, null);
}
- if (e instanceof BadRequestException) {
- parametersParseException = new InvalidParameterException(e);
+ if (ioe instanceof BadRequestException) {
+ parametersParseException = new InvalidParameterException(ioe);
} else {
- parametersParseException = new InvalidParameterException(new BadRequestException(e));
+ parametersParseException = new InvalidParameterException(new BadRequestException(ioe));
}
}
if (formData != null) {
@@ -2990,7 +3112,7 @@
List acceptLanguages;
try {
acceptLanguages = AcceptLanguage.parse(new StringReader(value));
- } catch (IOException e) {
+ } catch (IOException ioe) {
// Mal-formed headers are ignore. Do the same in the unlikely event
// of an IOException.
return;
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/connector/RequestFacade.java tomcat11-11.0.15/java/org/apache/catalina/connector/RequestFacade.java
--- tomcat11-11.0.6/java/org/apache/catalina/connector/RequestFacade.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/connector/RequestFacade.java 2025-12-02 16:54:08.000000000 +0000
@@ -45,9 +45,6 @@
/**
* Facade class that wraps a Coyote request object. All methods are delegated to the wrapped request.
- *
- * @author Craig R. McClanahan
- * @author Remy Maucherat
*/
public class RequestFacade implements HttpServletRequest {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/connector/Response.java tomcat11-11.0.15/java/org/apache/catalina/connector/Response.java
--- tomcat11-11.0.6/java/org/apache/catalina/connector/Response.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/connector/Response.java 2025-12-02 16:54:08.000000000 +0000
@@ -62,9 +62,6 @@
/**
* Wrapper object for the Coyote response.
- *
- * @author Remy Maucherat
- * @author Craig R. McClanahan
*/
public class Response implements HttpServletResponse {
@@ -1358,8 +1355,8 @@
redirectURLCC.append(':');
redirectURLCC.append(location, 0, location.length());
return redirectURLCC.toString();
- } catch (IOException e) {
- throw new IllegalArgumentException(location, e);
+ } catch (IOException ioe) {
+ throw new IllegalArgumentException(location, ioe);
}
} else if (leadingSlash || !UriUtil.hasScheme(location)) {
@@ -1390,8 +1387,8 @@
redirectURLCC.append(location, 0, location.length());
normalize(redirectURLCC);
- } catch (IOException e) {
- throw new IllegalArgumentException(location, e);
+ } catch (IOException ioe) {
+ throw new IllegalArgumentException(location, ioe);
}
return redirectURLCC.toString();
@@ -1425,8 +1422,8 @@
if (cc.endsWith("/.") || cc.endsWith("/..")) {
try {
cc.append('/');
- } catch (IOException e) {
- throw new IllegalArgumentException(cc.toString(), e);
+ } catch (IOException ioe) {
+ throw new IllegalArgumentException(cc.toString(), ioe);
}
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/connector/ResponseFacade.java tomcat11-11.0.15/java/org/apache/catalina/connector/ResponseFacade.java
--- tomcat11-11.0.6/java/org/apache/catalina/connector/ResponseFacade.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/connector/ResponseFacade.java 2025-12-02 16:54:08.000000000 +0000
@@ -32,8 +32,6 @@
/**
* Facade class that wraps a Coyote response object. All methods are delegated to the wrapped response.
- *
- * @author Remy Maucherat
*/
public class ResponseFacade implements HttpServletResponse {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/core/ApplicationContext.java tomcat11-11.0.15/java/org/apache/catalina/core/ApplicationContext.java
--- tomcat11-11.0.6/java/org/apache/catalina/core/ApplicationContext.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/core/ApplicationContext.java 2025-12-02 16:54:08.000000000 +0000
@@ -83,9 +83,6 @@
/**
* Standard implementation of ServletContext that represents a web application's execution environment. An
* instance of this class is associated with each instance of StandardContext.
- *
- * @author Craig R. McClanahan
- * @author Remy Maucherat
*/
public class ApplicationContext implements ServletContext {
@@ -374,7 +371,7 @@
// From this point, the removal of path parameters, decoding and normalization is only for mapping purposes.
// Remove path parameters
- String uriToMap = stripPathParams(uri);
+ String uriToMap = org.apache.catalina.util.RequestUtil.stripPathParams(uri, null);
// Decode only if the uri derived from the provided path is expected to be encoded
if (getContext().getDispatchersUseEncodedPaths()) {
@@ -449,34 +446,6 @@
}
- // Package private to facilitate testing
- static String stripPathParams(String input) {
- // Shortcut
- if (input.indexOf(';') < 0) {
- return input;
- }
-
- StringBuilder sb = new StringBuilder(input.length());
- int pos = 0;
- int limit = input.length();
- while (pos < limit) {
- int nextSemiColon = input.indexOf(';', pos);
- if (nextSemiColon < 0) {
- nextSemiColon = limit;
- }
- sb.append(input, pos, nextSemiColon);
- int followingSlash = input.indexOf('/', nextSemiColon);
- if (followingSlash < 0) {
- pos = limit;
- } else {
- pos = followingSlash;
- }
- }
-
- return sb.toString();
- }
-
-
@Override
public URL getResource(String path) throws MalformedURLException {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/core/ApplicationContextFacade.java tomcat11-11.0.15/java/org/apache/catalina/core/ApplicationContextFacade.java
--- tomcat11-11.0.6/java/org/apache/catalina/core/ApplicationContextFacade.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/core/ApplicationContextFacade.java 2025-12-02 16:54:08.000000000 +0000
@@ -40,8 +40,6 @@
/**
* Facade object which masks the internal ApplicationContext object from the web application.
- *
- * @author Remy Maucherat
*/
public class ApplicationContextFacade implements ServletContext {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/core/ApplicationDispatcher.java tomcat11-11.0.15/java/org/apache/catalina/core/ApplicationDispatcher.java
--- tomcat11-11.0.6/java/org/apache/catalina/core/ApplicationDispatcher.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/core/ApplicationDispatcher.java 2025-12-02 16:54:08.000000000 +0000
@@ -45,6 +45,7 @@
import org.apache.coyote.BadRequestException;
import org.apache.coyote.CloseNowException;
import org.apache.tomcat.util.ExceptionUtils;
+import org.apache.tomcat.util.http.Method;
import org.apache.tomcat.util.res.StringManager;
/**
@@ -53,8 +54,6 @@
* resource. This implementation allows application level servlets to wrap the request and/or response objects that are
* passed on to the called resource, as long as the wrapping classes extend
* jakarta.servlet.ServletRequestWrapper and jakarta.servlet.ServletResponseWrapper.
- *
- * @author Craig R. McClanahan
*/
final class ApplicationDispatcher implements AsyncDispatcher, RequestDispatcher {
@@ -224,7 +223,7 @@
// All ERROR dispatches must be GET requests. Use the presence of ERROR_METHOD to determine if this is an
// error dispatch as not all components (JSP) set the dispatcher type.
if (request.getAttribute(ERROR_METHOD) != null) {
- wrequest.setMethod("GET");
+ wrequest.setMethod(Method.GET);
}
wrequest.setRequestURI(hrequest.getRequestURI());
wrequest.setContextPath(hrequest.getContextPath());
@@ -247,7 +246,7 @@
// All ERROR dispatches must be GET requests. Use the presence of ERROR_METHOD to determine if this is an
// error dispatch as not all components (JSP) set the dispatcher type.
if (request.getAttribute(ERROR_METHOD) != null) {
- wrequest.setMethod("GET");
+ wrequest.setMethod(Method.GET);
}
wrequest.setContextPath(context.getEncodedPath());
wrequest.setRequestURI(requestURI);
@@ -304,7 +303,7 @@
} catch (IllegalStateException | IOException f) {
// Ignore
}
- } catch (IOException e) {
+ } catch (IOException ignore) {
// Ignore
}
}
@@ -496,11 +495,11 @@
wrapper.getLogger().error(sm.getString("applicationDispatcher.allocateException", wrapper.getName()),
StandardWrapper.getRootCause(e));
servletException = e;
- } catch (Throwable e) {
- ExceptionUtils.handleThrowable(e);
- wrapper.getLogger().error(sm.getString("applicationDispatcher.allocateException", wrapper.getName()), e);
+ } catch (Throwable t) {
+ ExceptionUtils.handleThrowable(t);
+ wrapper.getLogger().error(sm.getString("applicationDispatcher.allocateException", wrapper.getName()), t);
servletException =
- new ServletException(sm.getString("applicationDispatcher.allocateException", wrapper.getName()), e);
+ new ServletException(sm.getString("applicationDispatcher.allocateException", wrapper.getName()), t);
// servlet = null; is already done so no need to do it explicitly
}
@@ -516,9 +515,9 @@
// Servlet Service Method is called by the FilterChain
} catch (BadRequestException | CloseNowException e) {
ioException = e;
- } catch (IOException e) {
- wrapper.getLogger().error(sm.getString("applicationDispatcher.serviceException", wrapper.getName()), e);
- ioException = e;
+ } catch (IOException ioe) {
+ wrapper.getLogger().error(sm.getString("applicationDispatcher.serviceException", wrapper.getName()), ioe);
+ ioException = ioe;
} catch (UnavailableException e) {
wrapper.getLogger().error(sm.getString("applicationDispatcher.serviceException", wrapper.getName()), e);
servletException = e;
@@ -548,11 +547,11 @@
} catch (ServletException e) {
wrapper.getLogger().error(sm.getString("applicationDispatcher.deallocateException", wrapper.getName()), e);
servletException = e;
- } catch (Throwable e) {
- ExceptionUtils.handleThrowable(e);
- wrapper.getLogger().error(sm.getString("applicationDispatcher.deallocateException", wrapper.getName()), e);
+ } catch (Throwable t) {
+ ExceptionUtils.handleThrowable(t);
+ wrapper.getLogger().error(sm.getString("applicationDispatcher.deallocateException", wrapper.getName()), t);
servletException = new ServletException(
- sm.getString("applicationDispatcher.deallocateException", wrapper.getName()), e);
+ sm.getString("applicationDispatcher.deallocateException", wrapper.getName()), t);
}
// Reset the old context class loader
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/core/ApplicationFilterChain.java tomcat11-11.0.15/java/org/apache/catalina/core/ApplicationFilterChain.java
--- tomcat11-11.0.6/java/org/apache/catalina/core/ApplicationFilterChain.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/core/ApplicationFilterChain.java 2025-12-02 16:54:08.000000000 +0000
@@ -35,8 +35,6 @@
* Implementation of jakarta.servlet.FilterChain used to manage the execution of a set of filters for a
* particular request. When the set of defined filters has all been executed, the next call to doFilter()
* will execute the servlet's service() method itself.
- *
- * @author Craig R. McClanahan
*/
public final class ApplicationFilterChain implements FilterChain {
@@ -109,9 +107,9 @@
filter.doFilter(request, response, this);
} catch (IOException | ServletException | RuntimeException e) {
throw e;
- } catch (Throwable e) {
- ExceptionUtils.handleThrowable(e);
- throw new ServletException(sm.getString("filterChain.filter"), e);
+ } catch (Throwable t) {
+ ExceptionUtils.handleThrowable(t);
+ throw new ServletException(sm.getString("filterChain.filter"), t);
}
return;
}
@@ -130,9 +128,9 @@
servlet.service(request, response);
} catch (IOException | ServletException | RuntimeException e) {
throw e;
- } catch (Throwable e) {
- ExceptionUtils.handleThrowable(e);
- throw new ServletException(sm.getString("filterChain.servlet"), e);
+ } catch (Throwable t) {
+ ExceptionUtils.handleThrowable(t);
+ throw new ServletException(sm.getString("filterChain.servlet"), t);
} finally {
if (dispatcherWrapsSameObject) {
lastServicedRequest.set(null);
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/core/ApplicationFilterConfig.java tomcat11-11.0.15/java/org/apache/catalina/core/ApplicationFilterConfig.java
--- tomcat11-11.0.6/java/org/apache/catalina/core/ApplicationFilterConfig.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/core/ApplicationFilterConfig.java 2025-12-02 16:54:08.000000000 +0000
@@ -48,8 +48,6 @@
/**
* Implementation of a jakarta.servlet.FilterConfig useful in managing the filter instances instantiated
* when a web application is first started.
- *
- * @author Craig R. McClanahan
*/
public final class ApplicationFilterConfig implements FilterConfig, Serializable {
@@ -178,11 +176,8 @@
@Override
public String toString() {
- return "ApplicationFilterConfig[" + "name=" +
- filterDef.getFilterName() +
- ", filterClass=" +
- filterDef.getFilterClass() +
- ']';
+ return "ApplicationFilterConfig[" + "name=" + filterDef.getFilterName() + ", filterClass=" +
+ filterDef.getFilterClass() + ']';
}
// --------------------------------------------------------- Public Methods
@@ -312,8 +307,8 @@
try {
oname = new ObjectName(onameStr);
Registry.getRegistry(null).registerComponent(this, oname, null);
- } catch (Exception ex) {
- log.warn(sm.getString("applicationFilterConfig.jmxRegisterFail", getFilterClass(), getFilterName()), ex);
+ } catch (Exception e) {
+ log.warn(sm.getString("applicationFilterConfig.jmxRegisterFail", getFilterClass(), getFilterName()), e);
}
}
@@ -326,9 +321,9 @@
if (log.isDebugEnabled()) {
log.debug(sm.getString("applicationFilterConfig.jmxUnregister", getFilterClass(), getFilterName()));
}
- } catch (Exception ex) {
+ } catch (Exception e) {
log.warn(sm.getString("applicationFilterConfig.jmxUnregisterFail", getFilterClass(), getFilterName()),
- ex);
+ e);
}
}
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/core/ApplicationFilterFactory.java tomcat11-11.0.15/java/org/apache/catalina/core/ApplicationFilterFactory.java
--- tomcat11-11.0.6/java/org/apache/catalina/core/ApplicationFilterFactory.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/core/ApplicationFilterFactory.java 2025-12-02 16:54:08.000000000 +0000
@@ -31,9 +31,6 @@
/**
* Factory for the creation and caching of Filters and creation of Filter Chains.
- *
- * @author Greg Murray
- * @author Remy Maucherat
*/
public final class ApplicationFilterFactory {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/core/ApplicationHttpRequest.java tomcat11-11.0.15/java/org/apache/catalina/core/ApplicationHttpRequest.java
--- tomcat11-11.0.6/java/org/apache/catalina/core/ApplicationHttpRequest.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/core/ApplicationHttpRequest.java 2025-12-02 16:54:08.000000000 +0000
@@ -59,9 +59,6 @@
* WARNING: Due to Java's lack of support for multiple inheritance, all of the logic in
* ApplicationRequest is duplicated in ApplicationHttpRequest. Make sure that you keep these
* two classes in synchronization when making changes!
- *
- * @author Craig R. McClanahan
- * @author Remy Maucherat
*/
class ApplicationHttpRequest extends HttpServletRequestWrapper {
@@ -556,7 +553,7 @@
if (localSession != null && !localSession.isValid()) {
localSession = null;
}
- } catch (IOException e) {
+ } catch (IOException ignore) {
// Ignore
}
if (localSession == null && create) {
@@ -602,7 +599,7 @@
Session session = null;
try {
session = manager.findSession(requestedSessionId);
- } catch (IOException e) {
+ } catch (IOException ignore) {
// Ignore
}
return (session != null) && session.isValid();
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/core/ApplicationHttpResponse.java tomcat11-11.0.15/java/org/apache/catalina/core/ApplicationHttpResponse.java
--- tomcat11-11.0.6/java/org/apache/catalina/core/ApplicationHttpResponse.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/core/ApplicationHttpResponse.java 2025-12-02 16:54:08.000000000 +0000
@@ -33,8 +33,6 @@
* WARNING: Due to Java's lack of support for multiple inheritance, all of the logic in
* ApplicationResponse is duplicated in ApplicationHttpResponse. Make sure that you keep these
* two classes in synchronization when making changes!
- *
- * @author Craig R. McClanahan
*/
class ApplicationHttpResponse extends HttpServletResponseWrapper {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/core/ApplicationMapping.java tomcat11-11.0.15/java/org/apache/catalina/core/ApplicationMapping.java
--- tomcat11-11.0.6/java/org/apache/catalina/core/ApplicationMapping.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/core/ApplicationMapping.java 2025-12-02 16:54:08.000000000 +0000
@@ -80,8 +80,8 @@
mapping = null;
}
- private record MappingImpl(String matchValue, String pattern, MappingMatch mappingType,
- String servletName) implements HttpServletMapping {
+ private record MappingImpl(String matchValue, String pattern, MappingMatch mappingType, String servletName)
+ implements HttpServletMapping {
@Override
public String getMatchValue() {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/core/ApplicationRequest.java tomcat11-11.0.15/java/org/apache/catalina/core/ApplicationRequest.java
--- tomcat11-11.0.6/java/org/apache/catalina/core/ApplicationRequest.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/core/ApplicationRequest.java 2025-12-02 16:54:08.000000000 +0000
@@ -36,8 +36,6 @@
* WARNING: Due to Java's lack of support for multiple inheritance, all of the logic in
* ApplicationRequest is duplicated in ApplicationHttpRequest. Make sure that you keep these
* two classes in synchronization when making changes!
- *
- * @author Craig R. McClanahan
*/
class ApplicationRequest extends ServletRequestWrapper {
@@ -49,8 +47,7 @@
RequestDispatcher.FORWARD_SERVLET_PATH, RequestDispatcher.FORWARD_PATH_INFO,
RequestDispatcher.FORWARD_QUERY_STRING, RequestDispatcher.FORWARD_MAPPING));
- private static final int shortestSpecialNameLength =
- specialsSet.stream().mapToInt(String::length).min().getAsInt();
+ private static final int shortestSpecialNameLength = specialsSet.stream().mapToInt(String::length).min().getAsInt();
/**
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/core/ApplicationResponse.java tomcat11-11.0.15/java/org/apache/catalina/core/ApplicationResponse.java
--- tomcat11-11.0.6/java/org/apache/catalina/core/ApplicationResponse.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/core/ApplicationResponse.java 2025-12-02 16:54:08.000000000 +0000
@@ -31,8 +31,6 @@
* WARNING: Due to Java's lack of support for multiple inheritance, all of the logic in
* ApplicationResponse is duplicated in ApplicationHttpResponse. Make sure that you keep these
* two classes in synchronization when making changes!
- *
- * @author Craig R. McClanahan
*/
class ApplicationResponse extends ServletResponseWrapper {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/core/ApplicationSessionCookieConfig.java tomcat11-11.0.15/java/org/apache/catalina/core/ApplicationSessionCookieConfig.java
--- tomcat11-11.0.6/java/org/apache/catalina/core/ApplicationSessionCookieConfig.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/core/ApplicationSessionCookieConfig.java 2025-12-02 16:54:08.000000000 +0000
@@ -221,7 +221,9 @@
cookie.setHttpOnly(true);
}
- cookie.setAttribute(Constants.COOKIE_PARTITIONED_ATTR, Boolean.toString(context.getUsePartitioned()));
+ if (context.getUsePartitioned()) {
+ cookie.setAttribute(Constants.COOKIE_PARTITIONED_ATTR, "");
+ }
cookie.setPath(SessionConfig.getSessionCookiePath(context));
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/core/AprLifecycleListener.java tomcat11-11.0.15/java/org/apache/catalina/core/AprLifecycleListener.java
--- tomcat11-11.0.6/java/org/apache/catalina/core/AprLifecycleListener.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/core/AprLifecycleListener.java 2025-12-02 16:54:08.000000000 +0000
@@ -19,6 +19,7 @@
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
+import java.util.concurrent.locks.Lock;
import org.apache.catalina.Lifecycle;
import org.apache.catalina.LifecycleEvent;
@@ -99,25 +100,27 @@
private static final int FIPS_OFF = 0;
- protected static final Object lock = new Object();
-
- // Guarded by lock
+ // Guarded APRStatus.getStatusLock()
private static int referenceCount = 0;
private boolean instanceInitialized = false;
public static boolean isAprAvailable() {
// https://bz.apache.org/bugzilla/show_bug.cgi?id=48613
- if (AprStatus.isInstanceCreated()) {
- synchronized (lock) {
+ if (org.apache.tomcat.jni.AprStatus.isInstanceCreated()) {
+ Lock writeLock = org.apache.tomcat.jni.AprStatus.getStatusLock().writeLock();
+ writeLock.lock();
+ try {
init();
+ } finally {
+ writeLock.unlock();
}
}
- return AprStatus.isAprAvailable();
+ return org.apache.tomcat.jni.AprStatus.isAprAvailable();
}
public AprLifecycleListener() {
- AprStatus.setInstanceCreated(true);
+ org.apache.tomcat.jni.AprStatus.setInstanceCreated(true);
}
// ---------------------------------------------- LifecycleListener Methods
@@ -131,7 +134,9 @@
public void lifecycleEvent(LifecycleEvent event) {
if (Lifecycle.BEFORE_INIT_EVENT.equals(event.getType())) {
- synchronized (lock) {
+ Lock writeLock = org.apache.tomcat.jni.AprStatus.getStatusLock().writeLock();
+ writeLock.lock();
+ try {
instanceInitialized = true;
if (!(event.getLifecycle() instanceof Server)) {
log.warn(sm.getString("listener.notServer", event.getLifecycle().getClass().getSimpleName()));
@@ -145,7 +150,7 @@
log.info(msg);
}
initInfoLogMessages.clear();
- if (AprStatus.isAprAvailable()) {
+ if (org.apache.tomcat.jni.AprStatus.isAprAvailable()) {
try {
initializeSSL();
} catch (Throwable t) {
@@ -156,15 +161,18 @@
}
// Failure to initialize FIPS mode is fatal
if (!(null == FIPSMode || "off".equalsIgnoreCase(FIPSMode)) && !isFIPSModeActive()) {
- String errorMessage = sm.getString("aprListener.initializeFIPSFailed");
- Error e = new Error(errorMessage);
+ Error e = new Error(sm.getString("aprListener.initializeFIPSFailed"));
// Log here, because thrown error might be not logged
- log.fatal(errorMessage, e);
+ log.fatal(e.getMessage(), e);
throw e;
}
+ } finally {
+ writeLock.unlock();
}
} else if (Lifecycle.AFTER_DESTROY_EVENT.equals(event.getType())) {
- synchronized (lock) {
+ Lock writeLock = org.apache.tomcat.jni.AprStatus.getStatusLock().writeLock();
+ writeLock.lock();
+ try {
// Instance may get destroyed without ever being initialized
if (instanceInitialized) {
referenceCount--;
@@ -173,7 +181,7 @@
// Still being used
return;
}
- if (!AprStatus.isAprAvailable()) {
+ if (!org.apache.tomcat.jni.AprStatus.isAprAvailable()) {
return;
}
try {
@@ -181,16 +189,18 @@
} catch (Throwable t) {
Throwable throwable = ExceptionUtils.unwrapInvocationTargetException(t);
ExceptionUtils.handleThrowable(throwable);
- log.info(sm.getString("aprListener.aprDestroy"));
+ log.warn(sm.getString("aprListener.aprDestroy"), throwable);
}
+ } finally {
+ writeLock.unlock();
}
}
}
private static void terminateAPR() {
- AprStatus.setAprInitialized(false);
- AprStatus.setAprAvailable(false);
+ org.apache.tomcat.jni.AprStatus.setAprInitialized(false);
+ org.apache.tomcat.jni.AprStatus.setAprAvailable(false);
fipsModeActive = false;
sslInitialized = false; // terminate() will clean the pool
// There could be unreferenced SSL_CTX still waiting for GC
@@ -202,10 +212,10 @@
int rqver = TCN_REQUIRED_MAJOR * 1000 + TCN_REQUIRED_MINOR * 100 + TCN_REQUIRED_PATCH;
int rcver = TCN_RECOMMENDED_MAJOR * 1000 + TCN_RECOMMENDED_MINOR * 100 + TCN_RECOMMENDED_PV;
- if (AprStatus.isAprInitialized()) {
+ if (org.apache.tomcat.jni.AprStatus.isAprInitialized()) {
return;
}
- AprStatus.setAprInitialized(true);
+ org.apache.tomcat.jni.AprStatus.setAprInitialized(true);
try {
Library.initialize(null);
@@ -260,7 +270,7 @@
initInfoLogMessages
.add(sm.getString("aprListener.tcnValid", Library.versionString(), Library.aprVersionString()));
- AprStatus.setAprAvailable(true);
+ org.apache.tomcat.jni.AprStatus.setAprAvailable(true);
}
private static void initializeSSL() throws Exception {
@@ -290,7 +300,7 @@
method = clazz.getMethod(methodName, paramTypes);
method.invoke(null, paramValues);
- AprStatus.setOpenSSLVersion(SSL.version());
+ org.apache.tomcat.jni.AprStatus.setOpenSSLVersion(SSL.version());
// OpenSSL 3 onwards uses providers
boolean usingProviders = tcnMajor > 1 || (tcnVersion > 1233 && (SSL.version() & 0xF0000000L) > 0x20000000);
@@ -430,17 +440,17 @@
}
public void setUseOpenSSL(boolean useOpenSSL) {
- if (useOpenSSL != AprStatus.getUseOpenSSL()) {
- AprStatus.setUseOpenSSL(useOpenSSL);
+ if (useOpenSSL != org.apache.tomcat.jni.AprStatus.getUseOpenSSL()) {
+ org.apache.tomcat.jni.AprStatus.setUseOpenSSL(useOpenSSL);
}
}
public static boolean getUseOpenSSL() {
- return AprStatus.getUseOpenSSL();
+ return org.apache.tomcat.jni.AprStatus.getUseOpenSSL();
}
public static boolean isInstanceCreated() {
- return AprStatus.isInstanceCreated();
+ return org.apache.tomcat.jni.AprStatus.isInstanceCreated();
}
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/core/AprStatus.java tomcat11-11.0.15/java/org/apache/catalina/core/AprStatus.java
--- tomcat11-11.0.6/java/org/apache/catalina/core/AprStatus.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/core/AprStatus.java 2025-12-02 16:54:08.000000000 +0000
@@ -18,58 +18,56 @@
/**
* Holds APR status without the need to load other classes.
+ *
+ * @deprecated Unused. Use {@link org.apache.tomcat.jni.AprStatus} instead. This class will be removed in Tomcat 12
+ * onwards.
*/
+@Deprecated
public class AprStatus {
- private static volatile boolean aprInitialized = false;
- private static volatile boolean aprAvailable = false;
- private static volatile boolean useOpenSSL = true;
- private static volatile boolean instanceCreated = false;
- private static volatile int openSSLVersion = 0;
public static boolean isAprInitialized() {
- return aprInitialized;
+ return org.apache.tomcat.jni.AprStatus.isAprInitialized();
}
public static boolean isAprAvailable() {
- return aprAvailable;
+ return org.apache.tomcat.jni.AprStatus.isAprAvailable();
}
public static boolean getUseOpenSSL() {
- return useOpenSSL;
+ return org.apache.tomcat.jni.AprStatus.getUseOpenSSL();
}
public static boolean isInstanceCreated() {
- return instanceCreated;
+ return org.apache.tomcat.jni.AprStatus.isInstanceCreated();
}
public static void setAprInitialized(boolean aprInitialized) {
- AprStatus.aprInitialized = aprInitialized;
+ org.apache.tomcat.jni.AprStatus.setAprInitialized(aprInitialized);
}
public static void setAprAvailable(boolean aprAvailable) {
- AprStatus.aprAvailable = aprAvailable;
+ org.apache.tomcat.jni.AprStatus.setAprAvailable(aprAvailable);
}
public static void setUseOpenSSL(boolean useOpenSSL) {
- AprStatus.useOpenSSL = useOpenSSL;
+ org.apache.tomcat.jni.AprStatus.setUseOpenSSL(useOpenSSL);
}
public static void setInstanceCreated(boolean instanceCreated) {
- AprStatus.instanceCreated = instanceCreated;
+ org.apache.tomcat.jni.AprStatus.setInstanceCreated(instanceCreated);
}
/**
* @return the openSSLVersion
*/
public static int getOpenSSLVersion() {
- return openSSLVersion;
+ return org.apache.tomcat.jni.AprStatus.getOpenSSLVersion();
}
/**
* @param openSSLVersion the openSSLVersion to set
*/
public static void setOpenSSLVersion(int openSSLVersion) {
- AprStatus.openSSLVersion = openSSLVersion;
+ org.apache.tomcat.jni.AprStatus.setOpenSSLVersion(openSSLVersion);
}
-
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/core/AsyncContextImpl.java tomcat11-11.0.15/java/org/apache/catalina/core/AsyncContextImpl.java
--- tomcat11-11.0.6/java/org/apache/catalina/core/AsyncContextImpl.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/core/AsyncContextImpl.java 2025-12-02 16:54:08.000000000 +0000
@@ -575,9 +575,8 @@
}
- private record AsyncRunnable(Request request, AsyncDispatcher applicationDispatcher,
- ServletRequest servletRequest,
- ServletResponse servletResponse) implements Runnable {
+ private record AsyncRunnable(Request request, AsyncDispatcher applicationDispatcher, ServletRequest servletRequest,
+ ServletResponse servletResponse) implements Runnable {
@Override
public void run() {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/core/ContainerBase.java tomcat11-11.0.15/java/org/apache/catalina/core/ContainerBase.java
--- tomcat11-11.0.6/java/org/apache/catalina/core/ContainerBase.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/core/ContainerBase.java 2025-12-02 16:54:08.000000000 +0000
@@ -115,8 +115,6 @@
*
*
* Subclasses that fire additional events should document them in the class comments of the implementation class.
- *
- * @author Craig R. McClanahan
*/
public abstract class ContainerBase extends LifecycleMBeanBase implements Container {
@@ -721,12 +719,12 @@
for (Future result : results) {
try {
result.get();
- } catch (Throwable e) {
- log.error(sm.getString("containerBase.threadedStartFailed"), e);
+ } catch (Throwable t) {
+ log.error(sm.getString("containerBase.threadedStartFailed"), t);
if (multiThrowable == null) {
multiThrowable = new MultiThrowable();
}
- multiThrowable.add(e);
+ multiThrowable.add(t);
}
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/core/DefaultInstanceManager.java tomcat11-11.0.15/java/org/apache/catalina/core/DefaultInstanceManager.java
--- tomcat11-11.0.6/java/org/apache/catalina/core/DefaultInstanceManager.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/core/DefaultInstanceManager.java 2025-12-02 16:54:08.000000000 +0000
@@ -185,8 +185,7 @@
}
/**
- * Call postConstruct method on the specified instance recursively from the deepest superclass
- * to actual class.
+ * Call postConstruct method on the specified instance recursively from the deepest superclass to actual class.
*
* @param instance object to call postconstruct methods on
* @param clazz (super) class to examine for postConstruct annotation.
@@ -223,8 +222,7 @@
/**
- * Call preDestroy method on the specified instance recursively from the deepest superclass
- * to actual class.
+ * Call preDestroy method on the specified instance recursively from the deepest superclass to actual class.
*
* @param instance object to call preDestroy methods on
* @param clazz (super) class to examine for preDestroy annotation.
@@ -323,18 +321,15 @@
} else if (WS_PRESENT &&
(webServiceRefAnnotation = method.getAnnotation(WebServiceRef.class)) != null) {
annotations.add(new AnnotationCacheEntry(method.getName(), method.getParameterTypes(),
- webServiceRefAnnotation.name(),
- AnnotationCacheEntryType.SETTER));
+ webServiceRefAnnotation.name(), AnnotationCacheEntryType.SETTER));
} else if (JPA_PRESENT && (persistenceContextAnnotation =
method.getAnnotation(PersistenceContext.class)) != null) {
annotations.add(new AnnotationCacheEntry(method.getName(), method.getParameterTypes(),
- persistenceContextAnnotation.name(),
- AnnotationCacheEntryType.SETTER));
+ persistenceContextAnnotation.name(), AnnotationCacheEntryType.SETTER));
} else if (JPA_PRESENT &&
(persistenceUnitAnnotation = method.getAnnotation(PersistenceUnit.class)) != null) {
annotations.add(new AnnotationCacheEntry(method.getName(), method.getParameterTypes(),
- persistenceUnitAnnotation.name(),
- AnnotationCacheEntryType.SETTER));
+ persistenceUnitAnnotation.name(), AnnotationCacheEntryType.SETTER));
}
}
}
@@ -384,18 +379,15 @@
} else if (WS_PRESENT &&
(webServiceRefAnnotation = field.getAnnotation(WebServiceRef.class)) != null) {
annotations.add(new AnnotationCacheEntry(fieldName, null,
- webServiceRefAnnotation.name(),
- AnnotationCacheEntryType.FIELD));
+ webServiceRefAnnotation.name(), AnnotationCacheEntryType.FIELD));
} else if (JPA_PRESENT && (persistenceContextAnnotation =
field.getAnnotation(PersistenceContext.class)) != null) {
annotations.add(new AnnotationCacheEntry(fieldName, null,
- persistenceContextAnnotation.name(),
- AnnotationCacheEntryType.FIELD));
+ persistenceContextAnnotation.name(), AnnotationCacheEntryType.FIELD));
} else if (JPA_PRESENT &&
(persistenceUnitAnnotation = field.getAnnotation(PersistenceUnit.class)) != null) {
annotations.add(new AnnotationCacheEntry(fieldName, null,
- persistenceUnitAnnotation.name(),
- AnnotationCacheEntryType.FIELD));
+ persistenceUnitAnnotation.name(), AnnotationCacheEntryType.FIELD));
}
}
}
@@ -650,8 +642,8 @@
return result;
}
- private record AnnotationCacheEntry(String accessibleObjectName, Class>[] paramTypes,
- String name, AnnotationCacheEntryType type) {
+ private record AnnotationCacheEntry(String accessibleObjectName, Class>[] paramTypes, String name,
+ AnnotationCacheEntryType type) {
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/core/JreMemoryLeakPreventionListener.java tomcat11-11.0.15/java/org/apache/catalina/core/JreMemoryLeakPreventionListener.java
--- tomcat11-11.0.6/java/org/apache/catalina/core/JreMemoryLeakPreventionListener.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/core/JreMemoryLeakPreventionListener.java 2025-12-02 16:54:08.000000000 +0000
@@ -78,9 +78,9 @@
}
/**
- * The first access to {@link DriverManager} will trigger the loading of all {@link java.sql.Driver}s in the
- * current class loader. The web application level memory leak protection can take care of this in most cases but
- * triggering the loading here has fewer side effects.
+ * The first access to {@link DriverManager} will trigger the loading of all {@link java.sql.Driver}s in the current
+ * class loader. The web application level memory leak protection can take care of this in most cases but triggering
+ * the loading here has fewer side effects.
*/
private boolean driverManagerProtection = true;
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/core/LocalStrings.properties tomcat11-11.0.15/java/org/apache/catalina/core/LocalStrings.properties
--- tomcat11-11.0.6/java/org/apache/catalina/core/LocalStrings.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/core/LocalStrings.properties 2025-12-02 16:54:08.000000000 +0000
@@ -269,7 +269,9 @@
standardHost.notContext=Child of a Host must be a Context
standardHost.nullName=Host name is required
standardHost.problematicAppBase=Using an empty string for appBase on host [{0}] will set it to CATALINA_BASE, which is a bad idea
+standardHost.problematicAppBaseParent=appBase on host [{0}] is a parent folder of CATALINA_BASE, which is a bad idea
standardHost.problematicLegacyAppBase=Using an empty string for legacyAppBase on host [{0}] will set it to CATALINA_BASE, which is a bad idea
+standardHost.problematicLegacyAppBaseParent=legacyAppBase on host [{0}] is a parent folder of CATALINA_BASE, which is a bad idea
standardHostValve.customStatusFailed=Custom error page [{0}] could not be dispatched correctly
standardHostValve.exception=Exception Processing [{0}]
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/core/LocalStrings_ru.properties tomcat11-11.0.15/java/org/apache/catalina/core/LocalStrings_ru.properties
--- tomcat11-11.0.6/java/org/apache/catalina/core/LocalStrings_ru.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/core/LocalStrings_ru.properties 2025-12-02 16:54:08.000000000 +0000
@@ -28,17 +28,22 @@
applicationHttpRequest.sessionEndAccessFail=Исключение вызвало прекращение доступа к сессии при очистке запроса
aprListener.initializingFIPS=Инициализируется режим FIPS...
+aprListener.tcnVersion=Была обнаружена более старая версия [{0}] библиотеки Apache Tomcat Native, в то время как Tomcat рекомендует использовать как минимум версию [{1}]
filterChain.filter=При выполнении фильтра выброшено исключение
+naming.addEnvEntry=Добавляется переменная окружения [{0}]
naming.unbindFailed=Ошибка при отвязывании объекта: [{0}]
naming.wsdlFailed=wsdl файл не найден: [{0}]
standardContext.filterStart=Ошибка при старте фильтра [{0}]
standardContext.invalidWrapperClass=[{0}] не является подклассом StandardWrapper
+standardContext.managerFail=Невозможно запустить менеджер сессий
+standardContext.notStarted=Контекст с именем [{0}] ещё небыл запущен
standardContext.parameter.duplicate=Дублированный параметр инициализации контекста [{0}]
standardContext.predestroy.duplicate=Дублированное определение метода @PreDestroy для класса [{0}]
standardContext.securityConstraint.mixHttpMethod=Запрещено смешивать и в одной и той же коллекции веб-ресурсов
+standardContext.securityConstraint.pattern=Некорректный [{0}] в ограничении безопасности
standardContext.startingContext=Ошибка запуска контекста с именем [{0}]
standardWrapper.allocate=Ошибка при выделении экземпляра сервлета
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/core/NamingContextListener.java tomcat11-11.0.15/java/org/apache/catalina/core/NamingContextListener.java
--- tomcat11-11.0.6/java/org/apache/catalina/core/NamingContextListener.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/core/NamingContextListener.java 2025-12-02 16:54:08.000000000 +0000
@@ -76,8 +76,6 @@
/**
* Helper class used to initialize and populate the JNDI context associated with each context and server.
- *
- * @author Remy Maucherat
*/
public class NamingContextListener implements LifecycleListener, PropertyChangeListener {
@@ -235,7 +233,7 @@
try {
createNamingContext();
} catch (NamingException e) {
- log.error(sm.getString("naming.namingContextCreationFailed", e));
+ log.error(sm.getString("naming.namingContextCreationFailed", container), e);
}
namingResources.addPropertyChangeListener(this);
@@ -248,7 +246,7 @@
ContextBindings.bindClassLoader(container, token,
((Context) container).getLoader().getClassLoader());
} catch (NamingException e) {
- log.error(sm.getString("naming.bindFailed", e));
+ log.error(sm.getString("naming.bindFailed", container), e);
}
}
@@ -257,7 +255,7 @@
try {
ContextBindings.bindClassLoader(container, token, this.getClass().getClassLoader());
} catch (NamingException e) {
- log.error(sm.getString("naming.bindFailed", e));
+ log.error(sm.getString("naming.bindFailed", container), e);
}
if (container instanceof StandardServer) {
((StandardServer) container).setGlobalNamingContext(namingContext);
@@ -491,6 +489,13 @@
} else {
compCtx = namingContext.createSubcontext("comp");
envCtx = compCtx.createSubcontext("env");
+ /*
+ * Jakarta Platform Specification, 5.2.2: Application Component Environment Namespaces
+ *
+ * "java:module" and "java:comp" refer to the same namespace in a web module (i.e. a web application).
+ * Implement this by binding the "comp" sub-context we just created to the "module" name as well.
+ */
+ namingContext.bind("module", compCtx);
}
int i;
@@ -565,7 +570,7 @@
// Ignore because UserTransaction was obviously
// added via ResourceLink
} catch (NamingException e) {
- log.error(sm.getString("naming.bindFailed", e));
+ log.error(sm.getString("naming.bindFailed", "UserTransaction"), e);
}
}
@@ -574,7 +579,7 @@
try {
compCtx.bind("Resources", ((Context) container).getResources());
} catch (NamingException e) {
- log.error(sm.getString("naming.bindFailed", e));
+ log.error(sm.getString("naming.bindFailed", "Resources"), e);
}
}
@@ -648,7 +653,7 @@
createSubcontexts(envCtx, ejb.getName());
envCtx.bind(ejb.getName(), ref);
} catch (NamingException e) {
- log.error(sm.getString("naming.bindFailed", e));
+ log.error(sm.getString("naming.bindFailed", ejb.getName()), e);
}
}
@@ -748,7 +753,7 @@
createSubcontexts(envCtx, env.getName());
envCtx.bind(env.getName(), value);
} catch (NamingException e) {
- log.error(sm.getString("naming.invalidEnvEntryValue", e));
+ log.error(sm.getString("naming.invalidEnvEntryValue", env.getName()), e);
}
}
}
@@ -839,7 +844,7 @@
log.debug(sm.getString("naming.addSlash", service.getWsdlfile()));
}
} catch (MalformedURLException e) {
- log.error(sm.getString("naming.wsdlFailed", e));
+ log.error(sm.getString("naming.wsdlFailed", service.getWsdlfile()), e);
}
}
if (wsdlURL == null) {
@@ -874,7 +879,7 @@
log.debug(sm.getString("naming.addSlash", service.getJaxrpcmappingfile()));
}
} catch (MalformedURLException e) {
- log.error(sm.getString("naming.wsdlFailed", e));
+ log.error(sm.getString("naming.wsdlFailed", service.getJaxrpcmappingfile()), e);
}
}
if (jaxrpcURL == null) {
@@ -935,7 +940,7 @@
createSubcontexts(envCtx, service.getName());
envCtx.bind(service.getName(), ref);
} catch (NamingException e) {
- log.error(sm.getString("naming.bindFailed", e));
+ log.error(sm.getString("naming.bindFailed", service.getName()), e);
}
}
@@ -970,7 +975,7 @@
createSubcontexts(envCtx, resource.getName());
envCtx.bind(resource.getName(), ref);
} catch (NamingException e) {
- log.error(sm.getString("naming.bindFailed", e));
+ log.error(sm.getString("naming.bindFailed", resource.getName()), e);
}
if (("javax.sql.DataSource".equals(ref.getClassName()) ||
@@ -982,7 +987,7 @@
Registry.getRegistry(null).registerComponent(actualResource, on, null);
objectNames.put(resource.getName(), on);
} catch (Exception e) {
- log.warn(sm.getString("naming.jmxRegistrationFailed", e));
+ log.warn(sm.getString("naming.jmxRegistrationFailed", resource.getName()), e);
}
// Bug 63210. DBCP2 DataSources require an explicit close. This goes
// further and cleans up and AutoCloseable DataSource by default.
@@ -1022,7 +1027,7 @@
createSubcontexts(envCtx, resourceEnvRef.getName());
envCtx.bind(resourceEnvRef.getName(), ref);
} catch (NamingException e) {
- log.error(sm.getString("naming.bindFailed", e));
+ log.error(sm.getString("naming.bindFailed", resourceEnvRef.getName()), e);
}
}
@@ -1054,7 +1059,7 @@
createSubcontexts(envCtx, resourceLink.getName());
ctx.bind(resourceLink.getName(), ref);
} catch (NamingException e) {
- log.error(sm.getString("naming.bindFailed", e));
+ log.error(sm.getString("naming.bindFailed", resourceLink.getName()), e);
}
ResourceLinkFactory.registerGlobalResourceAccess(getGlobalNamingContext(), resourceLink.getName(),
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/core/OpenSSLLifecycleListener.java tomcat11-11.0.15/java/org/apache/catalina/core/OpenSSLLifecycleListener.java
--- tomcat11-11.0.6/java/org/apache/catalina/core/OpenSSLLifecycleListener.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/core/OpenSSLLifecycleListener.java 2025-12-02 16:54:08.000000000 +0000
@@ -125,7 +125,7 @@
} catch (Throwable t) {
Throwable throwable = ExceptionUtils.unwrapInvocationTargetException(t);
ExceptionUtils.handleThrowable(throwable);
- log.info(sm.getString("openssllistener.destroy"));
+ log.warn(sm.getString("openssllistener.destroy"), throwable);
}
}
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/core/PropertiesRoleMappingListener.java tomcat11-11.0.15/java/org/apache/catalina/core/PropertiesRoleMappingListener.java
--- tomcat11-11.0.6/java/org/apache/catalina/core/PropertiesRoleMappingListener.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/core/PropertiesRoleMappingListener.java 2025-12-02 16:54:08.000000000 +0000
@@ -110,9 +110,9 @@
Properties props = new Properties();
try (Resource resource = context.findConfigFileResource(roleMappingFile)) {
props.load(resource.getInputStream());
- } catch (IOException e) {
+ } catch (IOException ioe) {
throw new IllegalStateException(
- sm.getString("propertiesRoleMappingListener.roleMappingFileFail", roleMappingFile), e);
+ sm.getString("propertiesRoleMappingListener.roleMappingFileFail", roleMappingFile), ioe);
}
int linkCount = 0;
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/core/StandardContext.java tomcat11-11.0.15/java/org/apache/catalina/core/StandardContext.java
--- tomcat11-11.0.6/java/org/apache/catalina/core/StandardContext.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/core/StandardContext.java 2025-12-02 16:54:08.000000000 +0000
@@ -40,6 +40,7 @@
import java.util.Set;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.Lock;
@@ -137,9 +138,6 @@
/**
* Standard implementation of the Context interface. Each child container must be a Wrapper implementation to
* process the requests directed to a particular servlet.
- *
- * @author Craig R. McClanahan
- * @author Remy Maucherat
*/
public class StandardContext extends ContainerBase implements Context, NotificationEmitter {
@@ -425,7 +423,7 @@
/**
* The MIME mappings for this web application, keyed by extension.
*/
- private final Map mimeMappings = new HashMap<>();
+ private final ConcurrentMap mimeMappings = new ConcurrentHashMap<>();
/**
@@ -2445,8 +2443,8 @@
if (!workDir.isAbsolute()) {
try {
workDir = new File(getCatalinaBase().getCanonicalFile(), getWorkDir());
- } catch (IOException e) {
- log.warn(sm.getString("standardContext.workPath", getName()), e);
+ } catch (IOException ioe) {
+ log.warn(sm.getString("standardContext.workPath", getName()), ioe);
}
}
return workDir.getAbsolutePath();
@@ -2805,12 +2803,8 @@
@Override
public void addMimeMapping(String extension, String mimeType) {
-
- synchronized (mimeMappings) {
- mimeMappings.put(extension.toLowerCase(Locale.ENGLISH), mimeType);
- }
+ mimeMappings.put(extension.toLowerCase(Locale.ENGLISH), mimeType);
fireContainerEvent("addMimeMapping", extension);
-
}
@@ -3084,9 +3078,7 @@
@Override
public String[] findMimeMappings() {
- synchronized (mimeMappings) {
- return mimeMappings.keySet().toArray(new String[0]);
- }
+ return mimeMappings.keySet().toArray(new String[0]);
}
@@ -3381,12 +3373,8 @@
@Override
public void removeMimeMapping(String extension) {
-
- synchronized (mimeMappings) {
- mimeMappings.remove(extension);
- }
+ mimeMappings.remove(extension);
fireContainerEvent("removeMimeMapping", extension);
-
}
@@ -4076,7 +4064,7 @@
Throwable throwable = ExceptionUtils.unwrapInvocationTargetException(t);
ExceptionUtils.handleThrowable(throwable);
getLogger().error(sm.getString("standardContext.listenerStop", listeners[j].getClass().getName()),
- throwable);
+ throwable);
ok = false;
}
}
@@ -4098,7 +4086,7 @@
Throwable throwable = ExceptionUtils.unwrapInvocationTargetException(t);
ExceptionUtils.handleThrowable(throwable);
getLogger().error(sm.getString("standardContext.listenerStop", listeners[j].getClass().getName()),
- throwable);
+ throwable);
ok = false;
}
}
@@ -4369,8 +4357,8 @@
if ((getCluster() != null) && distributable) {
try {
contextManager = getCluster().createManager(getName());
- } catch (Exception ex) {
- log.error(sm.getString("standardContext.cluster.managerError"), ex);
+ } catch (Exception e) {
+ log.error(sm.getString("standardContext.cluster.managerError"), e);
ok = false;
}
} else {
@@ -4727,8 +4715,8 @@
// This object will no longer be visible or used.
try {
resetContext();
- } catch (Exception ex) {
- log.error(sm.getString("standardContext.resetContextFail", getName()), ex);
+ } catch (Exception e) {
+ log.error(sm.getString("standardContext.resetContextFail", getName()), e);
}
// reset the instance manager
@@ -4976,9 +4964,8 @@
if (isUseNaming()) {
try {
ContextBindings.bindThread(this, getNamingToken());
- } catch (NamingException e) {
- // Silent catch, as this is a normal case during the early
- // startup stages
+ } catch (NamingException ignore) {
+ // Silent catch, as this is a normal case during the early startup stages
}
}
@@ -5307,8 +5294,9 @@
try {
catalinaHomePath = getCatalinaBase().getCanonicalPath();
dir = new File(catalinaHomePath, workDir);
- } catch (IOException e) {
- log.warn(sm.getString("standardContext.workCreateException", workDir, getCatalinaBase(), getName()), e);
+ } catch (IOException ioe) {
+ log.warn(sm.getString("standardContext.workCreateException", workDir, getCatalinaBase(), getName()),
+ ioe);
}
}
if (!dir.mkdirs() && !dir.isDirectory()) {
@@ -5393,11 +5381,8 @@
@Override
protected String getObjectNameKeyProperties() {
- return "j2eeType=WebModule," + getObjectKeyPropertiesNameOnly() +
- ",J2EEApplication=" +
- getJ2EEApplication() +
- ",J2EEServer=" +
- getJ2EEServer();
+ return "j2eeType=WebModule," + getObjectKeyPropertiesNameOnly() + ",J2EEApplication=" + getJ2EEApplication() +
+ ",J2EEServer=" + getJ2EEServer();
}
private String getObjectKeyPropertiesNameOnly() {
@@ -5713,7 +5698,7 @@
}
@Override
- public Map getServletRegistrations() {
+ public Map getServletRegistrations() {
throw new UnsupportedOperationException(sm.getString("noPluggabilityServletContext.notAllowed"));
}
@@ -5743,7 +5728,7 @@
}
@Override
- public Map getFilterRegistrations() {
+ public Map getFilterRegistrations() {
throw new UnsupportedOperationException(sm.getString("noPluggabilityServletContext.notAllowed"));
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/core/StandardContextValve.java tomcat11-11.0.15/java/org/apache/catalina/core/StandardContextValve.java
--- tomcat11-11.0.6/java/org/apache/catalina/core/StandardContextValve.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/core/StandardContextValve.java 2025-12-02 16:54:08.000000000 +0000
@@ -32,8 +32,6 @@
* Valve that implements the default basic behavior for the StandardContext container implementation.
*
* USAGE CONSTRAINT: This implementation is likely to be useful only when processing HTTP requests.
- *
- * @author Craig R. McClanahan
*/
final class StandardContextValve extends ValveBase {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/core/StandardEngine.java tomcat11-11.0.15/java/org/apache/catalina/core/StandardEngine.java
--- tomcat11-11.0.6/java/org/apache/catalina/core/StandardEngine.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/core/StandardEngine.java 2025-12-02 16:54:08.000000000 +0000
@@ -45,8 +45,6 @@
/**
* Standard implementation of the Engine interface. Each child container must be a Host implementation to process
* the specific fully qualified host name of that virtual host.
- *
- * @author Craig R. McClanahan
*/
public class StandardEngine extends ContainerBase implements Engine {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/core/StandardEngineValve.java tomcat11-11.0.15/java/org/apache/catalina/core/StandardEngineValve.java
--- tomcat11-11.0.6/java/org/apache/catalina/core/StandardEngineValve.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/core/StandardEngineValve.java 2025-12-02 16:54:08.000000000 +0000
@@ -29,8 +29,6 @@
* Valve that implements the default basic behavior for the StandardEngine container implementation.
*
* USAGE CONSTRAINT: This implementation is likely to be useful only when processing HTTP requests.
- *
- * @author Craig R. McClanahan
*/
final class StandardEngineValve extends ValveBase {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/core/StandardHost.java tomcat11-11.0.15/java/org/apache/catalina/core/StandardHost.java
--- tomcat11-11.0.6/java/org/apache/catalina/core/StandardHost.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/core/StandardHost.java 2025-12-02 16:54:08.000000000 +0000
@@ -18,6 +18,7 @@
import java.io.File;
import java.io.IOException;
+import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -48,9 +49,6 @@
/**
* Standard implementation of the Host interface. Each child container must be a Context implementation to
* process the requests directed to a particular web application.
- *
- * @author Craig R. McClanahan
- * @author Remy Maucherat
*/
public class StandardHost extends ContainerBase implements Host {
@@ -231,6 +229,12 @@
// Ignore
}
+ Path appBasePath = file.toPath();
+ Path basePath = getCatalinaBase().toPath();
+ if (basePath.startsWith(appBasePath)) {
+ log.warn(sm.getString("standardHost.problematicAppBaseParent", getName()));
+ }
+
this.appBaseFile = file;
return file;
}
@@ -274,6 +278,12 @@
// Ignore
}
+ Path appBasePath = file.toPath();
+ Path basePath = getCatalinaBase().toPath();
+ if (basePath.startsWith(appBasePath)) {
+ log.warn(sm.getString("standardHost.problematicLegacyAppBaseParent", getName()));
+ }
+
this.legacyAppBaseFile = file;
return file;
}
@@ -330,7 +340,8 @@
}
try {
file = file.getCanonicalFile();
- } catch (IOException e) {// ignore
+ } catch (IOException ignore) {
+ // Ignore
}
this.hostConfigBase = file;
return file;
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/core/StandardHostValve.java tomcat11-11.0.15/java/org/apache/catalina/core/StandardHostValve.java
--- tomcat11-11.0.6/java/org/apache/catalina/core/StandardHostValve.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/core/StandardHostValve.java 2025-12-02 16:54:08.000000000 +0000
@@ -44,9 +44,6 @@
* Valve that implements the default basic behavior for the StandardHost container implementation.
*
* USAGE CONSTRAINT: This implementation is likely to be useful only when processing HTTP requests.
- *
- * @author Craig R. McClanahan
- * @author Remy Maucherat
*/
final class StandardHostValve extends ValveBase {
@@ -212,8 +209,8 @@
response.finishResponse();
} catch (ClientAbortException e) {
// Ignore
- } catch (IOException e) {
- container.getLogger().warn(sm.getString("standardHostValve.exception", errorPage), e);
+ } catch (IOException ioe) {
+ container.getLogger().warn(sm.getString("standardHostValve.exception", errorPage), ioe);
}
}
}
@@ -265,8 +262,8 @@
if (custom(request, response, errorPage)) {
try {
response.finishResponse();
- } catch (IOException e) {
- container.getLogger().warn(sm.getString("standardHostValve.exception", errorPage), e);
+ } catch (IOException ioe) {
+ container.getLogger().warn(sm.getString("standardHostValve.exception", errorPage), ioe);
}
}
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/core/StandardPipeline.java tomcat11-11.0.15/java/org/apache/catalina/core/StandardPipeline.java
--- tomcat11-11.0.6/java/org/apache/catalina/core/StandardPipeline.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/core/StandardPipeline.java 2025-12-02 16:54:08.000000000 +0000
@@ -43,8 +43,6 @@
* This implementation assumes that no calls to addValve() or removeValve are allowed while a
* request is currently being processed. Otherwise, the mechanism by which per-thread state is maintained will need to
* be modified.
- *
- * @author Craig R. McClanahan
*/
public class StandardPipeline extends LifecycleBase implements Pipeline {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/core/StandardServer.java tomcat11-11.0.15/java/org/apache/catalina/core/StandardServer.java
--- tomcat11-11.0.6/java/org/apache/catalina/core/StandardServer.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/core/StandardServer.java 2025-12-02 16:54:08.000000000 +0000
@@ -61,8 +61,6 @@
/**
* Standard implementation of the Server interface, available for use (but not required) when deploying and
* starting Catalina.
- *
- * @author Craig R. McClanahan
*/
public final class StandardServer extends LifecycleMBeanBase implements Server {
@@ -490,14 +488,14 @@
awaitSocket = null;
try {
s.close();
- } catch (IOException e) {
+ } catch (IOException ignore) {
// Ignored
}
}
t.interrupt();
try {
t.join(1000);
- } catch (InterruptedException e) {
+ } catch (InterruptedException ignore) {
// Ignored
}
}
@@ -530,9 +528,9 @@
// Set up a server socket to wait on
try {
awaitSocket = new ServerSocket(getPortWithOffset(), 1, InetAddress.getByName(address));
- } catch (IOException e) {
+ } catch (IOException ioe) {
log.error(sm.getString("standardServer.awaitSocket.fail", address, String.valueOf(getPortWithOffset()),
- String.valueOf(getPort()), String.valueOf(getPortOffset())), e);
+ String.valueOf(getPort()), String.valueOf(getPortOffset())), ioe);
return;
}
@@ -562,12 +560,12 @@
log.warn(sm.getString("standardServer.accept.timeout",
Long.valueOf(System.currentTimeMillis() - acceptStartTime)), ste);
continue;
- } catch (IOException e) {
+ } catch (IOException ioe) {
if (stopAwait) {
// Wait was aborted with socket.close()
break;
}
- log.error(sm.getString("standardServer.accept.error"), e);
+ log.error(sm.getString("standardServer.accept.error"), ioe);
break;
}
@@ -583,8 +581,8 @@
int ch;
try {
ch = stream.read();
- } catch (IOException e) {
- log.warn(sm.getString("standardServer.accept.readError"), e);
+ } catch (IOException ioe) {
+ log.warn(sm.getString("standardServer.accept.readError"), ioe);
ch = -1;
}
// Control character or EOF (-1) terminates loop
@@ -600,7 +598,7 @@
if (socket != null) {
socket.close();
}
- } catch (IOException e) {
+ } catch (IOException ignore) {
// Ignore
}
}
@@ -623,7 +621,7 @@
if (serverSocket != null) {
try {
serverSocket.close();
- } catch (IOException e) {
+ } catch (IOException ignore) {
// Ignore
}
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/core/StandardService.java tomcat11-11.0.15/java/org/apache/catalina/core/StandardService.java
--- tomcat11-11.0.6/java/org/apache/catalina/core/StandardService.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/core/StandardService.java 2025-12-02 16:54:08.000000000 +0000
@@ -46,8 +46,6 @@
/**
* Standard implementation of the Service interface. The associated Container is generally an instance of
* Engine, but this is not required.
- *
- * @author Craig R. McClanahan
*/
public class StandardService extends LifecycleMBeanBase implements Service {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/core/StandardWrapper.java tomcat11-11.0.15/java/org/apache/catalina/core/StandardWrapper.java
--- tomcat11-11.0.6/java/org/apache/catalina/core/StandardWrapper.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/core/StandardWrapper.java 2025-12-02 16:54:08.000000000 +0000
@@ -63,9 +63,6 @@
/**
* Standard implementation of the Wrapper interface that represents an individual servlet definition. No child
* Containers are allowed, and the parent Container must be a Context.
- *
- * @author Craig R. McClanahan
- * @author Remy Maucherat
*/
public class StandardWrapper extends ContainerBase implements ServletConfig, Wrapper, NotificationEmitter {
@@ -578,9 +575,9 @@
countAllocated.incrementAndGet();
} catch (ServletException e) {
throw e;
- } catch (Throwable e) {
- ExceptionUtils.handleThrowable(e);
- throw new ServletException(sm.getString("standardWrapper.allocate"), e);
+ } catch (Throwable t) {
+ ExceptionUtils.handleThrowable(t);
+ throw new ServletException(sm.getString("standardWrapper.allocate"), t);
}
}
if (!instanceInitialized) {
@@ -714,8 +711,8 @@
try {
jspMonitorON = new ObjectName(oname.toString());
Registry.getRegistry(null).registerComponent(instance, jspMonitorON, null);
- } catch (Exception ex) {
- log.warn(sm.getString("standardWrapper.jspMonitorError", instance));
+ } catch (Exception e) {
+ log.warn(sm.getString("standardWrapper.jspMonitorError", instance), e);
}
}
}
@@ -758,8 +755,8 @@
unavailable(null);
// Restore the context ClassLoader
throw new ServletException(sm.getString("standardWrapper.notServlet", servletClass), e);
- } catch (Throwable e) {
- Throwable throwable = ExceptionUtils.unwrapInvocationTargetException(e);
+ } catch (Throwable t) {
+ Throwable throwable = ExceptionUtils.unwrapInvocationTargetException(t);
ExceptionUtils.handleThrowable(throwable);
unavailable(null);
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/core/StandardWrapperFacade.java tomcat11-11.0.15/java/org/apache/catalina/core/StandardWrapperFacade.java
--- tomcat11-11.0.6/java/org/apache/catalina/core/StandardWrapperFacade.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/core/StandardWrapperFacade.java 2025-12-02 16:54:08.000000000 +0000
@@ -25,8 +25,6 @@
/**
* Facade for the StandardWrapper object.
- *
- * @author Remy Maucherat
*/
public final class StandardWrapperFacade implements ServletConfig {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/core/StandardWrapperValve.java tomcat11-11.0.15/java/org/apache/catalina/core/StandardWrapperValve.java
--- tomcat11-11.0.6/java/org/apache/catalina/core/StandardWrapperValve.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/core/StandardWrapperValve.java 2025-12-02 16:54:08.000000000 +0000
@@ -44,8 +44,6 @@
/**
* Valve that implements the default basic behavior for the StandardWrapper container implementation.
- *
- * @author Craig R. McClanahan
*/
final class StandardWrapperValve extends ValveBase {
@@ -122,11 +120,11 @@
StandardWrapper.getRootCause(e));
throwable = e;
exception(request, response, e);
- } catch (Throwable e) {
- ExceptionUtils.handleThrowable(e);
- container.getLogger().error(sm.getString("standardWrapper.allocateException", wrapper.getName()), e);
- throwable = e;
- exception(request, response, e);
+ } catch (Throwable t) {
+ ExceptionUtils.handleThrowable(t);
+ container.getLogger().error(sm.getString("standardWrapper.allocateException", wrapper.getName()), t);
+ throwable = t;
+ exception(request, response, t);
// servlet = null; is set here
}
@@ -183,11 +181,11 @@
}
throwable = e;
exception(request, response, e);
- } catch (IOException e) {
+ } catch (IOException ioe) {
container.getLogger()
- .error(sm.getString("standardWrapper.serviceException", wrapper.getName(), context.getName()), e);
- throwable = e;
- exception(request, response, e);
+ .error(sm.getString("standardWrapper.serviceException", wrapper.getName(), context.getName()), ioe);
+ throwable = ioe;
+ exception(request, response, ioe);
} catch (UnavailableException e) {
container.getLogger()
.error(sm.getString("standardWrapper.serviceException", wrapper.getName(), context.getName()), e);
@@ -210,12 +208,12 @@
}
throwable = e;
exception(request, response, e, e.getErrorCode());
- } catch (Throwable e) {
- ExceptionUtils.handleThrowable(e);
+ } catch (Throwable t) {
+ ExceptionUtils.handleThrowable(t);
container.getLogger()
- .error(sm.getString("standardWrapper.serviceException", wrapper.getName(), context.getName()), e);
- throwable = e;
- exception(request, response, e);
+ .error(sm.getString("standardWrapper.serviceException", wrapper.getName(), context.getName()), t);
+ throwable = t;
+ exception(request, response, t);
} finally {
// Release the filter chain (if any) for this request
if (filterChain != null) {
@@ -227,12 +225,12 @@
if (servlet != null) {
wrapper.deallocate(servlet);
}
- } catch (Throwable e) {
- ExceptionUtils.handleThrowable(e);
- container.getLogger().error(sm.getString("standardWrapper.deallocateException", wrapper.getName()), e);
+ } catch (Throwable t) {
+ ExceptionUtils.handleThrowable(t);
+ container.getLogger().error(sm.getString("standardWrapper.deallocateException", wrapper.getName()), t);
if (throwable == null) {
- throwable = e;
- exception(request, response, e);
+ throwable = t;
+ exception(request, response, t);
}
}
@@ -242,11 +240,11 @@
if ((servlet != null) && (wrapper.getAvailable() == Long.MAX_VALUE)) {
wrapper.unload();
}
- } catch (Throwable e) {
- ExceptionUtils.handleThrowable(e);
- container.getLogger().error(sm.getString("standardWrapper.unloadException", wrapper.getName()), e);
+ } catch (Throwable t) {
+ ExceptionUtils.handleThrowable(t);
+ container.getLogger().error(sm.getString("standardWrapper.unloadException", wrapper.getName()), t);
if (throwable == null) {
- exception(request, response, e);
+ exception(request, response, t);
}
}
long t2 = System.currentTimeMillis();
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/core/ThreadLocalLeakPreventionListener.java tomcat11-11.0.15/java/org/apache/catalina/core/ThreadLocalLeakPreventionListener.java
--- tomcat11-11.0.6/java/org/apache/catalina/core/ThreadLocalLeakPreventionListener.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/core/ThreadLocalLeakPreventionListener.java 2025-12-02 16:54:08.000000000 +0000
@@ -73,8 +73,7 @@
stopIdleThreads((Context) lifecycle);
}
} catch (Exception e) {
- String msg = sm.getString("threadLocalLeakPreventionListener.lifecycleEvent.error", event);
- log.error(msg, e);
+ log.error(sm.getString("threadLocalLeakPreventionListener.lifecycleEvent.error", event), e);
}
}
@@ -83,8 +82,7 @@
try {
super.containerEvent(event);
} catch (Exception e) {
- String msg = sm.getString("threadLocalLeakPreventionListener.containerEvent.error", event);
- log.error(msg, e);
+ log.error(sm.getString("threadLocalLeakPreventionListener.containerEvent.error", event), e);
}
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/deploy/NamingResourcesImpl.java tomcat11-11.0.15/java/org/apache/catalina/deploy/NamingResourcesImpl.java
--- tomcat11-11.0.6/java/org/apache/catalina/deploy/NamingResourcesImpl.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/deploy/NamingResourcesImpl.java 2025-12-02 16:54:08.000000000 +0000
@@ -62,8 +62,6 @@
/**
* Holds and manages the naming resources defined in the Jakarta EE Naming Context and their associated JNDI context.
- *
- * @author Remy Maucherat
*/
public class NamingResourcesImpl extends LifecycleMBeanBase implements Serializable, NamingResources {
@@ -515,8 +513,8 @@
/**
- * @return the array of defined environment entries for this web application. If none have been defined, a zero-length
- * array is returned.
+ * @return the array of defined environment entries for this web application. If none have been defined, a
+ * zero-length array is returned.
*/
public ContextEnvironment[] findEnvironments() {
@@ -651,8 +649,8 @@
/**
- * @return the array of resource environment reference names for this web application. If none have been specified, a
- * zero-length array is returned.
+ * @return the array of resource environment reference names for this web application. If none have been specified,
+ * a zero-length array is returned.
*/
public ContextResourceEnvRef[] findResourceEnvRefs() {
@@ -979,10 +977,10 @@
try {
m = resource.getClass().getMethod(closeMethod, (Class>[]) null);
} catch (SecurityException e) {
- log.debug(sm.getString("namingResources.cleanupCloseSecurity", closeMethod, name, container));
+ log.debug(sm.getString("namingResources.cleanupCloseSecurity", closeMethod, name, container), e);
return;
} catch (NoSuchMethodException e) {
- log.debug(sm.getString("namingResources.cleanupNoClose", name, container, closeMethod));
+ log.debug(sm.getString("namingResources.cleanupNoClose", name, container, closeMethod), e);
return;
}
try {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/filters/Constants.java tomcat11-11.0.15/java/org/apache/catalina/filters/Constants.java
--- tomcat11-11.0.6/java/org/apache/catalina/filters/Constants.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/filters/Constants.java 2025-12-02 16:54:08.000000000 +0000
@@ -16,11 +16,10 @@
*/
package org.apache.catalina.filters;
+import org.apache.tomcat.util.http.Method;
/**
* Manifest constants for this Java package.
- *
- * @author Craig R. McClanahan
*/
public final class Constants {
@@ -44,7 +43,8 @@
*/
public static final String CSRF_NONCE_REQUEST_PARAM_NAME_KEY = "org.apache.catalina.filters.CSRF_NONCE_PARAM_NAME";
- public static final String METHOD_GET = "GET";
+ @Deprecated
+ public static final String METHOD_GET = Method.GET;
public static final String CSRF_REST_NONCE_HEADER_NAME = "X-CSRF-Token";
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/filters/CorsFilter.java tomcat11-11.0.15/java/org/apache/catalina/filters/CorsFilter.java
--- tomcat11-11.0.6/java/org/apache/catalina/filters/CorsFilter.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/filters/CorsFilter.java 2025-12-02 16:54:08.000000000 +0000
@@ -37,6 +37,7 @@
import org.apache.catalina.Globals;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
+import org.apache.tomcat.util.http.Method;
import org.apache.tomcat.util.http.RequestUtil;
import org.apache.tomcat.util.http.ResponseUtil;
import org.apache.tomcat.util.http.parser.MediaType;
@@ -129,7 +130,8 @@
@Override
public void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse,
final FilterChain filterChain) throws IOException, ServletException {
- if (!(servletRequest instanceof HttpServletRequest request) || !(servletResponse instanceof HttpServletResponse response)) {
+ if (!(servletRequest instanceof HttpServletRequest request) ||
+ !(servletResponse instanceof HttpServletResponse response)) {
throw new ServletException(sm.getString("corsFilter.onlyHttp"));
}
@@ -403,7 +405,7 @@
response.addHeader(RESPONSE_HEADER_ACCESS_CONTROL_EXPOSE_HEADERS, exposedHeadersString);
}
- if ("OPTIONS".equals(method)) {
+ if (Method.OPTIONS.equals(method)) {
// For an OPTIONS request, the response will vary based on the
// value or absence of the following headers. Hence, they need to be
// included in the Vary header.
@@ -544,7 +546,7 @@
if (originHeader.isEmpty() || !RequestUtil.isValidOrigin(originHeader)) {
return CORSRequestType.INVALID_CORS;
}
- if(RequestUtil.isSameOrigin(request, originHeader)) {
+ if (RequestUtil.isSameOrigin(request, originHeader)) {
return CORSRequestType.NOT_CORS;
}
String method = request.getMethod();
@@ -552,8 +554,9 @@
return CORSRequestType.INVALID_CORS;
}
switch (method) {
- case "OPTIONS":
- String accessControlRequestMethodHeader = request.getHeader(REQUEST_HEADER_ACCESS_CONTROL_REQUEST_METHOD);
+ case Method.OPTIONS:
+ String accessControlRequestMethodHeader =
+ request.getHeader(REQUEST_HEADER_ACCESS_CONTROL_REQUEST_METHOD);
if (accessControlRequestMethodHeader != null) {
if (accessControlRequestMethodHeader.isEmpty()) {
return CORSRequestType.INVALID_CORS;
@@ -561,10 +564,10 @@
return CORSRequestType.PRE_FLIGHT;
}
return CORSRequestType.ACTUAL;
- case "GET":
- case "HEAD":
+ case Method.GET:
+ case Method.HEAD:
return CORSRequestType.SIMPLE;
- case "POST":
+ case Method.POST:
String mediaType = MediaType.parseMediaTypeOnly(request.getContentType());
if (mediaType == null || SIMPLE_HTTP_REQUEST_CONTENT_TYPE_VALUES.contains(mediaType)) {
return CORSRequestType.SIMPLE;
@@ -891,7 +894,7 @@
* @see http://www.w3.org/TR/cors/#terminology
*/
public static final Collection SIMPLE_HTTP_REQUEST_CONTENT_TYPE_VALUES =
- Set.of(Globals.CONTENT_TYPE_FORM_URL_ENCODING, "multipart/form-data", "text/plain");
+ Set.of(Globals.CONTENT_TYPE_FORM_URL_ENCODING, "multipart/form-data", "text/plain");
// ------------------------------------------------ Configuration Defaults
/**
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/filters/CsrfPreventionFilter.java tomcat11-11.0.15/java/org/apache/catalina/filters/CsrfPreventionFilter.java
--- tomcat11-11.0.6/java/org/apache/catalina/filters/CsrfPreventionFilter.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/filters/CsrfPreventionFilter.java 2025-12-02 16:54:08.000000000 +0000
@@ -42,6 +42,7 @@
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
+import org.apache.tomcat.util.http.Method;
/**
* Provides basic CSRF protection for a web application. The filter assumes that:
@@ -444,7 +445,7 @@
}
protected boolean skipNonceCheck(HttpServletRequest request) {
- if (!Constants.METHOD_GET.equals(request.getMethod())) {
+ if (!Method.GET.equals(request.getMethod())) {
return false;
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/filters/ExpiresFilter.java tomcat11-11.0.15/java/org/apache/catalina/filters/ExpiresFilter.java
--- tomcat11-11.0.6/java/org/apache/catalina/filters/ExpiresFilter.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/filters/ExpiresFilter.java 2025-12-02 16:54:08.000000000 +0000
@@ -44,6 +44,7 @@
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.apache.tomcat.util.buf.StringUtils;
+import org.apache.tomcat.util.http.Method;
/**
*
@@ -490,7 +491,7 @@
* ({@link StartingPoint#ACCESS_TIME}) or the last time the HTML-page/servlet-response was modified (
* {@link StartingPoint#LAST_MODIFICATION_TIME}).
*/
- public enum StartingPoint {
+ public enum StartingPoint {
ACCESS_TIME,
LAST_MODIFICATION_TIME
}
@@ -1367,7 +1368,7 @@
// Don't add cache headers unless the request is a GET or a HEAD request
String method = request.getMethod();
- if (!"GET".equals(method) && !"HEAD".equals(method)) {
+ if (!Method.GET.equals(method) && !Method.HEAD.equals(method)) {
if (log.isDebugEnabled()) {
log.debug(sm.getString("expiresFilter.invalidMethod", request.getRequestURI(), method));
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/filters/RemoteAddrFilter.java tomcat11-11.0.15/java/org/apache/catalina/filters/RemoteAddrFilter.java
--- tomcat11-11.0.6/java/org/apache/catalina/filters/RemoteAddrFilter.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/filters/RemoteAddrFilter.java 2025-12-02 16:54:08.000000000 +0000
@@ -30,8 +30,9 @@
* Concrete implementation of RequestFilter that filters based on the string representation of the remote
* client's IP address.
*
- * @author Craig R. McClanahan
+ * @deprecated This Filter will be removed in Tomcat 12 onwards. Use {@link RemoteCIDRFilter} instead.
*/
+@Deprecated
public final class RemoteAddrFilter extends RequestFilter {
// Log must be non-static as loggers are created per class-loader and this
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/filters/RemoteCIDRFilter.java tomcat11-11.0.15/java/org/apache/catalina/filters/RemoteCIDRFilter.java
--- tomcat11-11.0.6/java/org/apache/catalina/filters/RemoteCIDRFilter.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/filters/RemoteCIDRFilter.java 2025-12-02 16:54:08.000000000 +0000
@@ -20,8 +20,6 @@
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.Collections;
import java.util.List;
import jakarta.servlet.FilterChain;
@@ -31,9 +29,9 @@
import jakarta.servlet.http.HttpServletResponse;
import org.apache.catalina.util.NetMask;
+import org.apache.catalina.util.NetMaskSet;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
-import org.apache.tomcat.util.buf.StringUtils;
public final class RemoteCIDRFilter extends FilterBase {
@@ -49,14 +47,14 @@
private final Log log = LogFactory.getLog(RemoteCIDRFilter.class); // must not be static
/**
- * The list of allowed {@link NetMask}s
+ * The allowed {@link NetMask}s.
*/
- private final List allow = new ArrayList<>();
+ private final NetMaskSet allow = new NetMaskSet();
/**
- * The list of denied {@link NetMask}s
+ * The denied {@link NetMask}s.
*/
- private final List deny = new ArrayList<>();
+ private final NetMaskSet deny = new NetMaskSet();
/**
@@ -77,7 +75,7 @@
* @throws IllegalArgumentException One or more netmasks are invalid
*/
public void setAllow(final String input) {
- final List messages = fillFromInput(input, allow);
+ final List messages = allow.addAll(input);
if (messages.isEmpty()) {
return;
@@ -109,7 +107,7 @@
* @throws IllegalArgumentException One or more netmasks are invalid
*/
public void setDeny(final String input) {
- final List messages = fillFromInput(input, deny);
+ final List messages = deny.addAll(input);
if (messages.isEmpty()) {
return;
@@ -174,22 +172,17 @@
return false;
}
- for (final NetMask nm : deny) {
- if (nm.matches(addr)) {
- return false;
- }
+ if (deny.contains(addr)) {
+ return false;
}
- for (final NetMask nm : allow) {
- if (nm.matches(addr)) {
- return true;
- }
+ if (allow.contains(addr)) {
+ return true;
}
// Allow if deny is specified but allow isn't
// Deny this request otherwise
return !deny.isEmpty() && allow.isEmpty();
-
}
@@ -199,35 +192,4 @@
writer.write(sm.getString("http.403"));
writer.flush();
}
-
-
- /**
- * Fill a {@link NetMask} list from a string input containing a comma-separated list of (hopefully valid)
- * {@link NetMask}s.
- *
- * @param input The input string
- * @param target The list to fill
- *
- * @return a string list of processing errors (empty when no errors)
- */
- private List fillFromInput(final String input, final List target) {
- target.clear();
- if (input == null || input.isEmpty()) {
- return Collections.emptyList();
- }
-
- final List messages = new ArrayList<>();
- NetMask nm;
-
- for (final String s : StringUtils.splitCommaSeparated(input)) {
- try {
- nm = new NetMask(s);
- target.add(nm);
- } catch (IllegalArgumentException e) {
- messages.add(s + ": " + e.getMessage());
- }
- }
-
- return Collections.unmodifiableList(messages);
- }
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/filters/RemoteHostFilter.java tomcat11-11.0.15/java/org/apache/catalina/filters/RemoteHostFilter.java
--- tomcat11-11.0.6/java/org/apache/catalina/filters/RemoteHostFilter.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/filters/RemoteHostFilter.java 2025-12-02 16:54:08.000000000 +0000
@@ -28,8 +28,6 @@
/**
* Concrete implementation of RequestFilter that filters based on the remote client's host name.
- *
- * @author Craig R. McClanahan
*/
public final class RemoteHostFilter extends RequestFilter {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/filters/RemoteIpFilter.java tomcat11-11.0.15/java/org/apache/catalina/filters/RemoteIpFilter.java
--- tomcat11-11.0.6/java/org/apache/catalina/filters/RemoteIpFilter.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/filters/RemoteIpFilter.java 2025-12-02 16:54:08.000000000 +0000
@@ -42,6 +42,7 @@
import org.apache.catalina.AccessLog;
import org.apache.catalina.Globals;
+import org.apache.catalina.util.NetMaskSet;
import org.apache.catalina.util.RequestUtil;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
@@ -93,7 +94,7 @@
*
*
Configuration parameters
*
- *
XForwardedFilter property
+ *
RemoteIpFilter property
*
Description
*
Equivalent mod_remoteip directive
*
Format
@@ -109,18 +110,12 @@
*
*
*
internalProxies
- *
Regular expression that matches the IP addresses of internal proxies. If they appear in the
- * remoteIpHeader value, they will be trusted and will not appear in the proxiesHeader
- * value
+ *
Either a comma separated list of CIDR blocks or a single regular expression that matches the IP addresses of
+ * internal proxies. If they appear in the remoteIpHeader value, they will be trusted and will not appear
+ * in the proxiesHeader value
*
RemoteIPInternalProxy
- *
Regular expression (in the syntax supported by {@link java.util.regex.Pattern java.util.regex})
Regular expression that matches the IP addresses of trusted proxies. If they appear in the
- * remoteIpHeader value, they will be trusted and will appear in the proxiesHeader value
+ *
Either a comma separated list of CIDR blocks or a single regular expression that matches the IP addresses of
+ * internal proxies. If they appear in the remoteIpHeader value, they will be trusted and will appear in
+ * the proxiesHeader value
*
RemoteIPTrustedProxy
- *
Regular expression (in the syntax supported by {@link java.util.regex.Pattern java.util.regex})
+ *
Comma separated list of CIDR blocks or a single regular expression {@link Pattern}
*
*
*
@@ -177,27 +173,21 @@
*
false
*
*
- *
- * Regular expression vs. IP address blocks:mod_remoteip allows to use address blocks
- * (e.g. 192.168/16) to configure RemoteIPInternalProxy and RemoteIPTrustedProxy
- * ; as the JVM doesn't have a library similar to apr_ipsubnet_test,
- * we rely on regular expressions.
- *
@@ -673,31 +670,16 @@
protected static final String ENABLE_LOOKUPS_PARAMETER = "enableLookups";
- /**
- * @see #setHttpServerPort(int)
- */
private int httpServerPort = 80;
- /**
- * @see #setHttpsServerPort(int)
- */
private int httpsServerPort = 443;
- /**
- * @see #setInternalProxies(String)
- */
- private Pattern internalProxies =
- Pattern.compile("10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}|" + "192\\.168\\.\\d{1,3}\\.\\d{1,3}|" +
- "169\\.254\\.\\d{1,3}\\.\\d{1,3}|" + "127\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}|" +
- "100\\.6[4-9]{1}\\.\\d{1,3}\\.\\d{1,3}|" + "100\\.[7-9]{1}\\d{1}\\.\\d{1,3}\\.\\d{1,3}|" +
- "100\\.1[0-1]{1}\\d{1}\\.\\d{1,3}\\.\\d{1,3}|" + "100\\.12[0-7]{1}\\.\\d{1,3}\\.\\d{1,3}|" +
- "172\\.1[6-9]{1}\\.\\d{1,3}\\.\\d{1,3}|" + "172\\.2[0-9]{1}\\.\\d{1,3}\\.\\d{1,3}|" +
- "172\\.3[0-1]{1}\\.\\d{1,3}\\.\\d{1,3}|" + "0:0:0:0:0:0:0:1|::1|" +
- "fe[89ab]\\p{XDigit}:.*|" + "f[cd]\\p{XDigit}{2}+:.*");
+ private Pattern internalProxiesRegex = null;
+
+ private NetMaskSet internalProxiesCidr =
+ NetMaskSet.parse("10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,169.254.0.0/16,100.64.0.0/10,127.0.0.0/8," +
+ "::1/128,fe80::/10,fc00::/7");
- /**
- * @see #setProtocolHeader(String)
- */
private String protocolHeader = "X-Forwarded-Proto";
private String protocolHeaderHttpsValue = "https";
@@ -710,34 +692,25 @@
private boolean changeLocalPort = false;
- /**
- * @see #setProxiesHeader(String)
- */
private String proxiesHeader = "X-Forwarded-By";
- /**
- * @see #setRemoteIpHeader(String)
- */
private String remoteIpHeader = "X-Forwarded-For";
- /**
- * @see #setRequestAttributesEnabled(boolean)
- */
private boolean requestAttributesEnabled = true;
- /**
- * @see #setTrustedProxies(String)
- */
- private Pattern trustedProxies = null;
+ private Pattern trustedProxiesRegex = null;
+
+ private NetMaskSet trustedProxiesCidr = null;
private boolean enableLookups;
+
public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws IOException, ServletException {
- boolean isInternal = internalProxies != null && internalProxies.matcher(request.getRemoteAddr()).matches();
+ boolean isInternal = isInternalProxy(request.getRemoteAddr());
- if (isInternal || (trustedProxies != null && trustedProxies.matcher(request.getRemoteAddr()).matches())) {
+ if (isInternal || isTrustedProxy(request.getRemoteAddr())) {
String remoteIp = null;
Deque proxiesHeaderValue = new ArrayDeque<>();
StringBuilder concatRemoteIpHeaderValue = new StringBuilder();
@@ -759,9 +732,10 @@
for (idx = remoteIpHeaderValue.length - 1; idx >= 0; idx--) {
String currentRemoteIp = remoteIpHeaderValue[idx];
remoteIp = currentRemoteIp;
- if (internalProxies != null && internalProxies.matcher(currentRemoteIp).matches()) {
+
+ if (isInternalProxy(currentRemoteIp)) {
// do nothing, internalProxies IPs are not appended to the
- } else if (trustedProxies != null && trustedProxies.matcher(currentRemoteIp).matches()) {
+ } else if (isTrustedProxy(currentRemoteIp)) {
proxiesHeaderValue.addFirst(currentRemoteIp);
} else {
idx--; // decrement idx because break statement doesn't do it
@@ -842,7 +816,7 @@
}
} catch (IllegalArgumentException iae) {
- log.debug(sm.getString("remoteIpFilter.invalidHostHeader", hostHeaderValue, hostHeader));
+ log.debug(sm.getString("remoteIpFilter.invalidHostHeader", hostHeaderValue, hostHeader), iae);
}
}
}
@@ -877,6 +851,47 @@
}
+ /**
+ * Checks if the given IP address is from an internal proxy.
+ *
+ * @param remoteIp The IP address to check
+ *
+ * @return {@code true} if the IP address is from an internal proxy, otherwise {@code false}
+ */
+ private boolean isInternalProxy(String remoteIp) {
+ if (internalProxiesRegex != null && internalProxiesRegex.matcher(remoteIp).matches()) {
+ return true;
+ }
+ return checkIsCidr(internalProxiesCidr, remoteIp);
+ }
+
+ /**
+ * Checks if the given IP address is from a trusted proxy.
+ *
+ * @param remoteIp The IP address to check
+ *
+ * @return {@code true} if the IP address is from a trusted proxy, otherwise {@code false}
+ */
+ private boolean isTrustedProxy(String remoteIp) {
+ if (trustedProxiesRegex != null && trustedProxiesRegex.matcher(remoteIp).matches()) {
+ return true;
+ }
+
+ return checkIsCidr(trustedProxiesCidr, remoteIp);
+ }
+
+ private boolean checkIsCidr(NetMaskSet netMaskSet, String remoteIp) {
+ if (netMaskSet == null) {
+ return false;
+ }
+ try {
+ return netMaskSet.contains(remoteIp);
+ } catch (UnknownHostException uhe) {
+ log.debug(sm.getString("remoteIpFilter.invalidRemoteAddress", remoteIp), uhe);
+ }
+ return false;
+ }
+
/*
* Considers the value to be secure if it exclusively holds forwards for {@link #protocolHeaderHttpsValue}.
*/
@@ -904,7 +919,7 @@
try {
port = Integer.parseInt(portHeaderValue);
} catch (NumberFormatException nfe) {
- log.debug(sm.getString("remoteIpFilter.invalidPort", portHeaderValue, getPortHeader()));
+ log.debug(sm.getString("remoteIpFilter.invalidPort", portHeaderValue, getPortHeader()), nfe);
}
}
}
@@ -940,8 +955,36 @@
return httpsServerPort;
}
+ /**
+ * Obtain the currently configured regular expression Pattern for internal proxies.
+ *
+ * @return The currently configured regular expression Pattern for internal proxies
+ *
+ * @deprecated The implementation of this method will be replaced with the implementation of
+ * {@link #getInternalProxiesAsString()} in Tomcat 12 onwards with the return type changing to
+ * {@code String}
+ */
+ @Deprecated
public Pattern getInternalProxies() {
- return internalProxies;
+ return internalProxiesRegex;
+ }
+
+ /**
+ * Obtain the currently configured internal proxies.
+ *
+ * @return The currently configured internal proxies.
+ *
+ * @deprecated This method will be renamed to {@code getInternalProxies()} as of Tomcat 12
+ */
+ @Deprecated
+ public String getInternalProxiesAsString() {
+ if (internalProxiesCidr != null) {
+ return internalProxiesCidr.toString();
+ } else if (internalProxiesRegex != null) {
+ return internalProxiesRegex.toString();
+ } else {
+ return null;
+ }
}
public String getProtocolHeader() {
@@ -973,8 +1016,36 @@
return requestAttributesEnabled;
}
+ /**
+ * Obtain the currently configured regular expression Pattern for trusted proxies.
+ *
+ * @return The currently configured regular expression Pattern for trusted proxies
+ *
+ * @deprecated The implementation of this method will be replaced with the implementation of
+ * {@link #getTrustedProxiesAsString()} in Tomcat 12 onwards with the return type changing to
+ * {@code String}
+ */
+ @Deprecated
public Pattern getTrustedProxies() {
- return trustedProxies;
+ return trustedProxiesRegex;
+ }
+
+ /**
+ * Obtain the currently configured trusted proxies.
+ *
+ * @return The currently configured trusted proxies.
+ *
+ * @deprecated This method will be renamed to {@code getInternalProxies()} as of Tomcat 12
+ */
+ @Deprecated
+ public String getTrustedProxiesAsString() {
+ if (trustedProxiesCidr != null) {
+ return trustedProxiesCidr.toString();
+ } else if (trustedProxiesRegex != null) {
+ return trustedProxiesRegex.toString();
+ } else {
+ return null;
+ }
}
public boolean getEnableLookups() {
@@ -1108,21 +1179,20 @@
}
/**
- *
- * Regular expression that defines the internal proxies.
- *
- *
- * Default value :
- * 10\.\d{1,3}\.\d{1,3}\.\d{1,3}|192\.168\.\d{1,3}\.\d{1,3}|169\.254.\d{1,3}.\d{1,3}|127\.\d{1,3}\.\d{1,3}\.\d{1,3}|0:0:0:0:0:0:0:1
- *
+ * Set the internal proxies either as a comma separated list of CIDR blocks or a single regular expression.
*
- * @param internalProxies The regexp
+ * @param internalProxies The new internal proxies
*/
public void setInternalProxies(String internalProxies) {
if (internalProxies == null || internalProxies.isEmpty()) {
- this.internalProxies = null;
+ this.internalProxiesRegex = null;
+ this.internalProxiesCidr = null;
+ } else if (internalProxies.indexOf('/') > 0) {
+ this.internalProxiesRegex = null;
+ this.internalProxiesCidr = NetMaskSet.parse(internalProxies);
} else {
- this.internalProxies = Pattern.compile(internalProxies);
+ this.internalProxiesRegex = Pattern.compile(internalProxies);
+ this.internalProxiesCidr = null;
}
}
@@ -1244,20 +1314,20 @@
}
/**
- *
- * Regular expression defining proxies that are trusted when they appear in the {@link #remoteIpHeader} header.
- *
- *
- * Default value : empty list, no external proxy is trusted.
- *
+ * Set the trusted proxies either as a comma separated list of CIDR blocks or a single regular expression.
*
- * @param trustedProxies The trusted proxies regexp
+ * @param trustedProxies The new trusted proxies
*/
public void setTrustedProxies(String trustedProxies) {
if (trustedProxies == null || trustedProxies.isEmpty()) {
- this.trustedProxies = null;
+ this.trustedProxiesRegex = null;
+ this.trustedProxiesCidr = null;
+ } else if (trustedProxies.indexOf('/') > 0) {
+ this.trustedProxiesRegex = null;
+ this.trustedProxiesCidr = NetMaskSet.parse(trustedProxies);
} else {
- this.trustedProxies = Pattern.compile(trustedProxies);
+ this.trustedProxiesCidr = null;
+ this.trustedProxiesRegex = Pattern.compile(trustedProxies);
}
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/filters/RequestDumperFilter.java tomcat11-11.0.15/java/org/apache/catalina/filters/RequestDumperFilter.java
--- tomcat11-11.0.6/java/org/apache/catalina/filters/RequestDumperFilter.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/filters/RequestDumperFilter.java 2025-12-02 16:54:08.000000000 +0000
@@ -47,8 +47,6 @@
* org.apache.catalina.filter.RequestDumperFilter logger is directed to a dedicated file and that the
* org.apache.juli.VerbatimFormatter is used.
*
- *
- * @author Craig R. McClanahan
*/
public class RequestDumperFilter extends GenericFilter {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/ha/ClusterListener.java tomcat11-11.0.15/java/org/apache/catalina/ha/ClusterListener.java
--- tomcat11-11.0.6/java/org/apache/catalina/ha/ClusterListener.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/ha/ClusterListener.java 2025-12-02 16:54:08.000000000 +0000
@@ -26,8 +26,6 @@
/**
* Receive SessionID cluster change from other backup node after primary session node is failed.
- *
- * @author Peter Rossbach
*/
public abstract class ClusterListener implements ChannelListener {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/ha/ClusterManager.java tomcat11-11.0.15/java/org/apache/catalina/ha/ClusterManager.java
--- tomcat11-11.0.6/java/org/apache/catalina/ha/ClusterManager.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/ha/ClusterManager.java 2025-12-02 16:54:08.000000000 +0000
@@ -26,8 +26,6 @@
/**
* The common interface used by all cluster manager. This is so that we can have a more pluggable way of swapping
* session managers for different algorithms.
- *
- * @author Peter Rossbach
*/
public interface ClusterManager extends Manager {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/ha/ClusterRuleSet.java tomcat11-11.0.15/java/org/apache/catalina/ha/ClusterRuleSet.java
--- tomcat11-11.0.6/java/org/apache/catalina/ha/ClusterRuleSet.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/ha/ClusterRuleSet.java 2025-12-02 16:54:08.000000000 +0000
@@ -20,11 +20,7 @@
import org.apache.tomcat.util.digester.RuleSet;
/**
- *
* RuleSet for processing the contents of a Cluster definition element.
- *
- *
- * @author Peter Rossbach
*/
public class ClusterRuleSet implements RuleSet {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/ha/ClusterValve.java tomcat11-11.0.15/java/org/apache/catalina/ha/ClusterValve.java
--- tomcat11-11.0.6/java/org/apache/catalina/ha/ClusterValve.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/ha/ClusterValve.java 2025-12-02 16:54:08.000000000 +0000
@@ -21,8 +21,6 @@
/**
* Cluster valves are a simple extension to the Tomcat valve architecture with a small addition of being able to
* reference the cluster component in the container it sits in.
- *
- * @author Peter Rossbach
*/
public interface ClusterValve extends Valve {
/**
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/ha/authenticator/ClusterSingleSignOn.java tomcat11-11.0.15/java/org/apache/catalina/ha/authenticator/ClusterSingleSignOn.java
--- tomcat11-11.0.6/java/org/apache/catalina/ha/authenticator/ClusterSingleSignOn.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/ha/authenticator/ClusterSingleSignOn.java 2025-12-02 16:54:08.000000000 +0000
@@ -46,8 +46,6 @@
*
The web applications themselves must use one of the standard Authenticators found in the
* org.apache.catalina.authenticator package.
* IMPLEMENTATION NOTE : Correct behavior of session storing and reloading depends upon external calls to the
* start() and stop() methods of this class at the correct times.
- *
- * @author Craig R. McClanahan
- * @author Peter Rossbach
*/
public class DeltaManager extends ClusterManagerBase {
@@ -76,6 +75,7 @@
private int stateTransferTimeout = 60;
private boolean sendAllSessions = true;
private int sendAllSessionsSize = 1000;
+ private boolean enableStatistics = true;
/**
* wait time between send session block (default 2 sec)
@@ -88,25 +88,25 @@
// -------------------------------------------------------- stats attributes
- private volatile long sessionReplaceCounter = 0;
- private volatile long counterReceive_EVT_GET_ALL_SESSIONS = 0;
- private volatile long counterReceive_EVT_ALL_SESSION_DATA = 0;
- private volatile long counterReceive_EVT_SESSION_CREATED = 0;
- private volatile long counterReceive_EVT_SESSION_EXPIRED = 0;
- private volatile long counterReceive_EVT_SESSION_ACCESSED = 0;
- private volatile long counterReceive_EVT_SESSION_DELTA = 0;
- private volatile int counterReceive_EVT_ALL_SESSION_TRANSFERCOMPLETE = 0;
- private volatile long counterReceive_EVT_CHANGE_SESSION_ID = 0;
- private volatile long counterReceive_EVT_ALL_SESSION_NOCONTEXTMANAGER = 0;
- private volatile long counterSend_EVT_GET_ALL_SESSIONS = 0;
- private volatile long counterSend_EVT_ALL_SESSION_DATA = 0;
- private volatile long counterSend_EVT_SESSION_CREATED = 0;
- private volatile long counterSend_EVT_SESSION_DELTA = 0;
- private volatile long counterSend_EVT_SESSION_ACCESSED = 0;
- private volatile long counterSend_EVT_SESSION_EXPIRED = 0;
- private volatile int counterSend_EVT_ALL_SESSION_TRANSFERCOMPLETE = 0;
- private volatile long counterSend_EVT_CHANGE_SESSION_ID = 0;
- private volatile int counterNoStateTransferred = 0;
+ private final AtomicLong sessionReplaceCounter = new AtomicLong(0);
+ private final AtomicLong counterReceive_EVT_GET_ALL_SESSIONS = new AtomicLong(0);
+ private final AtomicLong counterReceive_EVT_ALL_SESSION_DATA = new AtomicLong(0);
+ private final AtomicLong counterReceive_EVT_SESSION_CREATED = new AtomicLong(0);
+ private final AtomicLong counterReceive_EVT_SESSION_EXPIRED = new AtomicLong(0);
+ private final AtomicLong counterReceive_EVT_SESSION_ACCESSED = new AtomicLong(0);
+ private final AtomicLong counterReceive_EVT_SESSION_DELTA = new AtomicLong(0);
+ private final AtomicInteger counterReceive_EVT_ALL_SESSION_TRANSFERCOMPLETE = new AtomicInteger(0);
+ private final AtomicLong counterReceive_EVT_CHANGE_SESSION_ID = new AtomicLong(0);
+ private final AtomicLong counterReceive_EVT_ALL_SESSION_NOCONTEXTMANAGER = new AtomicLong(0);
+ private final AtomicLong counterSend_EVT_GET_ALL_SESSIONS = new AtomicLong(0);
+ private final AtomicLong counterSend_EVT_ALL_SESSION_DATA = new AtomicLong(0);
+ private final AtomicLong counterSend_EVT_SESSION_CREATED = new AtomicLong(0);
+ private final AtomicLong counterSend_EVT_SESSION_DELTA = new AtomicLong(0);
+ private final AtomicLong counterSend_EVT_SESSION_ACCESSED = new AtomicLong(0);
+ private final AtomicLong counterSend_EVT_SESSION_EXPIRED = new AtomicLong(0);
+ private final AtomicInteger counterSend_EVT_ALL_SESSION_TRANSFERCOMPLETE = new AtomicInteger(0);
+ private final AtomicLong counterSend_EVT_CHANGE_SESSION_ID = new AtomicLong(0);
+ private final AtomicInteger counterNoStateTransferred = new AtomicInteger(0);
// ------------------------------------------------------------- Constructor
@@ -130,98 +130,98 @@
* @return Returns the counterSend_EVT_GET_ALL_SESSIONS.
*/
public long getCounterSend_EVT_GET_ALL_SESSIONS() {
- return counterSend_EVT_GET_ALL_SESSIONS;
+ return counterSend_EVT_GET_ALL_SESSIONS.get();
}
/**
* @return Returns the counterSend_EVT_SESSION_ACCESSED.
*/
public long getCounterSend_EVT_SESSION_ACCESSED() {
- return counterSend_EVT_SESSION_ACCESSED;
+ return counterSend_EVT_SESSION_ACCESSED.get();
}
/**
* @return Returns the counterSend_EVT_SESSION_CREATED.
*/
public long getCounterSend_EVT_SESSION_CREATED() {
- return counterSend_EVT_SESSION_CREATED;
+ return counterSend_EVT_SESSION_CREATED.get();
}
/**
* @return Returns the counterSend_EVT_SESSION_DELTA.
*/
public long getCounterSend_EVT_SESSION_DELTA() {
- return counterSend_EVT_SESSION_DELTA;
+ return counterSend_EVT_SESSION_DELTA.get();
}
/**
* @return Returns the counterSend_EVT_SESSION_EXPIRED.
*/
public long getCounterSend_EVT_SESSION_EXPIRED() {
- return counterSend_EVT_SESSION_EXPIRED;
+ return counterSend_EVT_SESSION_EXPIRED.get();
}
/**
* @return Returns the counterSend_EVT_ALL_SESSION_DATA.
*/
public long getCounterSend_EVT_ALL_SESSION_DATA() {
- return counterSend_EVT_ALL_SESSION_DATA;
+ return counterSend_EVT_ALL_SESSION_DATA.get();
}
/**
* @return Returns the counterSend_EVT_ALL_SESSION_TRANSFERCOMPLETE.
*/
public int getCounterSend_EVT_ALL_SESSION_TRANSFERCOMPLETE() {
- return counterSend_EVT_ALL_SESSION_TRANSFERCOMPLETE;
+ return counterSend_EVT_ALL_SESSION_TRANSFERCOMPLETE.get();
}
/**
* @return Returns the counterSend_EVT_CHANGE_SESSION_ID.
*/
public long getCounterSend_EVT_CHANGE_SESSION_ID() {
- return counterSend_EVT_CHANGE_SESSION_ID;
+ return counterSend_EVT_CHANGE_SESSION_ID.get();
}
/**
* @return Returns the counterReceive_EVT_ALL_SESSION_DATA.
*/
public long getCounterReceive_EVT_ALL_SESSION_DATA() {
- return counterReceive_EVT_ALL_SESSION_DATA;
+ return counterReceive_EVT_ALL_SESSION_DATA.get();
}
/**
* @return Returns the counterReceive_EVT_GET_ALL_SESSIONS.
*/
public long getCounterReceive_EVT_GET_ALL_SESSIONS() {
- return counterReceive_EVT_GET_ALL_SESSIONS;
+ return counterReceive_EVT_GET_ALL_SESSIONS.get();
}
/**
* @return Returns the counterReceive_EVT_SESSION_ACCESSED.
*/
public long getCounterReceive_EVT_SESSION_ACCESSED() {
- return counterReceive_EVT_SESSION_ACCESSED;
+ return counterReceive_EVT_SESSION_ACCESSED.get();
}
/**
* @return Returns the counterReceive_EVT_SESSION_CREATED.
*/
public long getCounterReceive_EVT_SESSION_CREATED() {
- return counterReceive_EVT_SESSION_CREATED;
+ return counterReceive_EVT_SESSION_CREATED.get();
}
/**
* @return Returns the counterReceive_EVT_SESSION_DELTA.
*/
public long getCounterReceive_EVT_SESSION_DELTA() {
- return counterReceive_EVT_SESSION_DELTA;
+ return counterReceive_EVT_SESSION_DELTA.get();
}
/**
* @return Returns the counterReceive_EVT_SESSION_EXPIRED.
*/
public long getCounterReceive_EVT_SESSION_EXPIRED() {
- return counterReceive_EVT_SESSION_EXPIRED;
+ return counterReceive_EVT_SESSION_EXPIRED.get();
}
@@ -229,35 +229,35 @@
* @return Returns the counterReceive_EVT_ALL_SESSION_TRANSFERCOMPLETE.
*/
public int getCounterReceive_EVT_ALL_SESSION_TRANSFERCOMPLETE() {
- return counterReceive_EVT_ALL_SESSION_TRANSFERCOMPLETE;
+ return counterReceive_EVT_ALL_SESSION_TRANSFERCOMPLETE.get();
}
/**
* @return Returns the counterReceive_EVT_CHANGE_SESSION_ID.
*/
public long getCounterReceive_EVT_CHANGE_SESSION_ID() {
- return counterReceive_EVT_CHANGE_SESSION_ID;
+ return counterReceive_EVT_CHANGE_SESSION_ID.get();
}
/**
* @return Returns the counterReceive_EVT_ALL_SESSION_NOCONTEXTMANAGER.
*/
public long getCounterReceive_EVT_ALL_SESSION_NOCONTEXTMANAGER() {
- return counterReceive_EVT_ALL_SESSION_NOCONTEXTMANAGER;
+ return counterReceive_EVT_ALL_SESSION_NOCONTEXTMANAGER.get();
}
/**
* @return Returns the sessionReplaceCounter.
*/
public long getSessionReplaceCounter() {
- return sessionReplaceCounter;
+ return sessionReplaceCounter.get();
}
/**
* @return Returns the counterNoStateTransferred.
*/
public int getCounterNoStateTransferred() {
- return counterNoStateTransferred;
+ return counterNoStateTransferred.get();
}
public int getReceivedQueueSize() {
@@ -391,6 +391,19 @@
this.notifyContainerListenersOnReplication = notifyContainerListenersOnReplication;
}
+ /**
+ * @return the enableStatistics
+ */
+ public boolean getEnableStatistics() {
+ return this.enableStatistics;
+ }
+
+ /**
+ * @param enableStatistics the enableStatistics to set
+ */
+ public void setEnableStatistics(boolean enableStatistics) {
+ this.enableStatistics = enableStatistics;
+ }
// --------------------------------------------------------- Public Methods
@@ -433,7 +446,9 @@
log.trace(sm.getString("deltaManager.sendMessage.newSession", name, sessionId));
}
msg.setTimestamp(session.getCreationTime());
- counterSend_EVT_SESSION_CREATED++;
+ if (enableStatistics) {
+ counterSend_EVT_SESSION_CREATED.incrementAndGet();
+ }
send(msg);
}
}
@@ -495,10 +510,12 @@
SessionMessage msg = new SessionMessageImpl(getName(), SessionMessage.EVT_CHANGE_SESSION_ID, data,
orgSessionID, orgSessionID + "-" + System.currentTimeMillis());
msg.setTimestamp(System.currentTimeMillis());
- counterSend_EVT_CHANGE_SESSION_ID++;
+ if (enableStatistics) {
+ counterSend_EVT_CHANGE_SESSION_ID.incrementAndGet();
+ }
send(msg);
- } catch (IOException e) {
- log.error(sm.getString("deltaManager.unableSerializeSessionID", newSessionID), e);
+ } catch (IOException ioe) {
+ log.error(sm.getString("deltaManager.unableSerializeSessionID", newSessionID), ioe);
}
}
}
@@ -573,7 +590,9 @@
session.resetDeltaRequest();
// FIXME How inform other session id cache like SingleSignOn
if (findSession(session.getIdInternal()) != null) {
- sessionReplaceCounter++;
+ if (enableStatistics) {
+ sessionReplaceCounter.incrementAndGet();
+ }
// FIXME better is to grap this sessions again !
if (log.isWarnEnabled()) {
log.warn(sm.getString("deltaManager.loading.existing.session", session.getIdInternal()));
@@ -587,9 +606,9 @@
} catch (ClassNotFoundException e) {
log.error(sm.getString("deltaManager.loading.cnfe", e), e);
throw e;
- } catch (IOException e) {
- log.error(sm.getString("deltaManager.loading.ioe", e), e);
- throw e;
+ } catch (IOException ioe) {
+ log.error(sm.getString("deltaManager.loading.ioe", ioe), ioe);
+ throw ioe;
}
}
@@ -615,9 +634,9 @@
}
// Flush and close the output stream
oos.flush();
- } catch (IOException e) {
- log.error(sm.getString("deltaManager.unloading.ioe", e), e);
- throw e;
+ } catch (IOException ioe) {
+ log.error(sm.getString("deltaManager.unloading.ioe", ioe), ioe);
+ throw ioe;
}
// send object data as byte[]
@@ -684,7 +703,9 @@
// set reference time
stateTransferCreateSendTime = beforeSendTime;
// request session state
- counterSend_EVT_GET_ALL_SESSIONS++;
+ if (enableStatistics) {
+ counterSend_EVT_GET_ALL_SESSIONS.incrementAndGet();
+ }
stateTransferred = false;
// FIXME This send call block the deploy thread, when sender waitForAck is enabled
try {
@@ -764,8 +785,8 @@
do {
try {
Thread.sleep(100);
- } catch (Exception sleep) {
- //
+ } catch (Exception ignore) {
+ // Ignore
}
reqNow = System.currentTimeMillis();
isTimeout = ((reqNow - reqStart) > (1000L * getStateTransferTimeout()));
@@ -776,7 +797,7 @@
do {
try {
Thread.sleep(100);
- } catch (Exception sleep) {
+ } catch (Exception ignore) {
// Ignore
}
} while ((!getStateTransferred()) && (!isNoContextManagerReceived()));
@@ -784,7 +805,9 @@
}
}
if (isTimeout) {
- counterNoStateTransferred++;
+ if (enableStatistics) {
+ counterNoStateTransferred.incrementAndGet();
+ }
log.error(sm.getString("deltaManager.noSessionState", getName(), new Date(beforeSendTime),
Long.valueOf(reqNow - beforeSendTime)));
} else if (isNoContextManagerReceived()) {
@@ -893,17 +916,21 @@
return null;
}
if (session.isDirty()) {
- counterSend_EVT_SESSION_DELTA++;
+ if (enableStatistics) {
+ counterSend_EVT_SESSION_DELTA.incrementAndGet();
+ }
msg = new SessionMessageImpl(getName(), SessionMessage.EVT_SESSION_DELTA, session.getDiff(), sessionId,
sessionId + "-" + System.currentTimeMillis());
}
- } catch (IOException x) {
- log.error(sm.getString("deltaManager.createMessage.unableCreateDeltaRequest", sessionId), x);
+ } catch (IOException ioe) {
+ log.error(sm.getString("deltaManager.createMessage.unableCreateDeltaRequest", sessionId), ioe);
return null;
}
if (msg == null) {
if (!expires && !session.isPrimarySession()) {
- counterSend_EVT_SESSION_ACCESSED++;
+ if (enableStatistics) {
+ counterSend_EVT_SESSION_ACCESSED.incrementAndGet();
+ }
msg = new SessionMessageImpl(getName(), SessionMessage.EVT_SESSION_ACCESSED, null, sessionId,
sessionId + "-" + System.currentTimeMillis());
if (log.isDebugEnabled()) {
@@ -922,7 +949,9 @@
if (!expires && (msg == null)) {
long replDelta = System.currentTimeMillis() - session.getLastTimeReplicated();
if (session.getMaxInactiveInterval() >= 0 && replDelta > (session.getMaxInactiveInterval() * 1000L)) {
- counterSend_EVT_SESSION_ACCESSED++;
+ if (enableStatistics) {
+ counterSend_EVT_SESSION_ACCESSED.incrementAndGet();
+ }
msg = new SessionMessageImpl(getName(), SessionMessage.EVT_SESSION_ACCESSED, null, sessionId,
sessionId + "-" + System.currentTimeMillis());
if (log.isDebugEnabled()) {
@@ -958,25 +987,25 @@
}
}
rejectedSessions = 0;
- sessionReplaceCounter = 0;
- counterNoStateTransferred = 0;
+ sessionReplaceCounter.set(0);
+ counterNoStateTransferred.set(0);
setMaxActive(getActiveSessions());
- counterReceive_EVT_ALL_SESSION_DATA = 0;
- counterReceive_EVT_GET_ALL_SESSIONS = 0;
- counterReceive_EVT_SESSION_ACCESSED = 0;
- counterReceive_EVT_SESSION_CREATED = 0;
- counterReceive_EVT_SESSION_DELTA = 0;
- counterReceive_EVT_SESSION_EXPIRED = 0;
- counterReceive_EVT_ALL_SESSION_TRANSFERCOMPLETE = 0;
- counterReceive_EVT_CHANGE_SESSION_ID = 0;
- counterSend_EVT_ALL_SESSION_DATA = 0;
- counterSend_EVT_GET_ALL_SESSIONS = 0;
- counterSend_EVT_SESSION_ACCESSED = 0;
- counterSend_EVT_SESSION_CREATED = 0;
- counterSend_EVT_SESSION_DELTA = 0;
- counterSend_EVT_SESSION_EXPIRED = 0;
- counterSend_EVT_ALL_SESSION_TRANSFERCOMPLETE = 0;
- counterSend_EVT_CHANGE_SESSION_ID = 0;
+ counterReceive_EVT_ALL_SESSION_DATA.set(0);
+ counterReceive_EVT_GET_ALL_SESSIONS.set(0);
+ counterReceive_EVT_SESSION_ACCESSED.set(0);
+ counterReceive_EVT_SESSION_CREATED.set(0);
+ counterReceive_EVT_SESSION_DELTA.set(0);
+ counterReceive_EVT_SESSION_EXPIRED.set(0);
+ counterReceive_EVT_ALL_SESSION_TRANSFERCOMPLETE.set(0);
+ counterReceive_EVT_CHANGE_SESSION_ID.set(0);
+ counterSend_EVT_ALL_SESSION_DATA.set(0);
+ counterSend_EVT_GET_ALL_SESSIONS.set(0);
+ counterSend_EVT_SESSION_ACCESSED.set(0);
+ counterSend_EVT_SESSION_CREATED.set(0);
+ counterSend_EVT_SESSION_DELTA.set(0);
+ counterSend_EVT_SESSION_EXPIRED.set(0);
+ counterSend_EVT_ALL_SESSION_TRANSFERCOMPLETE.set(0);
+ counterSend_EVT_CHANGE_SESSION_ID.set(0);
}
@@ -989,7 +1018,9 @@
*/
protected void sessionExpired(String id) {
if (cluster.getMembers().length > 0) {
- counterSend_EVT_SESSION_EXPIRED++;
+ if (enableStatistics) {
+ counterSend_EVT_SESSION_EXPIRED.incrementAndGet();
+ }
SessionMessage msg = new SessionMessageImpl(getName(), SessionMessage.EVT_SESSION_EXPIRED, null, id,
id + "-EXPIRED-MSG");
msg.setTimestamp(System.currentTimeMillis());
@@ -1091,8 +1122,8 @@
// we didn't recognize the message type, do nothing
break;
} // switch
- } catch (Exception x) {
- log.error(sm.getString("deltaManager.receiveMessage.error", getName()), x);
+ } catch (Exception e) {
+ log.error(sm.getString("deltaManager.receiveMessage.error", getName()), e);
} finally {
currentThread.setContextClassLoader(contextLoader);
}
@@ -1108,7 +1139,9 @@
* @param sender Member which sent the message
*/
protected void handleALL_SESSION_TRANSFERCOMPLETE(SessionMessage msg, Member sender) {
- counterReceive_EVT_ALL_SESSION_TRANSFERCOMPLETE++;
+ if (enableStatistics) {
+ counterReceive_EVT_ALL_SESSION_TRANSFERCOMPLETE.incrementAndGet();
+ }
if (log.isDebugEnabled()) {
log.debug(sm.getString("deltaManager.receiveMessage.transfercomplete", getName(), sender.getHost(),
Integer.valueOf(sender.getPort())));
@@ -1127,7 +1160,9 @@
* @throws ClassNotFoundException Serialization error
*/
protected void handleSESSION_DELTA(SessionMessage msg, Member sender) throws IOException, ClassNotFoundException {
- counterReceive_EVT_SESSION_DELTA++;
+ if (enableStatistics) {
+ counterReceive_EVT_SESSION_DELTA.incrementAndGet();
+ }
byte[] delta = msg.getSession();
DeltaSession session = (DeltaSession) findSession(msg.getSessionID());
if (session == null) {
@@ -1152,7 +1187,9 @@
* @throws IOException Propagated IO error
*/
protected void handleSESSION_ACCESSED(SessionMessage msg, Member sender) throws IOException {
- counterReceive_EVT_SESSION_ACCESSED++;
+ if (enableStatistics) {
+ counterReceive_EVT_SESSION_ACCESSED.incrementAndGet();
+ }
DeltaSession session = (DeltaSession) findSession(msg.getSessionID());
if (session != null) {
if (log.isDebugEnabled()) {
@@ -1173,7 +1210,9 @@
* @throws IOException Propagated IO error
*/
protected void handleSESSION_EXPIRED(SessionMessage msg, Member sender) throws IOException {
- counterReceive_EVT_SESSION_EXPIRED++;
+ if (enableStatistics) {
+ counterReceive_EVT_SESSION_EXPIRED.incrementAndGet();
+ }
DeltaSession session = (DeltaSession) findSession(msg.getSessionID());
if (session != null) {
if (log.isDebugEnabled()) {
@@ -1190,7 +1229,9 @@
* @param sender Member which sent the message
*/
protected void handleSESSION_CREATED(SessionMessage msg, Member sender) {
- counterReceive_EVT_SESSION_CREATED++;
+ if (enableStatistics) {
+ counterReceive_EVT_SESSION_CREATED.incrementAndGet();
+ }
if (log.isDebugEnabled()) {
log.debug(sm.getString("deltaManager.receiveMessage.createNewSession", getName(), msg.getSessionID()));
}
@@ -1218,7 +1259,9 @@
*/
protected void handleALL_SESSION_DATA(SessionMessage msg, Member sender)
throws ClassNotFoundException, IOException {
- counterReceive_EVT_ALL_SESSION_DATA++;
+ if (enableStatistics) {
+ counterReceive_EVT_ALL_SESSION_DATA.incrementAndGet();
+ }
if (log.isDebugEnabled()) {
log.debug(sm.getString("deltaManager.receiveMessage.allSessionDataBegin", getName()));
}
@@ -1240,7 +1283,9 @@
* @throws IOException IO error sending messages
*/
protected void handleGET_ALL_SESSIONS(SessionMessage msg, Member sender) throws IOException {
- counterReceive_EVT_GET_ALL_SESSIONS++;
+ if (enableStatistics) {
+ counterReceive_EVT_GET_ALL_SESSIONS.incrementAndGet();
+ }
// get a list of all the session from this manager
if (log.isDebugEnabled()) {
log.debug(sm.getString("deltaManager.receiveMessage.unloadingBegin", getName()));
@@ -1264,7 +1309,7 @@
if (getSendAllSessionsWaitTime() > 0 && remain > 0) {
try {
Thread.sleep(getSendAllSessionsWaitTime());
- } catch (Exception sleep) {
+ } catch (Exception ignore) {
// Ignore
}
}
@@ -1277,7 +1322,9 @@
if (log.isDebugEnabled()) {
log.debug(sm.getString("deltaManager.createMessage.allSessionTransferred", getName()));
}
- counterSend_EVT_ALL_SESSION_TRANSFERCOMPLETE++;
+ if (enableStatistics) {
+ counterSend_EVT_ALL_SESSION_TRANSFERCOMPLETE.incrementAndGet();
+ }
cluster.send(newmsg, sender);
}
@@ -1290,7 +1337,9 @@
* @throws IOException IO error with serialization
*/
protected void handleCHANGE_SESSION_ID(SessionMessage msg, Member sender) throws IOException {
- counterReceive_EVT_CHANGE_SESSION_ID++;
+ if (enableStatistics) {
+ counterReceive_EVT_CHANGE_SESSION_ID.incrementAndGet();
+ }
DeltaSession session = (DeltaSession) findSession(msg.getSessionID());
if (session != null) {
String newSessionID = deserializeSessionId(msg.getSession());
@@ -1308,7 +1357,9 @@
* @param sender Member which sent the message
*/
protected void handleALL_SESSION_NOCONTEXTMANAGER(SessionMessage msg, Member sender) {
- counterReceive_EVT_ALL_SESSION_NOCONTEXTMANAGER++;
+ if (enableStatistics) {
+ counterReceive_EVT_ALL_SESSION_NOCONTEXTMANAGER.incrementAndGet();
+ }
if (log.isDebugEnabled()) {
log.debug(sm.getString("deltaManager.receiveMessage.noContextManager", getName(), sender.getHost(),
Integer.valueOf(sender.getPort())));
@@ -1336,7 +1387,9 @@
if (log.isDebugEnabled()) {
log.debug(sm.getString("deltaManager.createMessage.allSessionData", getName()));
}
- counterSend_EVT_ALL_SESSION_DATA++;
+ if (enableStatistics) {
+ counterSend_EVT_ALL_SESSION_DATA.incrementAndGet();
+ }
int sendOptions = Channel.SEND_OPTIONS_SYNCHRONIZED_ACK | Channel.SEND_OPTIONS_USE_ACK;
cluster.send(newmsg, sender, sendOptions);
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/ha/session/DeltaRequest.java tomcat11-11.0.15/java/org/apache/catalina/ha/session/DeltaRequest.java
--- tomcat11-11.0.6/java/org/apache/catalina/ha/session/DeltaRequest.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/ha/session/DeltaRequest.java 2025-12-02 16:54:08.000000000 +0000
@@ -147,8 +147,8 @@
if (!this.actionPool.isEmpty()) {
try {
info = actionPool.removeFirst();
- } catch (Exception x) {
- log.error(sm.getString("deltaRequest.removeUnable"), x);
+ } catch (Exception e) {
+ log.error(sm.getString("deltaRequest.removeUnable"), e);
info = new AttributeInfo(type, action, name, value);
}
info.init(type, action, name, value);
@@ -251,8 +251,8 @@
AttributeInfo info = actions.removeFirst();
info.recycle();
actionPool.addLast(info);
- } catch (Exception x) {
- log.error(sm.getString("deltaRequest.removeUnable"), x);
+ } catch (Exception e) {
+ log.error(sm.getString("deltaRequest.removeUnable"), e);
}
}
}
@@ -264,8 +264,8 @@
public void setSessionId(String sessionId) {
this.sessionId = sessionId;
if (sessionId == null) {
- Exception e = new Exception(sm.getString("deltaRequest.ssid.null"));
- log.error(sm.getString("deltaRequest.ssid.null"), e.fillInStackTrace());
+ String msg = sm.getString("deltaRequest.ssid.null");
+ log.error(msg, new Exception(msg));
}
}
@@ -293,8 +293,8 @@
if (!this.actionPool.isEmpty()) {
try {
info = actionPool.removeFirst();
- } catch (Exception x) {
- log.error(sm.getString("deltaRequest.removeUnable"), x);
+ } catch (Exception e) {
+ log.error(sm.getString("deltaRequest.removeUnable"), e);
info = new AttributeInfo();
}
} else {
@@ -430,9 +430,8 @@
@Override
public String toString() {
- return "AttributeInfo[type=" + getType() + ", action=" + getAction() +
- ", name=" + getName() + ", value=" + getValue() +
- ", addr=" + super.toString() + ']';
+ return "AttributeInfo[type=" + getType() + ", action=" + getAction() + ", name=" + getName() + ", value=" +
+ getValue() + ", addr=" + super.toString() + ']';
}
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/ha/session/JvmRouteBinderValve.java tomcat11-11.0.15/java/org/apache/catalina/ha/session/JvmRouteBinderValve.java
--- tomcat11-11.0.6/java/org/apache/catalina/ha/session/JvmRouteBinderValve.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/ha/session/JvmRouteBinderValve.java 2025-12-02 16:54:08.000000000 +0000
@@ -58,8 +58,6 @@
* You can enable this mod_jk turnover mode via JMX before you drop a node to all backup nodes! Set enable true on all
* JvmRouteBinderValve backups, disable worker at mod_jk and then drop node and restart it! Then enable mod_jk worker
* and disable JvmRouteBinderValves again. This use case means that only requested sessions are migrated.
- *
- * @author Peter Rossbach
*/
public class JvmRouteBinderValve extends ValveBase implements ClusterValve {
@@ -258,8 +256,8 @@
Session catalinaSession = null;
try {
catalinaSession = getManager(request).findSession(sessionId);
- } catch (IOException e) {
- // Hups!
+ } catch (IOException ignore) {
+ // Error looking for session using old session ID. Treat it as not found.
}
String id = sessionId.substring(0, index);
String newSessionID = id + "." + localJvmRoute;
@@ -270,11 +268,11 @@
} else {
try {
catalinaSession = getManager(request).findSession(newSessionID);
- } catch (IOException e) {
- // Hups!
+ } catch (IOException ignore) {
+ // Error looking for session using new session ID. Treat it as not found.
}
if (catalinaSession != null) {
- // session is rewrite at other request, rewrite this also
+ // Session was rewritten in other, concurrent request. Rewrite this request also.
changeRequestSessionID(request, sessionId, newSessionID);
} else {
if (log.isDebugEnabled()) {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/ha/session/LocalStrings_ja.properties tomcat11-11.0.15/java/org/apache/catalina/ha/session/LocalStrings_ja.properties
--- tomcat11-11.0.6/java/org/apache/catalina/ha/session/LocalStrings_ja.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/ha/session/LocalStrings_ja.properties 2025-12-02 16:54:08.000000000 +0000
@@ -82,7 +82,7 @@
jvmRoute.changeSession=セッションを [{0}] から [{1}] へ変更しました。
jvmRoute.failover=他の jvmRoute へのフェールオーバーを検出しました。元のルートは [{0}]、新しいルートは [{1}]、セッション ID は [{2}] です。
jvmRoute.foundManager=Cluster Manager [{0}] を [{1}] で発見しました
-jvmRoute.missingJvmRouteAttribute=jvmRoute 属性にエンジンが指定されていません。
+jvmRoute.missingJvmRouteAttribute=Engine に jvmRoute 属性が指定されていません!
jvmRoute.noCluster=JvmRouterBinderValveは設定されていますが、クラスタリングは使用されていません。 PersistentManagerが使用されている場合、フェールオーバーは引き続き機能します。
jvmRoute.notFoundManager=[{0}]でCluster Managerが見つかりません。
jvmRoute.set.originalsessionid=オリジナルSession idをリクエスト属性[{0}]の値:[{1}]で設定します。
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/ha/session/SessionMessage.java tomcat11-11.0.15/java/org/apache/catalina/ha/session/SessionMessage.java
--- tomcat11-11.0.6/java/org/apache/catalina/ha/session/SessionMessage.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/ha/session/SessionMessage.java 2025-12-02 16:54:08.000000000 +0000
@@ -47,8 +47,8 @@
int EVT_SESSION_EXPIRED = 2;
/**
- * Event type used when a session has been accessed (ie, last access time has been updated). This is used so that the
- * replicated sessions will not expire on the network
+ * Event type used when a session has been accessed (ie, last access time has been updated). This is used so that
+ * the replicated sessions will not expire on the network
*/
int EVT_SESSION_ACCESSED = 3;
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/ha/session/SessionMessageImpl.java tomcat11-11.0.15/java/org/apache/catalina/ha/session/SessionMessageImpl.java
--- tomcat11-11.0.6/java/org/apache/catalina/ha/session/SessionMessageImpl.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/ha/session/SessionMessageImpl.java 2025-12-02 16:54:08.000000000 +0000
@@ -22,9 +22,7 @@
import org.apache.catalina.ha.ClusterMessageBase;
/**
- * Session cluster message
- *
- * @author Peter Rossbach
+ * Session cluster message.
*/
public class SessionMessageImpl extends ClusterMessageBase implements SessionMessage {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/ha/tcp/Constants.java tomcat11-11.0.15/java/org/apache/catalina/ha/tcp/Constants.java
--- tomcat11-11.0.6/java/org/apache/catalina/ha/tcp/Constants.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/ha/tcp/Constants.java 2025-12-02 16:54:08.000000000 +0000
@@ -18,8 +18,6 @@
/**
* Manifest constants for the org.apache.catalina.ha.tcp package.
- *
- * @author Peter Rossbach
*/
public class Constants {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/ha/tcp/ReplicationValve.java tomcat11-11.0.15/java/org/apache/catalina/ha/tcp/ReplicationValve.java
--- tomcat11-11.0.6/java/org/apache/catalina/ha/tcp/ReplicationValve.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/ha/tcp/ReplicationValve.java 2025-12-02 16:54:08.000000000 +0000
@@ -47,21 +47,14 @@
import org.apache.tomcat.util.res.StringManager;
/**
- *
* Implementation of a Valve that logs interesting contents from the specified Request (before processing) and the
* corresponding Response (after processing). It is especially useful in debugging problems related to headers and
* cookies.
- *
*
* This Valve may be attached to any Container, depending on the granularity of the logging you wish to perform.
- *
*
* primaryIndicator=true, then the request attribute org.apache.catalina.ha.tcp.isPrimarySession. is set true,
* when request processing is at sessions primary node.
- *
- *
- * @author Craig R. McClanahan
- * @author Peter Rossbach
*/
public class ReplicationValve extends ValveBase implements ClusterValve {
@@ -376,9 +369,9 @@
if (isCrossContext) {
sendCrossContextSession();
}
- } catch (Exception x) {
+ } catch (Exception e) {
// FIXME we have a lot of sends, but the trouble with one node stops the correct replication to other nodes!
- log.error(sm.getString("ReplicationValve.send.failure"), x);
+ log.error(sm.getString("ReplicationValve.send.failure"), e);
} finally {
if (doStatistics()) {
updateStats(totalstart, start, isAsync);
@@ -505,8 +498,8 @@
for (String invalidId : invalidIds) {
try {
send(manager, invalidId);
- } catch (Exception x) {
- log.error(sm.getString("ReplicationValve.send.invalid.failure", invalidId), x);
+ } catch (Exception e) {
+ log.error(sm.getString("ReplicationValve.send.invalid.failure", invalidId), e);
}
}
}
@@ -544,8 +537,7 @@
Long.valueOf(totalSendTime.longValue() / nrOfRequests.longValue()),
Long.valueOf(nrOfRequests.longValue()), Long.valueOf(nrOfSendRequests.longValue()),
Long.valueOf(nrOfCrossContextSendRequests.longValue()),
- Long.valueOf(nrOfFilterRequests.longValue()),
- Long.valueOf(totalRequestTime.longValue()),
+ Long.valueOf(nrOfFilterRequests.longValue()), Long.valueOf(totalRequestTime.longValue()),
Long.valueOf(totalSendTime.longValue())));
}
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/ha/tcp/SendMessageData.java tomcat11-11.0.15/java/org/apache/catalina/ha/tcp/SendMessageData.java
--- tomcat11-11.0.6/java/org/apache/catalina/ha/tcp/SendMessageData.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/ha/tcp/SendMessageData.java 2025-12-02 16:54:08.000000000 +0000
@@ -19,8 +19,6 @@
import org.apache.catalina.tribes.Member;
/**
- * @author Peter Rossbach
- *
* @param message The message that was sent
* @param destination The destination of the message
* @param exception The exception, if any, when attempting to send the message
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/ha/tcp/SimpleTcpCluster.java tomcat11-11.0.15/java/org/apache/catalina/ha/tcp/SimpleTcpCluster.java
--- tomcat11-11.0.6/java/org/apache/catalina/ha/tcp/SimpleTcpCluster.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/ha/tcp/SimpleTcpCluster.java 2025-12-02 16:54:08.000000000 +0000
@@ -59,9 +59,6 @@
/**
* A Cluster implementation using simple multicast. Responsible for setting up a cluster and provides callers
* with a valid multicast receiver/sender.
- *
- * @author Remy Maucherat
- * @author Peter Rossbach
*/
public class SimpleTcpCluster extends LifecycleMBeanBase
implements CatalinaCluster, MembershipListener, ChannelListener {
@@ -345,8 +342,8 @@
try {
manager = managerTemplate.cloneFromTemplate();
manager.setName(name);
- } catch (Exception x) {
- log.error(sm.getString("simpleTcpCluster.clustermanager.cloneFailed"), x);
+ } catch (Exception e) {
+ log.error(sm.getString("simpleTcpCluster.clustermanager.cloneFailed"), e);
manager = new DeltaManager();
} finally {
if (manager != null) {
@@ -468,9 +465,9 @@
clusterDeployer.start();
}
registerMember(channel.getLocalMember(false));
- } catch (Exception x) {
- log.error(sm.getString("simpleTcpCluster.startUnable"), x);
- throw new LifecycleException(x);
+ } catch (Exception e) {
+ log.error(sm.getString("simpleTcpCluster.startUnable"), e);
+ throw new LifecycleException(e);
}
setState(LifecycleState.STARTING);
@@ -558,8 +555,8 @@
channel.removeChannelListener(this);
channel.removeMembershipListener(this);
this.unregisterClusterValve();
- } catch (Exception x) {
- log.error(sm.getString("simpleTcpCluster.stopUnable"), x);
+ } catch (Exception e) {
+ log.error(sm.getString("simpleTcpCluster.stopUnable"), e);
}
channel.setUtilityExecutor(null);
@@ -610,8 +607,8 @@
log.debug(sm.getString("simpleTcpCluster.noMembers", msg));
}
}
- } catch (Exception x) {
- log.error(sm.getString("simpleTcpCluster.sendFailed"), x);
+ } catch (Exception e) {
+ log.error(sm.getString("simpleTcpCluster.sendFailed"), e);
}
}
@@ -629,8 +626,8 @@
// Notify our interested LifecycleListeners
fireLifecycleEvent(AFTER_MEMBERREGISTER_EVENT, member);
- } catch (Exception x) {
- log.error(sm.getString("simpleTcpCluster.member.addFailed"), x);
+ } catch (Exception e) {
+ log.error(sm.getString("simpleTcpCluster.member.addFailed"), e);
}
}
@@ -649,8 +646,8 @@
// Notify our interested LifecycleListeners
fireLifecycleEvent(AFTER_MEMBERUNREGISTER_EVENT, member);
- } catch (Exception x) {
- log.error(sm.getString("simpleTcpCluster.member.removeFailed"), x);
+ } catch (Exception e) {
+ log.error(sm.getString("simpleTcpCluster.member.removeFailed"), e);
}
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/loader/LocalStrings.properties tomcat11-11.0.15/java/org/apache/catalina/loader/LocalStrings.properties
--- tomcat11-11.0.6/java/org/apache/catalina/loader/LocalStrings.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/loader/LocalStrings.properties 2025-12-02 16:54:08.000000000 +0000
@@ -49,7 +49,7 @@
webappClassLoader.resourceModified=Resource [{0}] has been modified. The last modified time was [{1}] and is now [{2}]
webappClassLoader.restrictedPackage=Security violation, attempt to use restricted class [{0}]
webappClassLoader.stackTrace=The web application [{0}] appears to have started a thread named [{1}] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:{2}
-webappClassLoader.stackTraceRequestThread=The web application [{0}] is still processing a request that has yet to finish. This is very likely to create a memory leak. You can control the time allowed for requests to finish by using the unloadDelay attribute of the standard Context implementation. Stack trace of request processing thread:[{2}]
+webappClassLoader.stackTraceRequestThread=The thread [{1}] of web application [{0}] is still processing a request that has yet to finish. This is very likely to create a memory leak. You can control the time allowed for requests to finish by using the unloadDelay attribute of the standard Context implementation. Stack trace of request processing thread:[{2}]
webappClassLoader.stopThreadFail=Failed to terminate thread named [{0}] for web application [{1}]
webappClassLoader.stopTimerThreadFail=Failed to terminate TimerThread named [{0}] for web application [{1}]
webappClassLoader.stopped=Illegal access: this web application instance has been stopped already. Could not load [{0}]. The following stack trace is thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access.
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/loader/LocalStrings_fr.properties tomcat11-11.0.15/java/org/apache/catalina/loader/LocalStrings_fr.properties
--- tomcat11-11.0.6/java/org/apache/catalina/loader/LocalStrings_fr.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/loader/LocalStrings_fr.properties 2025-12-02 16:54:08.000000000 +0000
@@ -49,7 +49,7 @@
webappClassLoader.resourceModified=La ressource [{0}] a été modifiée, la date de dernière modification était [{1}] et est désormais [{2}]
webappClassLoader.restrictedPackage=Violation de sécurité en essayant d''utiliser à une classe à accès restreint [{0}]
webappClassLoader.stackTrace=L''application web [{0}] semble avoir démarré un thread nommé [{1}] mais ne l''a pas arrêté, ce qui va probablement créer une fuite de mémoire ; la trace du thread est : {2}
-webappClassLoader.stackTraceRequestThread=Une requête de l''application web [{0}] est toujours en cours, ce qui causera certainement une fuite de mémoire, vous pouvez contrôler le temps alloué en utilisant l''attribut unloadDelay de l''implémentation standard de Context ; trace du fil d’exécution de la requête : [{2}]
+webappClassLoader.stackTraceRequestThread=Le thread [{1}] de l''application web [{0}] est toujours en cours, ce qui risque de causer une fuite de mémoire. Vous pouvez contrôler le temps alloué en utilisant l''attribut unloadDelay de l''implémentation standard de Context ; trace de la pile d''exécution de la requête : [{2}]
webappClassLoader.stopThreadFail=Impossible de terminer le thread nommé [{0}] pour l''application [{1}]
webappClassLoader.stopTimerThreadFail=Echec de l''arrêt du TimerThread nommé [{0}] pour l''application web [{1}]
webappClassLoader.stopped=Impossible de charger [{0}], ce chargeur de classes a déjà été arrêté
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/loader/LocalStrings_ja.properties tomcat11-11.0.15/java/org/apache/catalina/loader/LocalStrings_ja.properties
--- tomcat11-11.0.6/java/org/apache/catalina/loader/LocalStrings_ja.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/loader/LocalStrings_ja.properties 2025-12-02 16:54:08.000000000 +0000
@@ -49,7 +49,7 @@
webappClassLoader.resourceModified=リソース [{0}] は変更されています。直前の更新日時は [{1}]、最新の更新日時は [{2}] です。
webappClassLoader.restrictedPackage=セキュリティー違反。制限されたクラス [{0}] を使おうとしました。
webappClassLoader.stackTrace=Webアプリケーション [{0}] は [{1}] という名前のスレッドを開始したようですが、停止に失敗しました。これはメモリリークを引き起こす可能性が非常に高いです。スレッドのスタックトレース: {2}
-webappClassLoader.stackTraceRequestThread=Webアプリケーション[{0}]はまだ完了していないリクエストを処理しています。 これはメモリリークを引き起こす可能性が非常に高いです。 リクエストの終了時間は、StandardContext実装のunloadDelay属性を使用して制御できます。 リクエスト処理スレッドのスタックトレース:[{2}]
+webappClassLoader.stackTraceRequestThread=Webアプリケーション[{0}]のスレッド[{1}]はまだ完了していないリクエストを処理しています。 これはメモリリークを引き起こす可能性が非常に高いです。 リクエストの終了時間は、StandardContext実装のunloadDelay属性を使用して制御できます。 リクエスト処理スレッドのスタックトレース:[{2}]
webappClassLoader.stopThreadFail=Web アプリケーション [{1}] のスレッド [{0}] は終了できません。
webappClassLoader.stopTimerThreadFail=Webアプリケーション [{1}] の [{0}] という名前のTimerThreadを終了できませんでした
webappClassLoader.stopped=不正なアクセス: このWebアプリケーションのインスタンスは既に停止されています Could not load [{0}]. 不正なアクセスを引き起こしたスレッドを終了させ、投げられたエラーによりデバッグ用に次のスタックトレースが生成されましたが,機能に影響はありません
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/loader/LocalStrings_ko.properties tomcat11-11.0.15/java/org/apache/catalina/loader/LocalStrings_ko.properties
--- tomcat11-11.0.6/java/org/apache/catalina/loader/LocalStrings_ko.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/loader/LocalStrings_ko.properties 2025-12-02 16:54:08.000000000 +0000
@@ -49,7 +49,7 @@
webappClassLoader.resourceModified=리소스 [{0}]이(가) 변경된 적이 있습니다. 최종 변경 시간이 [{1}]이었는데, 이제 [{2}](으)로 바뀌었습니다.
webappClassLoader.restrictedPackage=보안 위반 행위: 제한된 클래스 [{0}]을(를) 사용하려 시도했습니다.
webappClassLoader.stackTrace=웹 애플리케이션 [{0}]이(가) [{1}](이)라는 이름의 쓰레드를 시작시킨 것으로 보이지만, 해당 쓰레드를 중지시키지 못했습니다. 이는 메모리 누수를 유발할 가능성이 큽니다. 해당 쓰레드의 스택 트레이스:{2}
-webappClassLoader.stackTraceRequestThread=웹 애플리케이션 [{0}]이(가) 여전히 완료되지 않은 요청을 처리하고 있습니다. 이는 메모리 누수를 유발할 가능성이 높습니다. 표준 컨텍스트 구현의 unloadDelay 속성을 이용하여, 요청 완료 허용 시간을 통제할 수 있습니다. 요청 처리 쓰레드의 스택 트레이스:[{2}]
+webappClassLoader.stackTraceRequestThread=웹 애플리케이션 [{0}]의 쓰레드 [{1}]가 여전히 완료되지 않은 요청을 처리하고 있습니다. 이는 메모리 누수를 유발할 가능성이 높습니다. 표준 컨텍스트 구현의 unloadDelay 속성을 이용하여, 요청 완료 허용 시간을 통제할 수 있습니다. 요청 처리 쓰레드의 스택 트레이스:[{2}]
webappClassLoader.stopThreadFail=웹 애플리케이션 [{1}]을 위한, [{0}](이)라는 이름의 쓰레드를 종료시키지 못했습니다.
webappClassLoader.stopTimerThreadFail=웹 애플리케이션 [{1}]을(를) 위한, [{0}](이)라는 이름의 TimerThread를 종료시키지 못했습니다.
webappClassLoader.stopped=불허되는 접근: 이 웹 애플리케이션 인스턴스는 이미 중지되었습니다. [{0}]을(를) 로드할 수 없습니다. 디버그 목적 및 불허되는 접근을 발생시킨 해당 쓰레드를 종료시키기 위한 시도로서, 다음 스택 트레이스가 생성됩니다.
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/loader/LocalStrings_zh_CN.properties tomcat11-11.0.15/java/org/apache/catalina/loader/LocalStrings_zh_CN.properties
--- tomcat11-11.0.6/java/org/apache/catalina/loader/LocalStrings_zh_CN.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/loader/LocalStrings_zh_CN.properties 2025-12-02 16:54:08.000000000 +0000
@@ -49,7 +49,7 @@
webappClassLoader.resourceModified=资源[{0}]已被修改。上次修改时间是[{1}],现在是[{2}]
webappClassLoader.restrictedPackage=安全冲突,尝试使用受限类[{0}]
webappClassLoader.stackTrace=Web应用程序[{0}]似乎启动了一个名为[{1}]的线程,但未能停止它。这很可能会造成内存泄漏。线程的堆栈跟踪:[{2}]
-webappClassLoader.stackTraceRequestThread=web应用程序[{0}]仍在处理一个尚未完成的请求。这很可能会造成内存泄漏。您可以使用标准上下文实现的unloadDelay属性来控制请求完成所允许的时间。请求处理线程的堆栈跟踪:[{2}]
+webappClassLoader.stackTraceRequestThread=web应用程序[{0}]中的线程[{1}]仍在处理一个尚未完成的请求。这很可能会造成内存泄漏。您可以使用标准上下文实现的unloadDelay属性来控制请求完成所允许的时间。请求处理线程的堆栈跟踪:[{2}]
webappClassLoader.stopThreadFail=为web应用程序[{1}]终止线程[{0}]失败
webappClassLoader.stopTimerThreadFail=无法终止名为[{0}]的TimerThread,web应用程序:[{1}]
webappClassLoader.stopped=非法访问:此Web应用程序实例已停止。无法加载[{0}]。为了调试以及终止导致非法访问的线程,将抛出以下堆栈跟踪。
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/loader/ResourceEntry.java tomcat11-11.0.15/java/org/apache/catalina/loader/ResourceEntry.java
--- tomcat11-11.0.6/java/org/apache/catalina/loader/ResourceEntry.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/loader/ResourceEntry.java 2025-12-02 16:54:08.000000000 +0000
@@ -18,8 +18,6 @@
/**
* Resource entry.
- *
- * @author Remy Maucherat
*/
public class ResourceEntry {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/loader/WebappClassLoaderBase.java tomcat11-11.0.15/java/org/apache/catalina/loader/WebappClassLoaderBase.java
--- tomcat11-11.0.6/java/org/apache/catalina/loader/WebappClassLoaderBase.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/loader/WebappClassLoaderBase.java 2025-12-02 16:54:08.000000000 +0000
@@ -102,9 +102,6 @@
* IMPLEMENTATION NOTE - As of 8.0, this class loader implements {@link InstrumentableClassLoader},
* permitting web application classes to instrument other classes in the same web application. It does not permit
* instrumentation of system or container classes or classes in other web apps.
- *
- * @author Remy Maucherat
- * @author Craig R. McClanahan
*/
public abstract class WebappClassLoaderBase extends URLClassLoader
implements Lifecycle, InstrumentableClassLoader, WebappProperties {
@@ -974,13 +971,13 @@
while ((numRead = stream.read(buf)) >= 0) {
baos.write(buf, 0, numRead);
}
- } catch (IOException e) {
- log.error(sm.getString("webappClassLoader.transformError", name), e);
+ } catch (IOException ioe) {
+ log.error(sm.getString("webappClassLoader.transformError", name), ioe);
return null;
} finally {
try {
stream.close();
- } catch (IOException e) {
+ } catch (IOException ignore) {
// Ignore
}
}
@@ -1008,7 +1005,7 @@
stream = url.openStream();
}
}
- } catch (IOException e) {
+ } catch (IOException ioe) {
// Ignore
}
if (stream != null) {
@@ -1244,9 +1241,8 @@
// It is not permitted to load resources once the web application has
// been stopped.
if (!state.isAvailable()) {
- String msg = sm.getString("webappClassLoader.stopped", resource);
- IllegalStateException ise = new IllegalStateException(msg);
- log.info(msg, ise);
+ IllegalStateException ise = new IllegalStateException(sm.getString("webappClassLoader.stopped", resource));
+ log.info(ise.getMessage(), ise);
throw ise;
}
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/loader/WebappLoader.java tomcat11-11.0.15/java/org/apache/catalina/loader/WebappLoader.java
--- tomcat11-11.0.6/java/org/apache/catalina/loader/WebappLoader.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/loader/WebappLoader.java 2025-12-02 16:54:08.000000000 +0000
@@ -20,9 +20,9 @@
import java.beans.PropertyChangeSupport;
import java.io.File;
import java.lang.reflect.Constructor;
+import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLClassLoader;
-import java.nio.charset.StandardCharsets;
import javax.management.ObjectName;
@@ -41,7 +41,6 @@
import org.apache.tomcat.jakartaee.EESpecProfile;
import org.apache.tomcat.jakartaee.EESpecProfiles;
import org.apache.tomcat.util.ExceptionUtils;
-import org.apache.tomcat.util.buf.UDecoder;
import org.apache.tomcat.util.compat.JreCompat;
import org.apache.tomcat.util.modeler.Registry;
import org.apache.tomcat.util.res.StringManager;
@@ -54,9 +53,6 @@
* This class loader is configured via the Resources children of its Context prior to calling start(). When
* a new class is required, these Resources will be consulted first to locate the class. If it is not present, the
* system class loader will be used instead.
- *
- * @author Craig R. McClanahan
- * @author Remy Maucherat
*/
public class WebappLoader extends LifecycleMBeanBase implements Loader {
@@ -320,11 +316,11 @@
MigrationUtil.addJakartaEETransformer(classLoader, getJakartaConverter());
}
+ classLoader.start();
+
// Configure our repositories
setClassPath();
- classLoader.start();
-
String contextName = context.getName();
if (!contextName.startsWith("/")) {
contextName = "/" + contextName;
@@ -470,14 +466,19 @@
URL[] repositories = ((URLClassLoader) loader).getURLs();
for (URL url : repositories) {
String repository = url.toString();
- if (repository.startsWith("file://")) {
- repository = UDecoder.URLDecode(repository.substring(7), StandardCharsets.UTF_8);
- } else if (repository.startsWith("file:")) {
- repository = UDecoder.URLDecode(repository.substring(5), StandardCharsets.UTF_8);
- } else {
+ if (repository == null) {
continue;
}
- if (repository == null) {
+ if (repository.startsWith("file:")) {
+ // Let the JRE handle all the edge cases for URL to path conversion.
+ try {
+ File f = new File(url.toURI());
+ repository = f.getAbsolutePath();
+ } catch (URISyntaxException | IllegalArgumentException e) {
+ // Can't convert from URL to URI. Treat as non-file URL and skip.
+ continue;
+ }
+ } else {
continue;
}
if (!classpath.isEmpty()) {
@@ -486,8 +487,7 @@
classpath.append(repository);
}
} else if (loader == ClassLoader.getSystemClassLoader()) {
- // From Java 9 the internal class loaders no longer extend
- // URLCLassLoader
+ // From Java 9 the internal class loaders no longer extend URLCLassLoader
String cp = System.getProperty("java.class.path");
if (cp != null && !cp.isEmpty()) {
if (!classpath.isEmpty()) {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/manager/Constants.java tomcat11-11.0.15/java/org/apache/catalina/manager/Constants.java
--- tomcat11-11.0.6/java/org/apache/catalina/manager/Constants.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/manager/Constants.java 2025-12-02 16:54:08.000000000 +0000
@@ -36,6 +36,7 @@
HTML_HEADER_SECTION =
"\n" +
"\n" +
+ "\n" +
"\n";
BODY_HEADER_SECTION =
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/manager/HTMLManagerServlet.java tomcat11-11.0.15/java/org/apache/catalina/manager/HTMLManagerServlet.java
--- tomcat11-11.0.6/java/org/apache/catalina/manager/HTMLManagerServlet.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/manager/HTMLManagerServlet.java 2025-12-02 16:54:08.000000000 +0000
@@ -63,10 +63,6 @@
* However if you use a software that parses the output of ManagerServlet you won't be able to upgrade to
* this Servlet since the output are not in the same format ar from ManagerServlet
*
- * @author Bip Thelin
- * @author Malcolm Edgar
- * @author Glenn L. Nielsen
- *
* @see ManagerServlet
*/
public class HTMLManagerServlet extends ManagerServlet {
@@ -272,6 +268,7 @@
* @param cn Name of the application to be deployed
* @param war URL of the web application archive to be deployed
* @param smClient internationalized strings
+ *
* @return message String
*/
protected String deployInternal(String config, ContextName cn, String war, StringManager smClient) {
@@ -292,6 +289,7 @@
* @param response The response
* @param message a message to display
* @param smClient internationalized strings
+ *
* @throws IOException an IO error occurred
*/
protected void list(HttpServletRequest request, HttpServletResponse response, String message,
@@ -570,7 +568,9 @@
*
* @param cn Name of the application to be restarted
* @param smClient StringManager for the client's locale
+ *
* @return message String
+ *
* @see ManagerServlet#reload(PrintWriter, ContextName, StringManager)
*/
protected String reload(ContextName cn, StringManager smClient) {
@@ -588,7 +588,9 @@
*
* @param cn Name of the application to be undeployed
* @param smClient StringManager for the client's locale
+ *
* @return message String
+ *
* @see ManagerServlet#undeploy(PrintWriter, ContextName, StringManager)
*/
protected String undeploy(ContextName cn, StringManager smClient) {
@@ -607,7 +609,9 @@
* @param cn Name of the application to list session information
* @param idle Expire all sessions with idle time ≥ idle for this context
* @param smClient StringManager for the client's locale
+ *
* @return message String
+ *
* @see ManagerServlet#sessions(PrintWriter, ContextName, int, StringManager)
*/
protected String sessions(ContextName cn, int idle, StringManager smClient) {
@@ -625,7 +629,9 @@
*
* @param cn Name of the application to be started
* @param smClient StringManager for the client's locale
+ *
* @return message String
+ *
* @see ManagerServlet#start(PrintWriter, ContextName, StringManager)
*/
protected String start(ContextName cn, StringManager smClient) {
@@ -643,7 +649,9 @@
*
* @param cn Name of the application to be stopped
* @param smClient StringManager for the client's locale
+ *
* @return message String
+ *
* @see ManagerServlet#stop(PrintWriter, ContextName, StringManager)
*/
protected String stop(ContextName cn, StringManager smClient) {
@@ -660,7 +668,9 @@
* Find potential memory leaks caused by web application reload.
*
* @param smClient StringManager for the client's locale
+ *
* @return message String
+ *
* @see ManagerServlet#findleaks(boolean, PrintWriter, StringManager)
*/
protected String findleaks(StringManager smClient) {
@@ -742,6 +752,7 @@
* @param cn Name of the application from which to expire sessions
* @param req The Servlet request
* @param smClient StringManager for the client's locale
+ *
* @return message string
*/
protected String expireSessions(ContextName cn, HttpServletRequest req, StringManager smClient) {
@@ -764,6 +775,7 @@
* @param req The Servlet request
* @param resp The Servlet response
* @param smClient StringManager for the client's locale
+ *
* @throws ServletException Propagated Servlet error
* @throws IOException An IO error occurred
*/
@@ -849,6 +861,7 @@
* @param req The Servlet request
* @param resp The Servlet response
* @param smClient StringManager for the client's locale
+ *
* @throws ServletException Propagated Servlet error
* @throws IOException An IO error occurred
*/
@@ -898,6 +911,7 @@
* @param cn Name of the application for which the sessions will be listed
* @param sessionId the session id
* @param smClient StringManager for the client's locale
+ *
* @throws ServletException Propagated Servlet error
* @throws IOException An IO error occurred
*/
@@ -920,6 +934,7 @@
* @param cn Name of the application for which sessions are to be invalidated
* @param sessionIds the session ids of the sessions
* @param smClient StringManager for the client's locale
+ *
* @return number of invalidated sessions
*/
protected int invalidateSessions(ContextName cn, String[] sessionIds, StringManager smClient) {
@@ -958,6 +973,7 @@
* @param sessionId the session id
* @param attributeName the attribute name
* @param smClient StringManager for the client's locale
+ *
* @return true if there was an attribute removed, false otherwise
*/
protected boolean removeSessionAttribute(ContextName cn, String sessionId, String attributeName,
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/manager/JMXProxyServlet.java tomcat11-11.0.15/java/org/apache/catalina/manager/JMXProxyServlet.java
--- tomcat11-11.0.6/java/org/apache/catalina/manager/JMXProxyServlet.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/manager/JMXProxyServlet.java 2025-12-02 16:54:08.000000000 +0000
@@ -44,8 +44,6 @@
/**
* This servlet will dump JMX attributes in a simple format and implement proxy services for modeler.
- *
- * @author Costin Manolache
*/
public class JMXProxyServlet extends HttpServlet {
@@ -150,9 +148,9 @@
writer.print(" = ");
writer.println(MBeanDumper.escape(valueStr));
- } catch (Exception ex) {
- writer.println("Error - " + ex.toString());
- ex.printStackTrace(writer);
+ } catch (Exception e) {
+ writer.println("Error - " + e.toString());
+ e.printStackTrace(writer);
}
}
@@ -161,9 +159,9 @@
try {
setAttributeInternal(onameStr, att, val);
writer.println("OK - Attribute set");
- } catch (Exception ex) {
- writer.println("Error - " + ex.toString());
- ex.printStackTrace(writer);
+ } catch (Exception e) {
+ writer.println("Error - " + e.toString());
+ e.printStackTrace(writer);
}
}
@@ -175,9 +173,9 @@
names = mBeanServer.queryNames(new ObjectName(qry), null);
writer.println("OK - Number of results: " + names.size());
writer.println();
- } catch (Exception ex) {
- writer.println("Error - " + ex.toString());
- ex.printStackTrace(writer);
+ } catch (Exception e) {
+ writer.println("Error - " + e.toString());
+ e.printStackTrace(writer);
return;
}
@@ -207,9 +205,9 @@
} else {
writer.println("OK - Operation " + op + " without return value");
}
- } catch (Exception ex) {
- writer.println("Error - " + ex.toString());
- ex.printStackTrace(writer);
+ } catch (Exception e) {
+ writer.println("Error - " + e.toString());
+ e.printStackTrace(writer);
}
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/manager/JspHelper.java tomcat11-11.0.15/java/org/apache/catalina/manager/JspHelper.java
--- tomcat11-11.0.6/java/org/apache/catalina/manager/JspHelper.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/manager/JspHelper.java 2025-12-02 16:54:08.000000000 +0000
@@ -30,8 +30,6 @@
/**
* Helper JavaBean for JSPs, because JSTL 1.1/EL 2.0 is too dumb to do what I need (call methods with parameters), or I
* am too dumb to use it correctly. :)
- *
- * @author Cédrik LIME
*/
public class JspHelper {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/manager/LocalStrings.properties tomcat11-11.0.15/java/org/apache/catalina/manager/LocalStrings.properties
--- tomcat11-11.0.6/java/org/apache/catalina/manager/LocalStrings.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/manager/LocalStrings.properties 2025-12-02 16:54:08.000000000 +0000
@@ -125,7 +125,8 @@
managerServlet.alreadyContext=FAIL - Application already exists at path [{0}]
managerServlet.certsNotAvailable=Certificate information cannot be obtained from this connector at runtime
-managerServlet.copyError=Could not copy configuration file from path [{0}]
+managerServlet.certsNotLoaded=Certificates were not loaded for this connector
+managerServlet.copyFail=FAIL - Unable to copy [{0}] to [{1}], details of the error may be in the server logs
managerServlet.deleteFail=FAIL - Unable to delete [{0}]. The continued presence of this file may cause problems.
managerServlet.deployFailed=FAIL - Failed to deploy application at context path [{0}]
managerServlet.deployed=OK - Deployed application at context path [{0}]
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/manager/LocalStrings_fr.properties tomcat11-11.0.15/java/org/apache/catalina/manager/LocalStrings_fr.properties
--- tomcat11-11.0.6/java/org/apache/catalina/manager/LocalStrings_fr.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/manager/LocalStrings_fr.properties 2025-12-02 16:54:08.000000000 +0000
@@ -123,7 +123,8 @@
managerServlet.alreadyContext=FAIL - l''application existe déjà dans le chemin [{0}]
managerServlet.certsNotAvailable=L'information sur les certificats ne peut pas être obtenu de ce connecteur au cours de son exécution
-managerServlet.copyError=Impossible de copier le fichier de configuration à partir du chemin [{0}]
+managerServlet.certsNotLoaded=Les certificats n'ont pas été chargés pour ce connecteur
+managerServlet.copyFail=FAIL - Impossible de copier [{0}] vers [{1}], les détails de l''erreur peuvent se trouver dans les logs du serveur
managerServlet.deleteFail=FAIL - Impossible de supprimer [{0}], ce qui pourrait causer des problèmes
managerServlet.deployFailed=FAIL - Echec au déploiement de l''application pour le chemin de contexte [{0}]
managerServlet.deployed=OK - Application déployée pour le chemin de contexte [{0}]
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/manager/LocalStrings_ja.properties tomcat11-11.0.15/java/org/apache/catalina/manager/LocalStrings_ja.properties
--- tomcat11-11.0.6/java/org/apache/catalina/manager/LocalStrings_ja.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/manager/LocalStrings_ja.properties 2025-12-02 16:54:08.000000000 +0000
@@ -125,7 +125,8 @@
managerServlet.alreadyContext=FAIL - アプリケーションは、既にパス [{0}] に存在します
managerServlet.certsNotAvailable=実行時にこのコネクタから証明書情報を取得できません。
-managerServlet.copyError=パス [{0}] から設定ファイルをコピーできません
+managerServlet.certsNotLoaded=このコネクタの証明書は読み込まれませんでした
+managerServlet.copyFail=FAIL - [{0}] を [{1}] にコピーできません。エラーの詳細はサーバーログに記載されている可能性があります
managerServlet.deleteFail=FAIL - [{0}]を削除できません。 このファイルが継続して存在すると、問題が発生する可能性があります。
managerServlet.deployFailed=FAIL - コンテキストパス [{0}] にアプリケーションを配備できません。
managerServlet.deployed=OK - コンテキストパス [{0}] でアプリケーションを配備しました
@@ -180,7 +181,7 @@
managerServlet.sessions=OK - コンテキストパス [{0}] のアプリケーションのセッション情報です
managerServlet.sessiontimeout=[{0}]分: [{1}]セッション
managerServlet.sessiontimeout.expired=[{0}]分: expired [{1}]セッション
-managerServlet.sessiontimeout.unlimited=unlimited 分: [{0}]セッション
+managerServlet.sessiontimeout.unlimited=無制限の時間: [{0}] セッション
managerServlet.sslConnectorCerts=OK - コネクタ/証明書チェーンの情報
managerServlet.sslConnectorCiphers=OK - Connector/ SSL暗号情報
managerServlet.sslConnectorTrustedCerts=OK - コネクタ/信頼された証明書情報
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/manager/LocalStrings_ko.properties tomcat11-11.0.15/java/org/apache/catalina/manager/LocalStrings_ko.properties
--- tomcat11-11.0.6/java/org/apache/catalina/manager/LocalStrings_ko.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/manager/LocalStrings_ko.properties 2025-12-02 16:54:08.000000000 +0000
@@ -124,7 +124,6 @@
managerServlet.alreadyContext=실패 - 애플리케이션이 이미 경로 [{0}]에 존재합니다.
managerServlet.certsNotAvailable=이 Connector로부터, 인증서 정보를 런타임에 구할 수 없습니다.
-managerServlet.copyError=경로 [{0}](으)로부터 설정 파일을 복사할 수 없었습니다.
managerServlet.deleteFail=실패 - [{0}]을(를) 삭제할 수 없습니다. 이 파일이 계속해서 존재하면 문제들을 일으킬 수 있습니다.
managerServlet.deployFailed=실패 - 컨텍스트 경로 [{0}]에, 애플리케이션을 배치하지 못했습니다.
managerServlet.deployed=OK - 컨텍스트 경로 [{0}]에 애플리케이션을 배치했습니다.
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/manager/LocalStrings_pt_BR.properties tomcat11-11.0.15/java/org/apache/catalina/manager/LocalStrings_pt_BR.properties
--- tomcat11-11.0.6/java/org/apache/catalina/manager/LocalStrings_pt_BR.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/manager/LocalStrings_pt_BR.properties 2025-12-02 16:54:08.000000000 +0000
@@ -20,7 +20,6 @@
htmlManagerServlet.appsSessions=Sessões
htmlManagerServlet.serverIPAddress=Endereço IP
-managerServlet.copyError=Não foi possível copiar o arquivo de configuração do caminho [{0}]
managerServlet.deployed=OK - Instalada aplicação no path de contexto [{0}]
managerServlet.mkdirFail=FALHA - Incapaz de criar o diretório [{0}]
-managerServlet.resourcesAll=Recursos de todos os tipos, listados.
+managerServlet.resourcesAll=OK - Recursos de todos os tipos, listados.
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/manager/LocalStrings_ru.properties tomcat11-11.0.15/java/org/apache/catalina/manager/LocalStrings_ru.properties
--- tomcat11-11.0.6/java/org/apache/catalina/manager/LocalStrings_ru.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/manager/LocalStrings_ru.properties 2025-12-02 16:54:08.000000000 +0000
@@ -53,7 +53,7 @@
htmlManagerServlet.connectorStateThreadCount=Текущее число потоков:
htmlManagerServlet.deployButton=Развернуть
htmlManagerServlet.deployConfig=Путь XML файла конфигурации контекста:
-htmlManagerServlet.deployPath=Путь:
+htmlManagerServlet.deployPath=Путь к контексту:
htmlManagerServlet.deployServer=Развернуть серверный WAR файл
htmlManagerServlet.deployTitle=Развернуть
htmlManagerServlet.deployUpload=WAR файл для развёртывания
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/manager/LocalStrings_zh_CN.properties tomcat11-11.0.15/java/org/apache/catalina/manager/LocalStrings_zh_CN.properties
--- tomcat11-11.0.6/java/org/apache/catalina/manager/LocalStrings_zh_CN.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/manager/LocalStrings_zh_CN.properties 2025-12-02 16:54:08.000000000 +0000
@@ -123,7 +123,6 @@
managerServlet.alreadyContext=失败 - 应用程序已存在于路径 [{0}]
managerServlet.certsNotAvailable=在运行期,无法从连接器中获取认证信息
-managerServlet.copyError=无法从路径[{0}]拷贝配置文件
managerServlet.deleteFail=失败 - 不能删除[{0}]。这个文件一直存在会出现问题。
managerServlet.deployFailed=FAIL - 在上下文路径[{0}]下部署应用失败
managerServlet.deployed=OK - 以应用path [{0}] 部署应用
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/manager/ManagerServlet.java tomcat11-11.0.15/java/org/apache/catalina/manager/ManagerServlet.java
--- tomcat11-11.0.6/java/org/apache/catalina/manager/ManagerServlet.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/manager/ManagerServlet.java 2025-12-02 16:54:08.000000000 +0000
@@ -146,9 +146,6 @@
*
debug - The debugging detail level that controls the amount of information that is logged by this servlet.
* Default is zero.
*
- *
- * @author Craig R. McClanahan
- * @author Remy Maucherat
*/
public class ManagerServlet extends HttpServlet implements ContainerServlet {
@@ -375,8 +372,7 @@
}
String config = request.getParameter("config");
String tag = request.getParameter("tag");
- boolean update = request.getParameter("update") != null
- && request.getParameter("update").equals("true");
+ boolean update = request.getParameter("update") != null && request.getParameter("update").equals("true");
// Prepare our output writer to generate the response message
response.setContentType("text/plain;charset=" + Constants.CHARSET);
@@ -736,7 +732,9 @@
return;
}
if (!ExpandWar.copy(new File(config), new File(configBase, baseName + ".xml"))) {
- throw new Exception(sm.getString("managerServlet.copyError", config));
+ writer.println(smClient.getString("managerServlet.copyFail", new File(config),
+ new File(configBase, baseName + ".xml")));
+ return;
}
}
// Upload WAR
@@ -754,7 +752,10 @@
}
if (tag != null) {
// Copy WAR to the host's appBase
- ExpandWar.copy(uploadedWar, deployedWar);
+ if (!ExpandWar.copy(uploadedWar, deployedWar)) {
+ writer.println(smClient.getString("managerServlet.copyFail", uploadedWar, deployedWar));
+ return;
+ }
}
} finally {
removeServiced(name);
@@ -808,7 +809,10 @@
writer.println(smClient.getString("managerServlet.deleteFail", deployedWar));
return;
}
- ExpandWar.copy(localWar, deployedWar);
+ if (!ExpandWar.copy(localWar, deployedWar)) {
+ writer.println(smClient.getString("managerServlet.copyFail", localWar, deployedWar));
+ return;
+ }
} finally {
removeServiced(name);
}
@@ -902,7 +906,11 @@
writer.println(smClient.getString("managerServlet.deleteFail", localConfigFile));
return;
}
- ExpandWar.copy(configFile, localConfigFile);
+ if (!ExpandWar.copy(configFile, localConfigFile)) {
+ writer.println(
+ smClient.getString("managerServlet.copyFail", configFile, localConfigFile));
+ return;
+ }
}
}
if (war != null) {
@@ -922,7 +930,10 @@
writer.println(smClient.getString("managerServlet.deleteFail", localWarFile));
return;
}
- ExpandWar.copy(warFile, localWarFile);
+ if (!ExpandWar.copy(warFile, localWarFile)) {
+ writer.println(smClient.getString("managerServlet.copyFail", warFile, localWarFile));
+ return;
+ }
}
}
} finally {
@@ -1491,11 +1502,11 @@
try (ServletInputStream istream = request.getInputStream(); OutputStream ostream = new FileOutputStream(war)) {
IOTools.flow(istream, ostream);
- } catch (IOException e) {
+ } catch (IOException ioe) {
if (war.exists() && !war.delete()) {
writer.println(smClient.getString("managerServlet.deleteFail", war));
}
- throw e;
+ throw ioe;
}
}
@@ -1557,12 +1568,16 @@
if (alias == null) {
alias = SSLUtilBase.DEFAULT_KEY_ALIAS;
}
- X509Certificate[] certs = sslContext.getCertificateChain(alias);
- if (certs == null) {
- certList.add(smClient.getString("managerServlet.certsNotAvailable"));
+ if (sslContext == null) {
+ certList.add(smClient.getString("managerServlet.certsNotLoaded"));
} else {
- for (Certificate cert : certs) {
- certList.add(cert.toString());
+ X509Certificate[] certs = sslContext.getCertificateChain(alias);
+ if (certs == null) {
+ certList.add(smClient.getString("managerServlet.certsNotAvailable"));
+ } else {
+ for (Certificate cert : certs) {
+ certList.add(cert.toString());
+ }
}
}
result.put(name, certList);
@@ -1590,14 +1605,18 @@
String name = connector.toString() + "-" + sslHostConfig.getHostName();
List certList = new ArrayList<>();
SSLContext sslContext = sslHostConfig.getCertificates().iterator().next().getSslContext();
- X509Certificate[] certs = sslContext.getAcceptedIssuers();
- if (certs == null) {
- certList.add(smClient.getString("managerServlet.certsNotAvailable"));
- } else if (certs.length == 0) {
- certList.add(smClient.getString("managerServlet.trustedCertsNotConfigured"));
+ if (sslContext == null) {
+ certList.add(smClient.getString("managerServlet.certsNotLoaded"));
} else {
- for (Certificate cert : certs) {
- certList.add(cert.toString());
+ X509Certificate[] certs = sslContext.getAcceptedIssuers();
+ if (certs == null) {
+ certList.add(smClient.getString("managerServlet.certsNotAvailable"));
+ } else if (certs.length == 0) {
+ certList.add(smClient.getString("managerServlet.trustedCertsNotConfigured"));
+ } else {
+ for (Certificate cert : certs) {
+ certList.add(cert.toString());
+ }
}
}
result.put(name, certList);
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/manager/StatusManagerServlet.java tomcat11-11.0.15/java/org/apache/catalina/manager/StatusManagerServlet.java
--- tomcat11-11.0.6/java/org/apache/catalina/manager/StatusManagerServlet.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/manager/StatusManagerServlet.java 2025-12-02 16:54:08.000000000 +0000
@@ -45,8 +45,6 @@
/**
* This servlet will display a complete status of the HTTP/1.1 connector.
- *
- * @author Remy Maucherat
*/
public class StatusManagerServlet extends HttpServlet implements NotificationListener {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/manager/StatusTransformer.java tomcat11-11.0.15/java/org/apache/catalina/manager/StatusTransformer.java
--- tomcat11-11.0.6/java/org/apache/catalina/manager/StatusTransformer.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/manager/StatusTransformer.java 2025-12-02 16:54:08.000000000 +0000
@@ -40,8 +40,6 @@
/**
* This is a refactoring of the servlet to externalize the output into a simple class. Although we could use XSLT, that
* is unnecessarily complex.
- *
- * @author Peter Lin
*/
public class StatusTransformer {
@@ -805,6 +803,8 @@
writer.print("");
writer.print("
");
+ writer.print("State: ");
+ writer.print(mBeanServer.getAttribute(objectName, "stateName"));
Object startTime = mBeanServer.getAttribute(objectName, "startTime");
writer.print(" Start time: " + new Date(((Long) startTime).longValue()));
writer.print(" Startup time: ");
@@ -831,6 +831,8 @@
} else if (mode == 2) {
indent(writer, 2).append('{').println();
appendJSonValue(indent(writer, 3), "name", JSONFilter.escape(JSONFilter.escape(name))).append(',');
+ appendJSonValue(writer, "state", mBeanServer.getAttribute(objectName, "stateName"));
+ writer.append(',');
appendJSonValue(writer, "startTime",
new Date(((Long) mBeanServer.getAttribute(objectName, "startTime")).longValue()).toString())
.append(',');
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/manager/host/HTMLHostManagerServlet.java tomcat11-11.0.15/java/org/apache/catalina/manager/host/HTMLHostManagerServlet.java
--- tomcat11-11.0.6/java/org/apache/catalina/manager/host/HTMLHostManagerServlet.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/manager/host/HTMLHostManagerServlet.java 2025-12-02 16:54:08.000000000 +0000
@@ -48,11 +48,6 @@
* However if you use a software that parses the output of HostManagerServlet you won't be able to upgrade
* to this Servlet since the output are not in the same format as from HostManagerServlet
*
- * @author Bip Thelin
- * @author Malcolm Edgar
- * @author Glenn L. Nielsen
- * @author Peter Rossbach
- *
* @see org.apache.catalina.manager.ManagerServlet
*/
public class HTMLHostManagerServlet extends HostManagerServlet {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/manager/host/HostManagerServlet.java tomcat11-11.0.15/java/org/apache/catalina/manager/host/HostManagerServlet.java
--- tomcat11-11.0.6/java/org/apache/catalina/manager/host/HostManagerServlet.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/manager/host/HostManagerServlet.java 2025-12-02 16:54:08.000000000 +0000
@@ -77,9 +77,6 @@
*
debug - The debugging detail level that controls the amount of information that is logged by this servlet.
* Default is zero.
*
- *
- * @author Craig R. McClanahan
- * @author Remy Maucherat
*/
public class HostManagerServlet extends HttpServlet implements ContainerServlet {
@@ -333,7 +330,7 @@
}
try {
appBaseFile = file.getCanonicalFile();
- } catch (IOException e) {
+ } catch (IOException ioe) {
appBaseFile = file;
}
if (!appBaseFile.mkdirs() && !appBaseFile.isDirectory()) {
@@ -357,7 +354,7 @@
}
Path dest = new File(configBaseFile, "manager.xml").toPath();
Files.copy(is, dest);
- } catch (IOException e) {
+ } catch (IOException ioe) {
writer.println(smClient.getString("hostManagerServlet.managerXml"));
return;
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/manager/host/LocalStrings_ja.properties tomcat11-11.0.15/java/org/apache/catalina/manager/host/LocalStrings_ja.properties
--- tomcat11-11.0.6/java/org/apache/catalina/manager/host/LocalStrings_ja.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/manager/host/LocalStrings_ja.properties 2025-12-02 16:54:08.000000000 +0000
@@ -18,7 +18,7 @@
hostManagerServlet.add=add: ホスト [{0}] を追加
hostManagerServlet.addFailed=FAIL - ホスト [{0}] を追加できません。
-hostManagerServlet.addSuccess=OK - ホスト [{0}] を追加しました
+hostManagerServlet.addSuccess=OK - ホスト [{0}] を追加しました
hostManagerServlet.alreadyHost=FAIL - ホスト名[{0}]のホストが既に存在します
hostManagerServlet.alreadyStarted=FAIL - ホスト [{0}] はすでに開始しています。
hostManagerServlet.alreadyStopped=FAIL - Host [{0}] はすでに停止しています。
@@ -42,7 +42,7 @@
hostManagerServlet.postCommand=FAIL - コマンド [{0}] をGETリクエストで使用しようとしましたが、POSTが必要です
hostManagerServlet.remove=remove: ホスト [{0}] を削除します。
hostManagerServlet.removeFailed=FAIL - Host [{0}] を削除できません。
-hostManagerServlet.removeSuccess=OK - ホスト [{0}] を削除しました
+hostManagerServlet.removeSuccess=OK - ホスト [{0}] を削除しました
hostManagerServlet.start=開始:名前[{0}]のホストを起動しています
hostManagerServlet.startFailed=FAIL - ホスト [{0}] の起動に失敗しました
hostManagerServlet.started=OK - ホスト [{0}] を開始しました
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/manager/host/LocalStrings_ru.properties tomcat11-11.0.15/java/org/apache/catalina/manager/host/LocalStrings_ru.properties
--- tomcat11-11.0.6/java/org/apache/catalina/manager/host/LocalStrings_ru.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/manager/host/LocalStrings_ru.properties 2025-12-02 16:54:08.000000000 +0000
@@ -39,13 +39,13 @@
hostManagerServlet.persistFailed=Ошибка - Не удалось сохранить конфигурацию
hostManagerServlet.persisted=OK - Конфигурация сохранена
hostManagerServlet.postCommand=Ошибка - Команда [{0}] была подана при помощи запроса GET, но требуется POST
-hostManagerServlet.remove=remove: Удаление сервера [{0}]
+hostManagerServlet.remove=remove: Удаление хоста [{0}]
hostManagerServlet.removeFailed=Ошибка - Не удалось удалить сервер [{0}]
hostManagerServlet.removeSuccess=OK - Сервер удалён [{0}]
-hostManagerServlet.start=start: Запуск сервера с именем [{0}]
+hostManagerServlet.start=start: Запуск хоста с именем [{0}]
hostManagerServlet.startFailed=Ошибка - Не удалось запустить сервер [{0}]
hostManagerServlet.started=OK - Сервер [{0}] запущен
-hostManagerServlet.stop=stop: Остановка сервера с именем [{0}]
+hostManagerServlet.stop=stop: Остановка хоста с именем [{0}]
hostManagerServlet.stopFailed=Ошибка - Не удалось остановить сервер [{0}]
hostManagerServlet.stopped=OK - Сервер [{0}] остановлен
hostManagerServlet.unknownCommand=Ошибка - Неизвестная команда [{0}]
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/manager/host/LocalStrings_zh_CN.properties tomcat11-11.0.15/java/org/apache/catalina/manager/host/LocalStrings_zh_CN.properties
--- tomcat11-11.0.6/java/org/apache/catalina/manager/host/LocalStrings_zh_CN.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/manager/host/LocalStrings_zh_CN.properties 2025-12-02 16:54:08.000000000 +0000
@@ -18,7 +18,7 @@
hostManagerServlet.add=添加:添加主机[{0}]
hostManagerServlet.addFailed=失败 - 添加主机 [{0}] 失败
-hostManagerServlet.addSuccess=确定-添加主机[{0}]
+hostManagerServlet.addSuccess=OK - 确定-添加主机[{0}]
hostManagerServlet.alreadyHost=失败 - 主机名称[{0}]已经存在
hostManagerServlet.alreadyStarted=失败 - Host[{0}]已经启动。
hostManagerServlet.alreadyStopped=失败 - 主机[{0}]已经停止
@@ -42,12 +42,12 @@
hostManagerServlet.postCommand=失败 - 尝试通过GET请求使用命令[{0}],但是需要使用POST请求
hostManagerServlet.remove=移除:正在移除主机 [{0}]
hostManagerServlet.removeFailed=失败 - 无法移除主机 [{0}]
-hostManagerServlet.removeSuccess=确定-已删除主机[{0}]
+hostManagerServlet.removeSuccess=OK - 已删除主机[{0}]
hostManagerServlet.start=启动:启动主机[{0}]
hostManagerServlet.startFailed=失败 - 无法启动主机 [{0}]
hostManagerServlet.started=OK - 主机 [{0}] 已启动
hostManagerServlet.stop=停止:停止主机[{0}]
-hostManagerServlet.stopFailed=失败 - 无法停止主机 [{0}]
+hostManagerServlet.stopFailed=OK - 无法停止主机 [{0}]
hostManagerServlet.stopped=OK - 主机 [{0}] 已停止
hostManagerServlet.unknownCommand=失败 - 未知命令 [{0}]
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/manager/util/SessionUtils.java tomcat11-11.0.15/java/org/apache/catalina/manager/util/SessionUtils.java
--- tomcat11-11.0.6/java/org/apache/catalina/manager/util/SessionUtils.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/manager/util/SessionUtils.java 2025-12-02 16:54:08.000000000 +0000
@@ -32,8 +32,6 @@
/**
* Utility methods on HttpSessions.
- *
- * @author Cédrik LIME
*/
public class SessionUtils {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/mapper/LocalStrings_ru.properties tomcat11-11.0.15/java/org/apache/catalina/mapper/LocalStrings_ru.properties
--- tomcat11-11.0.6/java/org/apache/catalina/mapper/LocalStrings_ru.properties 1970-01-01 00:00:00.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/mapper/LocalStrings_ru.properties 2025-12-02 16:54:08.000000000 +0000
@@ -0,0 +1,19 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Do not edit this file directly.
+# To edit translations see: https://tomcat.apache.org/getinvolved.html#Translations
+
+mapper.addHostAlias.success=Зарегистрирован псевдоним [{0}] для хоста [{1}]
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/mapper/Mapper.java tomcat11-11.0.15/java/org/apache/catalina/mapper/Mapper.java
--- tomcat11-11.0.6/java/org/apache/catalina/mapper/Mapper.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/mapper/Mapper.java 2025-12-02 16:54:08.000000000 +0000
@@ -41,8 +41,6 @@
/**
* Mapper, which implements the servlet API mapping rules (which are derived from the HTTP rules).
- *
- * @author Remy Maucherat
*/
public final class Mapper {
@@ -451,7 +449,7 @@
* @param resourceOnly true if this wrapper always expects a physical resource to be present (such as a JSP)
*/
private void addWrapper(ContextVersion context, String path, Wrapper wrapper, boolean jspWildCard,
- boolean resourceOnly) {
+ boolean resourceOnly) {
synchronized (context) {
if (path.endsWith("/*")) {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/mapper/MapperListener.java tomcat11-11.0.15/java/org/apache/catalina/mapper/MapperListener.java
--- tomcat11-11.0.6/java/org/apache/catalina/mapper/MapperListener.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/mapper/MapperListener.java 2025-12-02 16:54:08.000000000 +0000
@@ -40,9 +40,6 @@
/**
* Mapper listener.
- *
- * @author Remy Maucherat
- * @author Costin Manolache
*/
public class MapperListener extends LifecycleMBeanBase implements ContainerListener, LifecycleListener {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/mapper/MappingData.java tomcat11-11.0.15/java/org/apache/catalina/mapper/MappingData.java
--- tomcat11-11.0.6/java/org/apache/catalina/mapper/MappingData.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/mapper/MappingData.java 2025-12-02 16:54:08.000000000 +0000
@@ -25,8 +25,6 @@
/**
* Mapping data.
- *
- * @author Remy Maucherat
*/
public class MappingData {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/mapper/WrapperMappingInfo.java tomcat11-11.0.15/java/org/apache/catalina/mapper/WrapperMappingInfo.java
--- tomcat11-11.0.6/java/org/apache/catalina/mapper/WrapperMappingInfo.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/mapper/WrapperMappingInfo.java 2025-12-02 16:54:08.000000000 +0000
@@ -21,13 +21,12 @@
/**
* Encapsulates information used to register a Wrapper mapping.
*
- * @param mapping The URL pattern
- * @param wrapper The wrapper for the Servlet
- * @param jspWildCard Is this a mapping for JSP files?
- * @param resourceOnly Is this a resource only mapping?
+ * @param mapping The URL pattern
+ * @param wrapper The wrapper for the Servlet
+ * @param jspWildCard Is this a mapping for JSP files?
+ * @param resourceOnly Is this a resource only mapping?
*/
-public record WrapperMappingInfo(String mapping, Wrapper wrapper, boolean jspWildCard,
- boolean resourceOnly) {
+public record WrapperMappingInfo(String mapping, Wrapper wrapper, boolean jspWildCard, boolean resourceOnly) {
public String getMapping() {
return mapping;
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/mbeans/ClassNameMBean.java tomcat11-11.0.15/java/org/apache/catalina/mbeans/ClassNameMBean.java
--- tomcat11-11.0.6/java/org/apache/catalina/mbeans/ClassNameMBean.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/mbeans/ClassNameMBean.java 2025-12-02 16:54:08.000000000 +0000
@@ -26,8 +26,6 @@
*
*
* @param The type that this bean represents.
- *
- * @author Craig R. McClanahan
*/
public class ClassNameMBean extends BaseCatalinaMBean {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/mbeans/ConnectorMBean.java tomcat11-11.0.15/java/org/apache/catalina/mbeans/ConnectorMBean.java
--- tomcat11-11.0.6/java/org/apache/catalina/mbeans/ConnectorMBean.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/mbeans/ConnectorMBean.java 2025-12-02 16:54:08.000000000 +0000
@@ -27,12 +27,8 @@
import org.apache.tomcat.util.res.StringManager;
/**
- *
* A ModelMBean implementation for the org.apache.coyote.tomcat5.CoyoteConnector
* component.
- *
* A ModelMBean implementation for the org.apache.catalina.Role component.
*
- *
- * @author Craig R. McClanahan
*/
public class RoleMBean extends BaseModelMBean {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/mbeans/SparseUserDatabaseMBean.java tomcat11-11.0.15/java/org/apache/catalina/mbeans/SparseUserDatabaseMBean.java
--- tomcat11-11.0.6/java/org/apache/catalina/mbeans/SparseUserDatabaseMBean.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/mbeans/SparseUserDatabaseMBean.java 2025-12-02 16:54:08.000000000 +0000
@@ -40,8 +40,6 @@
* register the corresponding user and make it available for management). All the MBeans created for users, groups and
* roles are then discarded when save is invoked.
*
- *
- * @author Craig R. McClanahan
*/
public class SparseUserDatabaseMBean extends BaseModelMBean {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/mbeans/UserMBean.java tomcat11-11.0.15/java/org/apache/catalina/mbeans/UserMBean.java
--- tomcat11-11.0.6/java/org/apache/catalina/mbeans/UserMBean.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/mbeans/UserMBean.java 2025-12-02 16:54:08.000000000 +0000
@@ -35,8 +35,6 @@
*
* A ModelMBean implementation for the org.apache.catalina.User component.
*
- *
- * @author Craig R. McClanahan
*/
public class UserMBean extends BaseModelMBean {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/realm/CombinedRealm.java tomcat11-11.0.15/java/org/apache/catalina/realm/CombinedRealm.java
--- tomcat11-11.0.6/java/org/apache/catalina/realm/CombinedRealm.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/realm/CombinedRealm.java 2025-12-02 16:54:08.000000000 +0000
@@ -359,7 +359,7 @@
// Stack trace will show where this was called from
UnsupportedOperationException uoe =
new UnsupportedOperationException(sm.getString("combinedRealm.getPassword"));
- log.error(sm.getString("combinedRealm.unexpectedMethod"), uoe);
+ log.error(uoe.getMessage(), uoe);
throw uoe;
}
@@ -369,7 +369,7 @@
// Stack trace will show where this was called from
UnsupportedOperationException uoe =
new UnsupportedOperationException(sm.getString("combinedRealm.getPrincipal"));
- log.error(sm.getString("combinedRealm.unexpectedMethod"), uoe);
+ log.error(uoe.getMessage(), uoe);
throw uoe;
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/realm/DataSourceRealm.java tomcat11-11.0.15/java/org/apache/catalina/realm/DataSourceRealm.java
--- tomcat11-11.0.6/java/org/apache/catalina/realm/DataSourceRealm.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/realm/DataSourceRealm.java 2025-12-02 16:54:08.000000000 +0000
@@ -34,11 +34,6 @@
/**
* Implementation of Realm that works with any JDBC JNDI DataSource. See the Realm How-To for more details on how
* to set up the database and for configuration options.
- *
- * @author Glenn L. Nielsen
- * @author Craig R. McClanahan
- * @author Carson McDonald
- * @author Ignacio Ortega
*/
public class DataSourceRealm extends RealmBase {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/realm/GenericPrincipal.java tomcat11-11.0.15/java/org/apache/catalina/realm/GenericPrincipal.java
--- tomcat11-11.0.6/java/org/apache/catalina/realm/GenericPrincipal.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/realm/GenericPrincipal.java 2025-12-02 16:54:08.000000000 +0000
@@ -34,8 +34,6 @@
/**
* Generic implementation of java.security.Principal that is available for use by Realm
* implementations.
- *
- * @author Craig R. McClanahan
*/
public class GenericPrincipal implements TomcatPrincipal, Serializable {
@@ -252,24 +250,24 @@
}
private record SerializablePrincipal(String name, String[] roles, Principal principal,
- Map attributes) implements Serializable {
- @Serial
- private static final long serialVersionUID = 1L;
-
- private SerializablePrincipal(String name, String[] roles, Principal principal, Map attributes) {
- this.name = name;
- this.roles = roles;
- if (principal instanceof Serializable) {
- this.principal = principal;
- } else {
- this.principal = null;
- }
- this.attributes = attributes;
+ Map attributes) implements Serializable {
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ private SerializablePrincipal(String name, String[] roles, Principal principal, Map attributes) {
+ this.name = name;
+ this.roles = roles;
+ if (principal instanceof Serializable) {
+ this.principal = principal;
+ } else {
+ this.principal = null;
}
+ this.attributes = attributes;
+ }
- @Serial
- private Object readResolve() {
- return new GenericPrincipal(name, Arrays.asList(roles), principal, null, null, attributes);
- }
+ @Serial
+ private Object readResolve() {
+ return new GenericPrincipal(name, Arrays.asList(roles), principal, null, null, attributes);
}
+ }
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/realm/JAASCallbackHandler.java tomcat11-11.0.15/java/org/apache/catalina/realm/JAASCallbackHandler.java
--- tomcat11-11.0.6/java/org/apache/catalina/realm/JAASCallbackHandler.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/realm/JAASCallbackHandler.java 2025-12-02 16:54:08.000000000 +0000
@@ -29,22 +29,15 @@
import org.apache.tomcat.util.res.StringManager;
/**
- *
* Implementation of the JAAS CallbackHandler interface, used to negotiate delivery of the username and
* credentials that were specified to our constructor. No interaction with the user is required (or possible).
- *
*
* This CallbackHandler will pre-digest the supplied password, if required by the
* <Realm> element in server.xml.
- *
*
* At present, JAASCallbackHandler knows how to handle callbacks of type
* javax.security.auth.callback.NameCallback and
* javax.security.auth.callback.PasswordCallback.
- *
- *
- * @author Craig R. McClanahan
- * @author Andrew R. Jaquith
*/
public class JAASCallbackHandler implements CallbackHandler {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/realm/JAASMemoryLoginModule.java tomcat11-11.0.15/java/org/apache/catalina/realm/JAASMemoryLoginModule.java
--- tomcat11-11.0.6/java/org/apache/catalina/realm/JAASMemoryLoginModule.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/realm/JAASMemoryLoginModule.java 2025-12-02 16:54:08.000000000 +0000
@@ -66,8 +66,6 @@
* requirements of the GenericPrincipal constructor. It does not actually perform the functionality
* required of a Realm implementation.
*
- *
- * @author Craig R. McClanahan
*/
public class JAASMemoryLoginModule extends MemoryRealm implements LoginModule {
// We need to extend MemoryRealm to avoid class cast
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/realm/JAASRealm.java tomcat11-11.0.15/java/org/apache/catalina/realm/JAASRealm.java
--- tomcat11-11.0.6/java/org/apache/catalina/realm/JAASRealm.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/realm/JAASRealm.java 2025-12-02 16:54:08.000000000 +0000
@@ -115,9 +115,6 @@
* JAASCallbackHandler will digest the password prior to passing it back to the
* LoginModule
*
- *
- * @author Craig R. McClanahan
- * @author Yoav Shapira
*/
public class JAASRealm extends RealmBase {
@@ -360,9 +357,9 @@
try {
Configuration config = getConfig();
loginContext = new LoginContext(appName, null, callbackHandler, config);
- } catch (Throwable e) {
- ExceptionUtils.handleThrowable(e);
- log.error(sm.getString("jaasRealm.unexpectedError"), e);
+ } catch (Throwable t) {
+ ExceptionUtils.handleThrowable(t);
+ log.error(sm.getString("jaasRealm.unexpectedError"), t);
// There is configuration issue with JAAS so mark the realm as
// unavailable
invocationSuccess = false;
@@ -395,7 +392,7 @@
}
} catch (AccountExpiredException e) {
if (log.isDebugEnabled()) {
- log.debug(sm.getString("jaasRealm.accountExpired", username));
+ log.debug(sm.getString("jaasRealm.accountExpired", username), e);
}
// JAAS checked LoginExceptions are successful authentication
// invocations so mark JAAS realm as available
@@ -403,7 +400,7 @@
return null;
} catch (CredentialExpiredException e) {
if (log.isDebugEnabled()) {
- log.debug(sm.getString("jaasRealm.credentialExpired", username));
+ log.debug(sm.getString("jaasRealm.credentialExpired", username), e);
}
// JAAS checked LoginExceptions are successful authentication
// invocations so mark JAAS realm as available
@@ -411,7 +408,7 @@
return null;
} catch (FailedLoginException e) {
if (log.isDebugEnabled()) {
- log.debug(sm.getString("jaasRealm.failedLogin", username));
+ log.debug(sm.getString("jaasRealm.failedLogin", username), e);
}
// JAAS checked LoginExceptions are successful authentication
// invocations so mark JAAS realm as available
@@ -423,9 +420,9 @@
// invocations so mark JAAS realm as available
invocationSuccess = true;
return null;
- } catch (Throwable e) {
- ExceptionUtils.handleThrowable(e);
- log.error(sm.getString("jaasRealm.unexpectedError"), e);
+ } catch (Throwable t) {
+ ExceptionUtils.handleThrowable(t);
+ log.error(sm.getString("jaasRealm.unexpectedError"), t);
// JAAS throws exception different from LoginException so mark the
// realm as unavailable
invocationSuccess = false;
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/realm/JNDIRealm.java tomcat11-11.0.15/java/org/apache/catalina/realm/JNDIRealm.java
--- tomcat11-11.0.6/java/org/apache/catalina/realm/JNDIRealm.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/realm/JNDIRealm.java 2025-12-02 16:54:08.000000000 +0000
@@ -135,9 +135,6 @@
* descriptor allows applications to refer to roles programmatically by names other than those used in the directory
* server itself.
*
- *
- * @author John Holman
- * @author Craig R. McClanahan
*/
public class JNDIRealm extends RealmBase {
@@ -1158,9 +1155,9 @@
} catch (NullPointerException | NamingException e) {
/*
* BZ 61313 NamingException may or may not indicate an error that is recoverable via fail over.
- * Therefore, a decision needs to be made whether to fail over or not. Generally, attempting to fail over
- * when it is not appropriate is better than not failing over when it is appropriate so the code always
- * attempts to fail over for NamingExceptions.
+ * Therefore, a decision needs to be made whether to fail over or not. Generally, attempting to fail
+ * over when it is not appropriate is better than not failing over when it is appropriate so the code
+ * always attempts to fail over for NamingExceptions.
*/
/*
@@ -1834,7 +1831,7 @@
}
boolean validated = false;
- Hashtable, ?> preservedEnvironment = context.getEnvironment();
+ Hashtable,?> preservedEnvironment = context.getEnvironment();
// Elicit an LDAP bind operation using the provided user credentials
try {
@@ -1850,7 +1847,7 @@
validated = true;
} catch (AuthenticationException e) {
if (containerLog.isTraceEnabled()) {
- containerLog.trace(" bind attempt failed");
+ containerLog.trace(" bind attempt failed", e);
}
} finally {
// Restore GSSAPI SASL if previously configured
@@ -2219,8 +2216,8 @@
if (tls != null) {
try {
tls.close();
- } catch (IOException e) {
- containerLog.error(sm.getString("jndiRealm.tlsClose"), e);
+ } catch (IOException ioe) {
+ containerLog.error(sm.getString("jndiRealm.tlsClose"), ioe);
}
}
// Close our opened connection
@@ -2566,8 +2563,8 @@
private SSLSocketFactory createSSLSocketFactoryFromClassName(String className) {
try {
Object o = constructInstance(className);
- if (o instanceof SSLSocketFactory) {
- return sslSocketFactory;
+ if (o instanceof SSLSocketFactory socketFactory) {
+ return socketFactory;
} else {
throw new IllegalArgumentException(sm.getString("jndiRealm.invalidSslSocketFactory", className));
}
@@ -2626,8 +2623,10 @@
try {
SSLSession negotiate = tls.negotiate(getSSLSocketFactory());
containerLog.debug(sm.getString("jndiRealm.negotiatedTls", negotiate.getProtocol()));
- } catch (IOException e) {
- throw new NamingException(e.getMessage());
+ } catch (IOException ioe) {
+ NamingException ne = new NamingException(ioe.getMessage());
+ ne.initCause(ioe);
+ throw ne;
}
} finally {
if (result != null) {
@@ -2760,8 +2759,8 @@
/**
* Given a string containing LDAP patterns for user locations (separated by parentheses in a pseudo-LDAP search
- * string format - "(location1)(location2)"), returns an array of those paths. Real LDAP search strings are supported
- * as well (though only the "|" "OR" type).
+ * string format - "(location1)(location2)"), returns an array of those paths. Real LDAP search strings are
+ * supported as well (though only the "|" "OR" type).
*
* @param userPatternString - a string LDAP search paths surrounded by parentheses
*
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/realm/LocalStrings_ru.properties tomcat11-11.0.15/java/org/apache/catalina/realm/LocalStrings_ru.properties
--- tomcat11-11.0.6/java/org/apache/catalina/realm/LocalStrings_ru.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/realm/LocalStrings_ru.properties 2025-12-02 16:54:08.000000000 +0000
@@ -17,6 +17,7 @@
# To edit translations see: https://tomcat.apache.org/getinvolved.html#Translations
dataSourceRealm.getPassword.exception=Исключение при получении пароля для [{0}]
+dataSourceRealm.getRoles.exception=Ошибка получения ролей для [{0}]
lockOutRealm.authLockedUser=Заблокированный пользователь [{0}] совершил попытку авторизоваться
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/realm/LockOutRealm.java tomcat11-11.0.15/java/org/apache/catalina/realm/LockOutRealm.java
--- tomcat11-11.0.6/java/org/apache/catalina/realm/LockOutRealm.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/realm/LockOutRealm.java 2025-12-02 16:54:08.000000000 +0000
@@ -220,7 +220,7 @@
// Check to see if user is locked
// Otherwise, user has not, yet, exceeded lock thresholds
return lockRecord.getFailures() >= failureCount &&
- (System.currentTimeMillis() - lockRecord.getLastFailureTime()) / 1000 < lockOutTime;
+ (System.currentTimeMillis() - lockRecord.getLastFailureTime()) / 1000 < lockOutTime;
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/realm/MemoryRealm.java tomcat11-11.0.15/java/org/apache/catalina/realm/MemoryRealm.java
--- tomcat11-11.0.6/java/org/apache/catalina/realm/MemoryRealm.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/realm/MemoryRealm.java 2025-12-02 16:54:08.000000000 +0000
@@ -38,8 +38,6 @@
* IMPLEMENTATION NOTE: It is assumed that the in-memory collection representing our defined users (and
* their roles) is initialized at application startup and never modified again. Therefore, no thread synchronization is
* performed around accesses to the principals collection.
- *
- * @author Craig R. McClanahan
*/
public class MemoryRealm extends RealmBase {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/realm/MemoryRuleSet.java tomcat11-11.0.15/java/org/apache/catalina/realm/MemoryRuleSet.java
--- tomcat11-11.0.6/java/org/apache/catalina/realm/MemoryRuleSet.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/realm/MemoryRuleSet.java 2025-12-02 16:54:08.000000000 +0000
@@ -25,8 +25,6 @@
*
* RuleSet for recognizing the users defined in the XML file processed by MemoryRealm.
*
- *
- * @author Craig R. McClanahan
*/
public class MemoryRuleSet implements RuleSet {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/realm/MessageDigestCredentialHandler.java tomcat11-11.0.15/java/org/apache/catalina/realm/MessageDigestCredentialHandler.java
--- tomcat11-11.0.6/java/org/apache/catalina/realm/MessageDigestCredentialHandler.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/realm/MessageDigestCredentialHandler.java 2025-12-02 16:54:08.000000000 +0000
@@ -58,6 +58,7 @@
private Charset encoding = StandardCharsets.UTF_8;
private String algorithm = null;
+ private boolean digestInRfc3112Order = false;
public String getEncoding() {
@@ -91,6 +92,16 @@
}
+ public boolean getDigestInRfc3112Order() {
+ return digestInRfc3112Order;
+ }
+
+
+ public void setDigestInRfc3112Order(boolean digestInRfc3112Order) {
+ this.digestInRfc3112Order = digestInRfc3112Order;
+ }
+
+
@Override
public boolean matches(String inputCredentials, String storedCredentials) {
if (inputCredentials == null || storedCredentials == null) {
@@ -162,7 +173,12 @@
if (salt == null) {
userDigest = ConcurrentMessageDigest.digest(algorithm, iterations, inputCredentialbytes);
} else {
- userDigest = ConcurrentMessageDigest.digest(algorithm, iterations, salt, inputCredentialbytes);
+ if (digestInRfc3112Order) {
+ // RFC 3112 states that the input order for the digest is credentials then salt
+ userDigest = ConcurrentMessageDigest.digest(algorithm, iterations, inputCredentialbytes, salt);
+ } else {
+ userDigest = ConcurrentMessageDigest.digest(algorithm, iterations, salt, inputCredentialbytes);
+ }
}
return HexUtils.toHexString(userDigest);
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/realm/NullRealm.java tomcat11-11.0.15/java/org/apache/catalina/realm/NullRealm.java
--- tomcat11-11.0.6/java/org/apache/catalina/realm/NullRealm.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/realm/NullRealm.java 2025-12-02 16:54:08.000000000 +0000
@@ -19,8 +19,8 @@
import java.security.Principal;
/**
- * Minimal Realm implementation that always returns null when an attempt is made to validate a username and password.
- * It is intended to be used as a default Realm implementation when no other Realm is specified.
+ * Minimal Realm implementation that always returns null when an attempt is made to validate a username and password. It
+ * is intended to be used as a default Realm implementation when no other Realm is specified.
*/
public class NullRealm extends RealmBase {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/realm/RealmBase.java tomcat11-11.0.15/java/org/apache/catalina/realm/RealmBase.java
--- tomcat11-11.0.6/java/org/apache/catalina/realm/RealmBase.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/realm/RealmBase.java 2025-12-02 16:54:08.000000000 +0000
@@ -69,8 +69,6 @@
/**
* Simple implementation of Realm that reads an XML file to configure the valid users, passwords, and roles. The
* file format (and default file location) are identical to those currently supported by Tomcat 3.X.
- *
- * @author Craig R. McClanahan
*/
public abstract class RealmBase extends LifecycleMBeanBase implements Realm {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/realm/UserDatabaseRealm.java tomcat11-11.0.15/java/org/apache/catalina/realm/UserDatabaseRealm.java
--- tomcat11-11.0.6/java/org/apache/catalina/realm/UserDatabaseRealm.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/realm/UserDatabaseRealm.java 2025-12-02 16:54:08.000000000 +0000
@@ -40,8 +40,6 @@
* available through the JNDI resources configured for this instance of Catalina. Set the resourceName
* parameter to the JNDI resources name for the configured instance of UserDatabase that we should consult.
*
- * @author Craig R. McClanahan
- *
* @since 4.1
*/
public class UserDatabaseRealm extends RealmBase {
@@ -113,8 +111,7 @@
* Determines whether this Realm is configured to obtain the associated {@link UserDatabase} from the global JNDI
* context or a local (web application) JNDI context.
*
- * @return {@code true} if a local JNDI context will be used, {@code false} if the global JNDI context will be
- * used
+ * @return {@code true} if a local JNDI context will be used, {@code false} if the global JNDI context will be used
*/
public boolean getLocalJndiResource() {
return localJndiResource;
@@ -221,13 +218,13 @@
containerLog.error(sm.getString("userDatabaseRealm.noNamingContext"));
return null;
}
- context = getServer().getGlobalNamingContext();
+ context = server.getGlobalNamingContext();
}
database = (UserDatabase) context.lookup(resourceName);
- } catch (Throwable e) {
- ExceptionUtils.handleThrowable(e);
+ } catch (Throwable t) {
+ ExceptionUtils.handleThrowable(t);
if (containerLog != null) {
- containerLog.error(sm.getString("userDatabaseRealm.lookup", resourceName), e);
+ containerLog.error(sm.getString("userDatabaseRealm.lookup", resourceName), t);
}
database = null;
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/security/SecurityListener.java tomcat11-11.0.15/java/org/apache/catalina/security/SecurityListener.java
--- tomcat11-11.0.6/java/org/apache/catalina/security/SecurityListener.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/security/SecurityListener.java 2025-12-02 16:54:08.000000000 +0000
@@ -221,8 +221,7 @@
if (allowedAgeDays >= 0) {
String buildDateString = ServerInfo.getServerBuiltISO();
- if (null == buildDateString || buildDateString.isEmpty() ||
- !Character.isDigit(buildDateString.charAt(0))) {
+ if (null == buildDateString || buildDateString.isEmpty() || !Character.isDigit(buildDateString.charAt(0))) {
log.warn(sm.getString("SecurityListener.buildDateUnreadable", buildDateString));
} else {
try {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/servlets/CGIServlet.java tomcat11-11.0.15/java/org/apache/catalina/servlets/CGIServlet.java
--- tomcat11-11.0.6/java/org/apache/catalina/servlets/CGIServlet.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/servlets/CGIServlet.java 2025-12-02 16:54:08.000000000 +0000
@@ -44,16 +44,21 @@
import jakarta.servlet.ServletConfig;
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
+import jakarta.servlet.UnavailableException;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
+import org.apache.catalina.Globals;
+import org.apache.catalina.WebResource;
+import org.apache.catalina.WebResourceRoot;
import org.apache.catalina.util.IOTools;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.apache.tomcat.util.compat.JrePlatform;
+import org.apache.tomcat.util.http.Method;
import org.apache.tomcat.util.res.StringManager;
@@ -193,17 +198,12 @@
*
Confirm use of ServletInputStream.available() in CGIRunner.run() is not needed
*
[add more to this TODO list]
*
- *
- * @author Martin T Dengler [root@martindengler.com]
- * @author Amy Roh
*/
public final class CGIServlet extends HttpServlet {
private static final Log log = LogFactory.getLog(CGIServlet.class);
private static final StringManager sm = StringManager.getManager(CGIServlet.class);
- /* some vars below copied from Craig R. McClanahan's InvokerServlet */
-
@Serial
private static final long serialVersionUID = 1L;
@@ -212,9 +212,9 @@
private static final String ALLOW_ANY_PATTERN = ".*";
static {
- DEFAULT_SUPER_METHODS.add("HEAD");
- DEFAULT_SUPER_METHODS.add("OPTIONS");
- DEFAULT_SUPER_METHODS.add("TRACE");
+ DEFAULT_SUPER_METHODS.add(Method.HEAD);
+ DEFAULT_SUPER_METHODS.add(Method.OPTIONS);
+ DEFAULT_SUPER_METHODS.add(Method.TRACE);
if (JrePlatform.IS_WINDOWS) {
DEFAULT_CMD_LINE_ARGUMENTS_DECODED_PATTERN = Pattern.compile("[\\w\\Q-.\\/:\\E]+");
@@ -245,6 +245,8 @@
private final Set cgiMethods = new HashSet<>();
private boolean cgiMethodsAll = false;
+ private transient WebResourceRoot resources = null;
+
/**
* The time (in milliseconds) to wait for the reading of stderr to complete before terminating the CGI process.
@@ -285,9 +287,6 @@
/**
* Sets instance variables.
- *
- * Modified from Craig R. McClanahan's InvokerServlet
- *
*
* @param config a ServletConfig object containing the servlet's configuration and initialization
* parameters
@@ -364,8 +363,8 @@
}
}
} else {
- cgiMethods.add("GET");
- cgiMethods.add("POST");
+ cgiMethods.add(Method.GET);
+ cgiMethods.add(Method.POST);
}
if (getServletConfig().getInitParameter("cmdLineArgumentsEncoded") != null) {
@@ -380,14 +379,18 @@
} else if (value != null) {
cmdLineArgumentsDecodedPattern = Pattern.compile(value);
}
+
+ // Load the web resources
+ resources = (WebResourceRoot) getServletContext().getAttribute(Globals.RESOURCES_ATTR);
+
+ if (resources == null) {
+ throw new UnavailableException(sm.getString("cgiServlet.noResources"));
+ }
}
/**
* Logs important Servlet API and container information.
- *
- * Based on SnoopAllServlet by Craig R. McClanahan
- *
*
* @param req HttpServletRequest object used as source of information
*/
@@ -418,7 +421,9 @@
}
}
} catch (IllegalStateException ise) {
- log.trace("Request Parameters: [Invalid]");
+ if (log.isTraceEnabled()) {
+ log.trace("Request Parameters: [Invalid]", ise);
+ }
}
log.trace("Protocol: [" + req.getProtocol() + "]");
log.trace("Remote Address: [" + req.getRemoteAddr() + "]");
@@ -548,7 +553,7 @@
CGIRunner cgi = new CGIRunner(cgiEnv.getCommand(), cgiEnv.getEnvironment(), cgiEnv.getWorkingDirectory(),
cgiEnv.getParameters());
- if ("POST".equals(req.getMethod())) {
+ if (Method.POST.equals(req.getMethod())) {
cgi.setInput(req.getInputStream());
}
cgi.setResponse(res);
@@ -571,7 +576,7 @@
@Override
protected void doOptions(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
// Note: This method will never be called if cgiMethods is "*" so that
- // case does nto need to be handled here.
+ // case does not need to be handled here.
Set allowedMethods = new HashSet<>();
allowedMethods.addAll(cgiMethods);
allowedMethods.addAll(DEFAULT_SUPER_METHODS);
@@ -628,9 +633,6 @@
/** pathInfo for the current request */
private String pathInfo = null;
- /** real file system directory of the enclosing servlet's web app */
- private String webAppRootDir = null;
-
/** tempdir for context - used to expand scripts in unexpanded wars */
private File tmpDir = null;
@@ -684,7 +686,6 @@
*/
protected void setupFromContext(ServletContext context) {
this.context = context;
- this.webAppRootDir = context.getRealPath("/");
this.tmpDir = (File) context.getAttribute(ServletContext.TEMPDIR);
}
@@ -722,8 +723,8 @@
// does not contain an unencoded "=" this is an indexed query.
// The parsed query string becomes the command line parameters
// for the cgi command.
- if (enableCmdLineArguments && (req.getMethod().equals("GET") || req.getMethod().equals("POST") ||
- req.getMethod().equals("HEAD"))) {
+ if (enableCmdLineArguments && (Method.GET.equals(req.getMethod()) || Method.POST.equals(req.getMethod()) ||
+ Method.HEAD.equals(req.getMethod()))) {
String qs;
if (isIncluded) {
qs = (String) req.getAttribute(RequestDispatcher.INCLUDE_QUERY_STRING);
@@ -788,10 +789,9 @@
* cgiPathPrefix is defined by setting this servlet's cgiPathPrefix init parameter
*
*
- * @param pathInfo String from HttpServletRequest.getPathInfo()
- * @param webAppRootDir String from context.getRealPath("/")
* @param contextPath String as from HttpServletRequest.getContextPath()
* @param servletPath String as from HttpServletRequest.getServletPath()
+ * @param pathInfo String from HttpServletRequest.getPathInfo()
* @param cgiPathPrefix subdirectory of webAppRootDir below which the web app's CGIs may be stored; can be null.
* The CGI search path will start at webAppRootDir + File.separator + cgiPathPrefix (or
* webAppRootDir alone if cgiPathPrefix is null). cgiPathPrefix is defined by setting
@@ -808,59 +808,104 @@
* found
*
*/
- protected String[] findCGI(String pathInfo, String webAppRootDir, String contextPath, String servletPath,
- String cgiPathPrefix) {
- String path;
- String name;
- String scriptname;
-
- if (webAppRootDir.lastIndexOf(File.separator) == (webAppRootDir.length() - 1)) {
- // strip the trailing "/" from the webAppRootDir
- webAppRootDir = webAppRootDir.substring(0, (webAppRootDir.length() - 1));
- }
+ protected String[] findCGI(String contextPath, String servletPath, String pathInfo, String cgiPathPrefix) {
- if (cgiPathPrefix != null) {
- webAppRootDir = webAppRootDir + File.separator + cgiPathPrefix;
- }
+ StringBuilder cgiPath = new StringBuilder();
+ StringBuilder urlPath = new StringBuilder();
- if (log.isTraceEnabled()) {
- log.trace(sm.getString("cgiServlet.find.path", pathInfo, webAppRootDir));
- }
+ WebResource cgiScript = null;
- File currentLocation = new File(webAppRootDir);
- StringTokenizer dirWalker = new StringTokenizer(pathInfo, "/");
- if (log.isTraceEnabled()) {
- log.trace(sm.getString("cgiServlet.find.location", currentLocation.getAbsolutePath()));
+ if (cgiPathPrefix == null || cgiPathPrefix.isEmpty()) {
+ cgiPath.append(servletPath);
+ } else {
+ cgiPath.append('/');
+ cgiPath.append(cgiPathPrefix);
}
- StringBuilder cginameBuilder = new StringBuilder();
- while (!currentLocation.isFile() && dirWalker.hasMoreElements()) {
- String nextElement = (String) dirWalker.nextElement();
- currentLocation = new File(currentLocation, nextElement);
- cginameBuilder.append('/').append(nextElement);
+ urlPath.append(servletPath);
+
+ StringTokenizer pathWalker = new StringTokenizer(pathInfo, "/");
+
+ while (pathWalker.hasMoreElements() && (cgiScript == null || !cgiScript.isFile())) {
+ String urlSegment = pathWalker.nextToken();
+ cgiPath.append('/');
+ cgiPath.append(urlSegment);
+ urlPath.append('/');
+ urlPath.append(urlSegment);
if (log.isTraceEnabled()) {
- log.trace(sm.getString("cgiServlet.find.location", currentLocation.getAbsolutePath()));
+ log.trace(sm.getString("cgiServlet.find.location", cgiPath.toString()));
}
+ cgiScript = resources.getResource(cgiPath.toString());
}
- String cginame = cginameBuilder.toString();
- if (!currentLocation.isFile()) {
+
+ // No script was found
+ if (cgiScript == null || !cgiScript.isFile()) {
return new String[] { null, null, null, null };
}
- path = currentLocation.getAbsolutePath();
- name = currentLocation.getName();
+ // Set-up return values
+ String path = null;
+ String scriptName = null;
+ String cgiName = null;
+ String name = null;
- if (servletPath.startsWith(cginame)) {
- scriptname = contextPath + cginame;
- } else {
- scriptname = contextPath + servletPath + cginame;
+ path = cgiScript.getCanonicalPath();
+ if (path == null) {
+ /*
+ * The script doesn't exist directly on the file system. It might be located in an archive or similar.
+ * Such scripts are extracted to the web application's temporary file location.
+ */
+ File tmpCgiFile = new File(tmpDir + cgiPath.toString());
+ if (!tmpCgiFile.exists()) {
+
+ // Create directories
+ File parent = tmpCgiFile.getParentFile();
+ if (!parent.mkdirs() && !parent.isDirectory()) {
+ log.warn(sm.getString("cgiServlet.expandCreateDirFail", parent.getAbsolutePath()));
+ return new String[] { null, null, null, null };
+ }
+
+ try (InputStream is = cgiScript.getInputStream()) {
+ synchronized (expandFileLock) {
+ // Check if file was created by concurrent request
+ if (!tmpCgiFile.exists()) {
+ try {
+ Files.copy(is, tmpCgiFile.toPath());
+ } catch (IOException ioe) {
+ log.warn(sm.getString("cgiServlet.expandFail", cgiScript.getURL(),
+ tmpCgiFile.getAbsolutePath()), ioe);
+ if (tmpCgiFile.exists()) {
+ if (!tmpCgiFile.delete()) {
+ log.warn(sm.getString("cgiServlet.expandDeleteFail",
+ tmpCgiFile.getAbsolutePath()));
+ }
+ }
+ return new String[] { null, null, null, null };
+ }
+ if (log.isDebugEnabled()) {
+ log.debug(sm.getString("cgiServlet.expandOk", cgiScript.getURL(),
+ tmpCgiFile.getAbsolutePath()));
+ }
+ }
+ }
+ } catch (IOException ioe) {
+ log.warn(sm.getString("cgiServlet.expandCloseFail", cgiScript.getURL()), ioe);
+ }
+ }
+ path = tmpCgiFile.getAbsolutePath();
}
+ scriptName = urlPath.toString();
+ cgiName = scriptName.substring(servletPath.length());
+ name = scriptName.substring(scriptName.lastIndexOf('/') + 1);
+
if (log.isTraceEnabled()) {
- log.trace(sm.getString("cgiServlet.find.found", name, path, scriptname, cginame));
+ log.trace(sm.getString("cgiServlet.find.found", name, path, scriptName, cgiName));
}
- return new String[] { path, scriptname, cginame, name };
+
+ return new String[] { path, scriptName, cgiName, name };
}
+
/**
* Constructs the CGI environment to be supplied to the invoked CGI script; relies heavily on Servlet API
* methods and findCGI
@@ -895,13 +940,7 @@
sPathInfoOrig = this.pathInfo;
sPathInfoOrig = sPathInfoOrig == null ? "" : sPathInfoOrig;
- if (webAppRootDir == null) {
- // The app has not been deployed in exploded form
- webAppRootDir = tmpDir.toString();
- expandCGIScript();
- }
-
- sCGINames = findCGI(sPathInfoOrig, webAppRootDir, contextPath, servletPath, cgiPathPrefix);
+ sCGINames = findCGI(contextPath, servletPath, sPathInfoOrig, cgiPathPrefix);
sCGIFullPath = sCGINames[0];
sCGIScriptName = sCGINames[1];
@@ -1028,93 +1067,6 @@
}
/**
- * Extracts requested resource from web app archive to context work directory to enable CGI script to be
- * executed.
- */
- protected void expandCGIScript() {
- StringBuilder srcPath = new StringBuilder();
- StringBuilder destPath = new StringBuilder();
- InputStream is = null;
-
- // paths depend on mapping
- if (cgiPathPrefix == null) {
- srcPath.append(pathInfo);
- is = context.getResourceAsStream(srcPath.toString());
- destPath.append(tmpDir);
- destPath.append(pathInfo);
- } else {
- // essentially same search algorithm as findCGI()
- srcPath.append(cgiPathPrefix);
- StringTokenizer pathWalker = new StringTokenizer(pathInfo, "/");
- // start with first element
- while (pathWalker.hasMoreElements() && (is == null)) {
- srcPath.append('/');
- srcPath.append(pathWalker.nextElement());
- is = context.getResourceAsStream(srcPath.toString());
- }
- destPath.append(tmpDir);
- destPath.append('/');
- destPath.append(srcPath);
- }
-
- if (is == null) {
- // didn't find anything, give up now
- log.warn(sm.getString("cgiServlet.expandNotFound", srcPath));
- return;
- }
-
- try {
- File f = new File(destPath.toString());
- if (f.exists()) {
- // Don't need to expand if it already exists
- return;
- }
-
- // create directories
- File dir = f.getParentFile();
- if (!dir.mkdirs() && !dir.isDirectory()) {
- log.warn(sm.getString("cgiServlet.expandCreateDirFail", dir.getAbsolutePath()));
- return;
- }
-
- try {
- synchronized (expandFileLock) {
- // make sure file doesn't exist
- if (f.exists()) {
- return;
- }
-
- // create file
- if (!f.createNewFile()) {
- return;
- }
-
- Files.copy(is, f.toPath());
-
- if (log.isDebugEnabled()) {
- log.debug(sm.getString("cgiServlet.expandOk", srcPath, destPath));
- }
- }
- } catch (IOException ioe) {
- log.warn(sm.getString("cgiServlet.expandFail", srcPath, destPath), ioe);
- // delete in case file is corrupted
- if (f.exists()) {
- if (!f.delete()) {
- log.warn(sm.getString("cgiServlet.expandDeleteFail", f.getAbsolutePath()));
- }
- }
- }
- } finally {
- try {
- is.close();
- } catch (IOException e) {
- log.warn(sm.getString("cgiServlet.expandCloseFail", srcPath), e);
- }
- }
- }
-
-
- /**
* Returns important CGI environment information in a multi-line text format.
*
* @return CGI environment info
@@ -1409,9 +1361,9 @@
*
Allowed characters in path segments: This implementation does not allow non-terminal NULL segments
* in the path -- IOExceptions may be thrown;
*
"." and ".." path segments: This implementation does not allow
- * "." and ".." in the path, and such characters will result in an IOException
- * being thrown (this should never happen since Tomcat normalises the requestURI before determining the
- * contextPath, servletPath and pathInfo);
+ * "." and ".." in the path, and such characters will result in an IOException being
+ * thrown (this should never happen since Tomcat normalises the requestURI before determining the contextPath,
+ * servletPath and pathInfo);
*
Implementation limitations: This implementation does not impose any limitations except as
* documented above. This implementation may be limited by the servlet container used to house this
* implementation. In particular, all the primary CGI variable values are derived either directly or indirectly
@@ -1442,14 +1394,10 @@
throw new IOException(sm.getString("cgiServlet.invalidCommand", command));
}
- /*
- * original content/structure of this section taken from
- * http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4216884 with major modifications by Martin Dengler
- */
Runtime rt;
BufferedReader cgiHeaderReader = null;
InputStream cgiOutput = null;
- BufferedReader commandsStdErr ;
+ BufferedReader commandsStdErr;
Thread errReaderThread = null;
BufferedOutputStream commandsStdIn;
Process proc = null;
@@ -1559,9 +1507,9 @@
}
} // replacement for Process.waitFor()
- } catch (IOException e) {
- log.warn(sm.getString("cgiServlet.runFail"), e);
- throw e;
+ } catch (IOException ioe) {
+ log.warn(sm.getString("cgiServlet.runFail"), ioe);
+ throw ioe;
} finally {
// Close the header reader
if (cgiHeaderReader != null) {
@@ -1584,7 +1532,7 @@
try {
errReaderThread.join(stderrTimeout);
} catch (InterruptedException e) {
- log.warn(sm.getString("cgiServlet.runReaderInterrupt"));
+ log.warn(sm.getString("cgiServlet.runReaderInterrupt"), e);
}
}
if (proc != null) {
@@ -1662,13 +1610,13 @@
log.warn(sm.getString("cgiServlet.runStdErr", line));
lineCount++;
}
- } catch (IOException e) {
- log.warn(sm.getString("cgiServlet.runStdErrFail"), e);
+ } catch (IOException ioe) {
+ log.warn(sm.getString("cgiServlet.runStdErrFail"), ioe);
} finally {
try {
rdr.close();
- } catch (IOException e) {
- log.warn(sm.getString("cgiServlet.runStdErrFail"), e);
+ } catch (IOException ioe) {
+ log.warn(sm.getString("cgiServlet.runStdErrFail"), ioe);
}
}
if (lineCount > 0) {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/servlets/DefaultServlet.java tomcat11-11.0.15/java/org/apache/catalina/servlets/DefaultServlet.java
--- tomcat11-11.0.6/java/org/apache/catalina/servlets/DefaultServlet.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/servlets/DefaultServlet.java 2025-12-02 16:54:08.000000000 +0000
@@ -75,6 +75,7 @@
import org.apache.catalina.webresources.CachedResource;
import org.apache.tomcat.util.buf.B2CConverter;
import org.apache.tomcat.util.http.FastHttpDateFormat;
+import org.apache.tomcat.util.http.Method;
import org.apache.tomcat.util.http.ResponseUtil;
import org.apache.tomcat.util.http.parser.ContentRange;
import org.apache.tomcat.util.http.parser.EntityTag;
@@ -126,9 +127,6 @@
* Then a request to /context/static/images/tomcat.jpg will succeed while a request to
* /context/images/tomcat2.jpg will fail.
*
- *
- * @author Craig R. McClanahan
- * @author Remy Maucherat
*/
public class DefaultServlet extends HttpServlet {
@@ -679,8 +677,8 @@
}
} else {
try {
- resp.sendError(resourceInputStream != null ?
- HttpServletResponse.SC_CONFLICT : HttpServletResponse.SC_BAD_REQUEST);
+ resp.sendError(resourceInputStream != null ? HttpServletResponse.SC_CONFLICT :
+ HttpServletResponse.SC_BAD_REQUEST);
} catch (IllegalStateException e) {
// Already committed, ignore
}
@@ -689,7 +687,7 @@
if (resourceInputStream != null) {
try {
resourceInputStream.close();
- } catch (IOException ioe) {
+ } catch (IOException ignore) {
// Ignore
}
}
@@ -748,17 +746,18 @@
int numBytesRead;
byte[] transferBuffer = new byte[BUFFER_SIZE];
try (BufferedInputStream requestBufInStream = new BufferedInputStream(req.getInputStream(), BUFFER_SIZE)) {
+ long rangeBytes = range.getEnd() - range.getStart() + 1L;
while ((numBytesRead = requestBufInStream.read(transferBuffer)) != -1) {
received += numBytesRead;
- if (received > range.getEnd() - range.getStart()) {
+ if (received > rangeBytes) {
throw new IllegalStateException(sm.getString("defaultServlet.wrongByteCountForRange",
- String.valueOf(received), String.valueOf(range.getEnd() - range.getStart())));
+ String.valueOf(received), String.valueOf(rangeBytes)));
}
randAccessContentFile.write(transferBuffer, 0, numBytesRead);
}
- if (received < range.getEnd() - range.getStart()) {
+ if (received < rangeBytes) {
throw new IllegalStateException(sm.getString("defaultServlet.wrongByteCountForRange",
- String.valueOf(received), String.valueOf(range.getEnd() - range.getStart())));
+ String.valueOf(received), String.valueOf(rangeBytes)));
}
}
@@ -1088,7 +1087,7 @@
response.setContentType(contentType);
}
}
- if (resource.isFile() && contentLength >= 0 && (!serveContent || ostream != null)) {
+ if (resource.isFile() && contentLength >= 0 && (!serveContent || ostream != null || writer != null)) {
if (debug > 0) {
log("DefaultServlet.serveFile: contentLength=" + contentLength);
}
@@ -1102,8 +1101,8 @@
if (serveContent) {
try {
response.setBufferSize(output);
- } catch (IllegalStateException e) {
- // Silent catch
+ } catch (IllegalStateException ignore) {
+ // Content has already been written - this must be an include. Ignore the error and continue.
}
InputStream renderResult = null;
if (ostream == null) {
@@ -1216,8 +1215,8 @@
if (serveContent) {
try {
response.setBufferSize(output);
- } catch (IllegalStateException e) {
- // Silent catch
+ } catch (IllegalStateException ignore) {
+ // Content has already been written - this must be an include. Ignore the error and continue.
}
if (ostream != null) {
if (!checkSendfile(request, response, resource, contentLength, range)) {
@@ -1234,7 +1233,7 @@
try {
response.setBufferSize(output);
} catch (IllegalStateException e) {
- // Silent catch
+ // Content has already been written - this must be an include. Ignore the error and continue.
}
if (ostream != null) {
copy(resource, contentLength, ostream, ranges, contentType);
@@ -1564,7 +1563,7 @@
return FULL;
}
- if (!"GET".equals(request.getMethod()) || !isRangeRequestsSupported()) {
+ if (!Method.GET.equals(request.getMethod()) || !isRangeRequestsSupported()) {
// RFC 9110 - Section 14.2: GET is the only method for which range handling is defined.
// Otherwise MUST ignore a Range header field
return FULL;
@@ -2014,15 +2013,15 @@
}
IOException e = copyRange(reader, new PrintWriter(buffer));
if (debug > 10) {
- log("readme '" + readmeFile + "' output error: " + e.getMessage());
+ log("readme '" + readmeFile + "' output error: " + ((e != null) ? e.getMessage() : ""));
}
- } catch (IOException e) {
- log(sm.getString("defaultServlet.readerCloseFailed"), e);
+ } catch (IOException ioe) {
+ log(sm.getString("defaultServlet.readerCloseFailed"), ioe);
} finally {
if (reader != null) {
try {
reader.close();
- } catch (IOException e) {
+ } catch (IOException ignore) {
// Ignore
}
}
@@ -2255,7 +2254,7 @@
WebResource resource) {
String method = request.getMethod();
- if (!"GET".equals(method) && !"HEAD".equals(method)) {
+ if (!Method.GET.equals(method) && !Method.HEAD.equals(method)) {
return true;
}
@@ -2363,7 +2362,7 @@
// 304 Not Modified.
// For every other method, 412 Precondition Failed is sent
// back.
- if ("GET".equals(request.getMethod()) || "HEAD".equals(request.getMethod())) {
+ if (Method.GET.equals(request.getMethod()) || Method.HEAD.equals(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
response.setHeader("ETag", resourceETag);
} else {
@@ -2453,8 +2452,7 @@
if (headerValue.length() > 2 && (headerValue.charAt(0) == '"' || headerValue.charAt(2) == '"')) {
boolean weakETag = headerValue.startsWith("W/\"");
- if ((!weakETag && headerValue.charAt(0) != '"') ||
- headerValue.charAt(headerValue.length() - 1) != '"' ||
+ if ((!weakETag && headerValue.charAt(0) != '"') || headerValue.charAt(headerValue.length() - 1) != '"' ||
headerValue.indexOf('"', weakETag ? 3 : 1) != headerValue.length() - 1) {
// Not a single entity tag
response.sendError(HttpServletResponse.SC_BAD_REQUEST);
@@ -2467,7 +2465,7 @@
long headerValueTime = -1L;
try {
headerValueTime = request.getDateHeader("If-Range");
- } catch (IllegalArgumentException e) {
+ } catch (IllegalArgumentException ignore) {
// Ignore
}
if (headerValueTime >= 0) {
@@ -2668,8 +2666,8 @@
break;
}
ostream.write(buffer, 0, len);
- } catch (IOException e) {
- exception = e;
+ } catch (IOException ioe) {
+ exception = ioe;
break;
}
}
@@ -2699,8 +2697,8 @@
break;
}
writer.write(buffer, 0, len);
- } catch (IOException e) {
- exception = e;
+ } catch (IOException ioe) {
+ exception = ioe;
break;
}
}
@@ -2729,8 +2727,8 @@
long skipped;
try {
skipped = istream.skip(start);
- } catch (IOException e) {
- return e;
+ } catch (IOException ioe) {
+ return ioe;
}
if (skipped < start) {
return new IOException(sm.getString("defaultServlet.skipfail", Long.valueOf(skipped), Long.valueOf(start)));
@@ -2751,8 +2749,8 @@
ostream.write(buffer, 0, (int) bytesToRead);
bytesToRead = 0;
}
- } catch (IOException e) {
- exception = e;
+ } catch (IOException ioe) {
+ exception = ioe;
len = -1;
}
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/servlets/LocalStrings.properties tomcat11-11.0.15/java/org/apache/catalina/servlets/LocalStrings.properties
--- tomcat11-11.0.6/java/org/apache/catalina/servlets/LocalStrings.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/servlets/LocalStrings.properties 2025-12-02 16:54:08.000000000 +0000
@@ -21,7 +21,6 @@
cgiServlet.expandCreateDirFail=Failed to create destination directory [{0}] for script expansion
cgiServlet.expandDeleteFail=Failed to delete file at [{0}] after IOException during expansion
cgiServlet.expandFail=Failed to expand script at path [{0}] to [{1}]
-cgiServlet.expandNotFound=Unable to expand [{0}] as it could not be found
cgiServlet.expandOk=Expanded script at path [{0}] to [{1}]
cgiServlet.find.found=Found CGI: name [{0}], path [{1}], script name [{2}] and CGI name [{3}]
cgiServlet.find.location=Looking for a file at [{0}]
@@ -29,6 +28,7 @@
cgiServlet.invalidArgumentDecoded=The decoded command line argument [{0}] did not match the configured cmdLineArgumentsDecoded pattern [{1}]
cgiServlet.invalidArgumentEncoded=The encoded command line argument [{0}] did not match the configured cmdLineArgumentsEncoded pattern [{1}]
cgiServlet.invalidCommand=Illegal Character in CGI command path ('.' or '..') detected, not running CGI [{0}]
+cgiServlet.noResources=No static resources were found
cgiServlet.notReady=CGI Servlet is not ready to run
cgiServlet.runBadHeader=Bad header line [{0}]
cgiServlet.runFail=I/O problems processing CGI
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/servlets/LocalStrings_fr.properties tomcat11-11.0.15/java/org/apache/catalina/servlets/LocalStrings_fr.properties
--- tomcat11-11.0.6/java/org/apache/catalina/servlets/LocalStrings_fr.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/servlets/LocalStrings_fr.properties 2025-12-02 16:54:08.000000000 +0000
@@ -21,7 +21,6 @@
cgiServlet.expandCreateDirFail=Echec de la création du répertoire de destination [{0}] pour la décompression du script
cgiServlet.expandDeleteFail=Impossible d''effacer le fichier [{0}] suite à une IOException pendant la décompression
cgiServlet.expandFail=Impossible de faire l''expansion du script au chemin [{0}] vers [{1}]
-cgiServlet.expandNotFound=Impossible de décompresser [{0}] car il n''a pas été trouvé
cgiServlet.expandOk=Extrait le script du chemin [{0}] vers [{1}]
cgiServlet.find.found=Trouvé le CGI : nom [{0}], chemin [{1}], nom de script [{2}] et nom du CGI [{3}]
cgiServlet.find.location=Recherche d''un fichier en [{0}]
@@ -29,6 +28,7 @@
cgiServlet.invalidArgumentDecoded=Les paramètres de ligne de commande décodés [{0}] ne correspondent pas au modèle cmdLineArgumentsDecoded configuré [{1}]
cgiServlet.invalidArgumentEncoded=Les paramètres de ligne de commande encodés [{0}] ne correspondent pas au modèle cmdLineArgumentsEncoded configuré [{1}]
cgiServlet.invalidCommand=Un caractère illégal (''.'' or ''..'') a été trouvé dans le chemin de commande CGI, le CGI [{0}] n''est pas exécuté
+cgiServlet.noResources=Pas de ressources statiques trouvées
cgiServlet.notReady=Le Servlet CGI n'est pas prêt à fonctionner
cgiServlet.runBadHeader=Mauvaise ligne d''en-tête [{0}]
cgiServlet.runFail=Problèmes d'IO lors de l'exécution du CGI
@@ -56,6 +56,7 @@
defaultServlet.resource.size=Taille
defaultServlet.skipfail=La lecture a échouée parce que seuls [{0}] octets étaient disponibles alors qu''il était nécessaire d''en sauter [{1}] pour atteindre le début de la plage demandée
defaultServlet.unknownBomConfig=La valeur [{0}] inconnue a été donnée pour le paramètre d’initialisation useBomIfPresent
+defaultServlet.wrongByteCountForRange=Une quantité invalide d''octets [{0}] a été reçue pour la range dont la longueur est [{1}]
defaultServlet.xslError=Erreur de transformation XSL
webdavservlet.dataSourceStore.error=Erreur [{0}] lors du traitement des prorpiétés pour le chemin [{1}]
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/servlets/LocalStrings_ja.properties tomcat11-11.0.15/java/org/apache/catalina/servlets/LocalStrings_ja.properties
--- tomcat11-11.0.6/java/org/apache/catalina/servlets/LocalStrings_ja.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/servlets/LocalStrings_ja.properties 2025-12-02 16:54:08.000000000 +0000
@@ -21,7 +21,6 @@
cgiServlet.expandCreateDirFail=スクリプトの展開先ディレクトリ[{0}]の作成に失敗しました。
cgiServlet.expandDeleteFail=拡張中にIOExceptionの後に [{0}] でファイルを削除できませんでした
cgiServlet.expandFail=パス [{0}] のスクリプトを [{1}] に展開できませんでした
-cgiServlet.expandNotFound=見つけることができなかったため [{0}] を展開できません
cgiServlet.expandOk=パス [{0}] の [{1}] に展開されたスクリプト
cgiServlet.find.found=見つかったCGI: 名前 [{0}]、パス [{1}]、スクリプト名 [{2}]、CGI名 [{3}]
cgiServlet.find.location=ファイル [{0}] を探しています。
@@ -29,6 +28,7 @@
cgiServlet.invalidArgumentDecoded=デコードされたコマンドライン引数 [{0}] は、構成されたcmdLineArgumentsDecoded パターン [{1}] にマッチしません
cgiServlet.invalidArgumentEncoded=エンコードされたコマンドライン引数 [{0}] は、構成されたcmdLineArgumentsEncoded パターン [{1}] にマッチしません
cgiServlet.invalidCommand=CGI コマンド パスに不正な文字 (''.'' または ''..'') が検出されました。CGI [{0}] は実行されていません
+cgiServlet.noResources=静的リソースが見つかりませんでした
cgiServlet.notReady=CGI サーブレットは実行の準備ができていません
cgiServlet.runBadHeader=悪いヘッダライン [{0}]
cgiServlet.runFail=CGI処理中のIO問題
@@ -56,6 +56,7 @@
defaultServlet.resource.size=サイズ
defaultServlet.skipfail=[{1}]バイトをスキップして要求された範囲の先頭に到達する必要がありましたが、[{0}]バイトしか利用できなかったため読み取りに失敗しました。
defaultServlet.unknownBomConfig=useBomIfPresentの初期化パラメーターに提供された認識されない値 [{0}]
+defaultServlet.wrongByteCountForRange=長さ [{1}] の範囲に対して無効な [{0}] バイトを受信しました
defaultServlet.xslError=XSL変換エラー
webdavservlet.dataSourceStore.error=パス [{1}] の無効なプロパティで [{0}] を処理中にエラーが発生しました
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/servlets/LocalStrings_ko.properties tomcat11-11.0.15/java/org/apache/catalina/servlets/LocalStrings_ko.properties
--- tomcat11-11.0.6/java/org/apache/catalina/servlets/LocalStrings_ko.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/servlets/LocalStrings_ko.properties 2025-12-02 16:54:08.000000000 +0000
@@ -21,7 +21,6 @@
cgiServlet.expandCreateDirFail=스크립트를 압축해제 하기 위한 대상 디렉토리 [{0}]을(를) 생성하지 못했습니다.
cgiServlet.expandDeleteFail=압축해제 중 IOException이 발생한 후, [{0}]에 위치한 해당 파일을 삭제하지 못했습니다.
cgiServlet.expandFail=경로 [{0}]의 스크립트를 [{1}](으)로 압축해제 하지 못했습니다.
-cgiServlet.expandNotFound=[{0}]을(를) 찾을 수 없어서 압축해제 할 수 없습니다.
cgiServlet.expandOk=[{0}] 경로에 있는 스트립트가 [{1}](으)로 압축 해제되었습니다.
cgiServlet.find.found=CGI 발견: 이름 [{0}], 경로 [{1}], 스크립트 이름 [{2}], CGI 이름 [{3}]
cgiServlet.find.location=[{0}]에 위치한 파일을 찾는 중
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/servlets/LocalStrings_ru.properties tomcat11-11.0.15/java/org/apache/catalina/servlets/LocalStrings_ru.properties
--- tomcat11-11.0.6/java/org/apache/catalina/servlets/LocalStrings_ru.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/servlets/LocalStrings_ru.properties 2025-12-02 16:54:08.000000000 +0000
@@ -17,6 +17,7 @@
# To edit translations see: https://tomcat.apache.org/getinvolved.html#Translations
cgiServlet.expandFail=Невозможно развернуть скрипт [{0}] в [{1}]
+cgiServlet.find.location=Поиск файла в [{0}]
cgiServlet.runInvalidStatus=Неверный статус [{0}]
defaultServlet.skipfail=Чтение завершилось ошибкой, потому что только [{0}] байт было доступно, а требовалось пропустить [{1}] байт, чтобы достигнуть начала требуемоего диапазона
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/servlets/LocalStrings_zh_CN.properties tomcat11-11.0.15/java/org/apache/catalina/servlets/LocalStrings_zh_CN.properties
--- tomcat11-11.0.6/java/org/apache/catalina/servlets/LocalStrings_zh_CN.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/servlets/LocalStrings_zh_CN.properties 2025-12-02 16:54:08.000000000 +0000
@@ -21,7 +21,6 @@
cgiServlet.expandCreateDirFail=无法为脚本扩展创建目标目录[{0}]
cgiServlet.expandDeleteFail=扩展期间,发生IOException异常后删除文件[{0}]失败
cgiServlet.expandFail=在路径[{0}] 到[{1}] 展开脚本失败.
-cgiServlet.expandNotFound=无法展开[{0}],因为找不到它。
cgiServlet.expandOk=从路径[{0}]到[{1}]扩展脚本
cgiServlet.find.found=找到CGI:name[{0}]、path[{1}]、script name[{2}]和CGI name[{3}]
cgiServlet.find.location=在 [{0}] 查找文件
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/servlets/WebdavServlet.java tomcat11-11.0.15/java/org/apache/catalina/servlets/WebdavServlet.java
--- tomcat11-11.0.6/java/org/apache/catalina/servlets/WebdavServlet.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/servlets/WebdavServlet.java 2025-12-02 16:54:08.000000000 +0000
@@ -64,6 +64,7 @@
import org.apache.tomcat.util.IntrospectionUtils;
import org.apache.tomcat.util.http.ConcurrentDateFormat;
import org.apache.tomcat.util.http.FastHttpDateFormat;
+import org.apache.tomcat.util.http.Method;
import org.apache.tomcat.util.http.RequestUtil;
import org.apache.tomcat.util.http.WebdavIfHeader;
import org.w3c.dom.Document;
@@ -99,6 +100,9 @@
* functionality. In particular, administrators should be aware that security constraints apply only to the request URL.
* Security constraints do not apply to any destination URL associated with the WebDAV operation (such as COPY or MOVE).
*
+ * If WebDAV functionality is included in a web application where legitimate users may access it via a browser, it is
+ * recommended that the application include CORS protection.
+ *
* To enable WebDAV for a context add the following to web.xml:
*
*
@@ -180,17 +184,6 @@
private static final long serialVersionUID = 1L;
- // -------------------------------------------------------------- Constants
-
- private static final String METHOD_PROPFIND = "PROPFIND";
- private static final String METHOD_PROPPATCH = "PROPPATCH";
- private static final String METHOD_MKCOL = "MKCOL";
- private static final String METHOD_COPY = "COPY";
- private static final String METHOD_MOVE = "MOVE";
- private static final String METHOD_LOCK = "LOCK";
- private static final String METHOD_UNLOCK = "UNLOCK";
-
-
/**
* Default lock timeout value.
*/
@@ -574,13 +567,13 @@
}
switch (method) {
- case METHOD_PROPFIND -> doPropfind(req, resp);
- case METHOD_PROPPATCH -> doProppatch(req, resp);
- case METHOD_MKCOL -> doMkcol(req, resp);
- case METHOD_COPY -> doCopy(req, resp);
- case METHOD_MOVE -> doMove(req, resp);
- case METHOD_LOCK -> doLock(req, resp);
- case METHOD_UNLOCK -> doUnlock(req, resp);
+ case Method.PROPFIND -> doPropfind(req, resp);
+ case Method.PROPPATCH -> doProppatch(req, resp);
+ case Method.MKCOL -> doMkcol(req, resp);
+ case Method.COPY -> doCopy(req, resp);
+ case Method.MOVE -> doMove(req, resp);
+ case Method.LOCK -> doLock(req, resp);
+ case Method.UNLOCK -> doUnlock(req, resp);
// DefaultServlet processing
default -> super.service(req, resp);
}
@@ -680,6 +673,10 @@
if (hrefs.hasNext()) {
currentHref = hrefs.next();
currentPath = getPathFromHref(currentHref, request);
+ if (currentPath == null) {
+ // The path was invalid
+ return false;
+ }
currentWebResource = resources.getResource(currentPath);
} else {
break;
@@ -836,7 +833,7 @@
try (InputStream is = req.getInputStream(); ByteArrayOutputStream os = new ByteArrayOutputStream()) {
IOTools.flow(is, os);
body = os.toByteArray();
- } catch (IOException e) {
+ } catch (IOException ioe) {
resp.sendError(WebdavStatus.SC_BAD_REQUEST);
return;
}
@@ -1037,7 +1034,7 @@
try (InputStream is = req.getInputStream(); ByteArrayOutputStream os = new ByteArrayOutputStream()) {
IOTools.flow(is, os);
body = os.toByteArray();
- } catch (IOException e) {
+ } catch (IOException ioe) {
resp.sendError(WebdavStatus.SC_BAD_REQUEST);
return;
}
@@ -1235,7 +1232,11 @@
String path = getRelativePath(req);
- deleteResource(path, req, resp);
+ WebResource resource = resources.getResource(path);
+ if (!checkIfHeaders(req, resp, resource)) {
+ resp.setStatus(HttpServletResponse.SC_PRECONDITION_FAILED);
+ }
+ deleteResource(path, req, resp, true);
}
@@ -1391,7 +1392,7 @@
try (InputStream is = req.getInputStream(); ByteArrayOutputStream os = new ByteArrayOutputStream()) {
IOTools.flow(is, os);
body = os.toByteArray();
- } catch (IOException e) {
+ } catch (IOException ioe) {
resp.sendError(WebdavStatus.SC_BAD_REQUEST);
return;
}
@@ -1841,7 +1842,7 @@
if (!allowSpecialPaths) {
String upperCasePath = path.toUpperCase(Locale.ENGLISH);
return upperCasePath.startsWith("/WEB-INF/") || upperCasePath.startsWith("/META-INF/") ||
- upperCasePath.equals("/WEB-INF") || upperCasePath.equals("/META-INF");
+ upperCasePath.equals("/WEB-INF") || upperCasePath.equals("/META-INF");
}
return false;
}
@@ -1969,7 +1970,7 @@
if (parentPath == path || parentLock.depth > 0) {
if (parentLock.isExclusive()) {
return !ifHeader.contains(":" + parentLock.token + ">") ||
- (parentLock.principal != null && !parentLock.principal.equals(principal));
+ (parentLock.principal != null && !parentLock.principal.equals(principal));
} else {
for (String token : parentLock.sharedTokens) {
LockInfo lock = sharedLocks.get(token);
@@ -2254,8 +2255,8 @@
} else {
store.copy(source, dest);
}
- } catch (IOException e) {
- log(sm.getString("webdavservlet.inputstreamclosefail", source), e);
+ } catch (IOException ioe) {
+ log(sm.getString("webdavservlet.inputstreamclosefail", source), ioe);
}
} else {
errorList.put(source, Integer.valueOf(WebdavStatus.SC_INTERNAL_SERVER_ERROR));
@@ -2268,27 +2269,6 @@
/**
* Delete a resource.
*
- * @param path Path of the resource which is to be deleted
- * @param req Servlet request
- * @param resp Servlet response
- *
- * @return true if the delete is successful
- *
- * @throws IOException If an IO error occurs
- */
- private boolean deleteResource(String path, HttpServletRequest req, HttpServletResponse resp) throws IOException {
- WebResource resource = resources.getResource(path);
- if (!checkIfHeaders(req, resp, resource)) {
- resp.setStatus(HttpServletResponse.SC_PRECONDITION_FAILED);
- return false;
- }
- return deleteResource(path, req, resp, true);
- }
-
-
- /**
- * Delete a resource.
- *
* @param path Path of the resource which is to be deleted
* @param req Servlet request
* @param resp Servlet response
@@ -2746,8 +2726,8 @@
private static boolean propertyEquals(Node node1, Node node2) {
return node1.getLocalName().equals(node2.getLocalName()) &&
- ((node1.getNamespaceURI() == null && node2.getNamespaceURI() == null) ||
- (node1.getNamespaceURI() != null && node1.getNamespaceURI().equals(node2.getNamespaceURI())));
+ ((node1.getNamespaceURI() == null && node2.getNamespaceURI() == null) ||
+ (node1.getNamespaceURI() != null && node1.getNamespaceURI().equals(node2.getNamespaceURI())));
}
@@ -3040,8 +3020,6 @@
/**
* Wraps the HttpServletResponse class to abstract the specific protocol used. To support other protocols we would only
* need to modify this class and the WebDavRetCode classes.
- *
- * @author Marc Eaddy
*/
class WebdavStatus {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/session/Constants.java tomcat11-11.0.15/java/org/apache/catalina/session/Constants.java
--- tomcat11-11.0.6/java/org/apache/catalina/session/Constants.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/session/Constants.java 2025-12-02 16:54:08.000000000 +0000
@@ -22,8 +22,6 @@
/**
* Manifest constants for the org.apache.catalina.session package.
- *
- * @author Craig R. McClanahan
*/
public class Constants {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/session/DataSourceStore.java tomcat11-11.0.15/java/org/apache/catalina/session/DataSourceStore.java
--- tomcat11-11.0.6/java/org/apache/catalina/session/DataSourceStore.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/session/DataSourceStore.java 2025-12-02 16:54:08.000000000 +0000
@@ -45,8 +45,6 @@
/**
* Implementation of the {@link org.apache.catalina.Store Store} interface that stores serialized session objects in a
* database. Sessions that are saved are still subject to being expired based on inactivity.
- *
- * @author Bip Thelin
*/
public class DataSourceStore extends StoreBase {
@@ -362,7 +360,7 @@
}
}
} catch (SQLException e) {
- manager.getContext().getLogger().error(sm.getString("dataSourceStore.SQLException", e));
+ manager.getContext().getLogger().error(sm.getString("dataSourceStore.SQLException"), e);
keys = new String[0];
// Close the connection so that it gets reopened next time
} finally {
@@ -396,7 +394,7 @@
numberOfTries = 0;
}
} catch (SQLException e) {
- manager.getContext().getLogger().error(sm.getString("dataSourceStore.SQLException", e));
+ manager.getContext().getLogger().error(sm.getString("dataSourceStore.SQLException"), e);
} finally {
release(_conn);
}
@@ -443,7 +441,7 @@
numberOfTries = 0;
}
} catch (SQLException e) {
- contextLog.error(sm.getString("dataSourceStore.SQLException", e));
+ contextLog.error(sm.getString("dataSourceStore.SQLException"), e);
} finally {
context.unbind(oldThreadContextCL);
release(_conn);
@@ -469,7 +467,7 @@
// Break out after the finally block
numberOfTries = 0;
} catch (SQLException e) {
- manager.getContext().getLogger().error(sm.getString("dataSourceStore.SQLException", e));
+ manager.getContext().getLogger().error(sm.getString("dataSourceStore.SQLException"), e);
} finally {
release(_conn);
}
@@ -517,7 +515,7 @@
// Break out after the finally block
numberOfTries = 0;
} catch (SQLException e) {
- manager.getContext().getLogger().error(sm.getString("dataSourceStore.SQLException", e));
+ manager.getContext().getLogger().error(sm.getString("dataSourceStore.SQLException"), e);
} finally {
release(_conn);
}
@@ -563,8 +561,8 @@
numberOfTries = 0;
}
} catch (SQLException e) {
- manager.getContext().getLogger().error(sm.getString("dataSourceStore.SQLException", e));
- } catch (IOException e) {
+ manager.getContext().getLogger().error(sm.getString("dataSourceStore.SQLException"), e);
+ } catch (IOException ioe) {
// Ignore
} finally {
release(_conn);
@@ -600,7 +598,7 @@
}
}
} catch (SQLException ex) {
- manager.getContext().getLogger().error(sm.getString("dataSourceStore.checkConnectionSQLException", ex));
+ manager.getContext().getLogger().error(sm.getString("dataSourceStore.checkConnectionSQLException"), ex);
}
return conn;
@@ -685,7 +683,7 @@
try {
dbConnection.close();
} catch (SQLException e) {
- manager.getContext().getLogger().error(sm.getString("dataSourceStore.close", e));
+ manager.getContext().getLogger().error(sm.getString("dataSourceStore.close"), e);
}
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/session/FileStore.java tomcat11-11.0.15/java/org/apache/catalina/session/FileStore.java
--- tomcat11-11.0.6/java/org/apache/catalina/session/FileStore.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/session/FileStore.java 2025-12-02 16:54:08.000000000 +0000
@@ -26,6 +26,7 @@
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;
+import java.util.concurrent.locks.Lock;
import jakarta.servlet.ServletContext;
@@ -33,13 +34,12 @@
import org.apache.catalina.Session;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
+import org.apache.tomcat.util.concurrent.KeyedReentrantReadWriteLock;
import org.apache.tomcat.util.res.StringManager;
/**
* Concrete implementation of the Store interface that utilizes a file per saved Session in a configured
* directory. Sessions that are saved are still subject to being expired based on inactivity.
- *
- * @author Craig R. McClanahan
*/
public final class FileStore extends StoreBase {
@@ -61,7 +61,7 @@
* The pathname of the directory in which Sessions are stored. This may be an absolute pathname, or a relative path
* that is resolved against the temporary work directory for this application.
*/
- private String directory = ".";
+ private volatile String directory = ".";
/**
@@ -69,6 +69,7 @@
*/
private File directoryFile = null;
+ private KeyedReentrantReadWriteLock sessionLocksById = new KeyedReentrantReadWriteLock();
/**
* Name to register for this Store, used for logging.
@@ -97,7 +98,7 @@
*
* @param path The new directory path
*/
- public void setDirectory(String path) {
+ public synchronized void setDirectory(String path) {
String oldDirectory = this.directory;
this.directory = path;
this.directoryFile = null;
@@ -182,7 +183,7 @@
public Session load(String id) throws ClassNotFoundException, IOException {
// Open an input stream to the specified pathname, if any
File file = file(id);
- if (file == null || !file.exists()) {
+ if (file == null) {
return null;
}
@@ -194,19 +195,28 @@
}
ClassLoader oldThreadContextCL = context.bind(null);
-
- try (FileInputStream fis = new FileInputStream(file.getAbsolutePath());
- ObjectInputStream ois = getObjectInputStream(fis)) {
-
- StandardSession session = (StandardSession) manager.createEmptySession();
- session.readObjectData(ois);
- session.setManager(manager);
- return session;
- } catch (FileNotFoundException e) {
- if (contextLog.isDebugEnabled()) {
- contextLog.debug(sm.getString("fileStore.noFile", id, file.getAbsolutePath()));
+ try {
+ Lock readLock = sessionLocksById.getLock(id).readLock();
+ readLock.lock();
+ try {
+ if (!file.exists()) {
+ return null;
+ }
+ try (FileInputStream fis = new FileInputStream(file.getAbsolutePath());
+ ObjectInputStream ois = getObjectInputStream(fis)) {
+ StandardSession session = (StandardSession) manager.createEmptySession();
+ session.readObjectData(ois);
+ session.setManager(manager);
+ return session;
+ } catch (FileNotFoundException e) {
+ if (contextLog.isDebugEnabled()) {
+ contextLog.debug(sm.getString("fileStore.noFile", id, file.getAbsolutePath()), e);
+ }
+ return null;
+ }
+ } finally {
+ readLock.unlock();
}
- return null;
} finally {
context.unbind(oldThreadContextCL);
}
@@ -224,8 +234,14 @@
.trace(sm.getString(getStoreName() + ".removing", id, file.getAbsolutePath()));
}
- if (file.exists() && !file.delete()) {
- throw new IOException(sm.getString("fileStore.deleteSessionFailed", file));
+ Lock writeLock = sessionLocksById.getLock(id).writeLock();
+ writeLock.lock();
+ try {
+ if (file.exists() && !file.delete()) {
+ throw new IOException(sm.getString("fileStore.deleteSessionFailed", file));
+ }
+ } finally {
+ writeLock.unlock();
}
}
@@ -242,9 +258,15 @@
.trace(sm.getString(getStoreName() + ".saving", session.getIdInternal(), file.getAbsolutePath()));
}
- try (FileOutputStream fos = new FileOutputStream(file.getAbsolutePath());
- ObjectOutputStream oos = new ObjectOutputStream(new BufferedOutputStream(fos))) {
- ((StandardSession) session).writeObjectData(oos);
+ Lock writeLock = sessionLocksById.getLock(session.getIdInternal()).writeLock();
+ writeLock.lock();
+ try {
+ try (FileOutputStream fos = new FileOutputStream(file.getAbsolutePath());
+ ObjectOutputStream oos = new ObjectOutputStream(new BufferedOutputStream(fos))) {
+ ((StandardSession) session).writeObjectData(oos);
+ }
+ } finally {
+ writeLock.unlock();
}
}
@@ -255,12 +277,12 @@
* Return a File object representing the pathname to our session persistence directory, if any. The directory will
* be created if it does not already exist.
*/
- private File directory() throws IOException {
+ private synchronized File directory() throws IOException {
+ // Synchronised to avoid concurrent attempts to create the directory.
if (this.directory == null) {
return null;
}
if (this.directoryFile != null) {
- // NOTE: Race condition is harmless, so do not synchronize
return this.directoryFile;
}
File file = new File(this.directory);
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/session/LocalStrings.properties tomcat11-11.0.15/java/org/apache/catalina/session/LocalStrings.properties
--- tomcat11-11.0.6/java/org/apache/catalina/session/LocalStrings.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/session/LocalStrings.properties 2025-12-02 16:54:08.000000000 +0000
@@ -16,11 +16,11 @@
# Do not edit this file directly.
# To edit translations see: https://tomcat.apache.org/getinvolved.html#Translations
-dataSourceStore.SQLException=SQL Error [{0}]
+dataSourceStore.SQLException=SQL Error
dataSourceStore.checkConnectionDBClosed=The database connection is null or was found to be closed. Trying to re-open it.
dataSourceStore.checkConnectionDBReOpenFail=The re-open on the database failed. The database could be down.
-dataSourceStore.checkConnectionSQLException=A SQL exception occurred [{0}]
-dataSourceStore.close=Exception closing database connection [{0}]
+dataSourceStore.checkConnectionSQLException=A SQL exception occurred checking the connection
+dataSourceStore.close=Exception closing database connection
dataSourceStore.commitSQLException=SQLException committing connection before closing
dataSourceStore.loading=Loading Session [{0}] from database [{1}]
dataSourceStore.missingDataSource=No data source available
@@ -54,7 +54,7 @@
persistentManager.loading=Loading [{0}] persisted sessions
persistentManager.noStore=No Store configured, persistence disabled
persistentManager.removeError=Error removing session [{0}] from the store
-persistentManager.serializeError=Error serializing Session [{0}]: [{1}]
+persistentManager.serializeError=Error serializing Session [{0}]
persistentManager.storeClearError=Error clearning all sessions from the store
persistentManager.storeKeysException=Unable to determine the list of session IDs for sessions in the session store, assuming that the store is empty
persistentManager.storeLoadError=Error swapping in sessions from the store
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/session/LocalStrings_es.properties tomcat11-11.0.15/java/org/apache/catalina/session/LocalStrings_es.properties
--- tomcat11-11.0.6/java/org/apache/catalina/session/LocalStrings_es.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/session/LocalStrings_es.properties 2025-12-02 16:54:08.000000000 +0000
@@ -19,8 +19,8 @@
dataSourceStore.SQLException=Error SQL [{0}]
dataSourceStore.checkConnectionDBClosed=La conexióna a base de datos es nula o está cerrada. Intentando reabrirla.
dataSourceStore.checkConnectionDBReOpenFail=Falló la reapertura de la base de datos. Puede que la base de datos esté caída.
-dataSourceStore.checkConnectionSQLException=Ha tenido lugar una excepción SQL [{0}]
-dataSourceStore.close=Excepción cerrando conexión a base de datos [{0}]
+dataSourceStore.checkConnectionSQLException=Ha tenido lugar una excepción SQL
+dataSourceStore.close=Excepción cerrando conexión a base de datos
dataSourceStore.loading=Cargando Sesión [{0}] desde base de datos [{1}]
dataSourceStore.missingDataSourceName=No se proporcionó un nombre JNDI válido
dataSourceStore.removing=Quitando Sesión [{0}] en base de datos [{1}]
@@ -38,7 +38,7 @@
persistentManager.backupMaxIdle=Respaldando sesión [{0}] a Almacén, ociosa durante [{1}] segundos
persistentManager.deserializeError=Error des-serializando Sesión [{0}]: [{1}]
persistentManager.loading=Cargando [{0}] sesiones persistidas
-persistentManager.serializeError=Error serializando Sesión [{0}]: [{1}]
+persistentManager.serializeError=Error serializando Sesión [{0}]
persistentManager.storeKeysException=Imposible determinar la lista de IDs de sesiones en la tienda de sesiones, asumiendo que la tienda esta vacia
persistentManager.storeSizeException=No se puede determinar el numero de sesiones en el almacenamiento de sesiones, asumiendo que el almacenamiento esta vacío
persistentManager.swapIn=Intercambiando sesión [{0}] a dentro desde Almacén
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/session/LocalStrings_fr.properties tomcat11-11.0.15/java/org/apache/catalina/session/LocalStrings_fr.properties
--- tomcat11-11.0.6/java/org/apache/catalina/session/LocalStrings_fr.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/session/LocalStrings_fr.properties 2025-12-02 16:54:08.000000000 +0000
@@ -19,8 +19,8 @@
dataSourceStore.SQLException=Erreur SQL [{0}]
dataSourceStore.checkConnectionDBClosed=La connexion à la base de données est nulle ou a été trouvée fermée. Tentative de réouverture.
dataSourceStore.checkConnectionDBReOpenFail=La tentative de réouverture de la base de données a échoué. La base de données est peut-être arrêtée.
-dataSourceStore.checkConnectionSQLException=Une exception SQL s''est produite [{0}]
-dataSourceStore.close=Exception lors de la fermeture de la connection vers la base de donnée [{0}]
+dataSourceStore.checkConnectionSQLException=Une exception SQL s'est produite
+dataSourceStore.close=Exception lors de la fermeture de la connection vers la base de donnée
dataSourceStore.commitSQLException=Une SQLException a été retournée lors du commit de la connection avant sa fermeture
dataSourceStore.loading=Chargement de la Session [{0}] depuis la base de données [{1}]
dataSourceStore.missingDataSource=Aucune source de données n'est disponible
@@ -54,7 +54,7 @@
persistentManager.loading=Chargement de [{0}] sessions persistantes
persistentManager.noStore=Aucun stockage (Store) n'a été configuré, la persistence est désactivée
persistentManager.removeError=Erreur en enlevant la session [{0}] du stockage
-persistentManager.serializeError=Erreur lors de la sérialisation de la session [{0}] : [{1}]
+persistentManager.serializeError=Erreur lors de la sérialisation de la session [{0}]
persistentManager.storeClearError=Erreur en supprimant toutes les sessions du stockage
persistentManager.storeKeysException=Incapacité de déterminer la liste des ID de session, pour les sessions dans le magasin de sessions. Supposant le magasin vide.
persistentManager.storeLoadError=Erreur en déplaçant les sessions à partir du stockage
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/session/LocalStrings_ja.properties tomcat11-11.0.15/java/org/apache/catalina/session/LocalStrings_ja.properties
--- tomcat11-11.0.6/java/org/apache/catalina/session/LocalStrings_ja.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/session/LocalStrings_ja.properties 2025-12-02 16:54:08.000000000 +0000
@@ -19,8 +19,8 @@
dataSourceStore.SQLException=SQLエラー [{0}]
dataSourceStore.checkConnectionDBClosed=データベース接続がnullであるか、クローズされているのが見つかりました。再オープンしてください。
dataSourceStore.checkConnectionDBReOpenFail=データベースの再オープンが失敗しました。データベースがダウンしているかもしれません。
-dataSourceStore.checkConnectionSQLException=SQL例外が発生しました [{0}]
-dataSourceStore.close=データベース接続 [{0}] をクローズ中の例外です
+dataSourceStore.checkConnectionSQLException=SQL例外が発生しました
+dataSourceStore.close=データベース接続 をクローズ中の例外です
dataSourceStore.commitSQLException=クローズ前のデータベース接続のコミット中にSQL例外が発生しました
dataSourceStore.loading=セッション [{0}] をデータベース [{1}] からロードします
dataSourceStore.missingDataSource=利用可能なデータソースがありません
@@ -54,7 +54,7 @@
persistentManager.loading=[{0}] の永続化セッションをロードします
persistentManager.noStore=ストアが構成されておらず、永続性が無効になっています
persistentManager.removeError=ストアからセッション[{0}]削除中のエラー
-persistentManager.serializeError=セッション [{0}] をシリアライズ中のエラーです: [{1}]
+persistentManager.serializeError=セッション [{0}] をシリアライズ中のエラーです
persistentManager.storeClearError=ストア上の全セッション消去中のエラー
persistentManager.storeKeysException=セッションストアからセッションIDのリストを取得できませんでした。セッションストアが空の可能性があります
persistentManager.storeLoadError=ストアからのセッションスワップイン中のエラー
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/session/LocalStrings_ko.properties tomcat11-11.0.15/java/org/apache/catalina/session/LocalStrings_ko.properties
--- tomcat11-11.0.6/java/org/apache/catalina/session/LocalStrings_ko.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/session/LocalStrings_ko.properties 2025-12-02 16:54:08.000000000 +0000
@@ -19,8 +19,8 @@
dataSourceStore.SQLException=SQL 오류 [{0}]
dataSourceStore.checkConnectionDBClosed=데이터베이스 연결이 널이거나 닫힌 상태입니다. 다시 열려고 시도합니다.
dataSourceStore.checkConnectionDBReOpenFail=데이터베이스에 대해 다시 연결을 맺지 못했습니다. 데이터베이스가 다운되었을 수 있습니다.
-dataSourceStore.checkConnectionSQLException=SQL 예외 발생 [{0}]
-dataSourceStore.close=데이터베이스 연결 [{0}]을(를) 닫는 동안 예외 발생
+dataSourceStore.checkConnectionSQLException=SQL 예외 발생
+dataSourceStore.close=데이터베이스 연결을(를) 닫는 동안 예외 발생
dataSourceStore.commitSQLException=데이터베이스 연결을 닫기 전, 커밋을 시도하는 중 SQLException 발생
dataSourceStore.loading=데이터베이스 [{1}](으)로부터 세션 [{0}]을(를) 로드합니다.
dataSourceStore.missingDataSource=DataSource를 사용할 수 없습니다.
@@ -51,7 +51,7 @@
persistentManager.isLoadedError=세션 [{0}]이(가) 메모리에 로드되었는지 점검 중 오류 발생
persistentManager.loading=[{0}]개의 저장된 세션들을 로드합니다.
persistentManager.removeError=세션 [{0}]을(를) 저장소로부터 제거하는 중 오류 발생
-persistentManager.serializeError=세션을 직렬화하는 중 오류 발생 [{0}]: [{1}]
+persistentManager.serializeError=세션을 직렬화하는 중 오류 발생 [{0}]
persistentManager.storeClearError=저장소로부터 모든 세션들을 해제하는 중 오류 발생
persistentManager.storeKeysException=세션 저장소에 있는 세션들의 ID 목록을 결정할 수 없습니다. 아마도 세션 저장소가 비어 있는 것 같습니다.
persistentManager.storeLoadError=저장소로부터 세션들을 메모리로 로드하는 중 오류 발생
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/session/LocalStrings_zh_CN.properties tomcat11-11.0.15/java/org/apache/catalina/session/LocalStrings_zh_CN.properties
--- tomcat11-11.0.6/java/org/apache/catalina/session/LocalStrings_zh_CN.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/session/LocalStrings_zh_CN.properties 2025-12-02 16:54:08.000000000 +0000
@@ -19,8 +19,8 @@
dataSourceStore.SQLException=SQL错误[{0}]
dataSourceStore.checkConnectionDBClosed=数据库连接为空或已关闭。正在尝试重新连接。
dataSourceStore.checkConnectionDBReOpenFail=重新打开数据库失败,数据库可能已经宕机。
-dataSourceStore.checkConnectionSQLException=发生 SQL 异常 [{0}]
-dataSourceStore.close=关闭数据库连接[{0}]时发生异常
+dataSourceStore.checkConnectionSQLException=发生 SQL 异常
+dataSourceStore.close=关闭数据库连接时发生异常
dataSourceStore.commitSQLException=关闭前提交连接的SQLException
dataSourceStore.loading=正在从数据库[{1}]加载会话[{0}]
dataSourceStore.missingDataSource=没有可用的数据源
@@ -51,7 +51,7 @@
persistentManager.isLoadedError=检查内存中是否加载了会话[{0}]时出错
persistentManager.loading=正在加载[{0}]持久化会话
persistentManager.removeError=从存储中删除会话[{0}]时出错
-persistentManager.serializeError=错误的序列化会话 [{0}]:[{1}]
+persistentManager.serializeError=错误的序列化会话 [{0}]
persistentManager.storeClearError=清除存储区中的所有会话时出错
persistentManager.storeKeysException=不能从 session存储中获取session ID 的列表,假设存储为空
persistentManager.storeLoadError=从存储区交换会话时出错
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/session/ManagerBase.java tomcat11-11.0.15/java/org/apache/catalina/session/ManagerBase.java
--- tomcat11-11.0.6/java/org/apache/catalina/session/ManagerBase.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/session/ManagerBase.java 2025-12-02 16:54:08.000000000 +0000
@@ -55,8 +55,6 @@
/**
* Minimal implementation of the Manager interface that supports no session persistence or distributable
* capabilities. This class may be subclassed to create more sophisticated Manager implementations.
- *
- * @author Craig R. McClanahan
*/
public abstract class ManagerBase extends LifecycleMBeanBase implements Manager {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/session/PersistentManager.java tomcat11-11.0.15/java/org/apache/catalina/session/PersistentManager.java
--- tomcat11-11.0.6/java/org/apache/catalina/session/PersistentManager.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/session/PersistentManager.java 2025-12-02 16:54:08.000000000 +0000
@@ -26,8 +26,6 @@
*
* If used with a load-balancer, the load-balancer must be configured to use sticky sessions for this manager to operate
* correctly.
- *
- * @author Kief Morris (kief@kief.com)
*/
public final class PersistentManager extends PersistentManagerBase {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/session/PersistentManagerBase.java tomcat11-11.0.15/java/org/apache/catalina/session/PersistentManagerBase.java
--- tomcat11-11.0.6/java/org/apache/catalina/session/PersistentManagerBase.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/session/PersistentManagerBase.java 2025-12-02 16:54:08.000000000 +0000
@@ -38,8 +38,6 @@
*
ClassLoader instance that should become the parent of the new class loader.
*
- *
- * @author Craig R. McClanahan
*/
public final class ClassLoaderFactory {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/startup/Constants.java tomcat11-11.0.15/java/org/apache/catalina/startup/Constants.java
--- tomcat11-11.0.6/java/org/apache/catalina/startup/Constants.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/startup/Constants.java 2025-12-02 16:54:08.000000000 +0000
@@ -20,8 +20,6 @@
* String constants for the startup package.
* Note that some values include a leading '/' and that some do not. This is intentional based on how the values are
* used.
- *
- * @author Craig R. McClanahan
*/
public final class Constants {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/startup/ContextConfig.java tomcat11-11.0.15/java/org/apache/catalina/startup/ContextConfig.java
--- tomcat11-11.0.6/java/org/apache/catalina/startup/ContextConfig.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/startup/ContextConfig.java 2025-12-02 16:54:08.000000000 +0000
@@ -118,8 +118,6 @@
/**
* Startup event listener for a Context that configures the properties of that Context, and the associated
* defined servlets.
- *
- * @author Craig R. McClanahan
*/
public class ContextConfig implements LifecycleListener {
@@ -601,8 +599,8 @@
}
} catch (MalformedURLException e) {
log.error(sm.getString("contextConfig.badUrl", defaultContextXml), e);
- } catch (IOException e) {
- // Not found
+ } catch (IOException ignore) {
+ // Ignore - Not found
}
}
@@ -643,8 +641,8 @@
}
} catch (MalformedURLException e) {
log.error(sm.getString("contextConfig.badUrl", hostContextFile), e);
- } catch (IOException e) {
- // Not found
+ } catch (IOException ignore) {
+ // Ignore - Not found
}
}
}
@@ -675,7 +673,7 @@
generateClassFooter(digester);
try (FileWriter writer = new FileWriter(contextXmlJavaSource)) {
writer.write(digester.getGeneratedCode().toString());
- } catch (IOException e) {
+ } catch (IOException ignore) {
// Ignore
}
digester.endGeneratingCode();
@@ -736,7 +734,8 @@
}
} catch (SAXParseException e) {
log.error(sm.getString("contextConfig.contextParse", context.getName()), e);
- log.error(sm.getString("contextConfig.defaultPosition", "" + e.getLineNumber(), "" + e.getColumnNumber()));
+ log.error(sm.getString("contextConfig.defaultPosition", Integer.toString(e.getLineNumber()),
+ Integer.toString(e.getColumnNumber())));
ok = false;
} catch (Exception e) {
log.error(sm.getString("contextConfig.contextParse", context.getName()), e);
@@ -746,8 +745,8 @@
if (stream != null) {
stream.close();
}
- } catch (IOException e) {
- log.error(sm.getString("contextConfig.contextClose"), e);
+ } catch (IOException ioe) {
+ log.error(sm.getString("contextConfig.contextClose"), ioe);
}
}
}
@@ -943,8 +942,8 @@
try {
fixDocBase();
- } catch (IOException e) {
- log.error(sm.getString("contextConfig.fixDocBase", context.getName()), e);
+ } catch (IOException ioe) {
+ log.error(sm.getString("contextConfig.fixDocBase", context.getName()), ioe);
}
antiLocking();
@@ -1618,8 +1617,8 @@
if (uc != null) {
try {
uc.getInputStream().close();
- } catch (IOException e) {
- ExceptionUtils.handleThrowable(e);
+ } catch (IOException ioe) {
+ ExceptionUtils.handleThrowable(ioe);
globalTimeStamp = -1;
}
}
@@ -1639,8 +1638,8 @@
if (uc != null) {
try {
uc.getInputStream().close();
- } catch (IOException e) {
- ExceptionUtils.handleThrowable(e);
+ } catch (IOException ioe) {
+ ExceptionUtils.handleThrowable(ioe);
hostTimeStamp = -1;
}
}
@@ -1761,8 +1760,8 @@
try {
WebappServiceLoader loader = new WebappServiceLoader<>(context);
detectedScis = loader.load(ServletContainerInitializer.class);
- } catch (IOException e) {
- log.error(sm.getString("contextConfig.servletContainerInitializerFail", context.getName()), e);
+ } catch (IOException ioe) {
+ log.error(sm.getString("contextConfig.servletContainerInitializerFail", context.getName()), ioe);
ok = false;
return;
}
@@ -1775,7 +1774,7 @@
ht = sci.getClass().getAnnotation(HandlesTypes.class);
} catch (Exception e) {
if (log.isDebugEnabled()) {
- log.info(sm.getString("contextConfig.sci.debug", sci.getClass().getName()), e);
+ log.debug(sm.getString("contextConfig.sci.debug", sci.getClass().getName()), e);
} else {
log.info(sm.getString("contextConfig.sci.info", sci.getClass().getName()));
}
@@ -1925,7 +1924,7 @@
if (source == null && stream != null) {
try {
stream.close();
- } catch (IOException e) {
+ } catch (IOException ignore) {
// Ignore
}
}
@@ -1975,7 +1974,7 @@
String hostWebXml = Container.getConfigPath(context, Constants.HostWebXml);
webXmlResource = ConfigFileLoader.getSource().getResource(hostWebXml);
}
- } catch (IOException e) {
+ } catch (IOException ignore) {
// Ignore if not found
return null;
}
@@ -1995,7 +1994,7 @@
if (source == null && stream != null) {
try {
stream.close();
- } catch (IOException e) {
+ } catch (IOException ioe) {
// Ignore
}
}
@@ -2194,8 +2193,8 @@
jar.nextEntry();
entryName = jar.getEntryName();
}
- } catch (IOException e) {
- log.error(sm.getString("contextConfig.jarFile", url), e);
+ } catch (IOException ioe) {
+ log.error(sm.getString("contextConfig.jarFile", url), ioe);
}
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/startup/ContextRuleSet.java tomcat11-11.0.15/java/org/apache/catalina/startup/ContextRuleSet.java
--- tomcat11-11.0.6/java/org/apache/catalina/startup/ContextRuleSet.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/startup/ContextRuleSet.java 2025-12-02 16:54:08.000000000 +0000
@@ -21,8 +21,6 @@
/**
* RuleSet for processing the contents of a Context definition element.
- *
- * @author Craig R. McClanahan
*/
public class ContextRuleSet implements RuleSet {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/startup/CopyParentClassLoaderRule.java tomcat11-11.0.15/java/org/apache/catalina/startup/CopyParentClassLoaderRule.java
--- tomcat11-11.0.6/java/org/apache/catalina/startup/CopyParentClassLoaderRule.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/startup/CopyParentClassLoaderRule.java 2025-12-02 16:54:08.000000000 +0000
@@ -27,8 +27,6 @@
/**
* Rule that copies the parentClassLoader property from the next-to-top item on the stack (which must be a
* Container) to the top item on the stack (which must also be a Container).
- *
- * @author Craig R. McClanahan
*/
public class CopyParentClassLoaderRule extends Rule {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/startup/EngineConfig.java tomcat11-11.0.15/java/org/apache/catalina/startup/EngineConfig.java
--- tomcat11-11.0.6/java/org/apache/catalina/startup/EngineConfig.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/startup/EngineConfig.java 2025-12-02 16:54:08.000000000 +0000
@@ -29,8 +29,6 @@
/**
* Startup event listener for an Engine that configures the properties of that Engine, and the associated defined
* contexts.
- *
- * @author Craig R. McClanahan
*/
public class EngineConfig implements LifecycleListener {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/startup/EngineRuleSet.java tomcat11-11.0.15/java/org/apache/catalina/startup/EngineRuleSet.java
--- tomcat11-11.0.6/java/org/apache/catalina/startup/EngineRuleSet.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/startup/EngineRuleSet.java 2025-12-02 16:54:08.000000000 +0000
@@ -22,8 +22,6 @@
/**
* RuleSet for processing the contents of an Engine definition element. This RuleSet does
* NOT include any rules for nested Host elements, which should be added via instances of HostRuleSet.
- *
- * @author Craig R. McClanahan
*/
public class EngineRuleSet implements RuleSet {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/startup/ExpandWar.java tomcat11-11.0.15/java/org/apache/catalina/startup/ExpandWar.java
--- tomcat11-11.0.6/java/org/apache/catalina/startup/ExpandWar.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/startup/ExpandWar.java 2025-12-02 16:54:08.000000000 +0000
@@ -40,10 +40,6 @@
/**
* Expand out a WAR in a Host's appBase.
- *
- * @author Craig R. McClanahan
- * @author Remy Maucherat
- * @author Glenn L. Nielsen
*/
public class ExpandWar {
@@ -263,8 +259,8 @@
throw new EOFException();
}
}
- } catch (IOException e) {
- log.error(sm.getString("expandWar.copy", fileSrc, fileDest), e);
+ } catch (IOException ioe) {
+ log.error(sm.getString("expandWar.copy", fileSrc, fileDest), ioe);
result = false;
}
}
@@ -274,8 +270,8 @@
/**
- * Delete the specified directory, including all of its contents and subdirectories recursively. Any failure will
- * be logged.
+ * Delete the specified directory, including all of its contents and subdirectories recursively. Any failure will be
+ * logged.
*
* @param dir File object representing the directory to be deleted
*
@@ -314,8 +310,8 @@
/**
- * Delete the specified directory, including all of its contents and subdirectories recursively. Any failure will
- * be logged.
+ * Delete the specified directory, including all of its contents and subdirectories recursively. Any failure will be
+ * logged.
*
* @param dir File object representing the directory to be deleted
*
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/startup/FailedContext.java tomcat11-11.0.15/java/org/apache/catalina/startup/FailedContext.java
--- tomcat11-11.0.6/java/org/apache/catalina/startup/FailedContext.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/startup/FailedContext.java 2025-12-02 16:54:08.000000000 +0000
@@ -1442,4 +1442,15 @@
public void setSuspendWrappedResponseAfterForward(boolean suspendWrappedResponseAfterForward) {
}
+ public long getStartTime() {
+ return -1;
+ }
+
+ public long getStartupTime() {
+ return -1;
+ }
+
+ public long getTldScanTime() {
+ return -1;
+ }
}
\ No newline at end of file
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/startup/HomesUserDatabase.java tomcat11-11.0.15/java/org/apache/catalina/startup/HomesUserDatabase.java
--- tomcat11-11.0.6/java/org/apache/catalina/startup/HomesUserDatabase.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/startup/HomesUserDatabase.java 2025-12-02 16:54:08.000000000 +0000
@@ -25,8 +25,6 @@
/**
* Concrete implementation of the UserDatabase interface considers all directories in a directory whose
* pathname is specified to our constructor to be "home" directories for those users.
- *
- * @author Craig R. McClanahan
*/
public final class HomesUserDatabase implements UserDatabase {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/startup/HostConfig.java tomcat11-11.0.15/java/org/apache/catalina/startup/HostConfig.java
--- tomcat11-11.0.6/java/org/apache/catalina/startup/HostConfig.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/startup/HostConfig.java 2025-12-02 16:54:08.000000000 +0000
@@ -68,9 +68,6 @@
/**
* Startup event listener for a Host that configures the properties of that Host, and the associated defined
* contexts.
- *
- * @author Craig R. McClanahan
- * @author Remy Maucherat
*/
public class HostConfig implements LifecycleListener {
@@ -350,7 +347,7 @@
}
try {
return file.getCanonicalFile();
- } catch (IOException e) {
+ } catch (IOException ioe) {
return file;
}
}
@@ -801,14 +798,15 @@
if (entry != null) {
xmlInWar = true;
}
- } catch (IOException e) {
- /* Ignore */
+ } catch (IOException ignore) {
+ // Ignore
}
// If there is an expanded directory then any xml in that directory
// should only be used if the directory is not out of date and
// unpackWARs is true. Note the code below may apply further limits
- boolean useXml = xml.exists() && unpackWARs && (!warTracker.exists() || warTracker.lastModified() == war.lastModified());
+ boolean useXml =
+ xml.exists() && unpackWARs && (!warTracker.exists() || warTracker.lastModified() == war.lastModified());
// If the xml file exists then expandedDir must exist so no need to
// test that here
@@ -885,8 +883,8 @@
OutputStream ostream = new FileOutputStream(xml)) {
IOTools.flow(istream, ostream);
}
- } catch (IOException e) {
- /* Ignore */
+ } catch (IOException ignore) {
+ // Ignore
}
}
}
@@ -1510,16 +1508,16 @@
String canonicalLocation;
try {
canonicalLocation = resource.getParentFile().getCanonicalPath();
- } catch (IOException e) {
- log.warn(sm.getString("hostConfig.canonicalizing", resource.getParentFile(), app.name), e);
+ } catch (IOException ioe) {
+ log.warn(sm.getString("hostConfig.canonicalizing", resource.getParentFile(), app.name), ioe);
return false;
}
String canonicalAppBase;
try {
canonicalAppBase = host.getAppBaseFile().getCanonicalPath();
- } catch (IOException e) {
- log.warn(sm.getString("hostConfig.canonicalizing", host.getAppBaseFile(), app.name), e);
+ } catch (IOException ioe) {
+ log.warn(sm.getString("hostConfig.canonicalizing", host.getAppBaseFile(), app.name), ioe);
return false;
}
@@ -1531,8 +1529,8 @@
String canonicalConfigBase;
try {
canonicalConfigBase = host.getConfigBaseFile().getCanonicalPath();
- } catch (IOException e) {
- log.warn(sm.getString("hostConfig.canonicalizing", host.getConfigBaseFile(), app.name), e);
+ } catch (IOException ioe) {
+ log.warn(sm.getString("hostConfig.canonicalizing", host.getConfigBaseFile(), app.name), ioe);
return false;
}
@@ -1823,8 +1821,7 @@
public boolean loggedDirWarning = false;
}
- private record DeployDescriptor(HostConfig config, ContextName cn,
- File descriptor) implements Runnable {
+ private record DeployDescriptor(HostConfig config, ContextName cn, File descriptor) implements Runnable {
@Override
public void run() {
try {
@@ -1846,8 +1843,7 @@
}
}
- private record DeployDirectory(HostConfig config, ContextName cn,
- File dir) implements Runnable {
+ private record DeployDirectory(HostConfig config, ContextName cn, File dir) implements Runnable {
@Override
public void run() {
try {
@@ -1859,8 +1855,7 @@
}
- private record MigrateApp(HostConfig config, ContextName cn, File source,
- File destination) implements Runnable {
+ private record MigrateApp(HostConfig config, ContextName cn, File source, File destination) implements Runnable {
@Override
public void run() {
try {
@@ -1873,16 +1868,15 @@
/*
- * The purpose of this class is to provide a way for HostConfig to get a Context to delete an expanded WAR after the
- * Context stops. This is to resolve this issue described in Bug 57772. The alternative solutions require either
- * duplicating a lot of the Context.reload() code in HostConfig or adding a new reload(boolean) method to Context
- * that allows the caller to optionally delete any expanded WAR.
- *
- * The LifecycleListener approach offers greater flexibility and enables the behaviour to be changed / extended /
- * removed in future without changing the Context API.
- */
- private record ExpandedDirectoryRemovalListener(File toDelete,
- String newDocBase) implements LifecycleListener {
+ * The purpose of this class is to provide a way for HostConfig to get a Context to delete an expanded WAR after the
+ * Context stops. This is to resolve this issue described in Bug 57772. The alternative solutions require either
+ * duplicating a lot of the Context.reload() code in HostConfig or adding a new reload(boolean) method to Context
+ * that allows the caller to optionally delete any expanded WAR.
+ *
+ * The LifecycleListener approach offers greater flexibility and enables the behaviour to be changed / extended /
+ * removed in future without changing the Context API.
+ */
+ private record ExpandedDirectoryRemovalListener(File toDelete, String newDocBase) implements LifecycleListener {
@Override
public void lifecycleEvent(LifecycleEvent event) {
if (Lifecycle.AFTER_STOP_EVENT.equals(event.getType())) {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/startup/HostRuleSet.java tomcat11-11.0.15/java/org/apache/catalina/startup/HostRuleSet.java
--- tomcat11-11.0.6/java/org/apache/catalina/startup/HostRuleSet.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/startup/HostRuleSet.java 2025-12-02 16:54:08.000000000 +0000
@@ -22,8 +22,6 @@
/**
* RuleSet for processing the contents of a Host definition element. This RuleSet does NOT
* include any rules for nested Context which should be added via instances of ContextRuleSet.
- *
- * @author Craig R. McClanahan
*/
public class HostRuleSet implements RuleSet {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/startup/ListenerCreateRule.java tomcat11-11.0.15/java/org/apache/catalina/startup/ListenerCreateRule.java
--- tomcat11-11.0.6/java/org/apache/catalina/startup/ListenerCreateRule.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/startup/ListenerCreateRule.java 2025-12-02 16:54:08.000000000 +0000
@@ -49,7 +49,7 @@
} catch (Exception e) {
String className = getRealClassName(attributes);
if (log.isDebugEnabled()) {
- log.info(sm.getString("listener.createFailed", className), e);
+ log.debug(sm.getString("listener.createFailed", className), e);
} else {
log.info(sm.getString("listener.createFailed", className));
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/startup/LocalStrings_ja.properties tomcat11-11.0.15/java/org/apache/catalina/startup/LocalStrings_ja.properties
--- tomcat11-11.0.6/java/org/apache/catalina/startup/LocalStrings_ja.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/startup/LocalStrings_ja.properties 2025-12-02 16:54:08.000000000 +0000
@@ -153,7 +153,7 @@
hostConfig.migrateError=マイグレーション失敗
hostConfig.reload=リロード中のコンテキスト [{0}]
hostConfig.resourceNotAbsolute=[{1}] は完全パスではないためコンテキスト [{0}] からリソースを削除できません
-hostConfig.start=HostConfig: 処理を停止します
+hostConfig.start=HostConfig: 処理を開始します
hostConfig.stop=HostConfig: 処理を停止します
hostConfig.undeploy=コンテキストパス [{0}] のWebアプリケーションの配備を解除します
hostConfig.undeployVersion=コンテキスト [{0}] について有効なセッションの存在しない古いバージョンの配備を解除します。
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/startup/LocalStrings_ru.properties tomcat11-11.0.15/java/org/apache/catalina/startup/LocalStrings_ru.properties
--- tomcat11-11.0.6/java/org/apache/catalina/startup/LocalStrings_ru.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/startup/LocalStrings_ru.properties 2025-12-02 16:54:08.000000000 +0000
@@ -24,8 +24,12 @@
contextConfig.defaultMissing=Не обнаружен глобальный web.xml
contextConfig.defaultPosition=Произошло в строке [{0}] столбце [{1}]
contextConfig.inputStreamWebResource=Не возможно обработать веб ресурс [{0}] для аннотаций\n
+contextConfig.jspFile.error=JSP файл [{0}] должен начинаться с ''/''
+contextConfig.processAnnotationsDir.debug=Сканируется директория в поисках файлов классов с аннотациями [{0}]
contextConfig.tomcatWebXmlError=Ошибка обработки /WEB-INF/tomcat-web.xml
+expandWar.createFailed=Невозможно создать директорию [{0}]
+
hostConfig.deployDir=Установка веб приложения в папку [{0}]
hostConfig.deployWar.error=Ошибка при развертывании архива с веб-приложением [{0}]
hostConfig.docBaseUrlInvalid=Предоставленый docBase не может быть представлен в виде URL
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/startup/MimeTypeMappings.properties tomcat11-11.0.15/java/org/apache/catalina/startup/MimeTypeMappings.properties
--- tomcat11-11.0.6/java/org/apache/catalina/startup/MimeTypeMappings.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/startup/MimeTypeMappings.properties 2025-12-02 16:54:08.000000000 +0000
@@ -62,6 +62,7 @@
atx=application/vnd.antix.game-component
au=audio/basic
avi=video/x-msvideo
+avif=image/avif
avx=video/x-rad-screenplay
aw=application/applixware
axa=audio/annodex
@@ -388,6 +389,7 @@
json=application/json
jsonml=application/jsonml+json
jspf=text/plain
+jxl=image/jxl
kar=audio/midi
karbon=application/vnd.kde.karbon
kfo=application/vnd.kde.kformula
@@ -430,6 +432,8 @@
m1v=video/mpeg
m21=application/mp21
m2a=audio/mpeg
+m2t=video/mp2t
+m2ts=video/mp2t
m2v=video/mpeg
m3a=audio/mpeg
m3u=audio/x-mpegurl
@@ -522,7 +526,7 @@
msi=application/x-msdownload
msl=application/vnd.mobius.msl
msty=application/vnd.muvee.style
-mts=model/vnd.mts
+mts=video/mp2t
mus=application/vnd.musician
musicxml=application/vnd.recordare.musicxml+xml
mvb=application/x-msmediaview
@@ -777,6 +781,8 @@
spq=application/scvp-vp-request
spx=audio/ogg
sql=application/x-sql
+sqlite=application/vnd.sqlite3
+sqlite3=application/vnd.sqlite3
src=application/x-wais-source
srt=application/x-subrip
sru=application/sru+xml
@@ -839,6 +845,7 @@
tr=text/troff
tra=application/vnd.trueapp
trm=application/x-msterminal
+ts=video/mp2t
tsd=application/timestamped-data
tsv=text/tab-separated-values
ttc=font/collection
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/startup/NamingRuleSet.java tomcat11-11.0.15/java/org/apache/catalina/startup/NamingRuleSet.java
--- tomcat11-11.0.6/java/org/apache/catalina/startup/NamingRuleSet.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/startup/NamingRuleSet.java 2025-12-02 16:54:08.000000000 +0000
@@ -21,9 +21,6 @@
/**
* RuleSet for processing the JNDI Enterprise Naming Context resource declaration elements.
- *
- * @author Craig R. McClanahan
- * @author Remy Maucherat
*/
public class NamingRuleSet implements RuleSet {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/startup/PasswdUserDatabase.java tomcat11-11.0.15/java/org/apache/catalina/startup/PasswdUserDatabase.java
--- tomcat11-11.0.6/java/org/apache/catalina/startup/PasswdUserDatabase.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/startup/PasswdUserDatabase.java 2025-12-02 16:54:08.000000000 +0000
@@ -30,8 +30,6 @@
/**
* Concrete implementation of the UserDatabase interface that processes the /etc/passwd file
* on a Unix system.
- *
- * @author Craig R. McClanahan
*/
public final class PasswdUserDatabase implements UserDatabase {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/startup/Tomcat.java tomcat11-11.0.15/java/org/apache/catalina/startup/Tomcat.java
--- tomcat11-11.0.6/java/org/apache/catalina/startup/Tomcat.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/startup/Tomcat.java 2025-12-02 16:54:08.000000000 +0000
@@ -131,8 +131,6 @@
*
* @see TestTomcat
- *
- * @author Costin Manolache
*/
public class Tomcat {
@@ -811,7 +809,7 @@
}
try {
baseFile = baseFile.getCanonicalFile();
- } catch (IOException e) {
+ } catch (IOException ioe) {
baseFile = baseFile.getAbsoluteFile();
}
server.setCatalinaBase(baseFile);
@@ -828,7 +826,7 @@
}
try {
homeFile = homeFile.getCanonicalFile();
- } catch (IOException e) {
+ } catch (IOException ioe) {
homeFile = homeFile.getAbsoluteFile();
}
server.setCatalinaHome(homeFile);
@@ -876,10 +874,10 @@
/**
- * By default, when calling addWebapp() to create a Context, the settings from the default web.xml are added to
- * the context. Calling this method with a false value prior to calling addWebapp() allows to opt out
- * of the default settings. In that event you will need to add the configurations yourself, either programmatically
- * or by using web.xml deployment descriptors.
+ * By default, when calling addWebapp() to create a Context, the settings from the default web.xml are added to the
+ * context. Calling this method with a false value prior to calling addWebapp() allows to opt out of
+ * the default settings. In that event you will need to add the configurations yourself, either programmatically or
+ * by using web.xml deployment descriptors.
*
* @param addDefaultWebXmlToWebapp false will prevent the class from automatically adding the default
* settings when calling addWebapp(). true will add the default
@@ -992,7 +990,6 @@
*
MIME mappings (subset of those in conf/web.xml)
*
Welcome files
*
- * TODO: Align the MIME mappings with conf/web.xml - possibly via a common file.
*
* @param contextPath The path of the context to set the defaults for
*/
@@ -1034,11 +1031,15 @@
ctx.addWelcomeFile("index.html");
ctx.addWelcomeFile("index.htm");
ctx.addWelcomeFile("index.jsp");
+ // Any application configured welcome files should override the defaults.
+ if (ctx instanceof StandardContext stdCtx) {
+ stdCtx.setReplaceWelcomeFiles(true);
+ }
}
/**
- * Add the default MIME type mappings to the provide Context.
+ * Add the default MIME type mappings to the provided Context.
*
* @param context The web application to which the default MIME type mappings should be added.
*/
@@ -1049,8 +1050,8 @@
for (Map.Entry
*
*
internalProxies
- *
Regular expression that matches the IP addresses of internal proxies. If they appear in the
- * remoteIpHeader value, they will be trusted and will not appear in the proxiesHeader
- * value
+ *
Either a comma separated list of CIDR blocks or a single regular expression that matches the IP addresses of
+ * internal proxies. If they appear in the remoteIpHeader value, they will be trusted and will not appear
+ * in the proxiesHeader value
*
RemoteIPInternalProxy
- *
Regular expression (in the syntax supported by {@link java.util.regex.Pattern java.util.regex})
Regular expression that matches the IP addresses of trusted proxies. If they appear in the
- * remoteIpHeader value, they will be trusted and will appear in the proxiesHeader value
+ *
Either a comma separated list of CIDR blocks or a single regular expression that matches the IP addresses of
+ * internal proxies. If they appear in the remoteIpHeader value, they will be trusted and will appear in
+ * the proxiesHeader value
*
RemoteIPTrustedProxy
- *
Regular expression (in the syntax supported by {@link java.util.regex.Pattern java.util.regex})
+ *
Comma separated list of CIDR blocks or a single regular expression {@link Pattern}
*
*
*
@@ -154,14 +150,6 @@
*
* This Valve may be attached to any Container, depending on the granularity of the filtering you wish to perform.
*
- *
- * Regular expression vs. IP address blocks:mod_remoteip allows to use address blocks
- * (e.g. 192.168/16) to configure RemoteIPInternalProxy and RemoteIPTrustedProxy
- * ; as Tomcat doesn't have a library similar to apr_ipsubnet_test,
- * RemoteIpValve uses regular expression to configure internalProxies and
- * trustedProxies in the same fashion as {@link RequestFilterValve} does.
- *
*/
public class RemoteIpValve extends ValveBase {
- /**
- * Logger
- */
+
private static final Log log = LogFactory.getLog(RemoteIpValve.class);
private String hostHeader = null;
private boolean changeLocalName = false;
- /**
- * @see #setHttpServerPort(int)
- */
private int httpServerPort = 80;
- /**
- * @see #setHttpsServerPort(int)
- */
private int httpsServerPort = 443;
private String portHeader = null;
private boolean changeLocalPort = false;
- /**
- * @see #setInternalProxies(String)
- */
- private Pattern internalProxies =
- Pattern.compile("10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}|" + "192\\.168\\.\\d{1,3}\\.\\d{1,3}|" +
- "169\\.254\\.\\d{1,3}\\.\\d{1,3}|" + "127\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}|" +
- "100\\.6[4-9]{1}\\.\\d{1,3}\\.\\d{1,3}|" + "100\\.[7-9]{1}\\d{1}\\.\\d{1,3}\\.\\d{1,3}|" +
- "100\\.1[0-1]{1}\\d{1}\\.\\d{1,3}\\.\\d{1,3}|" + "100\\.12[0-7]{1}\\.\\d{1,3}\\.\\d{1,3}|" +
- "172\\.1[6-9]{1}\\.\\d{1,3}\\.\\d{1,3}|" + "172\\.2[0-9]{1}\\.\\d{1,3}\\.\\d{1,3}|" +
- "172\\.3[0-1]{1}\\.\\d{1,3}\\.\\d{1,3}|" + "0:0:0:0:0:0:0:1|::1|" +
- "fe[89ab]\\p{XDigit}:.*|" + "f[cd]\\p{XDigit}{2}+:.*");
+ private Pattern internalProxiesRegex = null;
+
+ private NetMaskSet internalProxiesCidr =
+ NetMaskSet.parse("10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,169.254.0.0/16,100.64.0.0/10,127.0.0.0/8," +
+ "::1/128,fe80::/10,fc00::/7");
- /**
- * @see #setProtocolHeader(String)
- */
private String protocolHeader = "X-Forwarded-Proto";
- /**
- * @see #setProtocolHeaderHttpsValue(String)
- */
private String protocolHeaderHttpsValue = "https";
- /**
- * @see #setProxiesHeader(String)
- */
private String proxiesHeader = "X-Forwarded-By";
- /**
- * @see #setRemoteIpHeader(String)
- */
private String remoteIpHeader = "X-Forwarded-For";
- /**
- * @see #setRequestAttributesEnabled(boolean)
- */
private boolean requestAttributesEnabled = true;
- /**
- * @see RemoteIpValve#setTrustedProxies(String)
- */
- private Pattern trustedProxies = null;
+ private Pattern trustedProxiesRegex = null;
+
+ private NetMaskSet trustedProxiesCidr = null;
/**
@@ -496,15 +454,18 @@
}
/**
- * @see #setInternalProxies(String)
+ * Obtain the currently configured internal proxies.
*
- * @return Regular expression that defines the internal proxies
+ * @return The currently configured internal proxies.
*/
public String getInternalProxies() {
- if (internalProxies == null) {
+ if (internalProxiesCidr != null) {
+ return internalProxiesCidr.toString();
+ } else if (internalProxiesRegex != null) {
+ return internalProxiesRegex.toString();
+ } else {
return null;
}
- return internalProxies.toString();
}
/**
@@ -553,15 +514,18 @@
}
/**
- * @see #setTrustedProxies(String)
+ * Obtain the currently configured trusted proxies.
*
- * @return Regular expression that defines the trusted proxies
+ * @return The currently configured trusted proxies.
*/
public String getTrustedProxies() {
- if (trustedProxies == null) {
+ if (trustedProxiesCidr != null) {
+ return trustedProxiesCidr.toString();
+ } else if (trustedProxiesRegex != null) {
+ return trustedProxiesRegex.toString();
+ } else {
return null;
}
- return trustedProxies.toString();
}
@Override
@@ -576,9 +540,10 @@
final int originalLocalPort = request.getLocalPort();
final String originalProxiesHeader = request.getHeader(proxiesHeader);
final String originalRemoteIpHeader = request.getHeader(remoteIpHeader);
- boolean isInternal = internalProxies != null && internalProxies.matcher(originalRemoteAddr).matches();
- if (isInternal || (trustedProxies != null && trustedProxies.matcher(originalRemoteAddr).matches())) {
+ boolean isInternal = isInternalProxy(originalRemoteAddr);
+
+ if (isInternal || isTrustedProxy(originalRemoteAddr)) {
String remoteIp = null;
Deque proxiesHeaderValue = new ArrayDeque<>();
StringBuilder concatRemoteIpHeaderValue = new StringBuilder();
@@ -600,9 +565,9 @@
for (idx = remoteIpHeaderValue.length - 1; idx >= 0; idx--) {
String currentRemoteIp = remoteIpHeaderValue[idx];
remoteIp = currentRemoteIp;
- if (internalProxies != null && internalProxies.matcher(currentRemoteIp).matches()) {
+ if (isInternalProxy(currentRemoteIp)) {
// do nothing, internalProxies IPs are not appended to the
- } else if (trustedProxies != null && trustedProxies.matcher(currentRemoteIp).matches()) {
+ } else if (isTrustedProxy(currentRemoteIp)) {
proxiesHeaderValue.addFirst(currentRemoteIp);
} else {
idx--; // decrement idx because break statement doesn't do it
@@ -628,7 +593,9 @@
// We know we need a DNS look up so use getCanonicalHostName()
request.setRemoteHost(inetAddress.getCanonicalHostName());
} catch (UnknownHostException e) {
- log.debug(sm.getString("remoteIpValve.invalidRemoteAddress", remoteIp), e);
+ if (log.isDebugEnabled()) {
+ log.debug(sm.getString("remoteIpValve.invalidRemoteAddress", remoteIp), e);
+ }
request.setRemoteHost(remoteIp);
}
} else {
@@ -683,7 +650,7 @@
}
} catch (IllegalArgumentException iae) {
- log.debug(sm.getString("remoteIpValve.invalidHostHeader", hostHeaderValue, hostHeader));
+ log.debug(sm.getString("remoteIpValve.invalidHostHeader", hostHeaderValue, hostHeader), iae);
}
}
}
@@ -745,6 +712,47 @@
}
}
+ /**
+ * Checks if the given IP address is from an internal proxy.
+ *
+ * @param remoteIp The IP address to check
+ *
+ * @return {@code true} if the IP address is from an internal proxy, otherwise {@code false}
+ */
+ private boolean isInternalProxy(String remoteIp) {
+ if (internalProxiesRegex != null && internalProxiesRegex.matcher(remoteIp).matches()) {
+ return true;
+ }
+ return checkIsCidr(internalProxiesCidr, remoteIp);
+ }
+
+ /**
+ * Checks if the given IP address is from a trusted proxy.
+ *
+ * @param remoteIp The IP address to check
+ *
+ * @return {@code true} if the IP address is from a trusted proxy, otherwise {@code false}
+ */
+ private boolean isTrustedProxy(String remoteIp) {
+ if (trustedProxiesRegex != null && trustedProxiesRegex.matcher(remoteIp).matches()) {
+ return true;
+ }
+
+ return checkIsCidr(trustedProxiesCidr, remoteIp);
+ }
+
+ private boolean checkIsCidr(NetMaskSet netMaskSet, String remoteIp) {
+ if (netMaskSet == null) {
+ return false;
+ }
+ try {
+ return netMaskSet.contains(remoteIp);
+ } catch (UnknownHostException uhe) {
+ log.debug(sm.getString("remoteIpFilter.invalidRemoteAddress", remoteIp), uhe);
+ }
+ return false;
+ }
+
/*
* Considers the value to be secure if it exclusively holds forwards for {@link #protocolHeaderHttpsValue}.
*/
@@ -813,21 +821,20 @@
}
/**
- *
- * Regular expression that defines the internal proxies.
- *
- *
- * Default value :
- * 10\.\d{1,3}\.\d{1,3}\.\d{1,3}|192\.168\.\d{1,3}\.\d{1,3}|169\.254.\d{1,3}.\d{1,3}|127\.\d{1,3}\.\d{1,3}\.\d{1,3}|0:0:0:0:0:0:0:1
- *
+ * Set the internal proxies either as a comma separated list of CIDR blocks or a single regular expression.
*
- * @param internalProxies The proxy regular expression
+ * @param internalProxies The new internal proxies
*/
public void setInternalProxies(String internalProxies) {
if (internalProxies == null || internalProxies.isEmpty()) {
- this.internalProxies = null;
+ this.internalProxiesRegex = null;
+ this.internalProxiesCidr = null;
+ } else if (internalProxies.indexOf('/') > 0) {
+ this.internalProxiesRegex = null;
+ this.internalProxiesCidr = NetMaskSet.parse(internalProxies);
} else {
- this.internalProxies = Pattern.compile(internalProxies);
+ this.internalProxiesRegex = Pattern.compile(internalProxies);
+ this.internalProxiesCidr = null;
}
}
@@ -920,20 +927,20 @@
}
/**
- *
- * Regular expression defining proxies that are trusted when they appear in the {@link #remoteIpHeader} header.
- *
- *
- * Default value : empty list, no external proxy is trusted.
- *
+ * Set the trusted proxies either as a comma separated list of CIDR blocks or a single regular expression.
*
- * @param trustedProxies The regular expression
+ * @param trustedProxies The new trusted proxies
*/
public void setTrustedProxies(String trustedProxies) {
if (trustedProxies == null || trustedProxies.isEmpty()) {
- this.trustedProxies = null;
+ this.trustedProxiesRegex = null;
+ this.trustedProxiesCidr = null;
+ } else if (trustedProxies.indexOf('/') > 0) {
+ this.trustedProxiesRegex = null;
+ this.trustedProxiesCidr = NetMaskSet.parse(trustedProxies);
} else {
- this.trustedProxies = Pattern.compile(trustedProxies);
+ this.trustedProxiesCidr = null;
+ this.trustedProxiesRegex = Pattern.compile(trustedProxies);
}
}
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/valves/RequestFilterValve.java tomcat11-11.0.15/java/org/apache/catalina/valves/RequestFilterValve.java
--- tomcat11-11.0.6/java/org/apache/catalina/valves/RequestFilterValve.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/valves/RequestFilterValve.java 2025-12-02 16:54:08.000000000 +0000
@@ -53,8 +53,6 @@
* authentication instead of denial.
*
* This Valve may be attached to any Container, depending on the granularity of the filtering you wish to perform.
- *
- * @author Craig R. McClanahan
*/
public abstract class RequestFilterValve extends ValveBase {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/valves/SemaphoreValve.java tomcat11-11.0.15/java/org/apache/catalina/valves/SemaphoreValve.java
--- tomcat11-11.0.6/java/org/apache/catalina/valves/SemaphoreValve.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/valves/SemaphoreValve.java 2025-12-02 16:54:08.000000000 +0000
@@ -35,8 +35,6 @@
* perform. Note that internally, some async requests may require multiple serial requests to complete what - to the
* user - appears as a single request.
*
- *
- * @author Remy Maucherat
*/
public class SemaphoreValve extends ValveBase {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/valves/StuckThreadDetectionValve.java tomcat11-11.0.15/java/org/apache/catalina/valves/StuckThreadDetectionValve.java
--- tomcat11-11.0.6/java/org/apache/catalina/valves/StuckThreadDetectionValve.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/valves/StuckThreadDetectionValve.java 2025-12-02 16:54:08.000000000 +0000
@@ -325,7 +325,9 @@
// going out from here, maybe already serving a new request
this.interruptionSemaphore.acquire();
} catch (InterruptedException e) {
- log.debug(sm.getString("stuckThreadDetectionValve.interrupted"), e);
+ if (log.isDebugEnabled()) {
+ log.debug(sm.getString("stuckThreadDetectionValve.interrupted"), e);
+ }
}
// no need to release the semaphore, it will be GCed
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/valves/ValveBase.java tomcat11-11.0.15/java/org/apache/catalina/valves/ValveBase.java
--- tomcat11-11.0.6/java/org/apache/catalina/valves/ValveBase.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/valves/ValveBase.java 2025-12-02 16:54:08.000000000 +0000
@@ -31,8 +31,6 @@
* Convenience base class for implementations of the Valve interface. A subclass MUST implement
* an invoke() method to provide the required functionality, and MAY implement the
* Lifecycle interface to provide configuration management and lifecycle support.
- *
- * @author Craig R. McClanahan
*/
public abstract class ValveBase extends LifecycleMBeanBase implements Contained, Valve {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/valves/mbeans-descriptors.xml tomcat11-11.0.15/java/org/apache/catalina/valves/mbeans-descriptors.xml
--- tomcat11-11.0.6/java/org/apache/catalina/valves/mbeans-descriptors.xml 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/valves/mbeans-descriptors.xml 2025-12-02 16:54:08.000000000 +0000
@@ -554,7 +554,7 @@
type="java.lang.String"/>
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/valves/rewrite/LocalStrings.properties tomcat11-11.0.15/java/org/apache/catalina/valves/rewrite/LocalStrings.properties
--- tomcat11-11.0.6/java/org/apache/catalina/valves/rewrite/LocalStrings.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/valves/rewrite/LocalStrings.properties 2025-12-02 16:54:08.000000000 +0000
@@ -18,6 +18,8 @@
quotedStringTokenizer.tokenizeError=Error tokenizing text [{0}] after position [{1}] from mode [{2}]
+resolverImpl.tlsError=Unable to obtain TLS information
+
rewriteMap.tooManyParameters=Too many parameters for this map
rewriteMap.txtInvalidLine=Invalid line [{0}] in text file [{1}]
rewriteMap.txtReadError=Error reading text file [{0}]
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/valves/rewrite/LocalStrings_fr.properties tomcat11-11.0.15/java/org/apache/catalina/valves/rewrite/LocalStrings_fr.properties
--- tomcat11-11.0.6/java/org/apache/catalina/valves/rewrite/LocalStrings_fr.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/valves/rewrite/LocalStrings_fr.properties 2025-12-02 16:54:08.000000000 +0000
@@ -18,6 +18,8 @@
quotedStringTokenizer.tokenizeError=Erreur de découpage du texte [{0}] après la position [{1}] en utilisant le mode [{2}]
+resolverImpl.tlsError=Impossible d'obtenir l'information TLS
+
rewriteMap.tooManyParameters=Cette map ne supporte pas plusieurs paramètres
rewriteMap.txtInvalidLine=Ligne invalide [{0}] dans le fichier texte [{1}]
rewriteMap.txtReadError=Erreur en lisant le fichier texte [{0}]
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/valves/rewrite/LocalStrings_ja.properties tomcat11-11.0.15/java/org/apache/catalina/valves/rewrite/LocalStrings_ja.properties
--- tomcat11-11.0.6/java/org/apache/catalina/valves/rewrite/LocalStrings_ja.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/valves/rewrite/LocalStrings_ja.properties 2025-12-02 16:54:08.000000000 +0000
@@ -18,6 +18,8 @@
quotedStringTokenizer.tokenizeError=モード [{2}] の位置 [{1}] の後のテキスト [{0}] のトークン化中にエラーが発生しました
+resolverImpl.tlsError=TLS情報を取得できません
+
rewriteMap.tooManyParameters=このマップのパラメータが多すぎます
rewriteMap.txtInvalidLine=テキスト ファイル [{1}] の行 [{0}] が無効です
rewriteMap.txtReadError=テキスト ファイル [{0}] の読み取り中のエラー
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/valves/rewrite/QuotedStringTokenizer.java tomcat11-11.0.15/java/org/apache/catalina/valves/rewrite/QuotedStringTokenizer.java
--- tomcat11-11.0.6/java/org/apache/catalina/valves/rewrite/QuotedStringTokenizer.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/valves/rewrite/QuotedStringTokenizer.java 2025-12-02 16:54:08.000000000 +0000
@@ -71,9 +71,8 @@
currentMode = WordMode.SPACES;
}
}
- default ->
- throw new IllegalStateException(sm.getString("quotedStringTokenizer.tokenizeError", inputText,
- Integer.valueOf(pos), currentMode));
+ default -> throw new IllegalStateException(sm.getString("quotedStringTokenizer.tokenizeError",
+ inputText, Integer.valueOf(pos), currentMode));
}
pos++;
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/valves/rewrite/RandomizedTextRewriteMap.java tomcat11-11.0.15/java/org/apache/catalina/valves/rewrite/RandomizedTextRewriteMap.java
--- tomcat11-11.0.6/java/org/apache/catalina/valves/rewrite/RandomizedTextRewriteMap.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/valves/rewrite/RandomizedTextRewriteMap.java 2025-12-02 16:54:08.000000000 +0000
@@ -50,8 +50,11 @@
BufferedReader reader = new BufferedReader(new InputStreamReader(txtResource.getInputStream()))) {
while ((line = reader.readLine()) != null) {
if (line.startsWith("#") || line.isEmpty()) {
- // Ignore comment or empty lines
+ // Ignore comment line or empty lines
continue;
+ } else if (line.indexOf('#') > 0) {
+ // Ignore comment characters after '#'
+ line = line.substring(0, line.indexOf('#')).trim();
}
String[] keyValuePair = line.split(" ", 2);
if (keyValuePair.length > 1) {
@@ -69,8 +72,8 @@
throw new IllegalArgumentException(sm.getString("rewriteMap.txtInvalidLine", line, txtFilePath));
}
}
- } catch (IOException e) {
- throw new IllegalArgumentException(sm.getString("rewriteMap.txtReadError", txtFilePath), e);
+ } catch (IOException ioe) {
+ throw new IllegalArgumentException(sm.getString("rewriteMap.txtReadError", txtFilePath), ioe);
}
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/valves/rewrite/ResolverImpl.java tomcat11-11.0.15/java/org/apache/catalina/valves/rewrite/ResolverImpl.java
--- tomcat11-11.0.6/java/org/apache/catalina/valves/rewrite/ResolverImpl.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/valves/rewrite/ResolverImpl.java 2025-12-02 16:54:08.000000000 +0000
@@ -34,21 +34,42 @@
import org.apache.catalina.WebResource;
import org.apache.catalina.WebResourceRoot;
import org.apache.catalina.connector.Request;
+import org.apache.juli.logging.Log;
import org.apache.tomcat.util.http.FastHttpDateFormat;
import org.apache.tomcat.util.net.SSLSupport;
import org.apache.tomcat.util.net.jsse.PEMFile;
import org.apache.tomcat.util.net.openssl.ciphers.Cipher;
import org.apache.tomcat.util.net.openssl.ciphers.EncryptionLevel;
import org.apache.tomcat.util.net.openssl.ciphers.OpenSSLCipherConfigurationParser;
+import org.apache.tomcat.util.res.StringManager;
public class ResolverImpl extends Resolver {
- protected Request request;
+ private static final StringManager sm = StringManager.getManager(ResolverImpl.class);
+ protected final Request request;
+ private final Log containerLog;
+
+
+ /**
+ * Create a resolver for the given request.
+ *
+ * @param request The request
+ *
+ * @deprecated Will be removed in Tomcat 12 onwards. Use {@link #ResolverImpl(Request, Log)}
+ */
+ @Deprecated
public ResolverImpl(Request request) {
+ this(request, request.getContext().getLogger());
+ }
+
+
+ public ResolverImpl(Request request, Log containerLog) {
this.request = request;
+ this.containerLog = containerLog;
}
+
/**
* The following are not implemented:
*
@@ -192,8 +213,11 @@
}
}
}
- } catch (IOException e) {
+ } catch (IOException ioe) {
// TLS access error
+ if (containerLog.isDebugEnabled()) {
+ containerLog.debug(sm.getString("resolverImpl.tlsError"), ioe);
+ }
}
return null;
}
@@ -239,14 +263,14 @@
} else if (key.equals("CERT")) {
try {
return PEMFile.toPEM(certificates[0]);
- } catch (CertificateEncodingException e) {
+ } catch (CertificateEncodingException ignore) {
// Ignore
}
} else if (key.startsWith("CERT_CHAIN_")) {
key = key.substring("CERT_CHAIN_".length());
try {
return PEMFile.toPEM(certificates[Integer.parseInt(key)]);
- } catch (NumberFormatException | ArrayIndexOutOfBoundsException | CertificateEncodingException e) {
+ } catch (NumberFormatException | ArrayIndexOutOfBoundsException | CertificateEncodingException ignore) {
// Ignore
}
}
@@ -281,7 +305,7 @@
return elements.get(n);
}
}
- } catch (NumberFormatException | ArrayIndexOutOfBoundsException | CertificateParsingException e) {
+ } catch (NumberFormatException | ArrayIndexOutOfBoundsException | CertificateParsingException ignore) {
// Ignore
}
return null;
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/valves/rewrite/RewriteValve.java tomcat11-11.0.15/java/org/apache/catalina/valves/rewrite/RewriteValve.java
--- tomcat11-11.0.6/java/org/apache/catalina/valves/rewrite/RewriteValve.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/valves/rewrite/RewriteValve.java 2025-12-02 16:54:08.000000000 +0000
@@ -155,14 +155,17 @@
InputStream is = null;
// Process configuration file for this valve
+ // Process configuration file for this valve
if (getContainer() instanceof Context) {
context = true;
String webInfResourcePath = "/WEB-INF/" + resourcePath;
is = ((Context) getContainer()).getServletContext().getResourceAsStream(webInfResourcePath);
- if (containerLog.isDebugEnabled()) {
- if (is == null) {
- containerLog.debug(sm.getString("rewriteValve.noConfiguration", webInfResourcePath));
- } else {
+ if (is == null) {
+ if (containerLog.isInfoEnabled()) {
+ containerLog.info(sm.getString("rewriteValve.noConfiguration", webInfResourcePath));
+ }
+ } else {
+ if (containerLog.isDebugEnabled()) {
containerLog.debug(sm.getString("rewriteValve.readConfiguration", webInfResourcePath));
}
}
@@ -171,9 +174,9 @@
try {
ConfigurationSource.Resource resource = ConfigFileLoader.getSource().getResource(resourceName);
is = resource.getInputStream();
- } catch (IOException e) {
- if (containerLog.isDebugEnabled()) {
- containerLog.debug(sm.getString("rewriteValve.noConfiguration", resourceName), e);
+ } catch (IOException ioe) {
+ if (containerLog.isInfoEnabled()) {
+ containerLog.info(sm.getString("rewriteValve.noConfiguration", resourceName), ioe);
}
}
}
@@ -191,8 +194,8 @@
} finally {
try {
is.close();
- } catch (IOException e) {
- containerLog.error(sm.getString("rewriteValve.closeError"), e);
+ } catch (IOException ioe) {
+ containerLog.error(sm.getString("rewriteValve.closeError"), ioe);
}
}
@@ -202,6 +205,11 @@
if (containerLog == null) {
containerLog = LogFactory.getLog(getContainer().getLogName() + ".rewrite");
}
+ for (RewriteMap map : maps.values()) {
+ if (map instanceof Lifecycle) {
+ ((Lifecycle) map).stop();
+ }
+ }
maps.clear();
parse(new BufferedReader(new StringReader(configuration)));
}
@@ -226,6 +234,7 @@
protected void parse(BufferedReader reader) throws LifecycleException {
List rules = new ArrayList<>();
List conditions = new ArrayList<>();
+ ArrayList mapsConfiguration = new ArrayList<>();
while (true) {
try {
String line = reader.readLine();
@@ -246,7 +255,7 @@
for (RewriteCond condition : conditions) {
if (containerLog.isTraceEnabled()) {
containerLog.trace("Add condition " + condition.getCondPattern() + " test " +
- condition.getTestString() + " to rule with pattern " + rule.getPatternString() +
+ condition.getTestString() + " to rule with pattern " + rule.getPatternString() +
" and substitution " + rule.getSubstitutionString() +
(condition.isOrnext() ? " [OR]" : "") + (condition.isNocase() ? " [NC]" : ""));
}
@@ -267,16 +276,18 @@
((Lifecycle) map).start();
}
}
- } catch (IOException e) {
- containerLog.error(sm.getString("rewriteValve.readError"), e);
+ } catch (IOException ioe) {
+ containerLog.error(sm.getString("rewriteValve.readError"), ioe);
}
}
- this.rules = rules.toArray(new RewriteRule[0]);
+ this.mapsConfiguration = mapsConfiguration;
// Finish parsing the rules
- for (RewriteRule rule : this.rules) {
+ for (RewriteRule rule : rules) {
rule.parse(maps);
}
+
+ this.rules = rules.toArray(new RewriteRule[0]);
}
@Override
@@ -311,13 +322,13 @@
try {
- Resolver resolver = new ResolverImpl(request);
+ Resolver resolver = new ResolverImpl(request, containerLog);
invoked.set(Boolean.TRUE);
// As long as MB isn't a char sequence or affiliated, this has to be converted to a string
Charset uriCharset = request.getConnector().getURICharset();
- String originalQueryStringEncoded = request.getQueryString();
+ String queryStringOriginalEncoded = request.getQueryString();
MessageBytes urlMB = context ? request.getRequestPathMB() : request.getDecodedRequestURIMB();
urlMB.toChars();
CharSequence urlDecoded = urlMB.getCharChunk();
@@ -331,8 +342,6 @@
* without the two becoming confused. The re-write rules also need to be able to insert literal '%'
* characters without them being confused with %nn encoding.
*
- * The re-write rules cannot insert path parameters.
- *
* To meet these requirement, the URL is processed as follows.
*
* Step 1. The URL is partially re-encoded by encodeForRewrite(). This method encodes any literal '%', ';'
@@ -420,10 +429,10 @@
StringBuilder urlStringEncoded =
new StringBuilder(REWRITE_DEFAULT_ENCODER.encode(urlStringRewriteEncoded, uriCharset));
- if (!qsd && originalQueryStringEncoded != null && !originalQueryStringEncoded.isEmpty()) {
+ if (!qsd && queryStringOriginalEncoded != null && !queryStringOriginalEncoded.isEmpty()) {
if (rewrittenQueryStringRewriteEncoded == null) {
urlStringEncoded.append('?');
- urlStringEncoded.append(originalQueryStringEncoded);
+ urlStringEncoded.append(queryStringOriginalEncoded);
} else {
if (qsa) {
// if qsa is specified append the query
@@ -431,7 +440,7 @@
urlStringEncoded.append(
REWRITE_QUERY_ENCODER.encode(rewrittenQueryStringRewriteEncoded, uriCharset));
urlStringEncoded.append('&');
- urlStringEncoded.append(originalQueryStringEncoded);
+ urlStringEncoded.append(queryStringOriginalEncoded);
} else if (index == urlStringEncoded.length() - 1) {
// if the ? is the last character delete it, its only purpose was to
// prevent the rewrite module from appending the query string
@@ -455,11 +464,13 @@
if (context && urlStringEncoded.charAt(0) == '/' && !UriUtil.hasScheme(urlStringEncoded)) {
urlStringEncoded.insert(0, request.getContext().getEncodedPath());
}
+ String redirectPath;
if (rule.isNoescape()) {
- response.sendRedirect(UDecoder.URLDecode(urlStringEncoded.toString(), uriCharset));
+ redirectPath = UDecoder.URLDecode(urlStringEncoded.toString(), uriCharset);
} else {
- response.sendRedirect(urlStringEncoded.toString());
+ redirectPath = urlStringEncoded.toString();
}
+ response.sendRedirect(response.encodeRedirectURL(redirectPath));
response.setStatus(rule.getRedirectCode());
done = true;
break;
@@ -527,6 +538,9 @@
queryStringRewriteEncoded = urlStringRewriteEncoded.substring(queryIndex + 1);
urlStringRewriteEncoded = urlStringRewriteEncoded.substring(0, queryIndex);
}
+ // Parse path parameters from rewrite production and populate request path parameters
+ urlStringRewriteEncoded =
+ org.apache.catalina.util.RequestUtil.stripPathParams(urlStringRewriteEncoded, request);
// Save the current context path before re-writing starts
String contextPath = null;
if (context) {
@@ -542,24 +556,31 @@
// Step 3. Complete the 2nd stage to encoding.
chunk.append(REWRITE_DEFAULT_ENCODER.encode(urlStringRewriteEncoded, uriCharset));
- // Decoded and normalized URI
- // Rewriting may have denormalized the URL
- urlStringRewriteEncoded = RequestUtil.normalize(urlStringRewriteEncoded);
+ // Rewriting may have denormalized the URL and added encoded characters
+ // Decode then normalize
+ String urlStringRewriteDecoded = URLDecoder.decode(urlStringRewriteEncoded, uriCharset);
+ urlStringRewriteDecoded = RequestUtil.normalize(urlStringRewriteDecoded);
request.getCoyoteRequest().decodedURI().setChars(MessageBytes.EMPTY_CHAR_ARRAY, 0, 0);
chunk = request.getCoyoteRequest().decodedURI().getCharChunk();
if (context) {
// This is decoded and normalized
chunk.append(request.getServletContext().getContextPath());
}
- chunk.append(URLDecoder.decode(urlStringRewriteEncoded, uriCharset));
- // Set the new Query if there is one
- if (queryStringRewriteEncoded != null) {
+ chunk.append(urlStringRewriteDecoded);
+ // Set the new Query String
+ if (queryStringRewriteEncoded == null) {
+ // No new query string. Therefore the original is retained unless QSD is defined.
+ if (qsd) {
+ request.getCoyoteRequest().queryString().setChars(MessageBytes.EMPTY_CHAR_ARRAY, 0, 0);
+ }
+ } else {
+ // New query string. Therefore the original is dropped unless QSA is defined (and QSD is not).
request.getCoyoteRequest().queryString().setChars(MessageBytes.EMPTY_CHAR_ARRAY, 0, 0);
chunk = request.getCoyoteRequest().queryString().getCharChunk();
chunk.append(REWRITE_QUERY_ENCODER.encode(queryStringRewriteEncoded, uriCharset));
- if (qsa && originalQueryStringEncoded != null && !originalQueryStringEncoded.isEmpty()) {
+ if (qsa && queryStringOriginalEncoded != null && !queryStringOriginalEncoded.isEmpty()) {
chunk.append('&');
- chunk.append(originalQueryStringEncoded);
+ chunk.append(queryStringOriginalEncoded);
}
}
// Set the new host if it changed
@@ -569,6 +590,7 @@
chunk.append(host.toString());
}
request.getMappingData().recycle();
+ request.recycleSessionInfo();
// Reinvoke the whole request recursively
Connector connector = request.getConnector();
try {
@@ -653,6 +675,10 @@
while (flagsTokenizer.hasMoreElements()) {
parseRuleFlag(line, rule, flagsTokenizer.nextToken());
}
+ // If QSD and QSA are present, QSD always takes precedence
+ if (rule.isQsdiscard()) {
+ rule.setQsappend(false);
+ }
}
return rule;
} else if (token.equals("RewriteMap")) {
@@ -870,4 +896,6 @@
return input;
}
}
+
+
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/webresources/AbstractArchiveResourceSet.java tomcat11-11.0.15/java/org/apache/catalina/webresources/AbstractArchiveResourceSet.java
--- tomcat11-11.0.6/java/org/apache/catalina/webresources/AbstractArchiveResourceSet.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/webresources/AbstractArchiveResourceSet.java 2025-12-02 16:54:08.000000000 +0000
@@ -31,17 +31,21 @@
import org.apache.catalina.WebResource;
import org.apache.catalina.WebResourceRoot;
import org.apache.catalina.util.ResourceSet;
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
public abstract class AbstractArchiveResourceSet extends AbstractResourceSet {
+ private static final Log log = LogFactory.getLog(AbstractArchiveResourceSet.class);
+
private URL baseUrl;
private String baseUrlString;
- private JarFile archive = null;
+ protected JarFile archive = null;
protected Map archiveEntries = null;
protected final Object archiveLock = new Object();
- private long archiveUseCount = 0;
- private JarContents jarContents;
- private boolean retainBloomFilterForArchives = false;
+ protected long archiveUseCount = 0;
+ protected JarContents jarContents;
+ protected boolean retainBloomFilterForArchives = false;
protected final void setBaseUrl(URL baseUrl) {
this.baseUrl = baseUrl;
@@ -68,7 +72,7 @@
String webAppMount = getWebAppMount();
ArrayList result = new ArrayList<>();
- if (path.startsWith(webAppMount)) {
+ if (isPathMounted(path, webAppMount)) {
String pathInJar = getInternalPath() + path.substring(webAppMount.length());
// Always strip off the leading '/' to get the JAR path
if (!pathInJar.isEmpty() && pathInJar.charAt(0) == '/') {
@@ -108,13 +112,14 @@
return result.toArray(new String[0]);
}
+
@Override
public final Set listWebAppPaths(String path) {
checkPath(path);
String webAppMount = getWebAppMount();
ResourceSet result = new ResourceSet<>();
- if (path.startsWith(webAppMount)) {
+ if (isPathMounted(path, webAppMount)) {
String pathInJar = getInternalPath() + path.substring(webAppMount.length());
// Always strip off the leading '/' to get the JAR path and make
// sure it ends in '/'
@@ -225,7 +230,7 @@
// If the JAR has been mounted below the web application root, return
// an empty resource for requests outside of the mount point.
- if (path.startsWith(webAppMount)) {
+ if (isPathMounted(path, webAppMount)) {
String pathInJar = getInternalPath() + path.substring(webAppMount.length());
// Always strip off the leading '/' to get the JAR path
if (!pathInJar.isEmpty() && pathInJar.charAt(0) == '/') {
@@ -293,6 +298,25 @@
throw new IllegalArgumentException(sm.getString("abstractArchiveResourceSet.setReadOnlyFalse"));
}
+ /**
+ * {@inheritDoc}
+ *
+ * Calls to this method will be ignored as archives do not allow linking.
+ */
+ @Override
+ public void setAllowLinking(boolean allowLinking) {
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * Calls to this method always return {@code false} as archives do not allow linking.
+ */
+ @Override
+ public boolean getAllowLinking() {
+ return false;
+ }
+
protected JarFile openJarFile() throws IOException {
synchronized (archiveLock) {
if (archive == null) {
@@ -320,8 +344,8 @@
if (archive != null && archiveUseCount == 0) {
try {
archive.close();
- } catch (IOException e) {
- // Log at least WARN
+ } catch (IOException ioe) {
+ log.warn(sm.getString("abstractArchiveResourceSet.archiveCloseFailed"), ioe);
}
archive = null;
archiveEntries = null;
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/webresources/AbstractFileResourceSet.java tomcat11-11.0.15/java/org/apache/catalina/webresources/AbstractFileResourceSet.java
--- tomcat11-11.0.6/java/org/apache/catalina/webresources/AbstractFileResourceSet.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/webresources/AbstractFileResourceSet.java 2025-12-02 16:54:08.000000000 +0000
@@ -37,6 +37,7 @@
private String absoluteBase;
private String canonicalBase;
private boolean readOnly = false;
+ private Boolean allowLinking;
protected AbstractFileResourceSet(String internalPath) {
setInternalPath(internalPath);
@@ -56,6 +57,19 @@
return readOnly;
}
+ @Override
+ public void setAllowLinking(boolean allowLinking) {
+ this.allowLinking = Boolean.valueOf(allowLinking);
+ }
+
+ @Override
+ public boolean getAllowLinking() {
+ if (allowLinking == null) {
+ return getRoot().getAllowLinking();
+ }
+ return allowLinking.booleanValue();
+ }
+
protected final File file(String name, boolean mustExist) {
if (name.equals("/")) {
@@ -78,12 +92,12 @@
// If allow linking is enabled, files are not limited to being located
// under the fileBase so all further checks are disabled.
- if (getRoot().getAllowLinking()) {
+ if (getAllowLinking()) {
return file;
}
// Additional Windows specific checks to handle known problems with
- // File.getCanonicalPath()
+ // File.getCanonicalPath() and other issues
if (JrePlatform.IS_WINDOWS && isInvalidWindowsFilename(name)) {
return null;
}
@@ -92,7 +106,7 @@
String canPath = null;
try {
canPath = file.getCanonicalPath();
- } catch (IOException e) {
+ } catch (IOException ignore) {
// Ignore
}
if (canPath == null || !canPath.startsWith(canonicalBase)) {
@@ -150,38 +164,47 @@
protected void logIgnoredSymlink(String contextPath, String absPath, String canPath) {
- String msg = sm.getString("abstractFileResourceSet.canonicalfileCheckFailed", contextPath, absPath, canPath);
// Log issues with configuration files at a higher level
if (absPath.startsWith("/META-INF/") || absPath.startsWith("/WEB-INF/")) {
- log.error(msg);
+ log.error(sm.getString("abstractFileResourceSet.canonicalfileCheckFailed", contextPath, absPath, canPath));
} else {
- log.warn(msg);
+ log.warn(sm.getString("abstractFileResourceSet.canonicalfileCheckFailed", contextPath, absPath, canPath));
}
}
+
private boolean isInvalidWindowsFilename(String name) {
final int len = name.length();
if (len == 0) {
return false;
}
- // This consistently ~10 times faster than the equivalent regular
- // expression irrespective of input length.
+ // This is consistently ~10 times faster than the equivalent regular expression irrespective of input length.
for (int i = 0; i < len; i++) {
char c = name.charAt(i);
- if (c == '\"' || c == '<' || c == '>' || c == ':') {
- // These characters are disallowed in Windows file names and
- // there are known problems for file names with these characters
- // when using File#getCanonicalPath().
- // Note: There are additional characters that are disallowed in
- // Windows file names but these are not known to cause
- // problems when using File#getCanonicalPath().
+ /*
+ * '\"', ':', '<' and '>' are disallowed in Windows file names and there are known problems with these
+ * characters when using File#getCanonicalPath().
+ *
+ * Control characters (0x00-0x31) are not permitted and tend to be display strangely in log messages and
+ * similar.
+ *
+ * '*', '?' and '|' are also not allowed and, while they are not currently known to cause other
+ * difficulties, they are checked here rather than wasting cycles trying to find an invalid file later.
+ *
+ * The file separators ('/' and '\\') are not allowed in file names but are not excluded here as paths are
+ * passed to this method.
+ *
+ * Note: Characters are listed in ASCII order.
+ */
+ if (c < 32 || c == '\"' || c == '*' || c == ':' || c == '<' || c == '>' || c == '?' || c == '|') {
return true;
}
}
- // Windows does not allow file names to end in ' ' unless specific low
- // level APIs are used to create the files that bypass various checks.
- // File names that end in ' ' are known to cause problems when using
- // File#getCanonicalPath().
+ /*
+ * Windows does not allow file names to end in ' ' unless specific low-level APIs are used to create the files
+ * that bypass various checks. File names that end in ' ' are known to cause problems when using
+ * File#getCanonicalPath().
+ */
return name.charAt(len - 1) == ' ';
}
@@ -228,8 +251,8 @@
try {
this.canonicalBase = fileBase.getCanonicalPath();
- } catch (IOException e) {
- throw new IllegalArgumentException(e);
+ } catch (IOException ioe) {
+ throw new IllegalArgumentException(ioe);
}
// Need to handle mapping of the file system root as a special case
@@ -243,4 +266,4 @@
protected abstract void checkType(File file);
-}
+}
\ No newline at end of file
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/webresources/AbstractResource.java tomcat11-11.0.15/java/org/apache/catalina/webresources/AbstractResource.java
--- tomcat11-11.0.6/java/org/apache/catalina/webresources/AbstractResource.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/webresources/AbstractResource.java 2025-12-02 16:54:08.000000000 +0000
@@ -90,7 +90,7 @@
if (contentLength <= 16 * 1024) {
byte[] buf = getContent();
if (buf != null) {
- buf = ConcurrentMessageDigest.digest("SHA-1", buf);
+ buf = ConcurrentMessageDigest.digestSHA256(buf);
strongETag = "\"" + HexUtils.toHexString(buf) + "\"";
} else {
strongETag = getETag();
@@ -98,7 +98,7 @@
} else {
byte[] buf = new byte[4096];
try (InputStream is = getInputStream()) {
- MessageDigest digest = MessageDigest.getInstance("SHA-1");
+ MessageDigest digest = MessageDigest.getInstance("SHA-256");
while (true) {
int n = is.read(buf);
if (n <= 0) {
@@ -128,6 +128,14 @@
@Override
public final String getMimeType() {
+ if (mimeType == null) {
+ String name = getName();
+ int extensionStart = name.lastIndexOf('.');
+ if (extensionStart > -1) {
+ String extension = name.substring(extensionStart + 1);
+ mimeType = root.getContext().findMimeMapping(extension);
+ }
+ }
return mimeType;
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/webresources/AbstractResourceSet.java tomcat11-11.0.15/java/org/apache/catalina/webresources/AbstractResourceSet.java
--- tomcat11-11.0.6/java/org/apache/catalina/webresources/AbstractResourceSet.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/webresources/AbstractResourceSet.java 2025-12-02 16:54:08.000000000 +0000
@@ -71,9 +71,13 @@
public final void setWebAppMount(String webAppMount) {
checkPath(webAppMount);
- // Optimise internal processing
- if (webAppMount.equals("/")) {
- this.webAppMount = "";
+ /*
+ * Originally, only "/" was changed to "" to allow some optimisations. The fix for CVE-2025-49125 means that
+ * mounted WebResourceSets will break if webAppMount ends in '/'. So now the trailing "/" is removed in all
+ * cases.
+ */
+ if (webAppMount.endsWith("/")) {
+ this.webAppMount = webAppMount.substring(0, webAppMount.length() - 1);
} else {
this.webAppMount = webAppMount;
}
@@ -83,6 +87,18 @@
return webAppMount;
}
+ protected boolean isPathMounted(String path, String webAppMount) {
+ // Doesn't call getWebAppMount() as value might have changed
+ if (path.startsWith(webAppMount)) {
+ if (path.length() != webAppMount.length() && path.charAt(webAppMount.length()) != '/') {
+ return false;
+ }
+ return true;
+ }
+ return false;
+ }
+
+
public final void setBase(String base) {
this.base = base;
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/webresources/AbstractSingleArchiveResource.java tomcat11-11.0.15/java/org/apache/catalina/webresources/AbstractSingleArchiveResource.java
--- tomcat11-11.0.6/java/org/apache/catalina/webresources/AbstractSingleArchiveResource.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/webresources/AbstractSingleArchiveResource.java 2025-12-02 16:54:08.000000000 +0000
@@ -47,10 +47,10 @@
JarEntry jarEntry = jarFile.getJarEntry(getResource().getName());
InputStream is = jarFile.getInputStream(jarEntry);
return new JarInputStreamWrapper(jarEntry, is);
- } catch (IOException e) {
+ } catch (IOException ioe) {
if (getLog().isDebugEnabled()) {
getLog().debug(sm.getString("jarResource.getInputStreamFail", getResource().getName(), getBaseUrl()),
- e);
+ ioe);
}
if (jarFile != null) {
getArchiveResourceSet().closeJarFile();
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/webresources/AbstractSingleArchiveResourceSet.java tomcat11-11.0.15/java/org/apache/catalina/webresources/AbstractSingleArchiveResourceSet.java
--- tomcat11-11.0.6/java/org/apache/catalina/webresources/AbstractSingleArchiveResourceSet.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/webresources/AbstractSingleArchiveResourceSet.java 2025-12-02 16:54:08.000000000 +0000
@@ -142,8 +142,8 @@
try {
setBaseUrl(UriUtil.buildJarSafeUrl(new File(getBase())));
- } catch (IOException e) {
- throw new IllegalArgumentException(e);
+ } catch (IOException ioe) {
+ throw new IllegalArgumentException(ioe);
}
}
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/webresources/Cache.java tomcat11-11.0.15/java/org/apache/catalina/webresources/Cache.java
--- tomcat11-11.0.6/java/org/apache/catalina/webresources/Cache.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/webresources/Cache.java 2025-12-02 16:54:08.000000000 +0000
@@ -233,8 +233,9 @@
private boolean noCache(String path) {
// Don't cache classes. The class loader handles this.
// Don't cache JARs. The ResourceSet handles this.
- return (path.endsWith(".class") && (path.startsWith("/WEB-INF/classes/") || path.startsWith("/WEB-INF/lib/"))) ||
- (path.startsWith("/WEB-INF/lib/") && path.endsWith(".jar"));
+ return (path.endsWith(".class") &&
+ (path.startsWith("/WEB-INF/classes/") || path.startsWith("/WEB-INF/lib/"))) ||
+ (path.startsWith("/WEB-INF/lib/") && path.endsWith(".jar"));
}
private long evict(long targetSize, Iterator iter) {
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/webresources/CachedResource.java tomcat11-11.0.15/java/org/apache/catalina/webresources/CachedResource.java
--- tomcat11-11.0.6/java/org/apache/catalina/webresources/CachedResource.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/webresources/CachedResource.java 2025-12-02 16:54:08.000000000 +0000
@@ -296,7 +296,7 @@
if (cachedStrongETag == null) {
byte[] buf = getContent();
if (buf != null) {
- buf = ConcurrentMessageDigest.digest("SHA-1", buf);
+ buf = ConcurrentMessageDigest.digestSHA256(buf);
cachedStrongETag = "\"" + HexUtils.toHexString(buf) + "\"";
} else {
cachedStrongETag = webResource.getStrongETag();
@@ -575,6 +575,7 @@
}
@Override
+ @Deprecated
public Permission getPermission() throws IOException {
// Doesn't trigger a call to connect for file:// URLs
return resourceURL.openConnection().getPermission();
@@ -637,6 +638,7 @@
}
@Override
+ @Deprecated
public Permission getPermission() throws IOException {
// Doesn't trigger a call to connect for jar:// URLs
return resourceURL.openConnection().getPermission();
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/webresources/DirResourceSet.java tomcat11-11.0.15/java/org/apache/catalina/webresources/DirResourceSet.java
--- tomcat11-11.0.6/java/org/apache/catalina/webresources/DirResourceSet.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/webresources/DirResourceSet.java 2025-12-02 16:54:08.000000000 +0000
@@ -22,11 +22,11 @@
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
-import java.util.HashMap;
import java.util.Locale;
-import java.util.Map;
import java.util.Objects;
import java.util.Set;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReadWriteLock;
import java.util.jar.Manifest;
import org.apache.catalina.LifecycleException;
@@ -38,6 +38,7 @@
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.apache.tomcat.util.compat.JreCompat;
+import org.apache.tomcat.util.concurrent.KeyedReentrantReadWriteLock;
import org.apache.tomcat.util.http.RequestUtil;
/**
@@ -47,8 +48,7 @@
private static final Log log = LogFactory.getLog(DirResourceSet.class);
- private final Map resourceLocksByPath = new HashMap<>();
- private final Object resourceLocksByPathLock = new Object();
+ private KeyedReentrantReadWriteLock resourceLocksByPath = new KeyedReentrantReadWriteLock();
/**
@@ -96,20 +96,23 @@
}
- @SuppressWarnings("null") // lock can never be null when lock.key is read
@Override
public WebResource getResource(String path) {
checkPath(path);
String webAppMount = getWebAppMount();
WebResourceRoot root = getRoot();
boolean readOnly = isReadOnly();
- if (path.startsWith(webAppMount)) {
+ if (isPathMounted(path, webAppMount)) {
/*
* Lock the path for reading until the WebResource has been constructed. The lock prevents concurrent reads
* and writes (e.g. HTTP GET and PUT / DELETE) for the same path causing corruption of the FileResource
* where some of the fields are set as if the file exists and some as set as if it does not.
*/
- ResourceLock lock = readOnly ? null : lockForRead(path);
+ Lock readLock = null;
+ if (!readOnly) {
+ readLock = getLock(path).readLock();
+ readLock.lock();
+ }
try {
File f = file(path.substring(webAppMount.length()), false);
if (f == null) {
@@ -121,10 +124,10 @@
if (f.isDirectory() && path.charAt(path.length() - 1) != '/') {
path = path + '/';
}
- return new FileResource(root, path, f, readOnly, getManifest(), this, readOnly ? null : lock.key);
+ return new FileResource(root, path, f, readOnly, getManifest(), this, readOnly ? null : path);
} finally {
- if (!readOnly) {
- unlockForRead(lock);
+ if (readLock != null) {
+ readLock.unlock();
}
}
} else {
@@ -137,7 +140,7 @@
public String[] list(String path) {
checkPath(path);
String webAppMount = getWebAppMount();
- if (path.startsWith(webAppMount)) {
+ if (isPathMounted(path, webAppMount)) {
File f = file(path.substring(webAppMount.length()), true);
if (f == null) {
return EMPTY_STRING_ARRAY;
@@ -165,15 +168,16 @@
checkPath(path);
String webAppMount = getWebAppMount();
ResourceSet result = new ResourceSet<>();
- if (path.startsWith(webAppMount)) {
+ if (isPathMounted(path, webAppMount)) {
File f = file(path.substring(webAppMount.length()), true);
if (f != null) {
File[] list = f.listFiles();
if (list != null) {
+ String fCanPath = null;
for (File entry : list) {
// f has already been validated so the following checks
// can be much simpler than those in file()
- if (!getRoot().getAllowLinking()) {
+ if (!getAllowLinking()) {
// allow linking is disabled so need to check for
// symlinks
boolean symlink = true;
@@ -187,7 +191,9 @@
// that what is left does not contain a symlink.
absPath = entry.getAbsolutePath().substring(f.getAbsolutePath().length());
String entryCanPath = entry.getCanonicalPath();
- String fCanPath = f.getCanonicalPath();
+ if (fCanPath == null) {
+ fCanPath = f.getCanonicalPath();
+ }
if (entryCanPath.length() >= fCanPath.length()) {
canPath = entryCanPath.substring(fCanPath.length());
if (absPath.equals(canPath)) {
@@ -239,7 +245,7 @@
return false;
}
String webAppMount = getWebAppMount();
- if (path.startsWith(webAppMount)) {
+ if (isPathMounted(path, webAppMount)) {
File f = file(path.substring(webAppMount.length()), false);
if (f == null) {
return false;
@@ -269,7 +275,7 @@
}
String webAppMount = getWebAppMount();
- if (!path.startsWith(webAppMount)) {
+ if (!isPathMounted(path, webAppMount)) {
return false;
}
@@ -279,7 +285,8 @@
* HTTP GET and PUT / DELETE) for the same path causing corruption of the FileResource where some of the fields
* are set as if the file exists and some as set as if it does not.
*/
- ResourceLock lock = lockForWrite(path);
+ Lock writeLock = getLock(path).writeLock();
+ writeLock.lock();
try {
dest = file(path.substring(webAppMount.length()), false);
if (dest == null) {
@@ -302,7 +309,7 @@
return true;
} finally {
- unlockForWrite(lock);
+ writeLock.unlock();
}
}
@@ -325,8 +332,8 @@
if (mf != null && mf.isFile()) {
try (FileInputStream fis = new FileInputStream(mf)) {
setManifest(new Manifest(fis));
- } catch (IOException e) {
- log.warn(sm.getString("dirResourceSet.manifestFail", mf.getAbsolutePath()), e);
+ } catch (IOException ioe) {
+ log.warn(sm.getString("dirResourceSet.manifestFail", mf.getAbsolutePath()), ioe);
}
}
}
@@ -371,77 +378,40 @@
@Override
+ public ReadWriteLock getLock(String path) {
+ String key = getLockKey(path);
+ return resourceLocksByPath.getLock(key);
+ }
+
+
+ @SuppressWarnings("deprecation")
+ @Override
public ResourceLock lockForRead(String path) {
String key = getLockKey(path);
- ResourceLock resourceLock;
- synchronized (resourceLocksByPathLock) {
- /*
- * Obtain the ResourceLock and increment the usage count inside the sync to ensure that that map always has
- * a consistent view of the currently "in-use" ResourceLocks.
- */
- resourceLock = resourceLocksByPath.get(key);
- if (resourceLock == null) {
- resourceLock = new ResourceLock(key);
- resourceLocksByPath.put(key, resourceLock);
- }
- resourceLock.count.incrementAndGet();
- }
- // Obtain the lock outside the sync as it will block if there is a current write lock.
- resourceLock.reentrantLock.readLock().lock();
- return resourceLock;
+ resourceLocksByPath.getLock(key).readLock().lock();
+ return new ResourceLock(key);
}
+ @SuppressWarnings("deprecation")
@Override
public void unlockForRead(ResourceLock resourceLock) {
- // Unlock outside the sync as there is no need to do it inside.
- resourceLock.reentrantLock.readLock().unlock();
- synchronized (resourceLocksByPathLock) {
- /*
- * Decrement the usage count and remove ResourceLocks no longer required inside the sync to ensure that that
- * map always has a consistent view of the currently "in-use" ResourceLocks.
- */
- if (resourceLock.count.decrementAndGet() == 0) {
- resourceLocksByPath.remove(resourceLock.key);
- }
- }
+ resourceLocksByPath.getLock(resourceLock.key).readLock().unlock();
}
+ @SuppressWarnings("deprecation")
@Override
public ResourceLock lockForWrite(String path) {
String key = getLockKey(path);
- ResourceLock resourceLock;
- synchronized (resourceLocksByPathLock) {
- /*
- * Obtain the ResourceLock and increment the usage count inside the sync to ensure that that map always has
- * a consistent view of the currently "in-use" ResourceLocks.
- */
- resourceLock = resourceLocksByPath.get(key);
- if (resourceLock == null) {
- resourceLock = new ResourceLock(key);
- resourceLocksByPath.put(key, resourceLock);
- }
- resourceLock.count.incrementAndGet();
- }
- // Obtain the lock outside the sync as it will block if there are any other current locks.
- resourceLock.reentrantLock.writeLock().lock();
- return resourceLock;
+ resourceLocksByPath.getLock(key).writeLock().lock();
+ return new ResourceLock(key);
}
+ @SuppressWarnings("deprecation")
@Override
public void unlockForWrite(ResourceLock resourceLock) {
- // Unlock outside the sync as there is no need to do it inside.
- resourceLock.reentrantLock.writeLock().unlock();
- synchronized (resourceLocksByPathLock) {
- /*
- * Decrement the usage count and remove ResourceLocks no longer required inside the sync to ensure that that
- * map always has a consistent view of the currently "in-use" ResourceLocks.
- */
- if (resourceLock.count.decrementAndGet() == 0) {
- resourceLocksByPath.remove(resourceLock.key);
- }
- }
+ resourceLocksByPath.getLock(resourceLock.key).writeLock().unlock();
}
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/webresources/EmptyResource.java tomcat11-11.0.15/java/org/apache/catalina/webresources/EmptyResource.java
--- tomcat11-11.0.6/java/org/apache/catalina/webresources/EmptyResource.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/webresources/EmptyResource.java 2025-12-02 16:54:08.000000000 +0000
@@ -99,7 +99,7 @@
} else {
try {
return file.getCanonicalPath();
- } catch (IOException e) {
+ } catch (IOException ioe) {
return null;
}
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/webresources/EmptyResourceSet.java tomcat11-11.0.15/java/org/apache/catalina/webresources/EmptyResourceSet.java
--- tomcat11-11.0.6/java/org/apache/catalina/webresources/EmptyResourceSet.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/webresources/EmptyResourceSet.java 2025-12-02 16:54:08.000000000 +0000
@@ -143,6 +143,25 @@
/**
* {@inheritDoc}
*
+ * Calls to this method will be ignored as this implementation does not allow linking.
+ */
+ @Override
+ public void setAllowLinking(boolean allowLinking) {
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * Calls to this method always return {@code false} as this implementation does not allow linking.
+ */
+ @Override
+ public boolean getAllowLinking() {
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* This implementation always returns true.
*/
@Override
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/webresources/FileResource.java tomcat11-11.0.15/java/org/apache/catalina/webresources/FileResource.java
--- tomcat11-11.0.6/java/org/apache/catalina/webresources/FileResource.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/webresources/FileResource.java 2025-12-02 16:54:08.000000000 +0000
@@ -29,10 +29,10 @@
import java.nio.file.Files;
import java.nio.file.attribute.BasicFileAttributes;
import java.security.cert.Certificate;
+import java.util.concurrent.locks.Lock;
import java.util.jar.Manifest;
import org.apache.catalina.WebResourceLockSet;
-import org.apache.catalina.WebResourceLockSet.ResourceLock;
import org.apache.catalina.WebResourceRoot;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
@@ -134,15 +134,16 @@
* HTTP GET and PUT / DELETE) for the same path causing corruption of the FileResource where some of the fields
* are set as if the file exists and some as set as if it does not.
*/
- ResourceLock lock = null;
+ Lock writeLock = null;
if (lockSet != null) {
- lock = lockSet.lockForWrite(lockKey);
+ writeLock = lockSet.getLock(lockKey).writeLock();
+ writeLock.lock();
}
try {
return resource.delete();
} finally {
- if (lockSet != null) {
- lockSet.unlockForWrite(lock);
+ if (writeLock != null) {
+ writeLock.unlock();
}
}
}
@@ -267,9 +268,9 @@
try {
BasicFileAttributes attrs = Files.readAttributes(resource.toPath(), BasicFileAttributes.class);
return attrs.creationTime().toMillis();
- } catch (IOException e) {
+ } catch (IOException ioe) {
if (log.isDebugEnabled()) {
- log.debug(sm.getString("fileResource.getCreationFail", resource.getPath()), e);
+ log.debug(sm.getString("fileResource.getCreationFail", resource.getPath()), ioe);
}
return 0;
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/webresources/JarContents.java tomcat11-11.0.15/java/org/apache/catalina/webresources/JarContents.java
--- tomcat11-11.0.6/java/org/apache/catalina/webresources/JarContents.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/webresources/JarContents.java 2025-12-02 16:54:08.000000000 +0000
@@ -17,6 +17,7 @@
package org.apache.catalina.webresources;
import java.util.BitSet;
+import java.util.Collection;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
@@ -27,8 +28,7 @@
* from the beginning of the key. The hash methods are simple but good enough for this purpose.
*/
public final class JarContents {
- private final BitSet bits1;
- private final BitSet bits2;
+
/**
* Constant used by a typical hashing method.
*/
@@ -44,6 +44,10 @@
*/
private static final int TABLE_SIZE = 2048;
+ private final BitSet bits1 = new BitSet(TABLE_SIZE);
+ private final BitSet bits2 = new BitSet(TABLE_SIZE);
+
+
/**
* Parses the passed-in jar and populates the bit array.
*
@@ -51,52 +55,66 @@
*/
public JarContents(JarFile jar) {
Enumeration entries = jar.entries();
- bits1 = new BitSet(TABLE_SIZE);
- bits2 = new BitSet(TABLE_SIZE);
-
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
- String name = entry.getName();
- int startPos = 0;
+ processEntry(entry);
+ }
+ }
- // If the path starts with a slash, that's not useful information.
- // Skipping it increases the significance of our key by
- // removing an insignificant character.
- boolean precedingSlash = name.charAt(0) == '/';
- if (precedingSlash) {
- startPos = 1;
- }
- // Versioned entries should be added to the table according to their real name
- if (name.startsWith("META-INF/versions/", startPos)) {
- int i = name.indexOf('/', 18 + startPos);
- if (i > 0) {
- int version = Integer.parseInt(name.substring(18 + startPos, i));
- if (version <= Runtime.version().feature()) {
- startPos = i + 1;
- }
- }
- if (startPos == name.length()) {
- continue;
+ /**
+ * Populates the bit array from the provided set of JAR entries.
+ *
+ * @param entries The set of entries for the JAR file being processed
+ */
+ public JarContents(Collection entries) {
+ for (JarEntry entry : entries) {
+ processEntry(entry);
+ }
+ }
+
+
+ private void processEntry(JarEntry entry) {
+ String name = entry.getName();
+ int startPos = 0;
+
+ // If the path starts with a slash, that's not useful information.
+ // Skipping it increases the significance of our key by
+ // removing an insignificant character.
+ boolean precedingSlash = name.charAt(0) == '/';
+ if (precedingSlash) {
+ startPos = 1;
+ }
+
+ // Versioned entries should be added to the table according to their real name
+ if (name.startsWith("META-INF/versions/", startPos)) {
+ int i = name.indexOf('/', 18 + startPos);
+ if (i > 0) {
+ int version = Integer.parseInt(name.substring(18 + startPos, i));
+ if (version <= Runtime.version().feature()) {
+ startPos = i + 1;
}
}
+ if (startPos == name.length()) {
+ return;
+ }
+ }
- // Find the correct table slot
- int pathHash1 = hashcode(name, startPos, HASH_PRIME_1);
- int pathHash2 = hashcode(name, startPos, HASH_PRIME_2);
+ // Find the correct table slot
+ int pathHash1 = hashcode(name, startPos, HASH_PRIME_1);
+ int pathHash2 = hashcode(name, startPos, HASH_PRIME_2);
+
+ bits1.set(pathHash1 % TABLE_SIZE);
+ bits2.set(pathHash2 % TABLE_SIZE);
+
+ // While directory entry names always end in "/", application code
+ // may look them up without the trailing "/". Add this second form.
+ if (entry.isDirectory()) {
+ pathHash1 = hashcode(name, startPos, name.length() - 1, HASH_PRIME_1);
+ pathHash2 = hashcode(name, startPos, name.length() - 1, HASH_PRIME_2);
bits1.set(pathHash1 % TABLE_SIZE);
bits2.set(pathHash2 % TABLE_SIZE);
-
- // While directory entry names always end in "/", application code
- // may look them up without the trailing "/". Add this second form.
- if (entry.isDirectory()) {
- pathHash1 = hashcode(name, startPos, name.length() - 1, HASH_PRIME_1);
- pathHash2 = hashcode(name, startPos, name.length() - 1, HASH_PRIME_2);
-
- bits1.set(pathHash1 % TABLE_SIZE);
- bits2.set(pathHash2 % TABLE_SIZE);
- }
}
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/webresources/JarWarResource.java tomcat11-11.0.15/java/org/apache/catalina/webresources/JarWarResource.java
--- tomcat11-11.0.6/java/org/apache/catalina/webresources/JarWarResource.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/webresources/JarWarResource.java 2025-12-02 16:54:08.000000000 +0000
@@ -63,9 +63,9 @@
}
return new JarInputStreamWrapper(entry, jarIs);
- } catch (IOException e) {
+ } catch (IOException ioe) {
if (log.isDebugEnabled()) {
- log.debug(sm.getString("jarResource.getInputStreamFail", getResource().getName(), getBaseUrl()), e);
+ log.debug(sm.getString("jarResource.getInputStreamFail", getResource().getName(), getBaseUrl()), ioe);
}
// Ensure jarIs is closed if there is an exception
entry = null;
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/webresources/JarWarResourceSet.java tomcat11-11.0.15/java/org/apache/catalina/webresources/JarWarResourceSet.java
--- tomcat11-11.0.6/java/org/apache/catalina/webresources/JarWarResourceSet.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/webresources/JarWarResourceSet.java 2025-12-02 16:54:08.000000000 +0000
@@ -27,6 +27,7 @@
import java.util.jar.JarFile;
import java.util.jar.JarInputStream;
import java.util.jar.Manifest;
+import java.util.zip.ZipFile;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.WebResource;
@@ -140,17 +141,40 @@
if (jarFileIs != null) {
try {
jarFileIs.close();
- } catch (IOException e) {
+ } catch (IOException ignore) {
// Ignore
}
}
}
}
+ WebResourceRoot root = getRoot();
+ if (root.getArchiveIndexStrategyEnum().getUsesBloom()) {
+ jarContents = new JarContents(archiveEntries.values());
+ retainBloomFilterForArchives = root.getArchiveIndexStrategyEnum().getRetain();
+ }
return archiveEntries;
}
}
+ /**
+ * {@inheritDoc}
+ *
+ * JarWar needs to generate jarContents for the inner JAR, not the outer WAR.
+ */
+ @Override
+ protected JarFile openJarFile() throws IOException {
+ synchronized (archiveLock) {
+ if (archive == null) {
+ archive = new JarFile(new File(getBase()), true, ZipFile.OPEN_READ, Runtime.version());
+ // Don't populate JarContents here. Populate at the end of getArchiveEntries()
+ }
+ archiveUseCount++;
+ return archive;
+ }
+ }
+
+
protected void processArchivesEntriesForMultiRelease() {
int targetVersion = Runtime.version().feature();
@@ -234,8 +258,8 @@
try {
setBaseUrl(UriUtil.buildJarSafeUrl(new File(getBase())));
- } catch (IOException e) {
- throw new IllegalArgumentException(e);
+ } catch (IOException ioe) {
+ throw new IllegalArgumentException(ioe);
}
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/webresources/LocalStrings.properties tomcat11-11.0.15/java/org/apache/catalina/webresources/LocalStrings.properties
--- tomcat11-11.0.6/java/org/apache/catalina/webresources/LocalStrings.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/webresources/LocalStrings.properties 2025-12-02 16:54:08.000000000 +0000
@@ -16,6 +16,7 @@
# Do not edit this file directly.
# To edit translations see: https://tomcat.apache.org/getinvolved.html#Translations
+abstractArchiveResourceSet.archiveCloseFailed=Error closing archive. Archive may still be open.
abstractArchiveResourceSet.setReadOnlyFalse=Archive based WebResourceSets such as those based on JARs are hard-coded to be read-only and may not be configured to be read-write
abstractFileResourceSet.canonicalfileCheckFailed=Resource for web application [{0}] at path [{1}] was not loaded as the canonical path [{2}] did not match. Use of symlinks is one possible cause.
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/webresources/LocalStrings_fr.properties tomcat11-11.0.15/java/org/apache/catalina/webresources/LocalStrings_fr.properties
--- tomcat11-11.0.6/java/org/apache/catalina/webresources/LocalStrings_fr.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/webresources/LocalStrings_fr.properties 2025-12-02 16:54:08.000000000 +0000
@@ -16,6 +16,7 @@
# Do not edit this file directly.
# To edit translations see: https://tomcat.apache.org/getinvolved.html#Translations
+abstractArchiveResourceSet.archiveCloseFailed=Erreur lors de la fermeture de l'archive, elle pourrait toujours être ouverte
abstractArchiveResourceSet.setReadOnlyFalse=Les archives basées sur WebResourceSets telles que celles des JARs sont fixées comme étant en lecture seule et ne peuvent être configurées en lecture écriture
abstractFileResourceSet.canonicalfileCheckFailed=La ressource de l''application web [{0}] du chemin [{1}] n''a pas été chargée car le chemin canonique [{2}] ne correspond pas; l''utilisation de liens symboliques peut être une cause possible
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/webresources/LocalStrings_ja.properties tomcat11-11.0.15/java/org/apache/catalina/webresources/LocalStrings_ja.properties
--- tomcat11-11.0.6/java/org/apache/catalina/webresources/LocalStrings_ja.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/webresources/LocalStrings_ja.properties 2025-12-02 16:54:08.000000000 +0000
@@ -16,6 +16,7 @@
# Do not edit this file directly.
# To edit translations see: https://tomcat.apache.org/getinvolved.html#Translations
+abstractArchiveResourceSet.archiveCloseFailed=アーカイブを閉じる際にエラーが発生しました。アーカイブがまだ開いている可能性があります。
abstractArchiveResourceSet.setReadOnlyFalse=JAR に基づく WebResourceSet などのアーカイブ ベースの WebResourceSet は、読み取り専用にハードコードされており、読み取り/書き込み可能に構成されていない可能性があります
abstractFileResourceSet.canonicalfileCheckFailed=正規パス [{2}] が一致しなかったため、パス [{1}] のWebアプリケーション [{0}] のリソースが読み込まれませんでした。 シンボリックリンクの使用は、考えられる原因の1つです。
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/webresources/LocalStrings_ru.properties tomcat11-11.0.15/java/org/apache/catalina/webresources/LocalStrings_ru.properties
--- tomcat11-11.0.6/java/org/apache/catalina/webresources/LocalStrings_ru.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/webresources/LocalStrings_ru.properties 2025-12-02 16:54:08.000000000 +0000
@@ -16,6 +16,8 @@
# Do not edit this file directly.
# To edit translations see: https://tomcat.apache.org/getinvolved.html#Translations
+dirResourceSet.notDirectory=Директория указанная по основному и внутреннему пути [{0}]{1}[{2}] не существует.
+
extractingRoot.targetFailed=Ошибка создания директории [{0}] для распакованных JAR файлов
standardRoot.createUnknownType=Невозможно создать WebResourceSet неизвестного типа [{0}]
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/webresources/StandardRoot.java tomcat11-11.0.15/java/org/apache/catalina/webresources/StandardRoot.java
--- tomcat11-11.0.6/java/org/apache/catalina/webresources/StandardRoot.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/webresources/StandardRoot.java 2025-12-02 16:54:08.000000000 +0000
@@ -781,7 +781,7 @@
trackedResource.getCreatedBy());
try {
trackedResource.close();
- } catch (IOException e) {
+ } catch (IOException ignore) {
// Ignore
}
}
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/webresources/TomcatJarInputStream.java tomcat11-11.0.15/java/org/apache/catalina/webresources/TomcatJarInputStream.java
--- tomcat11-11.0.6/java/org/apache/catalina/webresources/TomcatJarInputStream.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/webresources/TomcatJarInputStream.java 2025-12-02 16:54:08.000000000 +0000
@@ -42,7 +42,7 @@
ZipEntry ze = super.createZipEntry(name);
if (metaInfEntry == null && "META-INF/".equals(name)) {
metaInfEntry = (JarEntry) ze;
- } else if (manifestEntry == null && "META-INF/MANIFESR.MF".equals(name)) {
+ } else if (manifestEntry == null && "META-INF/MANIFEST.MF".equals(name)) {
manifestEntry = (JarEntry) ze;
}
return ze;
diff -Nru tomcat11-11.0.6/java/org/apache/catalina/webresources/war/WarURLConnection.java tomcat11-11.0.15/java/org/apache/catalina/webresources/war/WarURLConnection.java
--- tomcat11-11.0.6/java/org/apache/catalina/webresources/war/WarURLConnection.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/catalina/webresources/war/WarURLConnection.java 2025-12-02 16:54:08.000000000 +0000
@@ -54,6 +54,7 @@
@Override
+ @Deprecated
public Permission getPermission() throws IOException {
return wrappedJarUrlConnection.getPermission();
}
diff -Nru tomcat11-11.0.6/java/org/apache/coyote/AbstractProcessor.java tomcat11-11.0.15/java/org/apache/coyote/AbstractProcessor.java
--- tomcat11-11.0.6/java/org/apache/coyote/AbstractProcessor.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/coyote/AbstractProcessor.java 2025-12-02 16:54:08.000000000 +0000
@@ -374,8 +374,8 @@
try {
// Validate and write response headers
prepareResponse();
- } catch (IOException e) {
- handleIOException(e);
+ } catch (IOException ioe) {
+ handleIOException(ioe);
}
}
break;
@@ -384,8 +384,8 @@
action(ActionCode.COMMIT, null);
try {
finishResponse();
- } catch (IOException e) {
- handleIOException(e);
+ } catch (IOException ioe) {
+ handleIOException(ioe);
}
break;
}
@@ -396,8 +396,8 @@
case EARLY_HINTS: {
try {
earlyHints();
- } catch (IOException e) {
- handleIOException(e);
+ } catch (IOException ioe) {
+ handleIOException(ioe);
}
break;
}
@@ -405,9 +405,9 @@
action(ActionCode.COMMIT, null);
try {
flush();
- } catch (IOException e) {
- handleIOException(e);
- response.setErrorException(e);
+ } catch (IOException ioe) {
+ handleIOException(ioe);
+ response.setErrorException(ioe);
}
break;
}
@@ -575,8 +575,8 @@
case ASYNC_POST_PROCESS: {
try {
asyncStateMachine.asyncPostProcess();
- } catch (IOException e) {
- handleIOException(e);
+ } catch (IOException ioe) {
+ handleIOException(ioe);
}
break;
}
@@ -1045,7 +1045,7 @@
// information (e.g. client IP)
setSocketWrapper(socketWrapper);
// Set up the minimal request information
- request.setStartTimeNanos(System.nanoTime());
+ request.markStartTime();
// Set up the minimal response information
response.setStatus(400);
response.setError();
diff -Nru tomcat11-11.0.6/java/org/apache/coyote/AbstractProtocol.java tomcat11-11.0.15/java/org/apache/coyote/AbstractProtocol.java
--- tomcat11-11.0.6/java/org/apache/coyote/AbstractProtocol.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/coyote/AbstractProtocol.java 2025-12-02 16:54:08.000000000 +0000
@@ -1017,9 +1017,9 @@
} finally {
try {
instanceManager.destroyInstance(httpUpgradeHandler);
- } catch (Throwable e) {
- ExceptionUtils.handleThrowable(e);
- getLog().error(sm.getString("abstractConnectionHandler.error"), e);
+ } catch (Throwable t) {
+ ExceptionUtils.handleThrowable(t);
+ getLog().error(sm.getString("abstractConnectionHandler.error"), t);
}
upgradeToken.contextBind().unbind(oldCL);
}
@@ -1036,14 +1036,19 @@
return state;
} catch (SocketException e) {
// SocketExceptions are normal
- getLog().debug(sm.getString("abstractConnectionHandler.socketexception.debug"), e);
- } catch (IOException e) {
+ if (getLog().isDebugEnabled()) {
+ getLog().debug(sm.getString("abstractConnectionHandler.socketexception.debug"), e);
+ }
+ } catch (IOException ioe) {
// IOExceptions are normal
- getLog().debug(sm.getString("abstractConnectionHandler.ioexception.debug"), e);
+ if (getLog().isDebugEnabled()) {
+ getLog().debug(sm.getString("abstractConnectionHandler.ioexception.debug"), ioe);
+ }
} catch (ProtocolException e) {
- // Protocol exceptions normally mean the client sent invalid or
- // incomplete data.
- getLog().debug(sm.getString("abstractConnectionHandler.protocolexception.debug"), e);
+ // Protocol exceptions normally mean the client sent invalid or incomplete data.
+ if (getLog().isDebugEnabled()) {
+ getLog().debug(sm.getString("abstractConnectionHandler.protocolexception.debug"), e);
+ }
}
// Future developers: if you discover any other
// rare-but-nonfatal exceptions, catch them here, and log as
@@ -1054,12 +1059,12 @@
// Worst case, it isn't recoverable and the attempt at logging
// will trigger another OOME.
getLog().error(sm.getString("abstractConnectionHandler.oome"), oome);
- } catch (Throwable e) {
- ExceptionUtils.handleThrowable(e);
+ } catch (Throwable t) {
+ ExceptionUtils.handleThrowable(t);
// any other exception or error is odd. Here we log it
// with "ERROR" level, so it will show up even on
// less-than-verbose logs.
- getLog().error(sm.getString("abstractConnectionHandler.error"), e);
+ getLog().error(sm.getString("abstractConnectionHandler.error"), t);
}
// Make sure socket/processor is removed from the list of current
diff -Nru tomcat11-11.0.6/java/org/apache/coyote/ActionCode.java tomcat11-11.0.15/java/org/apache/coyote/ActionCode.java
--- tomcat11-11.0.6/java/org/apache/coyote/ActionCode.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/coyote/ActionCode.java 2025-12-02 16:54:08.000000000 +0000
@@ -22,8 +22,6 @@
*
* @see ProtocolHandler
* @see ActionHook
- *
- * @author Remy Maucherat
*/
public enum ActionCode {
diff -Nru tomcat11-11.0.6/java/org/apache/coyote/ActionHook.java tomcat11-11.0.15/java/org/apache/coyote/ActionHook.java
--- tomcat11-11.0.6/java/org/apache/coyote/ActionHook.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/coyote/ActionHook.java 2025-12-02 16:54:08.000000000 +0000
@@ -22,8 +22,6 @@
* coyote connectors. Some standard actions are defined in ActionCode, however custom actions are permitted. The param
* object can be used to pass and return information related with the action. This interface is typically implemented by
* ProtocolHandlers, and the param is usually a Request or Response object.
- *
- * @author Remy Maucherat
*/
public interface ActionHook {
diff -Nru tomcat11-11.0.6/java/org/apache/coyote/Adapter.java tomcat11-11.0.15/java/org/apache/coyote/Adapter.java
--- tomcat11-11.0.6/java/org/apache/coyote/Adapter.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/coyote/Adapter.java 2025-12-02 16:54:08.000000000 +0000
@@ -21,8 +21,6 @@
/**
* Adapter. This represents the entry point in a coyote-based servlet container.
*
- * @author Remy Maucherat
- *
* @see ProtocolHandler
*/
public interface Adapter {
diff -Nru tomcat11-11.0.6/java/org/apache/coyote/CompressionConfig.java tomcat11-11.0.15/java/org/apache/coyote/CompressionConfig.java
--- tomcat11-11.0.6/java/org/apache/coyote/CompressionConfig.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/coyote/CompressionConfig.java 2025-12-02 16:54:08.000000000 +0000
@@ -201,18 +201,18 @@
Set tokens = new HashSet<>();
try {
TokenList.parseTokenList(responseHeaders.values("Content-Encoding"), tokens);
- } catch (IOException e) {
+ } catch (IOException ioe) {
// Because we are using StringReader, any exception here is a
// Tomcat bug.
- log.warn(sm.getString("compressionConfig.ContentEncodingParseFail"), e);
+ log.warn(sm.getString("compressionConfig.ContentEncodingParseFail"), ioe);
return false;
}
if (tokens.contains("identity")) {
// If identity, do not do content modifications
useContentEncoding = false;
- } else if (tokens.contains("br") || tokens.contains("compress") || tokens.contains("dcb")
- || tokens.contains("dcz") || tokens.contains("deflate") || tokens.contains("gzip")
- || tokens.contains("pack200-gzip") || tokens.contains("zstd")) {
+ } else if (tokens.contains("br") || tokens.contains("compress") || tokens.contains("dcb") ||
+ tokens.contains("dcz") || tokens.contains("deflate") || tokens.contains("gzip") ||
+ tokens.contains("pack200-gzip") || tokens.contains("zstd")) {
// Content should not be compressed twice
return false;
}
diff -Nru tomcat11-11.0.6/java/org/apache/coyote/Constants.java tomcat11-11.0.15/java/org/apache/coyote/Constants.java
--- tomcat11-11.0.6/java/org/apache/coyote/Constants.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/coyote/Constants.java 2025-12-02 16:54:08.000000000 +0000
@@ -21,8 +21,6 @@
/**
* Constants.
- *
- * @author Remy Maucherat
*/
public final class Constants {
diff -Nru tomcat11-11.0.6/java/org/apache/coyote/OutputBuffer.java tomcat11-11.0.15/java/org/apache/coyote/OutputBuffer.java
--- tomcat11-11.0.6/java/org/apache/coyote/OutputBuffer.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/coyote/OutputBuffer.java 2025-12-02 16:54:08.000000000 +0000
@@ -22,8 +22,6 @@
/**
* Output buffer. This class is used internally by the protocol implementation. All writes from higher level code should
* happen via Response.doWrite().
- *
- * @author Remy Maucherat
*/
public interface OutputBuffer {
diff -Nru tomcat11-11.0.6/java/org/apache/coyote/ProtocolHandler.java tomcat11-11.0.15/java/org/apache/coyote/ProtocolHandler.java
--- tomcat11-11.0.6/java/org/apache/coyote/ProtocolHandler.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/coyote/ProtocolHandler.java 2025-12-02 16:54:08.000000000 +0000
@@ -26,9 +26,6 @@
* Abstract the protocol implementation, including threading, etc. This is the main interface to be implemented by a
* coyote protocol. Adapter is the main interface to be implemented by a coyote servlet container.
*
- * @author Remy Maucherat
- * @author Costin Manolache
- *
* @see Adapter
*/
public interface ProtocolHandler {
diff -Nru tomcat11-11.0.6/java/org/apache/coyote/Request.java tomcat11-11.0.15/java/org/apache/coyote/Request.java
--- tomcat11-11.0.6/java/org/apache/coyote/Request.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/coyote/Request.java 2025-12-02 16:54:08.000000000 +0000
@@ -20,6 +20,7 @@
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
+import java.time.Instant;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
@@ -34,6 +35,7 @@
import org.apache.tomcat.util.buf.CharsetHolder;
import org.apache.tomcat.util.buf.MessageBytes;
import org.apache.tomcat.util.buf.UDecoder;
+import org.apache.tomcat.util.http.Method;
import org.apache.tomcat.util.http.MimeHeaders;
import org.apache.tomcat.util.http.Parameters;
import org.apache.tomcat.util.http.ServerCookies;
@@ -50,15 +52,6 @@
*
*
"org.apache.tomcat.request" - allows access to the low-level request object in trusted applications
*
- *
- * @author James Duncan Davidson [duncan@eng.sun.com]
- * @author James Todd [gonzo@eng.sun.com]
- * @author Jason Hunter [jch@eng.sun.com]
- * @author Harish Prabandham
- * @author Alex Cruikshank [alex@epitonic.com]
- * @author Hans Bergsten [hans@gefionsoftware.com]
- * @author Costin Manolache
- * @author Remy Maucherat
*/
public final class Request {
@@ -72,8 +65,8 @@
* another 3,000,000 years before it gets back to zero).
*
* Local testing shows that 5, 10, 50, 500 or 1000 threads can obtain 60,000,000+ IDs a second from a single
- * AtomicLong. That is about 17ns per request. It does not appear that the introduction of this counter will
- * cause a bottleneck for request processing.
+ * AtomicLong. That is about 17ns per request. It does not appear that the introduction of this counter will cause a
+ * bottleneck for request processing.
*/
private static final AtomicLong requestIdGenerator = new AtomicLong(0);
@@ -141,7 +134,7 @@
*/
private long contentLength = -1;
private MessageBytes contentTypeMB = null;
- private CharsetHolder charsetHolder = CharsetHolder.EMPTY;
+ private CharsetHolder charsetHolder = null;
/**
* Is there an expectation ?
@@ -162,6 +155,7 @@
private long bytesRead = 0;
// Time of the request - useful to avoid repeated calls to System.currentTime
private long startTimeNanos = -1;
+ private Instant startInstant = null;
private long threadId = 0;
private int available = 0;
@@ -314,10 +308,36 @@
return schemeMB;
}
+ /**
+ * Get a MessageBytes instance that holds the current request's HTTP method.
+ *
+ * @return a MessageBytes instance that holds the current request's HTTP method.
+ *
+ * @deprecated Use {@link #getMethod()}, {@link Request#setMethod(String)} and {@link #setMethod(byte[], int, int)}
+ */
+ @Deprecated
public MessageBytes method() {
return methodMB;
}
+ public void setMethod(String method) {
+ methodMB.setString(method);
+ }
+
+ public void setMethod(byte[] buf, int start, int len) {
+ String method = Method.bytesToString(buf, start, len);
+ if (method == null) {
+ methodMB.setBytes(buf, start, len);
+ method = methodMB.toStringType();
+ } else {
+ methodMB.setString(method);
+ }
+ }
+
+ public String getMethod() {
+ return methodMB.toStringType();
+ }
+
public MessageBytes requestURI() {
return uriMB;
}
@@ -443,7 +463,7 @@
public CharsetHolder getCharsetHolder() {
- if (charsetHolder.getName() == null) {
+ if (charsetHolder == null) {
charsetHolder = CharsetHolder.getInstance(getCharsetFromContentType(getContentType()));
}
return charsetHolder;
@@ -451,7 +471,11 @@
public void setCharsetHolder(CharsetHolder charsetHolder) {
- this.charsetHolder = charsetHolder;
+ if (charsetHolder == null || charsetHolder.getName() == null) {
+ this.charsetHolder = null;
+ } else {
+ this.charsetHolder = charsetHolder;
+ }
}
@@ -723,8 +747,26 @@
return startTimeNanos;
}
+ /**
+ * Set the start time using the value provided by {@code System.nanoTime()}.
+ *
+ * @param startTimeNanos The value returned from {@code System.nanoTime()} at the point the requests started.
+ *
+ * @deprecated Unused. Will be removed in Tomcat 12 onwards. Use {@link #markStartTime()}.
+ */
+ @Deprecated
public void setStartTimeNanos(long startTimeNanos) {
this.startTimeNanos = startTimeNanos;
+ startInstant = Instant.now();
+ }
+
+ public void markStartTime() {
+ startTimeNanos = System.nanoTime();
+ startInstant = Instant.now();
+ }
+
+ public Instant getStartInstant() {
+ return startInstant;
}
public long getThreadId() {
@@ -778,7 +820,7 @@
contentLength = -1;
contentTypeMB = null;
- charsetHolder = CharsetHolder.EMPTY;
+ charsetHolder = null;
expectation = false;
headers.recycle();
trailerFields.recycle();
@@ -835,6 +877,7 @@
allDataReadEventSent.set(false);
startTimeNanos = -1;
+ startInstant = null;
threadId = 0;
if (hook instanceof NonPipeliningProcessor) {
@@ -879,7 +922,7 @@
MediaType mediaType = null;
try {
mediaType = MediaType.parseMediaType(new StringReader(contentType));
- } catch (IOException e) {
+ } catch (IOException ioe) {
// Ignore - null test below handles this
}
if (mediaType != null) {
diff -Nru tomcat11-11.0.6/java/org/apache/coyote/RequestInfo.java tomcat11-11.0.15/java/org/apache/coyote/RequestInfo.java
--- tomcat11-11.0.6/java/org/apache/coyote/RequestInfo.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/coyote/RequestInfo.java 2025-12-02 16:54:08.000000000 +0000
@@ -25,9 +25,7 @@
* Structure holding the Request and Response objects. It also holds statistical information about request processing
* and provide management information about the requests being processed. Each thread uses a Request/Response pair that
* is recycled on each request. This object provides a place to collect global low-level statistics - without having to
- * deal with synchronization ( since each thread will have its own RequestProcessorMX ).
- *
- * @author Costin Manolache
+ * deal with synchronization (since each thread will have its own RequestProcessorMX).
*/
public class RequestInfo {
private RequestGroupInfo global = null;
@@ -65,7 +63,7 @@
// This is useful for long-running requests only
public String getMethod() {
- return req.method().toString();
+ return req.getMethod();
}
public String getCurrentUri() {
@@ -261,4 +259,18 @@
public void setLastRequestProcessingTime(long lastRequestProcessingTime) {
this.lastRequestProcessingTime = lastRequestProcessingTime;
}
+
+ public void recycleStatistcs() {
+ this.bytesSent = 0;
+ this.bytesReceived = 0;
+
+ this.processingTime = 0;
+ this.maxTime = 0;
+ this.maxRequestUri = null;
+
+ this.requestCount = 0;
+ this.errorCount = 0;
+
+ this.lastRequestProcessingTime = 0;
+ }
}
diff -Nru tomcat11-11.0.6/java/org/apache/coyote/Response.java tomcat11-11.0.15/java/org/apache/coyote/Response.java
--- tomcat11-11.0.6/java/org/apache/coyote/Response.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/coyote/Response.java 2025-12-02 16:54:08.000000000 +0000
@@ -41,13 +41,6 @@
/**
* Response object.
- *
- * @author James Duncan Davidson [duncan@eng.sun.com]
- * @author Jason Hunter [jch@eng.sun.com]
- * @author James Todd [gonzo@eng.sun.com]
- * @author Harish Prabandham
- * @author Hans Bergsten [hans@gefionsoftware.com]
- * @author Remy Maucherat
*/
public final class Response {
@@ -561,7 +554,7 @@
MediaType m = null;
try {
m = MediaType.parseMediaType(new StringReader(type));
- } catch (IOException e) {
+ } catch (IOException ignore) {
// Ignore - null test below handles this
}
if (m == null) {
diff -Nru tomcat11-11.0.6/java/org/apache/coyote/UpgradeToken.java tomcat11-11.0.15/java/org/apache/coyote/UpgradeToken.java
--- tomcat11-11.0.6/java/org/apache/coyote/UpgradeToken.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/coyote/UpgradeToken.java 2025-12-02 16:54:08.000000000 +0000
@@ -31,7 +31,7 @@
* @param protocol The desired protocol to upgrade to
*/
public record UpgradeToken(HttpUpgradeHandler httpUpgradeHandler, ContextBind contextBind,
- InstanceManager instanceManager, String protocol) {
+ InstanceManager instanceManager, String protocol) {
public ContextBind getContextBind() {
return contextBind;
diff -Nru tomcat11-11.0.6/java/org/apache/coyote/ajp/AbstractAjpProtocol.java tomcat11-11.0.15/java/org/apache/coyote/ajp/AbstractAjpProtocol.java
--- tomcat11-11.0.6/java/org/apache/coyote/ajp/AbstractAjpProtocol.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/coyote/ajp/AbstractAjpProtocol.java 2025-12-02 16:54:08.000000000 +0000
@@ -241,8 +241,8 @@
@Override
protected Processor createUpgradeProcessor(SocketWrapperBase> socket, UpgradeToken upgradeToken) {
- throw new IllegalStateException(sm.getString("ajpprotocol.noUpgradeHandler",
- upgradeToken.httpUpgradeHandler().getClass().getName()));
+ throw new IllegalStateException(
+ sm.getString("ajpprotocol.noUpgradeHandler", upgradeToken.httpUpgradeHandler().getClass().getName()));
}
diff -Nru tomcat11-11.0.6/java/org/apache/coyote/ajp/AjpMessage.java tomcat11-11.0.15/java/org/apache/coyote/ajp/AjpMessage.java
--- tomcat11-11.0.6/java/org/apache/coyote/ajp/AjpMessage.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/coyote/ajp/AjpMessage.java 2025-12-02 16:54:08.000000000 +0000
@@ -29,16 +29,9 @@
* A single packet for communication between the web server and the container. Designed to be reused many times with no
* creation of garbage. Understands the format of data types for these packets. Can be used (somewhat confusingly) for
* both incoming and outgoing packets.
- *
- * @author Henri Gomez
- * @author Dan Milstein
- * @author Keith Wannamaker
- * @author Kevin Seguin
- * @author Costin Manolache
*/
public class AjpMessage {
-
private static final Log log = LogFactory.getLog(AjpMessage.class);
/**
@@ -47,17 +40,11 @@
protected static final StringManager sm = StringManager.getManager(AjpMessage.class);
- // ------------------------------------------------------------ Constructor
-
-
public AjpMessage(int packetSize) {
buf = new byte[packetSize];
}
- // ----------------------------------------------------- Instance Variables
-
-
/**
* Fixed size buffer.
*/
@@ -78,9 +65,6 @@
protected int len;
- // --------------------------------------------------------- Public Methods
-
-
/**
* Prepare this packet for accumulating a message from the container to the web server. Set the write position to
* just after the header (but leave the length unwritten, because it is as yet unknown).
diff -Nru tomcat11-11.0.6/java/org/apache/coyote/ajp/AjpProcessor.java tomcat11-11.0.15/java/org/apache/coyote/ajp/AjpProcessor.java
--- tomcat11-11.0.6/java/org/apache/coyote/ajp/AjpProcessor.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/coyote/ajp/AjpProcessor.java 2025-12-02 16:54:08.000000000 +0000
@@ -48,6 +48,7 @@
import org.apache.tomcat.util.ExceptionUtils;
import org.apache.tomcat.util.buf.ByteChunk;
import org.apache.tomcat.util.buf.MessageBytes;
+import org.apache.tomcat.util.http.Method;
import org.apache.tomcat.util.http.MimeHeaders;
import org.apache.tomcat.util.net.AbstractEndpoint.Handler.SocketState;
import org.apache.tomcat.util.net.ApplicationBufferHandler;
@@ -128,20 +129,19 @@
System.arraycopy(pongMessage.getBuffer(), 0, pongMessageArray, 0, pongMessage.getLen());
// Build Map of Java Servlet to Jakarta Servlet attribute names
- jakartaAttributeMapping = Map.of(
- "jakarta.servlet.request.secure_protocol", "jakarta.servlet.request.secure_protocol",
- "jakarta.servlet.request.cipher_suite", "jakarta.servlet.request.cipher_suite",
- "jakarta.servlet.request.key_size", "jakarta.servlet.request.key_size",
- "jakarta.servlet.request.ssl_session", "jakarta.servlet.request.ssl_session",
- "jakarta.servlet.request.X509Certificate", "jakarta.servlet.request.X509Certificate",
- "javax.servlet.request.cipher_suite", "jakarta.servlet.request.cipher_suite",
- "javax.servlet.request.key_size", "jakarta.servlet.request.key_size",
- "javax.servlet.request.ssl_session", "jakarta.servlet.request.ssl_session",
- "javax.servlet.request.X509Certificate", "jakarta.servlet.request.X509Certificate");
-
- iisTlsAttributes = Set.of(
- "CERT_ISSUER", "CERT_SUBJECT", "CERT_COOKIE", "HTTPS_SERVER_SUBJECT", "CERT_FLAGS", "HTTPS_SECRETKEYSIZE",
- "CERT_SERIALNUMBER", "HTTPS_SERVER_ISSUER", "HTTPS_KEYSIZE");
+ jakartaAttributeMapping =
+ Map.of("jakarta.servlet.request.secure_protocol", "jakarta.servlet.request.secure_protocol",
+ "jakarta.servlet.request.cipher_suite", "jakarta.servlet.request.cipher_suite",
+ "jakarta.servlet.request.key_size", "jakarta.servlet.request.key_size",
+ "jakarta.servlet.request.ssl_session", "jakarta.servlet.request.ssl_session",
+ "jakarta.servlet.request.X509Certificate", "jakarta.servlet.request.X509Certificate",
+ "javax.servlet.request.cipher_suite", "jakarta.servlet.request.cipher_suite",
+ "javax.servlet.request.key_size", "jakarta.servlet.request.key_size",
+ "javax.servlet.request.ssl_session", "jakarta.servlet.request.ssl_session",
+ "javax.servlet.request.X509Certificate", "jakarta.servlet.request.X509Certificate");
+
+ iisTlsAttributes = Set.of("CERT_ISSUER", "CERT_SUBJECT", "CERT_COOKIE", "HTTPS_SERVER_SUBJECT", "CERT_FLAGS",
+ "HTTPS_SECRETKEYSIZE", "CERT_SERIALNUMBER", "HTTPS_SERVER_ISSUER", "HTTPS_KEYSIZE");
}
@@ -363,11 +363,11 @@
try {
socketWrapper.write(true, pongMessageArray, 0, pongMessageArray.length);
socketWrapper.flush(true);
- } catch (IOException e) {
+ } catch (IOException ioe) {
if (getLog().isDebugEnabled()) {
- getLog().debug(sm.getString("ajpprocessor.pongFail"), e);
+ getLog().debug(sm.getString("ajpprocessor.pongFail"), ioe);
}
- setErrorState(ErrorState.CLOSE_CONNECTION_NOW, e);
+ setErrorState(ErrorState.CLOSE_CONNECTION_NOW, ioe);
}
recycle();
continue;
@@ -380,13 +380,15 @@
setErrorState(ErrorState.CLOSE_CONNECTION_NOW, null);
break;
}
- request.setStartTimeNanos(System.nanoTime());
- } catch (IOException e) {
- setErrorState(ErrorState.CLOSE_CONNECTION_NOW, e);
+ request.markStartTime();
+ } catch (IOException ioe) {
+ setErrorState(ErrorState.CLOSE_CONNECTION_NOW, ioe);
break;
} catch (Throwable t) {
ExceptionUtils.handleThrowable(t);
- getLog().debug(sm.getString("ajpprocessor.header.error"), t);
+ if (getLog().isDebugEnabled()) {
+ getLog().debug(sm.getString("ajpprocessor.header.error"), t);
+ }
// 400 - Bad Request
response.setStatus(400);
setErrorState(ErrorState.CLOSE_CLEAN, t);
@@ -399,7 +401,9 @@
prepareRequest();
} catch (Throwable t) {
ExceptionUtils.handleThrowable(t);
- getLog().debug(sm.getString("ajpprocessor.request.prepare"), t);
+ if (getLog().isDebugEnabled()) {
+ getLog().debug(sm.getString("ajpprocessor.request.prepare"), t);
+ }
// 500 - Internal Server Error
response.setStatus(500);
setErrorState(ErrorState.CLOSE_CLEAN, t);
@@ -565,7 +569,7 @@
// Zero length message.
return true;
} else {
- if (messageLength > message.getBuffer().length) {
+ if (messageLength > (buf.length - Constants.H_SIZE)) {
// Message too long for the buffer
// Need to trigger a 400 response
String msg = sm.getString("ajpprocessor.header.tooLong", Integer.valueOf(messageLength),
@@ -639,7 +643,7 @@
byte methodCode = requestHeaderMessage.getByte();
if (methodCode != Constants.SC_M_JK_STORED) {
String methodName = Constants.getMethodForCode(methodCode - 1);
- request.method().setString(methodName);
+ request.setMethod(methodName);
}
requestHeaderMessage.getBytes(request.protocol());
@@ -807,7 +811,11 @@
}
case Constants.SC_A_SSL_KEY_SIZE ->
request.setAttribute(SSLSupport.KEY_SIZE_KEY, Integer.valueOf(requestHeaderMessage.getInt()));
- case Constants.SC_A_STORED_METHOD -> requestHeaderMessage.getBytes(request.method());
+ case Constants.SC_A_STORED_METHOD -> {
+ requestHeaderMessage.getBytes(tmpMB);
+ ByteChunk tmpBC = tmpMB.getByteChunk();
+ request.setMethod(tmpBC.getBytes(), tmpBC.getStart(), tmpBC.getLength());
+ }
case Constants.SC_A_SECRET -> {
requestHeaderMessage.getBytes(tmpMB);
if (secret != null && !secret.isEmpty()) {
@@ -871,9 +879,9 @@
protected void populateHost() {
try {
request.serverName().duplicate(request.localName());
- } catch (IOException e) {
+ } catch (IOException ioe) {
response.setStatus(400);
- setErrorState(ErrorState.CLOSE_CLEAN, e);
+ setErrorState(ErrorState.CLOSE_CLEAN, ioe);
}
}
@@ -901,7 +909,7 @@
// Responses with certain status codes and/or methods are not permitted to include a response body.
int statusCode = response.getStatus();
if (statusCode < 200 || statusCode == 204 || statusCode == 205 || statusCode == 304 ||
- request.method().equals("HEAD")) {
+ Method.HEAD.equals(request.getMethod())) {
// No entity body
swallowResponse = true;
}
@@ -1034,10 +1042,12 @@
if (empty && doRead) {
try {
refillReadBuffer(false);
- } catch (IOException timeout) {
- // Not ideal. This will indicate that data is available
- // which should trigger a read which in turn will trigger
- // another IOException and that one can be thrown.
+ } catch (IOException ioe) {
+ /*
+ * Probably a timeout. This approach isn't ideal but it works. Returning 1 will indicate that data is
+ * available which should trigger a read which in turn will trigger another IOException and that one can
+ * be thrown.
+ */
return 1;
}
}
@@ -1279,8 +1289,8 @@
// Validate and write response headers
try {
prepareResponse();
- } catch (IOException e) {
- setErrorState(ErrorState.CLOSE_CONNECTION_NOW, e);
+ } catch (IOException ioe) {
+ setErrorState(ErrorState.CLOSE_CONNECTION_NOW, ioe);
}
}
diff -Nru tomcat11-11.0.6/java/org/apache/coyote/ajp/Constants.java tomcat11-11.0.15/java/org/apache/coyote/ajp/Constants.java
--- tomcat11-11.0.6/java/org/apache/coyote/ajp/Constants.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/coyote/ajp/Constants.java 2025-12-02 16:54:08.000000000 +0000
@@ -19,10 +19,10 @@
import java.util.HashMap;
import java.util.Map;
+import org.apache.tomcat.util.http.Method;
+
/**
* Constants.
- *
- * @author Remy Maucherat
*/
public final class Constants {
@@ -104,10 +104,10 @@
public static final int MAX_SEND_SIZE = MAX_PACKET_SIZE - SEND_HEAD_LEN;
// Translates integer codes to names of HTTP methods
- private static final String[] methodTransArray =
- { "OPTIONS", "GET", "HEAD", "POST", "PUT", "DELETE", "TRACE", "PROPFIND", "PROPPATCH", "MKCOL", "COPY",
- "MOVE", "LOCK", "UNLOCK", "ACL", "REPORT", "VERSION-CONTROL", "CHECKIN", "CHECKOUT", "UNCHECKOUT",
- "SEARCH", "MKWORKSPACE", "UPDATE", "LABEL", "MERGE", "BASELINE-CONTROL", "MKACTIVITY" };
+ private static final String[] methodTransArray = { Method.OPTIONS, Method.GET, Method.HEAD, Method.POST, Method.PUT,
+ Method.DELETE, Method.TRACE, Method.PROPFIND, Method.PROPPATCH, Method.MKCOL, Method.COPY, Method.MOVE,
+ Method.LOCK, Method.UNLOCK, "ACL", "REPORT", "VERSION-CONTROL", "CHECKIN", "CHECKOUT", "UNCHECKOUT",
+ "SEARCH", "MKWORKSPACE", "UPDATE", "LABEL", "MERGE", "BASELINE-CONTROL", "MKACTIVITY" };
/**
* Converts an AJP coded HTTP method to the method name.
@@ -172,12 +172,8 @@
private static final Map responseTransMap = new HashMap<>(20);
static {
- try {
- for (int i = 0; i < SC_RESP_AJP13_MAX; i++) {
- responseTransMap.put(getResponseHeaderForCode(i), Integer.valueOf(0xA001 + i));
- }
- } catch (Exception e) {
- // Do nothing
+ for (int i = 0; i < SC_RESP_AJP13_MAX; i++) {
+ responseTransMap.put(getResponseHeaderForCode(i), Integer.valueOf(0xA001 + i));
}
}
diff -Nru tomcat11-11.0.6/java/org/apache/coyote/http11/AbstractHttp11Protocol.java tomcat11-11.0.15/java/org/apache/coyote/http11/AbstractHttp11Protocol.java
--- tomcat11-11.0.6/java/org/apache/coyote/http11/AbstractHttp11Protocol.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/coyote/http11/AbstractHttp11Protocol.java 2025-12-02 16:54:08.000000000 +0000
@@ -500,7 +500,7 @@
}
public boolean isTrailerHeaderAllowed(String headerName) {
- return allowedTrailerHeaders.contains(headerName);
+ return allowedTrailerHeaders.contains(headerName.trim().toLowerCase(Locale.ENGLISH));
}
public String getAllowedTrailerHeaders() {
@@ -759,6 +759,10 @@
}
+ public boolean checkSni(String sniHostName, String protocolHostName) {
+ return getEndpoint().checkSni(sniHostName, protocolHostName);
+ }
+
// ------------------------------------------------------------- Common code
@Override
diff -Nru tomcat11-11.0.6/java/org/apache/coyote/http11/Constants.java tomcat11-11.0.15/java/org/apache/coyote/http11/Constants.java
--- tomcat11-11.0.6/java/org/apache/coyote/http11/Constants.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/coyote/http11/Constants.java 2025-12-02 16:54:08.000000000 +0000
@@ -20,8 +20,6 @@
/**
* Constants.
- *
- * @author Remy Maucherat
*/
public final class Constants {
diff -Nru tomcat11-11.0.6/java/org/apache/coyote/http11/Http11InputBuffer.java tomcat11-11.0.15/java/org/apache/coyote/http11/Http11InputBuffer.java
--- tomcat11-11.0.6/java/org/apache/coyote/http11/Http11InputBuffer.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/coyote/http11/Http11InputBuffer.java 2025-12-02 16:54:08.000000000 +0000
@@ -355,7 +355,7 @@
// just skipping blank lines)
if (parsingRequestLinePhase == 0) {
parsingRequestLinePhase = 1;
- request.setStartTimeNanos(System.nanoTime());
+ request.markStartTime();
}
chr = byteBuffer.get();
} while (chr == Constants.CR || chr == Constants.LF);
@@ -383,8 +383,7 @@
chr = byteBuffer.get();
if (chr == Constants.SP || chr == Constants.HT) {
space = true;
- request.method().setBytes(byteBuffer.array(), parsingRequestLineStart,
- pos - parsingRequestLineStart);
+ request.setMethod(byteBuffer.array(), parsingRequestLineStart, pos - parsingRequestLineStart);
} else if (!HttpParser.isToken(chr)) {
// Avoid unknown protocol triggering an additional error
request.protocol().setString(Constants.HTTP_11);
diff -Nru tomcat11-11.0.6/java/org/apache/coyote/http11/Http11Processor.java tomcat11-11.0.15/java/org/apache/coyote/http11/Http11Processor.java
--- tomcat11-11.0.6/java/org/apache/coyote/http11/Http11Processor.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/coyote/http11/Http11Processor.java 2025-12-02 16:54:08.000000000 +0000
@@ -55,6 +55,7 @@
import org.apache.tomcat.util.buf.ByteChunk;
import org.apache.tomcat.util.buf.MessageBytes;
import org.apache.tomcat.util.http.FastHttpDateFormat;
+import org.apache.tomcat.util.http.Method;
import org.apache.tomcat.util.http.MimeHeaders;
import org.apache.tomcat.util.http.parser.HttpParser;
import org.apache.tomcat.util.http.parser.TokenList;
@@ -300,11 +301,11 @@
socketWrapper.setReadTimeout(protocol.getConnectionUploadTimeout());
}
}
- } catch (IOException e) {
+ } catch (IOException ioe) {
if (log.isDebugEnabled()) {
- log.debug(sm.getString("http11processor.header.parse"), e);
+ log.debug(sm.getString("http11processor.header.parse"), ioe);
}
- setErrorState(ErrorState.CLOSE_CONNECTION_NOW, e);
+ setErrorState(ErrorState.CLOSE_CONNECTION_NOW, ioe);
break;
} catch (Throwable t) {
ExceptionUtils.handleThrowable(t);
@@ -501,7 +502,7 @@
// Transfer the minimal information required for the copy of the Request
// that is passed to the HTTP upgrade process
dest.decodedURI().duplicate(source.decodedURI());
- dest.method().duplicate(source.method());
+ dest.setMethod(source.getMethod());
dest.getMimeHeaders().duplicate(source.getMimeHeaders());
dest.requestURI().duplicate(source.requestURI());
dest.queryString().duplicate(source.queryString());
@@ -574,7 +575,7 @@
long contentLength = -1;
try {
contentLength = request.getContentLengthLong();
- } catch (Exception e) {
+ } catch (Exception ignore) {
// Ignore, an error here is already processed in prepareRequest
// but is done again since the content length is still -1
}
@@ -606,6 +607,11 @@
http09 = true;
http11 = false;
keepAlive = false;
+ if (!Method.GET.equals(request.getMethod())) {
+ // Send 400, GET is the only allowed method for HTTP/0.9
+ response.setStatus(400);
+ setErrorState(ErrorState.CLOSE_CLEAN, null);
+ }
} else {
// Unsupported protocol
http09 = false;
@@ -746,7 +752,7 @@
try {
hostValueMB = headers.setValue("host");
hostValueMB.setBytes(uriB, uriBCStart + pos, slashPos - pos);
- } catch (IllegalStateException e) {
+ } catch (IllegalStateException ignore) {
// Edge case
// If the request has too many headers it won't be
// possible to create the host header. Ignore this as
@@ -774,6 +780,11 @@
// Validate host name and extract port if present
parseHost(hostValueMB);
+ // Match host name with SNI if required
+ if (!protocol.checkSni(socketWrapper.getSniHostName(), request.serverName().toString())) {
+ badRequest("http11processor.request.sni");
+ }
+
if (!getErrorState().isIoAllowed()) {
getAdapter().log(request, response, 0);
}
@@ -890,7 +901,7 @@
}
}
- boolean head = request.method().equals("HEAD");
+ boolean head = Method.HEAD.equals(request.getMethod());
if (head) {
// Any entity body, if present, should not be sent
outputBuffer.addActiveFilter(outputFilters[Constants.VOID_FILTER]);
@@ -1150,6 +1161,8 @@
endRequest();
inputBuffer.nextRequest();
outputBuffer.nextRequest();
+ // Set keep alive timeout for next request
+ socketWrapper.setReadTimeout(protocol.getKeepAliveTimeout());
if (socketWrapper.isReadPending()) {
return SocketState.LONG;
} else {
@@ -1192,8 +1205,8 @@
if (getErrorState().isIoAllowed()) {
try {
inputBuffer.endRequest();
- } catch (IOException e) {
- setErrorState(ErrorState.CLOSE_CONNECTION_NOW, e);
+ } catch (IOException ioe) {
+ setErrorState(ErrorState.CLOSE_CONNECTION_NOW, ioe);
} catch (Throwable t) {
ExceptionUtils.handleThrowable(t);
// 500 - Internal Server Error
@@ -1208,8 +1221,8 @@
try {
action(ActionCode.COMMIT, null);
outputBuffer.end();
- } catch (IOException e) {
- setErrorState(ErrorState.CLOSE_CONNECTION_NOW, e);
+ } catch (IOException ioe) {
+ setErrorState(ErrorState.CLOSE_CONNECTION_NOW, ioe);
} catch (Throwable t) {
ExceptionUtils.handleThrowable(t);
setErrorState(ErrorState.CLOSE_NOW, t);
@@ -1237,8 +1250,8 @@
if (!response.isCommitted() && request.hasExpectation()) {
try {
outputBuffer.sendAck();
- } catch (IOException e) {
- setErrorState(ErrorState.CLOSE_CONNECTION_NOW, e);
+ } catch (IOException ioe) {
+ setErrorState(ErrorState.CLOSE_CONNECTION_NOW, ioe);
}
}
}
diff -Nru tomcat11-11.0.6/java/org/apache/coyote/http11/InputFilter.java tomcat11-11.0.15/java/org/apache/coyote/http11/InputFilter.java
--- tomcat11-11.0.6/java/org/apache/coyote/http11/InputFilter.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/coyote/http11/InputFilter.java 2025-12-02 16:54:08.000000000 +0000
@@ -24,8 +24,6 @@
/**
* Input filter interface.
- *
- * @author Remy Maucherat
*/
public interface InputFilter extends InputBuffer {
diff -Nru tomcat11-11.0.6/java/org/apache/coyote/http11/LocalStrings.properties tomcat11-11.0.15/java/org/apache/coyote/http11/LocalStrings.properties
--- tomcat11-11.0.6/java/org/apache/coyote/http11/LocalStrings.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/coyote/http11/LocalStrings.properties 2025-12-02 16:54:08.000000000 +0000
@@ -39,6 +39,7 @@
http11processor.request.nonNumericContentLength=The request contained a content-length header with a non-numeric value
http11processor.request.prepare=Error preparing request
http11processor.request.process=Error processing request
+http11processor.request.sni=The host header does not match the SNI host
http11processor.request.unsupportedEncoding=Error preparing request, unsupported transfer encoding [{0}]
http11processor.request.unsupportedVersion=Error preparing request, unsupported HTTP version [{0}]
http11processor.response.finish=Error finishing response
diff -Nru tomcat11-11.0.6/java/org/apache/coyote/http11/OutputFilter.java tomcat11-11.0.15/java/org/apache/coyote/http11/OutputFilter.java
--- tomcat11-11.0.6/java/org/apache/coyote/http11/OutputFilter.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/coyote/http11/OutputFilter.java 2025-12-02 16:54:08.000000000 +0000
@@ -20,8 +20,6 @@
/**
* Output filter.
- *
- * @author Remy Maucherat
*/
public interface OutputFilter extends HttpOutputBuffer {
diff -Nru tomcat11-11.0.6/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java tomcat11-11.0.15/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java
--- tomcat11-11.0.6/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java 2025-12-02 16:54:08.000000000 +0000
@@ -20,6 +20,7 @@
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.Set;
+import java.util.concurrent.atomic.AtomicLong;
import org.apache.coyote.ActionCode;
import org.apache.coyote.BadRequestException;
@@ -38,8 +39,6 @@
/**
* Chunked input filter. Parses chunked data according to http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.6.1
- *
- * @author Remy Maucherat
*/
public class ChunkedInputFilter implements InputFilter, ApplicationBufferHandler, HeaderDataSource {
@@ -108,7 +107,7 @@
private volatile boolean crFound = false;
private volatile int chunkSizeDigitsRead = 0;
private volatile boolean parsingExtension = false;
- private volatile long extensionSize;
+ private final AtomicLong extensionSize = new AtomicLong(0);
private final HttpHeaderParser httpHeaderParser;
// ----------------------------------------------------------- Constructors
@@ -253,7 +252,7 @@
crFound = false;
chunkSizeDigitsRead = 0;
parsingExtension = false;
- extensionSize = 0;
+ extensionSize.set(0);
httpHeaderParser.recycle();
}
@@ -367,7 +366,7 @@
// semicolons may appear to separate multiple chunk-extensions.
// These need to be processed as part of parsing the extensions.
parsingExtension = true;
- extensionSize++;
+ extensionSize.incrementAndGet();
} else if (!parsingExtension) {
int charValue = HexUtils.getDec(chr);
if (charValue != -1 && chunkSizeDigitsRead < 8) {
@@ -381,8 +380,8 @@
// Extension 'parsing'
// Note that the chunk-extension is neither parsed nor
// validated. Currently it is simply ignored.
- extensionSize++;
- if (maxExtensionSize > -1 && extensionSize > maxExtensionSize) {
+ long extSize = extensionSize.incrementAndGet();
+ if (maxExtensionSize > -1 && extSize > maxExtensionSize) {
throwBadRequestException(sm.getString("chunkedInputFilter.maxExtension"));
}
}
@@ -430,7 +429,7 @@
// semicolons may appear to separate multiple chunk-extensions.
// These need to be processed as part of parsing the extensions.
parsingExtension = true;
- extensionSize++;
+ extensionSize.incrementAndGet();
} else if (!parsingExtension) {
int charValue = HexUtils.getDec(chr);
if (charValue != -1 && chunkSizeDigitsRead < 8) {
@@ -444,8 +443,8 @@
// Extension 'parsing'
// Note that the chunk-extension is neither parsed nor
// validated. Currently it is simply ignored.
- extensionSize++;
- if (maxExtensionSize > -1 && extensionSize > maxExtensionSize) {
+ long extSize = extensionSize.incrementAndGet();
+ if (maxExtensionSize > -1 && extSize > maxExtensionSize) {
return false;
}
}
diff -Nru tomcat11-11.0.6/java/org/apache/coyote/http11/filters/ChunkedOutputFilter.java tomcat11-11.0.15/java/org/apache/coyote/http11/filters/ChunkedOutputFilter.java
--- tomcat11-11.0.6/java/org/apache/coyote/http11/filters/ChunkedOutputFilter.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/coyote/http11/filters/ChunkedOutputFilter.java 2025-12-02 16:54:08.000000000 +0000
@@ -34,8 +34,6 @@
/**
* Chunked output filter.
- *
- * @author Remy Maucherat
*/
public class ChunkedOutputFilter implements OutputFilter {
diff -Nru tomcat11-11.0.6/java/org/apache/coyote/http11/filters/GzipOutputFilter.java tomcat11-11.0.15/java/org/apache/coyote/http11/filters/GzipOutputFilter.java
--- tomcat11-11.0.6/java/org/apache/coyote/http11/filters/GzipOutputFilter.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/coyote/http11/filters/GzipOutputFilter.java 2025-12-02 16:54:08.000000000 +0000
@@ -30,8 +30,6 @@
/**
* Gzip output filter.
- *
- * @author Remy Maucherat
*/
public class GzipOutputFilter implements OutputFilter {
@@ -98,9 +96,9 @@
log.trace("Flushing the compression stream!");
}
compressionStream.flush();
- } catch (IOException e) {
+ } catch (IOException ioe) {
if (log.isDebugEnabled()) {
- log.debug(sm.getString("gzipOutputFilter.flushFail"), e);
+ log.debug(sm.getString("gzipOutputFilter.flushFail"), ioe);
}
}
}
diff -Nru tomcat11-11.0.6/java/org/apache/coyote/http11/filters/IdentityInputFilter.java tomcat11-11.0.15/java/org/apache/coyote/http11/filters/IdentityInputFilter.java
--- tomcat11-11.0.6/java/org/apache/coyote/http11/filters/IdentityInputFilter.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/coyote/http11/filters/IdentityInputFilter.java 2025-12-02 16:54:08.000000000 +0000
@@ -29,8 +29,6 @@
/**
* Identity input filter.
- *
- * @author Remy Maucherat
*/
public class IdentityInputFilter implements InputFilter, ApplicationBufferHandler {
diff -Nru tomcat11-11.0.6/java/org/apache/coyote/http11/filters/IdentityOutputFilter.java tomcat11-11.0.15/java/org/apache/coyote/http11/filters/IdentityOutputFilter.java
--- tomcat11-11.0.6/java/org/apache/coyote/http11/filters/IdentityOutputFilter.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/coyote/http11/filters/IdentityOutputFilter.java 2025-12-02 16:54:08.000000000 +0000
@@ -25,8 +25,6 @@
/**
* Identity output filter.
- *
- * @author Remy Maucherat
*/
public class IdentityOutputFilter implements OutputFilter {
diff -Nru tomcat11-11.0.6/java/org/apache/coyote/http11/filters/VoidInputFilter.java tomcat11-11.0.15/java/org/apache/coyote/http11/filters/VoidInputFilter.java
--- tomcat11-11.0.6/java/org/apache/coyote/http11/filters/VoidInputFilter.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/coyote/http11/filters/VoidInputFilter.java 2025-12-02 16:54:08.000000000 +0000
@@ -27,8 +27,6 @@
/**
* Void input filter, which returns -1 when attempting a read. Used with a GET, HEAD, or a similar request.
- *
- * @author Remy Maucherat
*/
public class VoidInputFilter implements InputFilter {
diff -Nru tomcat11-11.0.6/java/org/apache/coyote/http11/filters/VoidOutputFilter.java tomcat11-11.0.15/java/org/apache/coyote/http11/filters/VoidOutputFilter.java
--- tomcat11-11.0.6/java/org/apache/coyote/http11/filters/VoidOutputFilter.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/coyote/http11/filters/VoidOutputFilter.java 2025-12-02 16:54:08.000000000 +0000
@@ -25,8 +25,6 @@
/**
* Void output filter, which silently swallows bytes written. Used with a 204 status (no content) or a HEAD request.
- *
- * @author Remy Maucherat
*/
public class VoidOutputFilter implements OutputFilter {
diff -Nru tomcat11-11.0.6/java/org/apache/coyote/http11/upgrade/UpgradeServletInputStream.java tomcat11-11.0.15/java/org/apache/coyote/http11/upgrade/UpgradeServletInputStream.java
--- tomcat11-11.0.6/java/org/apache/coyote/http11/upgrade/UpgradeServletInputStream.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/coyote/http11/upgrade/UpgradeServletInputStream.java 2025-12-02 16:54:08.000000000 +0000
@@ -79,8 +79,8 @@
try {
ready = Boolean.valueOf(socketWrapper.isReadyForRead());
- } catch (IOException e) {
- onError(e);
+ } catch (IOException ioe) {
+ onError(ioe);
}
return ready.booleanValue();
}
@@ -213,8 +213,8 @@
if (listener == null || !socketWrapper.isReadyForRead()) {
return;
}
- } catch (IOException e) {
- onError(e);
+ } catch (IOException ioe) {
+ onError(ioe);
}
ready = Boolean.TRUE;
ClassLoader oldCL = processor.getUpgradeToken().contextBind().bind(null);
diff -Nru tomcat11-11.0.6/java/org/apache/coyote/http2/AbstractNonZeroStream.java tomcat11-11.0.15/java/org/apache/coyote/http2/AbstractNonZeroStream.java
--- tomcat11-11.0.6/java/org/apache/coyote/http2/AbstractNonZeroStream.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/coyote/http2/AbstractNonZeroStream.java 2025-12-02 16:54:08.000000000 +0000
@@ -73,9 +73,9 @@
/**
* Notify that some data has been received.
*
- * @param payloadSize the byte count
+ * @param dataLength the byte count
*
* @throws Http2Exception if an error is detected
*/
- abstract void receivedData(int payloadSize) throws Http2Exception;
+ abstract void receivedData(int dataLength) throws Http2Exception;
}
diff -Nru tomcat11-11.0.6/java/org/apache/coyote/http2/ConnectionSettingsBase.java tomcat11-11.0.15/java/org/apache/coyote/http2/ConnectionSettingsBase.java
--- tomcat11-11.0.6/java/org/apache/coyote/http2/ConnectionSettingsBase.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/coyote/http2/ConnectionSettingsBase.java 2025-12-02 16:54:08.000000000 +0000
@@ -65,6 +65,11 @@
final void set(Setting setting, long value) throws T {
+ set(setting, value, false);
+ }
+
+
+ final void set(Setting setting, long value, boolean force) throws T {
if (log.isTraceEnabled()) {
log.trace(sm.getString("connectionSettings.debug", connectionId, getEndpointName(), setting,
Long.toString(value)));
@@ -90,11 +95,21 @@
}
}
- set(setting, Long.valueOf(value));
+ set(setting, Long.valueOf(value), force);
}
- synchronized void set(Setting setting, Long value) {
+ /**
+ * Specify a new value for setting with the option to force the change to take effect immediately rather than
+ * waiting until an {@code ACK} is received.
+ *
+ * @param setting The setting to update
+ * @param value The new value for the setting
+ * @param force {@code false} if an {@code ACK} must be received before the setting takes effect or {@code true}
+ * if the setting to take effect immediately. Even if the setting takes effect immediately, it
+ * will still be included in the next {@code SETTINGS} frame and an {@code ACK} will be expected.
+ */
+ synchronized void set(Setting setting, Long value, boolean force) {
current.put(setting, value);
}
diff -Nru tomcat11-11.0.6/java/org/apache/coyote/http2/ConnectionSettingsLocal.java tomcat11-11.0.15/java/org/apache/coyote/http2/ConnectionSettingsLocal.java
--- tomcat11-11.0.6/java/org/apache/coyote/http2/ConnectionSettingsLocal.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/coyote/http2/ConnectionSettingsLocal.java 2025-12-02 16:54:08.000000000 +0000
@@ -40,12 +40,15 @@
@Override
- final synchronized void set(Setting setting, Long value) {
+ final synchronized void set(Setting setting, Long value, boolean force) {
checkSend();
if (current.get(setting).longValue() == value.longValue()) {
pending.remove(setting);
} else {
pending.put(setting, value);
+ if (force) {
+ current.put(setting, value);
+ }
}
}
diff -Nru tomcat11-11.0.6/java/org/apache/coyote/http2/Hpack.java tomcat11-11.0.15/java/org/apache/coyote/http2/Hpack.java
--- tomcat11-11.0.6/java/org/apache/coyote/http2/Hpack.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/coyote/http2/Hpack.java 2025-12-02 16:54:08.000000000 +0000
@@ -18,6 +18,7 @@
import java.nio.ByteBuffer;
+import org.apache.tomcat.util.http.Method;
import org.apache.tomcat.util.res.StringManager;
final class Hpack {
@@ -26,8 +27,16 @@
private static final byte LOWER_DIFF = 'a' - 'A';
static final int DEFAULT_TABLE_SIZE = 4096;
- private static final int MAX_INTEGER_OCTETS = 8; // not sure what a good value for this is, but the spec says we
- // need to provide an upper bound
+ /*
+ * The HPack specification says there SHOULD be an upper bound on this.
+ *
+ * Tomcat has opted to limit values to INTEGER.MAX_VALUE. Give that there is the prefix byte and then each octet
+ * provides up to 7-bits, a total a 5 octets plus the prefix may be required.
+ *
+ * Note: The maximum value represented by 5 octets is greater than INTEGER.MAX_VALUE.
+ *
+ */
+ private static final int MAX_INTEGER_OCTETS = 5;
/**
* table that contains powers of two, used as both bitmask and to quickly calculate 2^n
@@ -52,8 +61,8 @@
HeaderField[] fields = new HeaderField[62];
// note that zero is not used
fields[1] = new HeaderField(":authority", null);
- fields[2] = new HeaderField(":method", "GET");
- fields[3] = new HeaderField(":method", "POST");
+ fields[2] = new HeaderField(":method", Method.GET);
+ fields[3] = new HeaderField(":method", Method.POST);
fields[4] = new HeaderField(":path", "/");
fields[5] = new HeaderField(":path", "/index.html");
fields[6] = new HeaderField(":scheme", "http");
@@ -151,10 +160,12 @@
int sp = source.position();
int mask = PREFIX_TABLE[n];
- int i = mask & source.get();
+ // Use long internally as the value may exceed Integer.MAX_VALUE
+ long result = mask & source.get();
int b;
- if (i < PREFIX_TABLE[n]) {
- return i;
+ if (result < PREFIX_TABLE[n]) {
+ // Casting is safe as result must be less than 255 at this point.
+ return (int) result;
} else {
int m = 0;
do {
@@ -169,11 +180,15 @@
return -1;
}
b = source.get();
- i = i + (b & 127) * (PREFIX_TABLE[m] + 1);
+ result = result + (b & 127) * (PREFIX_TABLE[m] + 1L);
+ if (result > Integer.MAX_VALUE) {
+ throw new HpackException(sm.getString("hpack.integerEncodedTooBig"));
+ }
m += 7;
} while ((b & 128) == 128);
}
- return i;
+ // Casting is safe as result must be less than Integer.MAX_VALUE at this point
+ return (int) result;
}
/**
diff -Nru tomcat11-11.0.6/java/org/apache/coyote/http2/HpackDecoder.java tomcat11-11.0.15/java/org/apache/coyote/http2/HpackDecoder.java
--- tomcat11-11.0.6/java/org/apache/coyote/http2/HpackDecoder.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/coyote/http2/HpackDecoder.java 2025-12-02 16:54:08.000000000 +0000
@@ -380,10 +380,9 @@
/**
* Are the headers pass to the recipient so far valid? The decoder needs to process all the headers to maintain
- * state even if there is a problem. In addition, it is easy for the intended recipient to track if the
- * complete set of headers is valid since to do that state needs to be maintained between the parsing of the
- * initial headers and the parsing of any trailer headers. The recipient is the best place to maintain that
- * state.
+ * state even if there is a problem. In addition, it is easy for the intended recipient to track if the complete
+ * set of headers is valid since to do that state needs to be maintained between the parsing of the initial
+ * headers and the parsing of any trailer headers. The recipient is the best place to maintain that state.
*
* @throws StreamException If the headers received to date are not valid
*/
diff -Nru tomcat11-11.0.6/java/org/apache/coyote/http2/Http2AsyncUpgradeHandler.java tomcat11-11.0.15/java/org/apache/coyote/http2/Http2AsyncUpgradeHandler.java
--- tomcat11-11.0.6/java/org/apache/coyote/http2/Http2AsyncUpgradeHandler.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/coyote/http2/Http2AsyncUpgradeHandler.java 2025-12-02 16:54:08.000000000 +0000
@@ -132,6 +132,10 @@
log.trace(sm.getString("upgradeHandler.rst.debug", connectionId, Integer.toString(se.getStreamId()),
se.getError(), se.getMessage()));
}
+
+ // Treat a sent reset like a received reset and increment the overhead count
+ increaseOverheadCount(FrameType.RST, getProtocol().getOverheadResetFactor());
+
// Write a RST frame
byte[] rstFrame = new byte[13];
// Length
@@ -334,7 +338,7 @@
(int) (sendfile.end - sendfile.pos);
sendfile.streamReservation = sendfile.stream.reserveWindowSize(reservation, true);
sendfile.connectionReservation = reserveWindowSize(sendfile.stream, sendfile.streamReservation, true);
- } catch (IOException e) {
+ } catch (IOException ioe) {
return SendfileState.ERROR;
}
@@ -371,7 +375,7 @@
ByteBuffer.wrap(header), sendfile.mappedBuffer);
try {
handleAsyncException();
- } catch (IOException e) {
+ } catch (IOException ioe) {
return SendfileState.ERROR;
}
}
@@ -396,8 +400,8 @@
if (sendfile.left == 0) {
try {
sendfile.stream.getOutputBuffer().end();
- } catch (IOException e) {
- failed(e, sendfile);
+ } catch (IOException ioe) {
+ failed(ioe, sendfile);
}
return;
}
@@ -414,8 +418,8 @@
sendfile.connectionReservation =
reserveWindowSize(sendfile.stream, sendfile.streamReservation, true);
}
- } catch (IOException e) {
- failed(e, sendfile);
+ } catch (IOException ioe) {
+ failed(ioe, sendfile);
return;
}
@@ -456,8 +460,8 @@
ByteBuffer.wrap(header), sendfile.mappedBuffer);
try {
handleAsyncException();
- } catch (IOException e) {
- failed(e, sendfile);
+ } catch (IOException ioe) {
+ failed(ioe, sendfile);
return;
}
}
diff -Nru tomcat11-11.0.6/java/org/apache/coyote/http2/Http2Parser.java tomcat11-11.0.15/java/org/apache/coyote/http2/Http2Parser.java
--- tomcat11-11.0.6/java/org/apache/coyote/http2/Http2Parser.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/coyote/http2/Http2Parser.java 2025-12-02 16:54:08.000000000 +0000
@@ -171,7 +171,7 @@
Integer.toString(dataLength), padding));
}
- ByteBuffer dest = output.startRequestBodyFrame(streamId, payloadSize, endOfStream);
+ ByteBuffer dest = output.startRequestBodyFrame(streamId, dataLength, endOfStream);
if (dest == null) {
swallowPayload(streamId, FrameType.DATA.getId(), dataLength, false, buffer);
// Process padding before sending any notifications in case padding
@@ -184,7 +184,7 @@
}
} else {
synchronized (dest) {
- if (dest.remaining() < payloadSize) {
+ if (dest.remaining() < dataLength) {
// Client has sent more data than permitted by Window size
swallowPayload(streamId, FrameType.DATA.getId(), dataLength, false, buffer);
if (Flags.hasPadding(flags)) {
@@ -281,7 +281,7 @@
// RFC 7450 priority frames are ignored. Still need to treat as overhead.
try {
swallowPayload(streamId, FrameType.PRIORITY.getId(), 5, false, buffer);
- } catch (ConnectionException e) {
+ } catch (ConnectionException ignore) {
// Will never happen because swallowPayload() is called with isPadding set
// to false
}
@@ -768,7 +768,7 @@
HpackDecoder getHpackDecoder();
// Data frames
- ByteBuffer startRequestBodyFrame(int streamId, int payloadSize, boolean endOfStream) throws Http2Exception;
+ ByteBuffer startRequestBodyFrame(int streamId, int dataLength, boolean endOfStream) throws Http2Exception;
void endRequestBodyFrame(int streamId, int dataLength) throws Http2Exception, IOException;
diff -Nru tomcat11-11.0.6/java/org/apache/coyote/http2/Http2Protocol.java tomcat11-11.0.15/java/org/apache/coyote/http2/Http2Protocol.java
--- tomcat11-11.0.6/java/org/apache/coyote/http2/Http2Protocol.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/coyote/http2/Http2Protocol.java 2025-12-02 16:54:08.000000000 +0000
@@ -133,9 +133,8 @@
@Override
public Processor getProcessor(SocketWrapperBase> socketWrapper, Adapter adapter) {
- return new UpgradeProcessorInternal(socketWrapper,
- new UpgradeToken(getInternalUpgradeHandler(socketWrapper, adapter, null), null,
- null, getUpgradeProtocolName()),null);
+ return new UpgradeProcessorInternal(socketWrapper, new UpgradeToken(
+ getInternalUpgradeHandler(socketWrapper, adapter, null), null, null, getUpgradeProtocolName()), null);
}
diff -Nru tomcat11-11.0.6/java/org/apache/coyote/http2/Http2UpgradeHandler.java tomcat11-11.0.15/java/org/apache/coyote/http2/Http2UpgradeHandler.java
--- tomcat11-11.0.6/java/org/apache/coyote/http2/Http2UpgradeHandler.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/coyote/http2/Http2UpgradeHandler.java 2025-12-02 16:54:08.000000000 +0000
@@ -163,8 +163,12 @@
remoteSettings = new ConnectionSettingsRemote(connectionId);
localSettings = new ConnectionSettingsLocal(connectionId);
- localSettings.set(Setting.MAX_CONCURRENT_STREAMS, protocol.getMaxConcurrentStreams());
- localSettings.set(Setting.INITIAL_WINDOW_SIZE, protocol.getInitialWindowSize());
+ /*
+ * Force set these initial limits. A well-behaved client should ACK the settings and adhere to them before it
+ * reaches the limits anyway.
+ */
+ localSettings.set(Setting.MAX_CONCURRENT_STREAMS, protocol.getMaxConcurrentStreams(), true);
+ localSettings.set(Setting.INITIAL_WINDOW_SIZE, protocol.getInitialWindowSize(), true);
pingManager.initiateDisabled = protocol.getInitiatePingDisabled();
@@ -521,7 +525,7 @@
try {
writeGoAwayFrame((1 << 31) - 1, Http2Error.NO_ERROR.getCode(), null);
- } catch (IOException ioe) {
+ } catch (IOException ignore) {
// This is fatal for the connection. Ignore it here. There will be
// further attempts at I/O in upgradeDispatch() and it can better
// handle the IO errors.
@@ -580,6 +584,9 @@
se.getError(), se.getMessage()));
}
+ // Treat a sent reset like a received reset and increment the overhead count
+ increaseOverheadCount(FrameType.RST, getProtocol().getOverheadResetFactor());
+
// Write a RST frame
byte[] rstFrame = new byte[13];
// Length
@@ -628,7 +635,7 @@
}
try {
writeGoAwayFrame(maxProcessedStreamId, code, msg);
- } catch (IOException ioe) {
+ } catch (IOException ignore) {
// Ignore. GOAWAY is sent on a best efforts basis and the original
// error has already been logged.
}
@@ -652,6 +659,7 @@
}
socketWrapper.flush(true);
} catch (IOException ioe) {
+ // Exception is logged further up stack
String msg = sm.getString("upgradeHandler.sendPrefaceFail", connectionId);
if (log.isDebugEnabled()) {
log.debug(msg);
@@ -944,8 +952,8 @@
} else if (windowSize < 1) {
/*
* The connection window has no capacity. If the stream has not been granted an allocation, and the
- * stream was not already added to the backlog due to a partial reservation (see next else if
- * block) add it to the backlog so it can obtain an allocation when capacity is available.
+ * stream was not already added to the backlog due to a partial reservation (see next else if block)
+ * add it to the backlog so it can obtain an allocation when capacity is available.
*/
if (stream.getConnectionAllocationMade() == 0 && stream.getConnectionAllocationRequested() == 0) {
stream.setConnectionAllocationRequested(reservation);
@@ -1349,39 +1357,59 @@
void reduceOverheadCount(FrameType frameType) {
- // A non-overhead frame reduces the overhead count by
- // Http2Protocol.DEFAULT_OVERHEAD_REDUCTION_FACTOR. A simple browser
- // request is likely to have one non-overhead frame (HEADERS) and one
- // overhead frame (REPRIORITISE). With the default settings the overhead
- // count will reduce by 10 for each simple request.
- // Requests and responses with bodies will create additional
- // non-overhead frames, further reducing the overhead count.
+ /*
+ * A non-overhead frame reduces the overhead count by {@code Http2Protocol.DEFAULT_OVERHEAD_REDUCTION_FACTOR}.
+ *
+ * A simple browser request is likely to have one non-overhead frame (HEADERS) that results in a response with
+ * one further non-overhead frame (DATA). With the default settings, the overhead count will reduce by 40 for
+ * each simple request.
+ *
+ * Requests and responses with bodies will create additional non-overhead frames, further reducing the overhead
+ * count.
+ */
updateOverheadCount(frameType, Http2Protocol.DEFAULT_OVERHEAD_REDUCTION_FACTOR);
}
@Override
public void increaseOverheadCount(FrameType frameType) {
- // An overhead frame increases the overhead count by
- // overheadCountFactor. By default, this means an overhead frame
- // increases the overhead count by 10. A simple browser request is
- // likely to have one non-overhead frame (HEADERS) and one overhead
- // frame (REPRIORITISE). With the default settings the overhead count
- // will reduce by 10 for each simple request.
+ /*
+ * An overhead frame (SETTINGS, PRIORITY, PING) increases the overhead count by overheadCountFactor. By default,
+ * this means an overhead frame increases the overhead count by 10.
+ *
+ * If the client ignores maxConcurrentStreams then any HEADERS frame received will also increase the overhead
+ * count by overheadCountFactor.
+ *
+ * A simple browser request should not trigger any overhead frames.
+ */
updateOverheadCount(frameType, getProtocol().getOverheadCountFactor());
}
- private void increaseOverheadCount(FrameType frameType, int increment) {
- // Overhead frames that indicate inefficient (and potentially malicious)
- // use of small frames trigger an increase that is inversely
- // proportional to size. The default threshold for all three potential
- // areas for abuse (HEADERS, DATA, WINDOW_UPDATE) is 1024 bytes. Frames
- // with sizes smaller than this will trigger an increase of
- // threshold/size.
- // DATA and WINDOW_UPDATE take an average over the last two non-final
- // frames to allow for client buffering schemes that can result in some
- // small DATA payloads.
+ /**
+ * Used to increase the overhead for frames that don't use the {@code overheadCountFactor} ({@code CONTINUATION},
+ * {@code DATA}, {@code WINDOW_UPDATE} and {@code RESET}).
+ *
+ * @param frameType The frame type triggering the overhead increase
+ * @param increment The amount by which the overhead is increased
+ */
+ protected void increaseOverheadCount(FrameType frameType, int increment) {
+ /*
+ * Three types of frame are susceptible to inefficient (and potentially malicious) use of small frames. These
+ * trigger an increase in overhead that is inversely proportional to size. The default threshold for all three
+ * potential areas for abuse (CONTINUATION, DATA, WINDOW_UPDATE) is 1024 bytes. Frames with sizes smaller than
+ * this will trigger an increase of threshold/size.
+ *
+ * The check for DATA and WINDOW_UPDATE frames takes an average over the last two frames to allow for client
+ * buffering schemes that can result in some small DATA payloads.
+ *
+ * The CONTINUATION and DATA frames checks are skipped for end of headers (CONTINUATION) and end of stream
+ * (DATA) as those frames may be small for legitimate reasons.
+ *
+ * RESET frames (received or sent) trigger an increase of overheadResetFactor.
+ *
+ * In all cases, the calling method determines the extent to which the overhead count is increased.
+ */
updateOverheadCount(frameType, increment);
}
@@ -1462,7 +1490,7 @@
@Override
- public ByteBuffer startRequestBodyFrame(int streamId, int payloadSize, boolean endOfStream) throws Http2Exception {
+ public ByteBuffer startRequestBodyFrame(int streamId, int dataLength, boolean endOfStream) throws Http2Exception {
// DATA frames reduce the overhead count ...
reduceOverheadCount(FrameType.DATA);
@@ -1476,8 +1504,8 @@
// average over two frames to avoid false positives.
if (!endOfStream) {
int overheadThreshold = protocol.getOverheadDataThreshold();
- int average = (lastNonFinalDataPayload >> 1) + (payloadSize >> 1);
- lastNonFinalDataPayload = payloadSize;
+ int average = (lastNonFinalDataPayload >> 1) + (dataLength >> 1);
+ lastNonFinalDataPayload = dataLength;
// Avoid division by zero
if (average == 0) {
average = 1;
@@ -1489,7 +1517,7 @@
AbstractNonZeroStream abstractNonZeroStream = getAbstractNonZeroStream(streamId, true);
abstractNonZeroStream.checkState(FrameType.DATA);
- abstractNonZeroStream.receivedData(payloadSize);
+ abstractNonZeroStream.receivedData(dataLength);
ByteBuffer result = abstractNonZeroStream.getInputByteBuffer(true);
if (log.isTraceEnabled()) {
@@ -1572,9 +1600,9 @@
if (payloadSize < overheadThreshold) {
if (payloadSize == 0) {
// Avoid division by zero
- increaseOverheadCount(FrameType.HEADERS, overheadThreshold);
+ increaseOverheadCount(FrameType.CONTINUATION, overheadThreshold);
} else {
- increaseOverheadCount(FrameType.HEADERS, overheadThreshold / payloadSize);
+ increaseOverheadCount(FrameType.CONTINUATION, overheadThreshold / payloadSize);
}
}
}
@@ -1831,6 +1859,10 @@
}
}
+ String getSniHostName() {
+ return socketWrapper.getSniHostName();
+ }
+
protected class PingManager {
protected boolean initiateDisabled = false;
@@ -1838,7 +1870,7 @@
// 10 seconds
protected final long pingIntervalNano = 10000000000L;
- protected int sequence = 0;
+ protected volatile int sequence = 0;
protected long lastPingNanoTime = Long.MIN_VALUE;
protected Queue inflightPings = new ConcurrentLinkedQueue<>();
@@ -1859,18 +1891,13 @@
if (force || now - lastPingNanoTime > pingIntervalNano) {
lastPingNanoTime = now;
byte[] payload = new byte[8];
- socketWrapper.getLock().lock();
- try {
- int sentSequence = ++sequence;
- PingRecord pingRecord = new PingRecord(sentSequence, now);
- inflightPings.add(pingRecord);
- ByteUtil.set31Bits(payload, 4, sentSequence);
- socketWrapper.write(true, PING, 0, PING.length);
- socketWrapper.write(true, payload, 0, payload.length);
- socketWrapper.flush(true);
- } finally {
- socketWrapper.getLock().unlock();
- }
+ int sentSequence = ++sequence;
+ PingRecord pingRecord = new PingRecord(sentSequence, now);
+ inflightPings.add(pingRecord);
+ ByteUtil.set31Bits(payload, 4, sentSequence);
+ socketWrapper.write(true, PING, 0, PING.length);
+ socketWrapper.write(true, payload, 0, payload.length);
+ socketWrapper.flush(true);
}
}
diff -Nru tomcat11-11.0.6/java/org/apache/coyote/http2/LocalStrings.properties tomcat11-11.0.15/java/org/apache/coyote/http2/LocalStrings.properties
--- tomcat11-11.0.6/java/org/apache/coyote/http2/LocalStrings.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/coyote/http2/LocalStrings.properties 2025-12-02 16:54:08.000000000 +0000
@@ -37,6 +37,7 @@
frameType.checkStream=Invalid frame type [{0}]
hpack.integerEncodedOverTooManyOctets=HPACK variable length integer encoded over too many octets, max is [{0}]
+hpack.integerEncodedTooBig=The maximum permitted value of an HPACK encoded variable length integer is Integer.MAX_VALUE
hpack.invalidCharacter=The Unicode character [{0}] at code point [{1}] cannot be encoded as it is outside the permitted range of 0 to 255.
hpackEncoder.encodeHeader=Encoding header [{0}] with value [{1}]
@@ -104,6 +105,7 @@
stream.header.unexpectedPseudoHeader=Connection [{0}], Stream [{1}], Pseudo header [{2}] received after a regular header
stream.header.unknownPseudoHeader=Connection [{0}], Stream [{1}], Unknown pseudo header [{2}] received
stream.host.inconsistent=Connection [{0}], Stream [{1}], The header host header [{2}] is inconsistent with previously provided values for host [{3}] and/or port [{4}]
+stream.host.sni=Connection [{0}], Stream [{1}], The host header [{2}] does not match the SNI host [{3}]
stream.inputBuffer.copy=Copying [{0}] bytes from inBuffer to outBuffer
stream.inputBuffer.dispatch=Data added to inBuffer when read interest is registered. Triggering a read dispatch
stream.inputBuffer.empty=The Stream input buffer is empty. Waiting for more data
diff -Nru tomcat11-11.0.6/java/org/apache/coyote/http2/LocalStrings_fr.properties tomcat11-11.0.15/java/org/apache/coyote/http2/LocalStrings_fr.properties
--- tomcat11-11.0.6/java/org/apache/coyote/http2/LocalStrings_fr.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/coyote/http2/LocalStrings_fr.properties 2025-12-02 16:54:08.000000000 +0000
@@ -37,6 +37,7 @@
frameType.checkStream=Type de trame invalide [{0}]
hpack.integerEncodedOverTooManyOctets=Un entier de taille variable de HPACK a été encodé sur trop d''octets, le maximum est de [{0}]
+hpack.integerEncodedTooBig=La valeur maximale permise pour un entier de longueur variable encodé par HPACK est Integer.MAX_VALUE
hpack.invalidCharacter=Le caractère Unicode [{0}] ayant le code point [{1}] ne peut être encodé, parce qu''il est en-dehors de l''éventail permis 0-255.
hpackEncoder.encodeHeader=Encodage de l''en-tête [{0}] avec la valeur [{1}]
@@ -77,6 +78,7 @@
http2Parser.processFrameHeaders.decodingFailed=Une erreur de décodage HPACK des en-têtes HTTP s'est produite
http2Parser.processFrameHeaders.payload=Connection [{0}], Flux [{1}], Traitement des en-têtes avec une taille de données de [{2}]
http2Parser.processFramePriorityUpdate.debug=Connection [{0}], Stream [{1}], Urgency [{2}], Incremental [{3}]
+http2Parser.processFramePriorityUpdate.invalid=Connection [{0}], Stream [{1}], La trame Priority Update a une valeur de champ de priorité invalide
http2Parser.processFramePriorityUpdate.streamZero=Connection [{0}], La trame de mise à jour de priorité a été recue pour le flux zéro
http2Parser.processFramePushPromise=Connexion [{0}], Flux (Stream) [{1}], les trames de promesse d''envoi ("Push promise frames") ne doivent pas être envoyées par le client.
http2Parser.processFrameSettings.ackWithNonZeroPayload=La trame de paramètres a été reçue avec un indicateur ACK activé et des données présentes
@@ -165,6 +167,7 @@
upgradeHandler.stream.even=Un nouvel ID de flux distant (remote stream) [{0}] a été requis, mais tous les flux distants doivent utiliser ID impairs
upgradeHandler.stream.notWritable=Connection [{0}], Flux [{1}], Impossible d''écrire sur ce flux
upgradeHandler.stream.old=Un nouveau flux distant avec l''ID [{0}] a été demandé mais le flux le plus récent est [{1}]
+upgradeHandler.throwable=Connection [{0}]
upgradeHandler.tooManyRemoteStreams=Le client a essayé d''utiliser plus de [{0}] flux actifs
upgradeHandler.tooMuchOverhead=Connection [{0}], Le traitement est trop coûteux donc la connection sera fermée
upgradeHandler.unexpectedAck=Connection [{0}], Flux [{1}], Une notification de réception de paramètres a été reçue alors qu''aucune n''était attendue
diff -Nru tomcat11-11.0.6/java/org/apache/coyote/http2/LocalStrings_ja.properties tomcat11-11.0.15/java/org/apache/coyote/http2/LocalStrings_ja.properties
--- tomcat11-11.0.6/java/org/apache/coyote/http2/LocalStrings_ja.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/coyote/http2/LocalStrings_ja.properties 2025-12-02 16:54:08.000000000 +0000
@@ -37,6 +37,7 @@
frameType.checkStream=無効なフレームタイプ [{0}]
hpack.integerEncodedOverTooManyOctets=エンコードされたHPACK可変長整数は多くのオクテットを超過。最大値は [{0}]
+hpack.integerEncodedTooBig=HPACKエンコードされた可変長整数の最大許容値はInteger.MAX_VALUEです
hpack.invalidCharacter=コードポイント [{1}] のユニコード文字 [{0}] は有効範囲 0 から 255 の範囲外のため、エンコードできません。
hpackEncoder.encodeHeader=ヘッダー[{0}]を値[{1}]でエンコードしています
@@ -77,6 +78,7 @@
http2Parser.processFrameHeaders.decodingFailed=HTTP ヘッダーの HPACK 復号化中にエラーが発生しました。
http2Parser.processFrameHeaders.payload=コネクション [{0}]、ストリーム [{1}]、サイズ [{2}] のヘッダーペイロードを処理中
http2Parser.processFramePriorityUpdate.debug=接続 [{0}]、ストリーム [{1}]、緊急度 [{2}]、増分 [{3}]
+http2Parser.processFramePriorityUpdate.invalid=コネクション [{0}]、ストリーム [{1}]、優先度フィールド値が無効な優先度更新フレーム
http2Parser.processFramePriorityUpdate.streamZero=接続 [{0}] は、ストリーム 0 を優先するための優先更新フレームを受信しました
http2Parser.processFramePushPromise=コネクション [{0}]、ストリーム [{1}]、クライアントから PUSH_PROMISE フレームを送信するべきではありません
http2Parser.processFrameSettings.ackWithNonZeroPayload=ACKフラグがセットされ、ペイロードが存在する状態で受信されたSettingsフレーム
@@ -165,6 +167,7 @@
upgradeHandler.stream.even=新しいリモートストリーム ID [{0}] を要求されましたがリモートストリームの ID は奇数でなければなりません。
upgradeHandler.stream.notWritable=コネクション [{0}]、ストリーム [{1}]、このストリームは書き込み可能ではありません
upgradeHandler.stream.old=新しいリモートストリーム ID [{0}] を要求されましたが、最新のストリームは [{1}] です。
+upgradeHandler.throwable=コネクション[{0}]
upgradeHandler.tooManyRemoteStreams=クライアントは [{0}] 以上のアクティブなストリームを使用しようとしました
upgradeHandler.tooMuchOverhead=コネクション [{0}]、オーバーヘッドが多すぎるため、接続が閉じられます。
upgradeHandler.unexpectedAck=コネクション [{0}]、ストリーム [{1}]、予期しないときにsettings ackを受信しました
@@ -177,7 +180,7 @@
upgradeHandler.windowUpdateConnection=コネクション [{0}]、ウィンドウの更新をクライアントに送信し、ウィンドウを[{1}]バイト増やします
upgradeHandler.windowUpdateStream=コネクション [{0}]、ストリーム [{1}]、ウィンドウの更新をクライアントに送信し、ウィンドウを [{2}] バイト増やします
upgradeHandler.writeBody=コネクション [{0}]、ストリーム [{1}]、データ長 [{2}]
-upgradeHandler.writeHeaders=コネクション [{0}], ストリーム [{1}]
+upgradeHandler.writeHeaders=コネクション [{0}], ストリーム [{1}], ヘッダの書き込み, EndOfStream [{2}]
windowAllocationManager.dispatched=コネクション [{0}]、ストリーム [{1}]、ディスパッチされました
windowAllocationManager.notified=コネクション [{0}]、ストリーム [{1}]、通知されました
diff -Nru tomcat11-11.0.6/java/org/apache/coyote/http2/RecycledStream.java tomcat11-11.0.15/java/org/apache/coyote/http2/RecycledStream.java
--- tomcat11-11.0.6/java/org/apache/coyote/http2/RecycledStream.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/coyote/http2/RecycledStream.java 2025-12-02 16:54:08.000000000 +0000
@@ -47,8 +47,8 @@
@Override
- void receivedData(int payloadSize) throws ConnectionException {
- remainingFlowControlWindow -= payloadSize;
+ void receivedData(int dataLength) throws ConnectionException {
+ remainingFlowControlWindow -= dataLength;
}
diff -Nru tomcat11-11.0.6/java/org/apache/coyote/http2/Stream.java tomcat11-11.0.15/java/org/apache/coyote/http2/Stream.java
--- tomcat11-11.0.6/java/org/apache/coyote/http2/Stream.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/coyote/http2/Stream.java 2025-12-02 16:54:08.000000000 +0000
@@ -46,6 +46,7 @@
import org.apache.juli.logging.LogFactory;
import org.apache.tomcat.util.buf.ByteChunk;
import org.apache.tomcat.util.buf.MessageBytes;
+import org.apache.tomcat.util.http.Method;
import org.apache.tomcat.util.http.MimeHeaders;
import org.apache.tomcat.util.http.parser.Host;
import org.apache.tomcat.util.http.parser.Priority;
@@ -160,7 +161,7 @@
this.coyoteResponse.setOutputBuffer(http2OutputBuffer);
this.coyoteRequest.setResponse(coyoteResponse);
this.coyoteRequest.protocol().setString("HTTP/2.0");
- this.coyoteRequest.setStartTimeNanos(System.nanoTime());
+ this.coyoteRequest.markStartTime();
}
@@ -362,9 +363,9 @@
switch (name) {
case ":method": {
- if (coyoteRequest.method().isNull()) {
- coyoteRequest.method().setString(value);
- if ("HEAD".equals(value)) {
+ if (coyoteRequest.getMethod() == null) {
+ coyoteRequest.setMethod(value);
+ if (Method.HEAD.equals(value)) {
configureVoidOutputFilter();
}
} else {
@@ -504,6 +505,11 @@
} else {
coyoteRequest.serverName().setString(value);
}
+ // Match host name with SNI if required
+ if (!handler.getProtocol().getHttp11Protocol().checkSni(handler.getSniHostName(), coyoteRequest.serverName().getString())) {
+ throw new HpackException(sm.getString("stream.host.sni", getConnectionId(), getIdAsString(), value,
+ handler.getSniHostName()));
+ }
}
@@ -546,8 +552,8 @@
final boolean receivedEndOfHeaders() throws ConnectionException {
- if (coyoteRequest.method().isNull() || coyoteRequest.scheme().isNull() ||
- !coyoteRequest.method().equals("CONNECT") && coyoteRequest.requestURI().isNull()) {
+ if (coyoteRequest.getMethod() == null || coyoteRequest.scheme().isNull() ||
+ !Method.CONNECT.equals(coyoteRequest.getMethod()) && coyoteRequest.requestURI().isNull()) {
throw new ConnectionException(sm.getString("stream.header.required", getConnectionId(), getIdAsString()),
Http2Error.PROTOCOL_ERROR);
}
@@ -669,8 +675,8 @@
@Override
- final void receivedData(int payloadSize) throws Http2Exception {
- contentLengthReceived += payloadSize;
+ final void receivedData(int dataLength) throws Http2Exception {
+ contentLengthReceived += dataLength;
long contentLengthHeader = coyoteRequest.getContentLengthLong();
if (contentLengthHeader > -1 && contentLengthReceived > contentLengthHeader) {
throw new ConnectionException(
@@ -1063,7 +1069,7 @@
// Only want to return false if the window size is zero AND we are
// already waiting for an allocation.
return (getWindowSize() <= 0 || !allocationManager.isWaitingForStream()) &&
- (handler.getWindowSize() <= 0 || !allocationManager.isWaitingForConnection()) && !dataLeft;
+ (handler.getWindowSize() <= 0 || !allocationManager.isWaitingForConnection()) && !dataLeft;
} finally {
writeLock.unlock();
}
diff -Nru tomcat11-11.0.6/java/org/apache/coyote/http2/StreamProcessor.java tomcat11-11.0.15/java/org/apache/coyote/http2/StreamProcessor.java
--- tomcat11-11.0.6/java/org/apache/coyote/http2/StreamProcessor.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/coyote/http2/StreamProcessor.java 2025-12-02 16:54:08.000000000 +0000
@@ -147,8 +147,14 @@
state = SocketState.CLOSED;
} finally {
if (state == SocketState.CLOSED) {
- stream.recycle();
+ /*
+ * Recycle this processor before the stream is recycled as recycling the stream will add the
+ * request and the response to the pool for re-use (if re-use is enabled) and the request
+ * statistics updating in StreamProcessor.recycle() needs to happen before the request and
+ * response are added to the pool to avoid concurrency issues corrupting the statistics.
+ */
recycle();
+ stream.recycle();
}
}
} finally {
@@ -308,7 +314,7 @@
stream.getInputBuffer().insertReplayedBody(body);
try {
stream.receivedEndOfStream();
- } catch (ConnectionException e) {
+ } catch (ConnectionException ignore) {
// Exception will not be thrown in this case
}
}
@@ -416,6 +422,12 @@
global.removeRequestProcessor(request.getRequestProcessor());
}
+ /*
+ * Clear the statistics ready for re-use of the request. If we don't clear the statistics, the statistics for
+ * the current request will be included in the statistics for all future requests.
+ */
+ request.getRequestProcessor().recycleStatistcs();
+
// Clear fields that can be cleared to aid GC and trigger NPEs if this
// is reused
setSocketWrapper(null);
@@ -493,8 +505,7 @@
HttpParser httpParser = handler.getProtocol().getHttp11Protocol().getHttpParser();
// Method name must be a token
- String method = request.method().toString();
- if (!HttpParser.isToken(method)) {
+ if (!HttpParser.isToken(request.getMethod())) {
return false;
}
diff -Nru tomcat11-11.0.6/java/org/apache/el/ExpressionFactoryImpl.java tomcat11-11.0.15/java/org/apache/el/ExpressionFactoryImpl.java
--- tomcat11-11.0.6/java/org/apache/el/ExpressionFactoryImpl.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/el/ExpressionFactoryImpl.java 2025-12-02 16:54:08.000000000 +0000
@@ -28,11 +28,8 @@
import org.apache.el.util.ExceptionUtils;
import org.apache.el.util.MessageFactory;
-
/**
* @see jakarta.el.ExpressionFactory
- *
- * @author Jacob Hookom [jacob@hookom.net]
*/
@aQute.bnd.annotation.spi.ServiceProvider(value = ExpressionFactory.class)
public class ExpressionFactoryImpl extends ExpressionFactory {
diff -Nru tomcat11-11.0.6/java/org/apache/el/MethodExpressionImpl.java tomcat11-11.0.15/java/org/apache/el/MethodExpressionImpl.java
--- tomcat11-11.0.6/java/org/apache/el/MethodExpressionImpl.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/el/MethodExpressionImpl.java 2025-12-02 16:54:08.000000000 +0000
@@ -63,8 +63,6 @@
* @see jakarta.el.Expression
* @see jakarta.el.ExpressionFactory
* @see jakarta.el.MethodExpression
- *
- * @author Jacob Hookom [jacob@hookom.net]
*/
public final class MethodExpressionImpl extends MethodExpression implements Externalizable {
diff -Nru tomcat11-11.0.6/java/org/apache/el/ValueExpressionImpl.java tomcat11-11.0.15/java/org/apache/el/ValueExpressionImpl.java
--- tomcat11-11.0.6/java/org/apache/el/ValueExpressionImpl.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/el/ValueExpressionImpl.java 2025-12-02 16:54:08.000000000 +0000
@@ -70,8 +70,6 @@
* @see jakarta.el.Expression
* @see jakarta.el.ExpressionFactory
* @see jakarta.el.ValueExpression
- *
- * @author Jacob Hookom [jacob@hookom.net]
*/
public final class ValueExpressionImpl extends ValueExpression implements Externalizable {
diff -Nru tomcat11-11.0.6/java/org/apache/el/lang/ELArithmetic.java tomcat11-11.0.15/java/org/apache/el/lang/ELArithmetic.java
--- tomcat11-11.0.6/java/org/apache/el/lang/ELArithmetic.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/el/lang/ELArithmetic.java 2025-12-02 16:54:08.000000000 +0000
@@ -26,9 +26,7 @@
/**
- * A helper class of Arithmetic defined by the EL Specification
- *
- * @author Jacob Hookom [jacob@hookom.net]
+ * A helper class of Arithmetic defined by the EL Specification.
*/
public abstract class ELArithmetic {
diff -Nru tomcat11-11.0.6/java/org/apache/el/lang/ELSupport.java tomcat11-11.0.15/java/org/apache/el/lang/ELSupport.java
--- tomcat11-11.0.6/java/org/apache/el/lang/ELSupport.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/el/lang/ELSupport.java 2025-12-02 16:54:08.000000000 +0000
@@ -38,9 +38,7 @@
/**
- * A helper class that implements the EL Specification
- *
- * @author Jacob Hookom [jacob@hookom.net]
+ * A helper class that implements the EL Specification.
*/
public class ELSupport {
@@ -177,8 +175,8 @@
}
/*
- * Going to have some casts /raw types somewhere so doing it here keeps them all in one place. There might
- * be a neater / better solution, but I couldn't find it.
+ * Going to have some casts /raw types somewhere so doing it here keeps them all in one place. There might be a
+ * neater / better solution, but I couldn't find it.
*/
@SuppressWarnings("unchecked")
public static Enum> coerceToEnum(final ELContext ctx, final Object obj,
@@ -227,8 +225,7 @@
*
* @throws ELException if object is not Boolean or String
*/
- public static Boolean coerceToBoolean(final ELContext ctx, final Object obj, boolean primitive)
- throws ELException {
+ public static Boolean coerceToBoolean(final ELContext ctx, final Object obj, boolean primitive) throws ELException {
if (ctx != null) {
boolean originalIsPropertyResolved = ctx.isPropertyResolved();
@@ -336,8 +333,7 @@
throw new ELException(MessageFactory.get("error.convert", number, number.getClass(), type));
}
- public static Number coerceToNumber(final ELContext ctx, final Object obj, final Class> type)
- throws ELException {
+ public static Number coerceToNumber(final ELContext ctx, final Object obj, final Class> type) throws ELException {
if (ctx != null) {
boolean originalIsPropertyResolved = ctx.isPropertyResolved();
@@ -476,8 +472,7 @@
}
}
- public static T coerceToType(final ELContext ctx, final Object obj, final Class type)
- throws ELException {
+ public static T coerceToType(final ELContext ctx, final Object obj, final Class type) throws ELException {
if (ctx != null) {
boolean originalIsPropertyResolved = ctx.isPropertyResolved();
diff -Nru tomcat11-11.0.6/java/org/apache/el/lang/ExpressionBuilder.java tomcat11-11.0.15/java/org/apache/el/lang/ExpressionBuilder.java
--- tomcat11-11.0.6/java/org/apache/el/lang/ExpressionBuilder.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/el/lang/ExpressionBuilder.java 2025-12-02 16:54:08.000000000 +0000
@@ -42,9 +42,6 @@
import org.apache.el.util.ExceptionUtils;
import org.apache.el.util.MessageFactory;
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- */
public final class ExpressionBuilder implements NodeVisitor {
private static final SynchronizedStack parserCache = new SynchronizedStack<>();
diff -Nru tomcat11-11.0.6/java/org/apache/el/lang/FunctionMapperFactory.java tomcat11-11.0.15/java/org/apache/el/lang/FunctionMapperFactory.java
--- tomcat11-11.0.6/java/org/apache/el/lang/FunctionMapperFactory.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/el/lang/FunctionMapperFactory.java 2025-12-02 16:54:08.000000000 +0000
@@ -22,9 +22,6 @@
import org.apache.el.util.MessageFactory;
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- */
public class FunctionMapperFactory extends FunctionMapper {
protected FunctionMapperImpl memento = null;
diff -Nru tomcat11-11.0.6/java/org/apache/el/lang/FunctionMapperImpl.java tomcat11-11.0.15/java/org/apache/el/lang/FunctionMapperImpl.java
--- tomcat11-11.0.6/java/org/apache/el/lang/FunctionMapperImpl.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/el/lang/FunctionMapperImpl.java 2025-12-02 16:54:08.000000000 +0000
@@ -30,10 +30,6 @@
import org.apache.el.util.MessageFactory;
import org.apache.el.util.ReflectionUtil;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- */
public class FunctionMapperImpl extends FunctionMapper implements Externalizable {
@Serial
diff -Nru tomcat11-11.0.6/java/org/apache/el/parser/ArithmeticNode.java tomcat11-11.0.15/java/org/apache/el/parser/ArithmeticNode.java
--- tomcat11-11.0.6/java/org/apache/el/parser/ArithmeticNode.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/el/parser/ArithmeticNode.java 2025-12-02 16:54:08.000000000 +0000
@@ -20,9 +20,6 @@
import org.apache.el.lang.EvaluationContext;
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- */
public abstract class ArithmeticNode extends SimpleNode {
public ArithmeticNode(int i) {
diff -Nru tomcat11-11.0.6/java/org/apache/el/parser/AstAnd.java tomcat11-11.0.15/java/org/apache/el/parser/AstAnd.java
--- tomcat11-11.0.6/java/org/apache/el/parser/AstAnd.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/el/parser/AstAnd.java 2025-12-02 16:54:08.000000000 +0000
@@ -22,10 +22,6 @@
import org.apache.el.lang.ELSupport;
import org.apache.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- */
public final class AstAnd extends BooleanNode {
public AstAnd(int id) {
super(id);
diff -Nru tomcat11-11.0.6/java/org/apache/el/parser/AstBracketSuffix.java tomcat11-11.0.15/java/org/apache/el/parser/AstBracketSuffix.java
--- tomcat11-11.0.6/java/org/apache/el/parser/AstBracketSuffix.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/el/parser/AstBracketSuffix.java 2025-12-02 16:54:08.000000000 +0000
@@ -21,10 +21,6 @@
import org.apache.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- */
public final class AstBracketSuffix extends SimpleNode {
public AstBracketSuffix(int id) {
super(id);
diff -Nru tomcat11-11.0.6/java/org/apache/el/parser/AstChoice.java tomcat11-11.0.15/java/org/apache/el/parser/AstChoice.java
--- tomcat11-11.0.6/java/org/apache/el/parser/AstChoice.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/el/parser/AstChoice.java 2025-12-02 16:54:08.000000000 +0000
@@ -22,10 +22,6 @@
import org.apache.el.lang.ELSupport;
import org.apache.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- */
public final class AstChoice extends SimpleNode {
public AstChoice(int id) {
super(id);
diff -Nru tomcat11-11.0.6/java/org/apache/el/parser/AstCompositeExpression.java tomcat11-11.0.15/java/org/apache/el/parser/AstCompositeExpression.java
--- tomcat11-11.0.6/java/org/apache/el/parser/AstCompositeExpression.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/el/parser/AstCompositeExpression.java 2025-12-02 16:54:08.000000000 +0000
@@ -22,10 +22,6 @@
import org.apache.el.lang.ELSupport;
import org.apache.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- */
public final class AstCompositeExpression extends SimpleNode {
public AstCompositeExpression(int id) {
diff -Nru tomcat11-11.0.6/java/org/apache/el/parser/AstDeferredExpression.java tomcat11-11.0.15/java/org/apache/el/parser/AstDeferredExpression.java
--- tomcat11-11.0.6/java/org/apache/el/parser/AstDeferredExpression.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/el/parser/AstDeferredExpression.java 2025-12-02 16:54:08.000000000 +0000
@@ -21,10 +21,6 @@
import org.apache.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- */
public final class AstDeferredExpression extends SimpleNode {
public AstDeferredExpression(int id) {
super(id);
diff -Nru tomcat11-11.0.6/java/org/apache/el/parser/AstDiv.java tomcat11-11.0.15/java/org/apache/el/parser/AstDiv.java
--- tomcat11-11.0.6/java/org/apache/el/parser/AstDiv.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/el/parser/AstDiv.java 2025-12-02 16:54:08.000000000 +0000
@@ -22,10 +22,6 @@
import org.apache.el.lang.ELArithmetic;
import org.apache.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- */
public final class AstDiv extends ArithmeticNode {
public AstDiv(int id) {
super(id);
diff -Nru tomcat11-11.0.6/java/org/apache/el/parser/AstDotSuffix.java tomcat11-11.0.15/java/org/apache/el/parser/AstDotSuffix.java
--- tomcat11-11.0.6/java/org/apache/el/parser/AstDotSuffix.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/el/parser/AstDotSuffix.java 2025-12-02 16:54:08.000000000 +0000
@@ -23,10 +23,6 @@
import org.apache.el.util.MessageFactory;
import org.apache.el.util.Validation;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- */
public final class AstDotSuffix extends SimpleNode {
public AstDotSuffix(int id) {
super(id);
diff -Nru tomcat11-11.0.6/java/org/apache/el/parser/AstDynamicExpression.java tomcat11-11.0.15/java/org/apache/el/parser/AstDynamicExpression.java
--- tomcat11-11.0.6/java/org/apache/el/parser/AstDynamicExpression.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/el/parser/AstDynamicExpression.java 2025-12-02 16:54:08.000000000 +0000
@@ -21,10 +21,6 @@
import org.apache.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- */
public final class AstDynamicExpression extends SimpleNode {
public AstDynamicExpression(int id) {
super(id);
diff -Nru tomcat11-11.0.6/java/org/apache/el/parser/AstEqual.java tomcat11-11.0.15/java/org/apache/el/parser/AstEqual.java
--- tomcat11-11.0.6/java/org/apache/el/parser/AstEqual.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/el/parser/AstEqual.java 2025-12-02 16:54:08.000000000 +0000
@@ -22,10 +22,6 @@
import org.apache.el.lang.ELSupport;
import org.apache.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- */
public final class AstEqual extends BooleanNode {
public AstEqual(int id) {
super(id);
diff -Nru tomcat11-11.0.6/java/org/apache/el/parser/AstFalse.java tomcat11-11.0.15/java/org/apache/el/parser/AstFalse.java
--- tomcat11-11.0.6/java/org/apache/el/parser/AstFalse.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/el/parser/AstFalse.java 2025-12-02 16:54:08.000000000 +0000
@@ -21,10 +21,6 @@
import org.apache.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- */
public final class AstFalse extends BooleanNode {
public AstFalse(int id) {
super(id);
diff -Nru tomcat11-11.0.6/java/org/apache/el/parser/AstFloatingPoint.java tomcat11-11.0.15/java/org/apache/el/parser/AstFloatingPoint.java
--- tomcat11-11.0.6/java/org/apache/el/parser/AstFloatingPoint.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/el/parser/AstFloatingPoint.java 2025-12-02 16:54:08.000000000 +0000
@@ -23,10 +23,6 @@
import org.apache.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- */
public final class AstFloatingPoint extends SimpleNode {
public AstFloatingPoint(int id) {
super(id);
diff -Nru tomcat11-11.0.6/java/org/apache/el/parser/AstFunction.java tomcat11-11.0.15/java/org/apache/el/parser/AstFunction.java
--- tomcat11-11.0.6/java/org/apache/el/parser/AstFunction.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/el/parser/AstFunction.java 2025-12-02 16:54:08.000000000 +0000
@@ -31,10 +31,6 @@
import org.apache.el.lang.EvaluationContext;
import org.apache.el.util.MessageFactory;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- */
public final class AstFunction extends SimpleNode {
private String localName = "";
diff -Nru tomcat11-11.0.6/java/org/apache/el/parser/AstGreaterThan.java tomcat11-11.0.15/java/org/apache/el/parser/AstGreaterThan.java
--- tomcat11-11.0.6/java/org/apache/el/parser/AstGreaterThan.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/el/parser/AstGreaterThan.java 2025-12-02 16:54:08.000000000 +0000
@@ -22,10 +22,6 @@
import org.apache.el.lang.ELSupport;
import org.apache.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- */
public final class AstGreaterThan extends BooleanNode {
public AstGreaterThan(int id) {
super(id);
diff -Nru tomcat11-11.0.6/java/org/apache/el/parser/AstGreaterThanEqual.java tomcat11-11.0.15/java/org/apache/el/parser/AstGreaterThanEqual.java
--- tomcat11-11.0.6/java/org/apache/el/parser/AstGreaterThanEqual.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/el/parser/AstGreaterThanEqual.java 2025-12-02 16:54:08.000000000 +0000
@@ -22,10 +22,6 @@
import org.apache.el.lang.ELSupport;
import org.apache.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- */
public final class AstGreaterThanEqual extends BooleanNode {
public AstGreaterThanEqual(int id) {
super(id);
diff -Nru tomcat11-11.0.6/java/org/apache/el/parser/AstIdentifier.java tomcat11-11.0.15/java/org/apache/el/parser/AstIdentifier.java
--- tomcat11-11.0.6/java/org/apache/el/parser/AstIdentifier.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/el/parser/AstIdentifier.java 2025-12-02 16:54:08.000000000 +0000
@@ -32,10 +32,6 @@
import org.apache.el.util.MessageFactory;
import org.apache.el.util.Validation;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- */
public final class AstIdentifier extends SimpleNode {
public AstIdentifier(int id) {
super(id);
diff -Nru tomcat11-11.0.6/java/org/apache/el/parser/AstInteger.java tomcat11-11.0.15/java/org/apache/el/parser/AstInteger.java
--- tomcat11-11.0.6/java/org/apache/el/parser/AstInteger.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/el/parser/AstInteger.java 2025-12-02 16:54:08.000000000 +0000
@@ -23,10 +23,6 @@
import org.apache.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- */
public final class AstInteger extends SimpleNode {
public AstInteger(int id) {
super(id);
diff -Nru tomcat11-11.0.6/java/org/apache/el/parser/AstLessThan.java tomcat11-11.0.15/java/org/apache/el/parser/AstLessThan.java
--- tomcat11-11.0.6/java/org/apache/el/parser/AstLessThan.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/el/parser/AstLessThan.java 2025-12-02 16:54:08.000000000 +0000
@@ -22,10 +22,6 @@
import org.apache.el.lang.ELSupport;
import org.apache.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- */
public final class AstLessThan extends BooleanNode {
public AstLessThan(int id) {
super(id);
diff -Nru tomcat11-11.0.6/java/org/apache/el/parser/AstLessThanEqual.java tomcat11-11.0.15/java/org/apache/el/parser/AstLessThanEqual.java
--- tomcat11-11.0.6/java/org/apache/el/parser/AstLessThanEqual.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/el/parser/AstLessThanEqual.java 2025-12-02 16:54:08.000000000 +0000
@@ -22,10 +22,6 @@
import org.apache.el.lang.ELSupport;
import org.apache.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- */
public final class AstLessThanEqual extends BooleanNode {
public AstLessThanEqual(int id) {
super(id);
diff -Nru tomcat11-11.0.6/java/org/apache/el/parser/AstLiteralExpression.java tomcat11-11.0.15/java/org/apache/el/parser/AstLiteralExpression.java
--- tomcat11-11.0.6/java/org/apache/el/parser/AstLiteralExpression.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/el/parser/AstLiteralExpression.java 2025-12-02 16:54:08.000000000 +0000
@@ -21,10 +21,6 @@
import org.apache.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- */
public final class AstLiteralExpression extends SimpleNode {
public AstLiteralExpression(int id) {
super(id);
diff -Nru tomcat11-11.0.6/java/org/apache/el/parser/AstMinus.java tomcat11-11.0.15/java/org/apache/el/parser/AstMinus.java
--- tomcat11-11.0.6/java/org/apache/el/parser/AstMinus.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/el/parser/AstMinus.java 2025-12-02 16:54:08.000000000 +0000
@@ -22,10 +22,6 @@
import org.apache.el.lang.ELArithmetic;
import org.apache.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- */
public final class AstMinus extends ArithmeticNode {
public AstMinus(int id) {
super(id);
diff -Nru tomcat11-11.0.6/java/org/apache/el/parser/AstMod.java tomcat11-11.0.15/java/org/apache/el/parser/AstMod.java
--- tomcat11-11.0.6/java/org/apache/el/parser/AstMod.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/el/parser/AstMod.java 2025-12-02 16:54:08.000000000 +0000
@@ -22,10 +22,6 @@
import org.apache.el.lang.ELArithmetic;
import org.apache.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- */
public final class AstMod extends ArithmeticNode {
public AstMod(int id) {
super(id);
diff -Nru tomcat11-11.0.6/java/org/apache/el/parser/AstMult.java tomcat11-11.0.15/java/org/apache/el/parser/AstMult.java
--- tomcat11-11.0.6/java/org/apache/el/parser/AstMult.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/el/parser/AstMult.java 2025-12-02 16:54:08.000000000 +0000
@@ -22,10 +22,6 @@
import org.apache.el.lang.ELArithmetic;
import org.apache.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- */
public final class AstMult extends ArithmeticNode {
public AstMult(int id) {
super(id);
diff -Nru tomcat11-11.0.6/java/org/apache/el/parser/AstNegative.java tomcat11-11.0.15/java/org/apache/el/parser/AstNegative.java
--- tomcat11-11.0.6/java/org/apache/el/parser/AstNegative.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/el/parser/AstNegative.java 2025-12-02 16:54:08.000000000 +0000
@@ -25,10 +25,6 @@
import org.apache.el.lang.ELSupport;
import org.apache.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- */
public final class AstNegative extends SimpleNode {
public AstNegative(int id) {
super(id);
diff -Nru tomcat11-11.0.6/java/org/apache/el/parser/AstNot.java tomcat11-11.0.15/java/org/apache/el/parser/AstNot.java
--- tomcat11-11.0.6/java/org/apache/el/parser/AstNot.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/el/parser/AstNot.java 2025-12-02 16:54:08.000000000 +0000
@@ -22,10 +22,6 @@
import org.apache.el.lang.ELSupport;
import org.apache.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- */
public final class AstNot extends SimpleNode {
public AstNot(int id) {
super(id);
diff -Nru tomcat11-11.0.6/java/org/apache/el/parser/AstNotEqual.java tomcat11-11.0.15/java/org/apache/el/parser/AstNotEqual.java
--- tomcat11-11.0.6/java/org/apache/el/parser/AstNotEqual.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/el/parser/AstNotEqual.java 2025-12-02 16:54:08.000000000 +0000
@@ -22,10 +22,6 @@
import org.apache.el.lang.ELSupport;
import org.apache.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- */
public final class AstNotEqual extends BooleanNode {
public AstNotEqual(int id) {
super(id);
diff -Nru tomcat11-11.0.6/java/org/apache/el/parser/AstNull.java tomcat11-11.0.15/java/org/apache/el/parser/AstNull.java
--- tomcat11-11.0.6/java/org/apache/el/parser/AstNull.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/el/parser/AstNull.java 2025-12-02 16:54:08.000000000 +0000
@@ -21,10 +21,6 @@
import org.apache.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- */
public final class AstNull extends SimpleNode {
public AstNull(int id) {
super(id);
diff -Nru tomcat11-11.0.6/java/org/apache/el/parser/AstOr.java tomcat11-11.0.15/java/org/apache/el/parser/AstOr.java
--- tomcat11-11.0.6/java/org/apache/el/parser/AstOr.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/el/parser/AstOr.java 2025-12-02 16:54:08.000000000 +0000
@@ -22,10 +22,6 @@
import org.apache.el.lang.ELSupport;
import org.apache.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- */
public final class AstOr extends BooleanNode {
public AstOr(int id) {
super(id);
diff -Nru tomcat11-11.0.6/java/org/apache/el/parser/AstPlus.java tomcat11-11.0.15/java/org/apache/el/parser/AstPlus.java
--- tomcat11-11.0.6/java/org/apache/el/parser/AstPlus.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/el/parser/AstPlus.java 2025-12-02 16:54:08.000000000 +0000
@@ -22,10 +22,6 @@
import org.apache.el.lang.ELArithmetic;
import org.apache.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- */
public final class AstPlus extends ArithmeticNode {
public AstPlus(int id) {
super(id);
diff -Nru tomcat11-11.0.6/java/org/apache/el/parser/AstString.java tomcat11-11.0.15/java/org/apache/el/parser/AstString.java
--- tomcat11-11.0.6/java/org/apache/el/parser/AstString.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/el/parser/AstString.java 2025-12-02 16:54:08.000000000 +0000
@@ -21,10 +21,6 @@
import org.apache.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- */
public final class AstString extends SimpleNode {
public AstString(int id) {
super(id);
diff -Nru tomcat11-11.0.6/java/org/apache/el/parser/AstTrue.java tomcat11-11.0.15/java/org/apache/el/parser/AstTrue.java
--- tomcat11-11.0.6/java/org/apache/el/parser/AstTrue.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/el/parser/AstTrue.java 2025-12-02 16:54:08.000000000 +0000
@@ -21,10 +21,6 @@
import org.apache.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- */
public final class AstTrue extends BooleanNode {
public AstTrue(int id) {
super(id);
diff -Nru tomcat11-11.0.6/java/org/apache/el/parser/AstValue.java tomcat11-11.0.15/java/org/apache/el/parser/AstValue.java
--- tomcat11-11.0.6/java/org/apache/el/parser/AstValue.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/el/parser/AstValue.java 2025-12-02 16:54:08.000000000 +0000
@@ -35,10 +35,6 @@
import org.apache.el.util.MessageFactory;
import org.apache.el.util.ReflectionUtil;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- */
public final class AstValue extends SimpleNode {
private static final Object[] EMPTY_ARRAY = new Object[0];
@@ -269,8 +265,8 @@
int paramCount = types.length;
- if (m.isVarArgs() && paramCount > 1 && (src == null || paramCount > src.length) || !m.isVarArgs() &&
- (src == null || src.length != paramCount)) {
+ if (m.isVarArgs() && paramCount > 1 && (src == null || paramCount > src.length) ||
+ !m.isVarArgs() && (src == null || src.length != paramCount)) {
String srcCount = null;
if (src != null) {
srcCount = Integer.toString(src.length);
diff -Nru tomcat11-11.0.6/java/org/apache/el/parser/BooleanNode.java tomcat11-11.0.15/java/org/apache/el/parser/BooleanNode.java
--- tomcat11-11.0.6/java/org/apache/el/parser/BooleanNode.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/el/parser/BooleanNode.java 2025-12-02 16:54:08.000000000 +0000
@@ -20,9 +20,6 @@
import org.apache.el.lang.EvaluationContext;
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- */
public abstract class BooleanNode extends SimpleNode {
public BooleanNode(int i) {
diff -Nru tomcat11-11.0.6/java/org/apache/el/parser/ELParser.java tomcat11-11.0.15/java/org/apache/el/parser/ELParser.java
--- tomcat11-11.0.6/java/org/apache/el/parser/ELParser.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/el/parser/ELParser.java 2025-12-02 16:54:08.000000000 +0000
@@ -26,7 +26,8 @@
boolean jjtc000 = true;
jjtree.openNodeScope(jjtn000);
try {
- label_1: while (true) {
+ label_1:
+ while (true) {
switch ((jj_ntk == -1) ? jj_ntk_f() : jj_ntk) {
case LITERAL_EXPRESSION:
case START_DYNAMIC_EXPRESSION:
@@ -219,7 +220,8 @@
*/
final public void Semicolon() throws ParseException {
Assignment();
- label_2: while (true) {
+ label_2:
+ while (true) {
switch ((jj_ntk == -1) ? jj_ntk_f() : jj_ntk) {
case SEMICOLON: {
;
@@ -292,7 +294,8 @@
case MINUS:
case IDENTIFIER: {
Choice();
- label_3: while (true) {
+ label_3:
+ while (true) {
if (jj_2_1(2)) {
;
} else {
@@ -434,7 +437,8 @@
switch ((jj_ntk == -1) ? jj_ntk_f() : jj_ntk) {
case IDENTIFIER: {
Identifier();
- label_4: while (true) {
+ label_4:
+ while (true) {
switch ((jj_ntk == -1) ? jj_ntk_f() : jj_ntk) {
case COMMA: {
;
@@ -534,7 +538,8 @@
}
}
jj_consume_token(RPAREN);
- label_5: while (true) {
+ label_5:
+ while (true) {
switch ((jj_ntk == -1) ? jj_ntk_f() : jj_ntk) {
case LPAREN: {
;
@@ -584,7 +589,8 @@
*/
final public void Choice() throws ParseException {
Or();
- label_6: while (true) {
+ label_6:
+ while (true) {
if (jj_2_5(3)) {
;
} else {
@@ -644,7 +650,8 @@
boolean jjtc001 = true;
jjtree.openNodeScope(jjtn001);
try {
- label_7: while (true) {
+ label_7:
+ while (true) {
switch ((jj_ntk == -1) ? jj_ntk_f() : jj_ntk) {
case OR0: {
jj_consume_token(OR0);
@@ -722,7 +729,8 @@
boolean jjtc001 = true;
jjtree.openNodeScope(jjtn001);
try {
- label_8: while (true) {
+ label_8:
+ while (true) {
switch ((jj_ntk == -1) ? jj_ntk_f() : jj_ntk) {
case AND0: {
jj_consume_token(AND0);
@@ -793,7 +801,8 @@
*/
final public void Equality() throws ParseException {
Compare();
- label_9: while (true) {
+ label_9:
+ while (true) {
switch ((jj_ntk == -1) ? jj_ntk_f() : jj_ntk) {
case EQ0:
case EQ1:
@@ -928,7 +937,8 @@
*/
final public void Compare() throws ParseException {
Concatenation();
- label_10: while (true) {
+ label_10:
+ while (true) {
switch ((jj_ntk == -1) ? jj_ntk_f() : jj_ntk) {
case GT0:
case GT1:
@@ -1176,7 +1186,8 @@
*/
final public void Concatenation() throws ParseException {
Math();
- label_11: while (true) {
+ label_11:
+ while (true) {
switch ((jj_ntk == -1) ? jj_ntk_f() : jj_ntk) {
case CONCAT: {
;
@@ -1231,7 +1242,8 @@
*/
final public void Math() throws ParseException {
Multiplication();
- label_12: while (true) {
+ label_12:
+ while (true) {
switch ((jj_ntk == -1) ? jj_ntk_f() : jj_ntk) {
case PLUS:
case MINUS: {
@@ -1336,7 +1348,8 @@
*/
final public void Multiplication() throws ParseException {
Unary();
- label_13: while (true) {
+ label_13:
+ while (true) {
switch ((jj_ntk == -1) ? jj_ntk_f() : jj_ntk) {
case MULT:
case DIV0:
@@ -1733,7 +1746,8 @@
jjtree.openNodeScope(jjtn001);
try {
ValuePrefix();
- label_14: while (true) {
+ label_14:
+ while (true) {
switch ((jj_ntk == -1) ? jj_ntk_f() : jj_ntk) {
case DOT:
case LBRACK: {
@@ -1926,7 +1940,8 @@
case MINUS:
case IDENTIFIER: {
Expression();
- label_15: while (true) {
+ label_15:
+ while (true) {
switch ((jj_ntk == -1) ? jj_ntk_f() : jj_ntk) {
case COMMA: {
;
@@ -2055,7 +2070,8 @@
case MINUS:
case IDENTIFIER: {
Expression();
- label_16: while (true) {
+ label_16:
+ while (true) {
switch ((jj_ntk == -1) ? jj_ntk_f() : jj_ntk) {
case COMMA: {
;
@@ -2130,7 +2146,8 @@
case MINUS:
case IDENTIFIER: {
Expression();
- label_17: while (true) {
+ label_17:
+ while (true) {
switch ((jj_ntk == -1) ? jj_ntk_f() : jj_ntk) {
case COMMA: {
;
@@ -2209,7 +2226,8 @@
case MINUS:
case IDENTIFIER: {
MapEntry();
- label_18: while (true) {
+ label_18:
+ while (true) {
switch ((jj_ntk == -1) ? jj_ntk_f() : jj_ntk) {
case COMMA: {
;
@@ -2350,7 +2368,8 @@
} else {
jjtn000.setLocalName(t0.image);
}
- label_19: while (true) {
+ label_19:
+ while (true) {
MethodParameters();
switch ((jj_ntk == -1) ? jj_ntk_f() : jj_ntk) {
case LPAREN: {
@@ -3417,9 +3436,9 @@
private boolean jj_3R_Multiplication_247_9_71() {
Token xsp;
xsp = jj_scanpos;
- if (jj_scan_token(51)) {
+ if (jj_scan_token(50)) {
jj_scanpos = xsp;
- if (jj_scan_token(52)) {
+ if (jj_scan_token(51)) {
return true;
}
}
@@ -3432,9 +3451,9 @@
private boolean jj_3R_Multiplication_245_9_70() {
Token xsp;
xsp = jj_scanpos;
- if (jj_scan_token(49)) {
+ if (jj_scan_token(48)) {
jj_scanpos = xsp;
- if (jj_scan_token(50)) {
+ if (jj_scan_token(49)) {
return true;
}
}
@@ -3891,11 +3910,10 @@
}
private static void jj_la1_init_1() {
- jj_la1_1 = new int[] { 0x0, 0x0, 0x0, 0x1008860, 0x1008860, 0x0, 0x1000000, 0x1000000, 0x1008860, 0x0, 0x600,
- 0x600, 0x600, 0x180, 0x180, 0x180, 0x1e, 0x6, 0x18, 0x1e, 0x1, 0x0, 0x0, 0x1, 0x0, 0x1, 0x200000,
- 0xc000, 0xc000, 0x1e2000, 0x60000, 0x180000, 0x1e2000, 0x60, 0x60, 0x8000, 0x1000860, 0x0, 0x1000000,
- 0x0, 0x0, 0x0, 0x1008860, 0x0, 0x1000000, 0x0, 0x0, 0x1008860, 0x0, 0x1008860, 0x0, 0x1008860, 0x0, 0x0,
- 0x0, 0x0, };
+ jj_la1_1 = new int[] { 0x0, 0x0, 0x0, 0x804860, 0x804860, 0x0, 0x800000, 0x800000, 0x804860, 0x0, 0x600, 0x600,
+ 0x600, 0x180, 0x180, 0x180, 0x1e, 0x6, 0x18, 0x1e, 0x1, 0x0, 0x0, 0x1, 0x0, 0x1, 0x100000, 0x6000,
+ 0x6000, 0xf1000, 0x30000, 0xc0000, 0xf1000, 0x60, 0x60, 0x4000, 0x800860, 0x0, 0x800000, 0x0, 0x0, 0x0,
+ 0x804860, 0x0, 0x800000, 0x0, 0x0, 0x804860, 0x0, 0x804860, 0x0, 0x804860, 0x0, 0x0, 0x0, 0x0, };
}
final private JJCalls[] jj_2_rtns = new JJCalls[9];
@@ -4170,7 +4188,7 @@
/** Generate ParseException. */
public ParseException generateParseException() {
jj_expentries.clear();
- boolean[] la1tokens = new boolean[62];
+ boolean[] la1tokens = new boolean[59];
if (jj_kind >= 0) {
la1tokens[jj_kind] = true;
jj_kind = -1;
@@ -4187,7 +4205,7 @@
}
}
}
- for (int i = 0; i < 62; i++) {
+ for (int i = 0; i < 59; i++) {
if (la1tokens[i]) {
jj_expentry = new int[1];
jj_expentry[0] = i;
diff -Nru tomcat11-11.0.6/java/org/apache/el/parser/ELParser.jjt tomcat11-11.0.15/java/org/apache/el/parser/ELParser.jjt
--- tomcat11-11.0.6/java/org/apache/el/parser/ELParser.jjt 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/el/parser/ELParser.jjt 2025-12-02 16:54:08.000000000 +0000
@@ -15,11 +15,6 @@
* limitations under the License.
*/
-/*
- Author: Jacob Hookom
- Email: jacob at hookom.net
-*/
-
/* == Option Declaration == */
options
{
@@ -535,7 +530,6 @@
| < OR0 : "||" >
| < OR1 : "or" >
| < EMPTY : "empty" >
-| < INSTANCEOF : "instanceof" >
| < MULT : "*" >
| < PLUS : "+" >
| < MINUS : "-" >
@@ -547,9 +541,7 @@
| < CONCAT : "+=" >
| < ASSIGN : "=" >
| < ARROW : "->" >
-| < IDENTIFIER : (|) (|)* >
-| < FUNCTIONSUFFIX : () >
-| < #IMPL_OBJ_START: "#" >
+| < IDENTIFIER : (|)* >
| < #JAVALETTER:
[
"\u0024",
diff -Nru tomcat11-11.0.6/java/org/apache/el/parser/ELParserConstants.java tomcat11-11.0.15/java/org/apache/el/parser/ELParserConstants.java
--- tomcat11-11.0.6/java/org/apache/el/parser/ELParserConstants.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/el/parser/ELParserConstants.java 2025-12-02 16:54:08.000000000 +0000
@@ -88,41 +88,35 @@
/** RegularExpression Id. */
int EMPTY = 43;
/** RegularExpression Id. */
- int INSTANCEOF = 44;
+ int MULT = 44;
/** RegularExpression Id. */
- int MULT = 45;
+ int PLUS = 45;
/** RegularExpression Id. */
- int PLUS = 46;
+ int MINUS = 46;
/** RegularExpression Id. */
- int MINUS = 47;
+ int QUESTIONMARK = 47;
/** RegularExpression Id. */
- int QUESTIONMARK = 48;
+ int DIV0 = 48;
/** RegularExpression Id. */
- int DIV0 = 49;
+ int DIV1 = 49;
/** RegularExpression Id. */
- int DIV1 = 50;
+ int MOD0 = 50;
/** RegularExpression Id. */
- int MOD0 = 51;
+ int MOD1 = 51;
/** RegularExpression Id. */
- int MOD1 = 52;
+ int CONCAT = 52;
/** RegularExpression Id. */
- int CONCAT = 53;
+ int ASSIGN = 53;
/** RegularExpression Id. */
- int ASSIGN = 54;
+ int ARROW = 54;
/** RegularExpression Id. */
- int ARROW = 55;
+ int IDENTIFIER = 55;
/** RegularExpression Id. */
- int IDENTIFIER = 56;
+ int JAVALETTER = 56;
/** RegularExpression Id. */
- int FUNCTIONSUFFIX = 57;
+ int JAVADIGIT = 57;
/** RegularExpression Id. */
- int IMPL_OBJ_START = 58;
- /** RegularExpression Id. */
- int JAVALETTER = 59;
- /** RegularExpression Id. */
- int JAVADIGIT = 60;
- /** RegularExpression Id. */
- int ILLEGAL_CHARACTER = 61;
+ int ILLEGAL_CHARACTER = 58;
/** Lexical state. */
int DEFAULT = 0;
@@ -137,8 +131,7 @@
"", "\"true\"", "\"false\"", "\"null\"", "\".\"", "\"(\"", "\")\"", "\"[\"", "\"]\"",
"\":\"", "\";\"", "\",\"", "\">\"", "\"gt\"", "\"<\"", "\"lt\"", "\">=\"", "\"ge\"", "\"<=\"", "\"le\"",
"\"==\"", "\"eq\"", "\"!=\"", "\"ne\"", "\"!\"", "\"not\"", "\"&&\"", "\"and\"", "\"||\"", "\"or\"",
- "\"empty\"", "\"instanceof\"", "\"*\"", "\"+\"", "\"-\"", "\"?\"", "\"/\"", "\"div\"", "\"%\"", "\"mod\"",
- "\"+=\"", "\"=\"", "\"->\"", "", "", "\"#\"", "", "",
- "", };
+ "\"empty\"", "\"*\"", "\"+\"", "\"-\"", "\"?\"", "\"/\"", "\"div\"", "\"%\"", "\"mod\"", "\"+=\"", "\"=\"",
+ "\"->\"", "", "", "", "", };
}
diff -Nru tomcat11-11.0.6/java/org/apache/el/parser/ELParserTokenManager.java tomcat11-11.0.15/java/org/apache/el/parser/ELParserTokenManager.java
--- tomcat11-11.0.6/java/org/apache/el/parser/ELParserTokenManager.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/el/parser/ELParserTokenManager.java 2025-12-02 16:54:08.000000000 +0000
@@ -301,77 +301,39 @@
if ((active0 & 0x20000L) != 0L) {
return 1;
}
- if ((active0 & 0x141d555401c000L) != 0L) {
- jjmatchedKind = 56;
- return 30;
+ if ((active0 & 0xa0d555401c000L) != 0L) {
+ jjmatchedKind = 55;
+ return 16;
}
return -1;
case 1:
- if ((active0 & 0x41554000000L) != 0L) {
- return 30;
- }
- if ((active0 & 0x1419400001c000L) != 0L) {
- jjmatchedKind = 56;
+ if ((active0 & 0xa09400001c000L) != 0L) {
+ jjmatchedKind = 55;
jjmatchedPos = 1;
- return 30;
+ return 16;
+ }
+ if ((active0 & 0x41554000000L) != 0L) {
+ return 16;
}
return -1;
case 2:
- if ((active0 & 0x14014000000000L) != 0L) {
- return 30;
+ if ((active0 & 0xa014000000000L) != 0L) {
+ return 16;
}
- if ((active0 & 0x18000001c000L) != 0L) {
- jjmatchedKind = 56;
+ if ((active0 & 0x8000001c000L) != 0L) {
+ jjmatchedKind = 55;
jjmatchedPos = 2;
- return 30;
+ return 16;
}
return -1;
case 3:
if ((active0 & 0x14000L) != 0L) {
- return 30;
+ return 16;
}
- if ((active0 & 0x180000008000L) != 0L) {
- jjmatchedKind = 56;
- jjmatchedPos = 3;
- return 30;
- }
- return -1;
- case 4:
if ((active0 & 0x80000008000L) != 0L) {
- return 30;
- }
- if ((active0 & 0x100000000000L) != 0L) {
- jjmatchedKind = 56;
- jjmatchedPos = 4;
- return 30;
- }
- return -1;
- case 5:
- if ((active0 & 0x100000000000L) != 0L) {
- jjmatchedKind = 56;
- jjmatchedPos = 5;
- return 30;
- }
- return -1;
- case 6:
- if ((active0 & 0x100000000000L) != 0L) {
- jjmatchedKind = 56;
- jjmatchedPos = 6;
- return 30;
- }
- return -1;
- case 7:
- if ((active0 & 0x100000000000L) != 0L) {
- jjmatchedKind = 56;
- jjmatchedPos = 7;
- return 30;
- }
- return -1;
- case 8:
- if ((active0 & 0x100000000000L) != 0L) {
- jjmatchedKind = 56;
- jjmatchedPos = 8;
- return 30;
+ jjmatchedKind = 55;
+ jjmatchedPos = 3;
+ return 16;
}
return -1;
default:
@@ -389,7 +351,7 @@
jjmatchedKind = 37;
return jjMoveStringLiteralDfa1_2(0x800000000L);
case 37:
- return jjStopAtPos(0, 51);
+ return jjStopAtPos(0, 50);
case 38:
return jjMoveStringLiteralDfa1_2(0x8000000000L);
case 40:
@@ -397,19 +359,19 @@
case 41:
return jjStopAtPos(0, 19);
case 42:
- return jjStopAtPos(0, 45);
+ return jjStopAtPos(0, 44);
case 43:
- jjmatchedKind = 46;
- return jjMoveStringLiteralDfa1_2(0x20000000000000L);
+ jjmatchedKind = 45;
+ return jjMoveStringLiteralDfa1_2(0x10000000000000L);
case 44:
return jjStopAtPos(0, 24);
case 45:
- jjmatchedKind = 47;
- return jjMoveStringLiteralDfa1_2(0x80000000000000L);
+ jjmatchedKind = 46;
+ return jjMoveStringLiteralDfa1_2(0x40000000000000L);
case 46:
return jjStartNfaWithStates_2(0, 17, 1);
case 47:
- return jjStopAtPos(0, 49);
+ return jjStopAtPos(0, 48);
case 58:
return jjStopAtPos(0, 22);
case 59:
@@ -418,13 +380,13 @@
jjmatchedKind = 27;
return jjMoveStringLiteralDfa1_2(0x80000000L);
case 61:
- jjmatchedKind = 54;
+ jjmatchedKind = 53;
return jjMoveStringLiteralDfa1_2(0x200000000L);
case 62:
jjmatchedKind = 25;
return jjMoveStringLiteralDfa1_2(0x20000000L);
case 63:
- return jjStopAtPos(0, 48);
+ return jjStopAtPos(0, 47);
case 91:
return jjStopAtPos(0, 20);
case 93:
@@ -432,19 +394,17 @@
case 97:
return jjMoveStringLiteralDfa1_2(0x10000000000L);
case 100:
- return jjMoveStringLiteralDfa1_2(0x4000000000000L);
+ return jjMoveStringLiteralDfa1_2(0x2000000000000L);
case 101:
return jjMoveStringLiteralDfa1_2(0x80400000000L);
case 102:
return jjMoveStringLiteralDfa1_2(0x8000L);
case 103:
return jjMoveStringLiteralDfa1_2(0x44000000L);
- case 105:
- return jjMoveStringLiteralDfa1_2(0x100000000000L);
case 108:
return jjMoveStringLiteralDfa1_2(0x110000000L);
case 109:
- return jjMoveStringLiteralDfa1_2(0x10000000000000L);
+ return jjMoveStringLiteralDfa1_2(0x8000000000000L);
case 110:
return jjMoveStringLiteralDfa1_2(0x5000010000L);
case 111:
@@ -484,49 +444,49 @@
return jjStopAtPos(1, 33);
} else if ((active0 & 0x800000000L) != 0L) {
return jjStopAtPos(1, 35);
- } else if ((active0 & 0x20000000000000L) != 0L) {
- return jjStopAtPos(1, 53);
+ } else if ((active0 & 0x10000000000000L) != 0L) {
+ return jjStopAtPos(1, 52);
}
break;
case 62:
- if ((active0 & 0x80000000000000L) != 0L) {
- return jjStopAtPos(1, 55);
+ if ((active0 & 0x40000000000000L) != 0L) {
+ return jjStopAtPos(1, 54);
}
break;
case 97:
return jjMoveStringLiteralDfa2_2(active0, 0x8000L);
case 101:
if ((active0 & 0x40000000L) != 0L) {
- return jjStartNfaWithStates_2(1, 30, 30);
+ return jjStartNfaWithStates_2(1, 30, 16);
} else if ((active0 & 0x100000000L) != 0L) {
- return jjStartNfaWithStates_2(1, 32, 30);
+ return jjStartNfaWithStates_2(1, 32, 16);
} else if ((active0 & 0x1000000000L) != 0L) {
- return jjStartNfaWithStates_2(1, 36, 30);
+ return jjStartNfaWithStates_2(1, 36, 16);
}
break;
case 105:
- return jjMoveStringLiteralDfa2_2(active0, 0x4000000000000L);
+ return jjMoveStringLiteralDfa2_2(active0, 0x2000000000000L);
case 109:
return jjMoveStringLiteralDfa2_2(active0, 0x80000000000L);
case 110:
- return jjMoveStringLiteralDfa2_2(active0, 0x110000000000L);
+ return jjMoveStringLiteralDfa2_2(active0, 0x10000000000L);
case 111:
- return jjMoveStringLiteralDfa2_2(active0, 0x10004000000000L);
+ return jjMoveStringLiteralDfa2_2(active0, 0x8004000000000L);
case 113:
if ((active0 & 0x400000000L) != 0L) {
- return jjStartNfaWithStates_2(1, 34, 30);
+ return jjStartNfaWithStates_2(1, 34, 16);
}
break;
case 114:
if ((active0 & 0x40000000000L) != 0L) {
- return jjStartNfaWithStates_2(1, 42, 30);
+ return jjStartNfaWithStates_2(1, 42, 16);
}
return jjMoveStringLiteralDfa2_2(active0, 0x4000L);
case 116:
if ((active0 & 0x4000000L) != 0L) {
- return jjStartNfaWithStates_2(1, 26, 30);
+ return jjStartNfaWithStates_2(1, 26, 16);
} else if ((active0 & 0x10000000L) != 0L) {
- return jjStartNfaWithStates_2(1, 28, 30);
+ return jjStartNfaWithStates_2(1, 28, 16);
}
break;
case 117:
@@ -555,27 +515,25 @@
switch (curChar) {
case 100:
if ((active0 & 0x10000000000L) != 0L) {
- return jjStartNfaWithStates_2(2, 40, 30);
- } else if ((active0 & 0x10000000000000L) != 0L) {
- return jjStartNfaWithStates_2(2, 52, 30);
+ return jjStartNfaWithStates_2(2, 40, 16);
+ } else if ((active0 & 0x8000000000000L) != 0L) {
+ return jjStartNfaWithStates_2(2, 51, 16);
}
break;
case 108:
return jjMoveStringLiteralDfa3_2(active0, 0x18000L);
case 112:
return jjMoveStringLiteralDfa3_2(active0, 0x80000000000L);
- case 115:
- return jjMoveStringLiteralDfa3_2(active0, 0x100000000000L);
case 116:
if ((active0 & 0x4000000000L) != 0L) {
- return jjStartNfaWithStates_2(2, 38, 30);
+ return jjStartNfaWithStates_2(2, 38, 16);
}
break;
case 117:
return jjMoveStringLiteralDfa3_2(active0, 0x4000L);
case 118:
- if ((active0 & 0x4000000000000L) != 0L) {
- return jjStartNfaWithStates_2(2, 50, 30);
+ if ((active0 & 0x2000000000000L) != 0L) {
+ return jjStartNfaWithStates_2(2, 49, 16);
}
break;
default:
@@ -597,18 +555,18 @@
switch (curChar) {
case 101:
if ((active0 & 0x4000L) != 0L) {
- return jjStartNfaWithStates_2(3, 14, 30);
+ return jjStartNfaWithStates_2(3, 14, 16);
}
break;
case 108:
if ((active0 & 0x10000L) != 0L) {
- return jjStartNfaWithStates_2(3, 16, 30);
+ return jjStartNfaWithStates_2(3, 16, 16);
}
break;
case 115:
return jjMoveStringLiteralDfa4_2(active0, 0x8000L);
case 116:
- return jjMoveStringLiteralDfa4_2(active0, 0x180000000000L);
+ return jjMoveStringLiteralDfa4_2(active0, 0x80000000000L);
default:
break;
}
@@ -626,16 +584,14 @@
return 4;
}
switch (curChar) {
- case 97:
- return jjMoveStringLiteralDfa5_2(active0, 0x100000000000L);
case 101:
if ((active0 & 0x8000L) != 0L) {
- return jjStartNfaWithStates_2(4, 15, 30);
+ return jjStartNfaWithStates_2(4, 15, 16);
}
break;
case 121:
if ((active0 & 0x80000000000L) != 0L) {
- return jjStartNfaWithStates_2(4, 43, 30);
+ return jjStartNfaWithStates_2(4, 43, 16);
}
break;
default:
@@ -644,104 +600,6 @@
return jjStartNfa_2(3, active0);
}
- private int jjMoveStringLiteralDfa5_2(long old0, long active0) {
- if (((active0 &= old0)) == 0L) {
- return jjStartNfa_2(3, old0);
- }
- try {
- curChar = input_stream.readChar();
- } catch (java.io.IOException e) {
- jjStopStringLiteralDfa_2(4, active0);
- return 5;
- }
- switch (curChar) {
- case 110:
- return jjMoveStringLiteralDfa6_2(active0, 0x100000000000L);
- default:
- break;
- }
- return jjStartNfa_2(4, active0);
- }
-
- private int jjMoveStringLiteralDfa6_2(long old0, long active0) {
- if (((active0 &= old0)) == 0L) {
- return jjStartNfa_2(4, old0);
- }
- try {
- curChar = input_stream.readChar();
- } catch (java.io.IOException e) {
- jjStopStringLiteralDfa_2(5, active0);
- return 6;
- }
- switch (curChar) {
- case 99:
- return jjMoveStringLiteralDfa7_2(active0, 0x100000000000L);
- default:
- break;
- }
- return jjStartNfa_2(5, active0);
- }
-
- private int jjMoveStringLiteralDfa7_2(long old0, long active0) {
- if (((active0 &= old0)) == 0L) {
- return jjStartNfa_2(5, old0);
- }
- try {
- curChar = input_stream.readChar();
- } catch (java.io.IOException e) {
- jjStopStringLiteralDfa_2(6, active0);
- return 7;
- }
- switch (curChar) {
- case 101:
- return jjMoveStringLiteralDfa8_2(active0, 0x100000000000L);
- default:
- break;
- }
- return jjStartNfa_2(6, active0);
- }
-
- private int jjMoveStringLiteralDfa8_2(long old0, long active0) {
- if (((active0 &= old0)) == 0L) {
- return jjStartNfa_2(6, old0);
- }
- try {
- curChar = input_stream.readChar();
- } catch (java.io.IOException e) {
- jjStopStringLiteralDfa_2(7, active0);
- return 8;
- }
- switch (curChar) {
- case 111:
- return jjMoveStringLiteralDfa9_2(active0, 0x100000000000L);
- default:
- break;
- }
- return jjStartNfa_2(7, active0);
- }
-
- private int jjMoveStringLiteralDfa9_2(long old0, long active0) {
- if (((active0 &= old0)) == 0L) {
- return jjStartNfa_2(7, old0);
- }
- try {
- curChar = input_stream.readChar();
- } catch (java.io.IOException e) {
- jjStopStringLiteralDfa_2(8, active0);
- return 9;
- }
- switch (curChar) {
- case 102:
- if ((active0 & 0x100000000000L) != 0L) {
- return jjStartNfaWithStates_2(9, 44, 30);
- }
- break;
- default:
- break;
- }
- return jjStartNfa_2(8, active0);
- }
-
private int jjStartNfaWithStates_2(int pos, int kind, int state) {
jjmatchedKind = kind;
jjmatchedPos = pos;
@@ -881,7 +739,7 @@
private int jjMoveNfa_2(int startState, int curPos) {
int startsAt = 0;
- jjnewStateCnt = 30;
+ jjnewStateCnt = 29;
int i = 1;
jjstateSet[0] = startState;
int kind = 0x7fffffff;
@@ -901,12 +759,12 @@
{
jjCheckNAddStates(18, 22);
}
- } else if ((0x1800000000L & l) != 0L) {
- if (kind > 56) {
- kind = 56;
+ } else if (curChar == 36) {
+ if (kind > 55) {
+ kind = 55;
}
{
- jjCheckNAddTwoStates(28, 29);
+ jjCheckNAdd(16);
}
} else if (curChar == 39) {
jjCheckNAddStates(23, 25);
@@ -916,24 +774,6 @@
jjCheckNAdd(1);
}
break;
- case 30:
- if ((0x3ff00100fffc1ffL & l) != 0L) {
- if (kind > 57) {
- kind = 57;
- }
- {
- jjCheckNAdd(29);
- }
- }
- if ((0x3ff00100fffc1ffL & l) != 0L) {
- if (kind > 56) {
- kind = 56;
- }
- {
- jjCheckNAdd(28);
- }
- }
- break;
case 1:
if ((0x3ff000000000000L & l) == 0L) {
break;
@@ -1000,6 +840,26 @@
}
break;
case 15:
+ if (curChar != 36) {
+ break;
+ }
+ if (kind > 55) {
+ kind = 55;
+ } {
+ jjCheckNAdd(16);
+ }
+ break;
+ case 16:
+ if ((0x3ff00100fffc1ffL & l) == 0L) {
+ break;
+ }
+ if (kind > 55) {
+ kind = 55;
+ } {
+ jjCheckNAdd(16);
+ }
+ break;
+ case 17:
if ((0x3ff000000000000L & l) == 0L) {
break;
}
@@ -1009,106 +869,76 @@
jjCheckNAddStates(18, 22);
}
break;
- case 16:
+ case 18:
if ((0x3ff000000000000L & l) == 0L) {
break;
}
if (kind > 10) {
kind = 10;
} {
- jjCheckNAdd(16);
+ jjCheckNAdd(18);
}
break;
- case 17:
+ case 19:
if ((0x3ff000000000000L & l) != 0L) {
- jjCheckNAddTwoStates(17, 18);
+ jjCheckNAddTwoStates(19, 20);
}
break;
- case 18:
+ case 20:
if (curChar != 46) {
break;
}
if (kind > 11) {
kind = 11;
} {
- jjCheckNAddTwoStates(19, 20);
+ jjCheckNAddTwoStates(21, 22);
}
break;
- case 19:
+ case 21:
if ((0x3ff000000000000L & l) == 0L) {
break;
}
if (kind > 11) {
kind = 11;
} {
- jjCheckNAddTwoStates(19, 20);
+ jjCheckNAddTwoStates(21, 22);
}
break;
- case 21:
+ case 23:
if ((0x280000000000L & l) != 0L) {
- jjCheckNAdd(22);
+ jjCheckNAdd(24);
}
break;
- case 22:
+ case 24:
if ((0x3ff000000000000L & l) == 0L) {
break;
}
if (kind > 11) {
kind = 11;
} {
- jjCheckNAdd(22);
+ jjCheckNAdd(24);
}
break;
- case 23:
+ case 25:
if ((0x3ff000000000000L & l) != 0L) {
- jjCheckNAddTwoStates(23, 24);
+ jjCheckNAddTwoStates(25, 26);
}
break;
- case 25:
+ case 27:
if ((0x280000000000L & l) != 0L) {
- jjCheckNAdd(26);
+ jjCheckNAdd(28);
}
break;
- case 26:
+ case 28:
if ((0x3ff000000000000L & l) == 0L) {
break;
}
if (kind > 11) {
kind = 11;
} {
- jjCheckNAdd(26);
- }
- break;
- case 27:
- if ((0x1800000000L & l) == 0L) {
- break;
- }
- if (kind > 56) {
- kind = 56;
- } {
- jjCheckNAddTwoStates(28, 29);
- }
- break;
- case 28:
- if ((0x3ff00100fffc1ffL & l) == 0L) {
- break;
- }
- if (kind > 56) {
- kind = 56;
- } {
jjCheckNAdd(28);
}
break;
- case 29:
- if ((0x3ff00100fffc1ffL & l) == 0L) {
- break;
- }
- if (kind > 57) {
- kind = 57;
- } {
- jjCheckNAdd(29);
- }
- break;
default:
break;
}
@@ -1121,30 +951,12 @@
if ((0x7fffffe87fffffeL & l) == 0L) {
break;
}
- if (kind > 56) {
- kind = 56;
+ if (kind > 55) {
+ kind = 55;
} {
- jjCheckNAddTwoStates(28, 29);
+ jjCheckNAdd(16);
}
break;
- case 30:
- if ((0x87fffffe87fffffeL & l) != 0L) {
- if (kind > 57) {
- kind = 57;
- }
- {
- jjCheckNAdd(29);
- }
- }
- if ((0x87fffffe87fffffeL & l) != 0L) {
- if (kind > 56) {
- kind = 56;
- }
- {
- jjCheckNAdd(28);
- }
- }
- break;
case 2:
if ((0x2000000020L & l) != 0L) {
jjAddStates(29, 30);
@@ -1180,35 +992,25 @@
jjCheckNAddStates(23, 25);
}
break;
- case 20:
- if ((0x2000000020L & l) != 0L) {
- jjAddStates(31, 32);
- }
- break;
- case 24:
- if ((0x2000000020L & l) != 0L) {
- jjAddStates(33, 34);
- }
- break;
- case 28:
+ case 16:
if ((0x87fffffe87fffffeL & l) == 0L) {
break;
}
- if (kind > 56) {
- kind = 56;
+ if (kind > 55) {
+ kind = 55;
} {
- jjCheckNAdd(28);
+ jjCheckNAdd(16);
}
break;
- case 29:
- if ((0x87fffffe87fffffeL & l) == 0L) {
- break;
+ case 22:
+ if ((0x2000000020L & l) != 0L) {
+ jjAddStates(31, 32);
+ }
+ break;
+ case 26:
+ if ((0x2000000020L & l) != 0L) {
+ jjAddStates(33, 34);
}
- if (kind > 57) {
- kind = 57;
- } {
- jjCheckNAdd(29);
- }
break;
default:
break;
@@ -1226,30 +1028,12 @@
if (!jjCanMove_1(hiByte, i1, i2, l1, l2)) {
break;
}
- if (kind > 56) {
- kind = 56;
+ if (kind > 55) {
+ kind = 55;
} {
- jjCheckNAddTwoStates(28, 29);
+ jjCheckNAdd(16);
}
break;
- case 30:
- if (jjCanMove_2(hiByte, i1, i2, l1, l2)) {
- if (kind > 56) {
- kind = 56;
- }
- {
- jjCheckNAdd(28);
- }
- }
- if (jjCanMove_2(hiByte, i1, i2, l1, l2)) {
- if (kind > 57) {
- kind = 57;
- }
- {
- jjCheckNAdd(29);
- }
- }
- break;
case 6:
if (jjCanMove_0(hiByte, i1, i2, l1, l2)) {
jjAddStates(26, 28);
@@ -1260,24 +1044,14 @@
jjAddStates(23, 25);
}
break;
- case 28:
- if (!jjCanMove_2(hiByte, i1, i2, l1, l2)) {
- break;
- }
- if (kind > 56) {
- kind = 56;
- } {
- jjCheckNAdd(28);
- }
- break;
- case 29:
+ case 16:
if (!jjCanMove_2(hiByte, i1, i2, l1, l2)) {
break;
}
- if (kind > 57) {
- kind = 57;
+ if (kind > 55) {
+ kind = 55;
} {
- jjCheckNAdd(29);
+ jjCheckNAdd(16);
}
break;
default:
@@ -1295,7 +1069,7 @@
kind = 0x7fffffff;
}
++curPos;
- if ((i = jjnewStateCnt) == (startsAt = 30 - (jjnewStateCnt = startsAt))) {
+ if ((i = jjnewStateCnt) == (startsAt = 29 - (jjnewStateCnt = startsAt))) {
return curPos;
}
try {
@@ -1312,77 +1086,39 @@
if ((active0 & 0x20000L) != 0L) {
return 1;
}
- if ((active0 & 0x141d555401c000L) != 0L) {
- jjmatchedKind = 56;
- return 30;
+ if ((active0 & 0xa0d555401c000L) != 0L) {
+ jjmatchedKind = 55;
+ return 16;
}
return -1;
case 1:
- if ((active0 & 0x41554000000L) != 0L) {
- return 30;
- }
- if ((active0 & 0x1419400001c000L) != 0L) {
- jjmatchedKind = 56;
+ if ((active0 & 0xa09400001c000L) != 0L) {
+ jjmatchedKind = 55;
jjmatchedPos = 1;
- return 30;
+ return 16;
+ }
+ if ((active0 & 0x41554000000L) != 0L) {
+ return 16;
}
return -1;
case 2:
- if ((active0 & 0x14014000000000L) != 0L) {
- return 30;
+ if ((active0 & 0xa014000000000L) != 0L) {
+ return 16;
}
- if ((active0 & 0x18000001c000L) != 0L) {
- jjmatchedKind = 56;
+ if ((active0 & 0x8000001c000L) != 0L) {
+ jjmatchedKind = 55;
jjmatchedPos = 2;
- return 30;
+ return 16;
}
return -1;
case 3:
if ((active0 & 0x14000L) != 0L) {
- return 30;
+ return 16;
}
- if ((active0 & 0x180000008000L) != 0L) {
- jjmatchedKind = 56;
- jjmatchedPos = 3;
- return 30;
- }
- return -1;
- case 4:
if ((active0 & 0x80000008000L) != 0L) {
- return 30;
- }
- if ((active0 & 0x100000000000L) != 0L) {
- jjmatchedKind = 56;
- jjmatchedPos = 4;
- return 30;
- }
- return -1;
- case 5:
- if ((active0 & 0x100000000000L) != 0L) {
- jjmatchedKind = 56;
- jjmatchedPos = 5;
- return 30;
- }
- return -1;
- case 6:
- if ((active0 & 0x100000000000L) != 0L) {
- jjmatchedKind = 56;
- jjmatchedPos = 6;
- return 30;
- }
- return -1;
- case 7:
- if ((active0 & 0x100000000000L) != 0L) {
- jjmatchedKind = 56;
- jjmatchedPos = 7;
- return 30;
- }
- return -1;
- case 8:
- if ((active0 & 0x100000000000L) != 0L) {
- jjmatchedKind = 56;
- jjmatchedPos = 8;
- return 30;
+ jjmatchedKind = 55;
+ jjmatchedPos = 3;
+ return 16;
}
return -1;
default:
@@ -1400,7 +1136,7 @@
jjmatchedKind = 37;
return jjMoveStringLiteralDfa1_1(0x800000000L);
case 37:
- return jjStopAtPos(0, 51);
+ return jjStopAtPos(0, 50);
case 38:
return jjMoveStringLiteralDfa1_1(0x8000000000L);
case 40:
@@ -1408,19 +1144,19 @@
case 41:
return jjStopAtPos(0, 19);
case 42:
- return jjStopAtPos(0, 45);
+ return jjStopAtPos(0, 44);
case 43:
- jjmatchedKind = 46;
- return jjMoveStringLiteralDfa1_1(0x20000000000000L);
+ jjmatchedKind = 45;
+ return jjMoveStringLiteralDfa1_1(0x10000000000000L);
case 44:
return jjStopAtPos(0, 24);
case 45:
- jjmatchedKind = 47;
- return jjMoveStringLiteralDfa1_1(0x80000000000000L);
+ jjmatchedKind = 46;
+ return jjMoveStringLiteralDfa1_1(0x40000000000000L);
case 46:
return jjStartNfaWithStates_1(0, 17, 1);
case 47:
- return jjStopAtPos(0, 49);
+ return jjStopAtPos(0, 48);
case 58:
return jjStopAtPos(0, 22);
case 59:
@@ -1429,13 +1165,13 @@
jjmatchedKind = 27;
return jjMoveStringLiteralDfa1_1(0x80000000L);
case 61:
- jjmatchedKind = 54;
+ jjmatchedKind = 53;
return jjMoveStringLiteralDfa1_1(0x200000000L);
case 62:
jjmatchedKind = 25;
return jjMoveStringLiteralDfa1_1(0x20000000L);
case 63:
- return jjStopAtPos(0, 48);
+ return jjStopAtPos(0, 47);
case 91:
return jjStopAtPos(0, 20);
case 93:
@@ -1443,19 +1179,17 @@
case 97:
return jjMoveStringLiteralDfa1_1(0x10000000000L);
case 100:
- return jjMoveStringLiteralDfa1_1(0x4000000000000L);
+ return jjMoveStringLiteralDfa1_1(0x2000000000000L);
case 101:
return jjMoveStringLiteralDfa1_1(0x80400000000L);
case 102:
return jjMoveStringLiteralDfa1_1(0x8000L);
case 103:
return jjMoveStringLiteralDfa1_1(0x44000000L);
- case 105:
- return jjMoveStringLiteralDfa1_1(0x100000000000L);
case 108:
return jjMoveStringLiteralDfa1_1(0x110000000L);
case 109:
- return jjMoveStringLiteralDfa1_1(0x10000000000000L);
+ return jjMoveStringLiteralDfa1_1(0x8000000000000L);
case 110:
return jjMoveStringLiteralDfa1_1(0x5000010000L);
case 111:
@@ -1495,49 +1229,49 @@
return jjStopAtPos(1, 33);
} else if ((active0 & 0x800000000L) != 0L) {
return jjStopAtPos(1, 35);
- } else if ((active0 & 0x20000000000000L) != 0L) {
- return jjStopAtPos(1, 53);
+ } else if ((active0 & 0x10000000000000L) != 0L) {
+ return jjStopAtPos(1, 52);
}
break;
case 62:
- if ((active0 & 0x80000000000000L) != 0L) {
- return jjStopAtPos(1, 55);
+ if ((active0 & 0x40000000000000L) != 0L) {
+ return jjStopAtPos(1, 54);
}
break;
case 97:
return jjMoveStringLiteralDfa2_1(active0, 0x8000L);
case 101:
if ((active0 & 0x40000000L) != 0L) {
- return jjStartNfaWithStates_1(1, 30, 30);
+ return jjStartNfaWithStates_1(1, 30, 16);
} else if ((active0 & 0x100000000L) != 0L) {
- return jjStartNfaWithStates_1(1, 32, 30);
+ return jjStartNfaWithStates_1(1, 32, 16);
} else if ((active0 & 0x1000000000L) != 0L) {
- return jjStartNfaWithStates_1(1, 36, 30);
+ return jjStartNfaWithStates_1(1, 36, 16);
}
break;
case 105:
- return jjMoveStringLiteralDfa2_1(active0, 0x4000000000000L);
+ return jjMoveStringLiteralDfa2_1(active0, 0x2000000000000L);
case 109:
return jjMoveStringLiteralDfa2_1(active0, 0x80000000000L);
case 110:
- return jjMoveStringLiteralDfa2_1(active0, 0x110000000000L);
+ return jjMoveStringLiteralDfa2_1(active0, 0x10000000000L);
case 111:
- return jjMoveStringLiteralDfa2_1(active0, 0x10004000000000L);
+ return jjMoveStringLiteralDfa2_1(active0, 0x8004000000000L);
case 113:
if ((active0 & 0x400000000L) != 0L) {
- return jjStartNfaWithStates_1(1, 34, 30);
+ return jjStartNfaWithStates_1(1, 34, 16);
}
break;
case 114:
if ((active0 & 0x40000000000L) != 0L) {
- return jjStartNfaWithStates_1(1, 42, 30);
+ return jjStartNfaWithStates_1(1, 42, 16);
}
return jjMoveStringLiteralDfa2_1(active0, 0x4000L);
case 116:
if ((active0 & 0x4000000L) != 0L) {
- return jjStartNfaWithStates_1(1, 26, 30);
+ return jjStartNfaWithStates_1(1, 26, 16);
} else if ((active0 & 0x10000000L) != 0L) {
- return jjStartNfaWithStates_1(1, 28, 30);
+ return jjStartNfaWithStates_1(1, 28, 16);
}
break;
case 117:
@@ -1566,27 +1300,25 @@
switch (curChar) {
case 100:
if ((active0 & 0x10000000000L) != 0L) {
- return jjStartNfaWithStates_1(2, 40, 30);
- } else if ((active0 & 0x10000000000000L) != 0L) {
- return jjStartNfaWithStates_1(2, 52, 30);
+ return jjStartNfaWithStates_1(2, 40, 16);
+ } else if ((active0 & 0x8000000000000L) != 0L) {
+ return jjStartNfaWithStates_1(2, 51, 16);
}
break;
case 108:
return jjMoveStringLiteralDfa3_1(active0, 0x18000L);
case 112:
return jjMoveStringLiteralDfa3_1(active0, 0x80000000000L);
- case 115:
- return jjMoveStringLiteralDfa3_1(active0, 0x100000000000L);
case 116:
if ((active0 & 0x4000000000L) != 0L) {
- return jjStartNfaWithStates_1(2, 38, 30);
+ return jjStartNfaWithStates_1(2, 38, 16);
}
break;
case 117:
return jjMoveStringLiteralDfa3_1(active0, 0x4000L);
case 118:
- if ((active0 & 0x4000000000000L) != 0L) {
- return jjStartNfaWithStates_1(2, 50, 30);
+ if ((active0 & 0x2000000000000L) != 0L) {
+ return jjStartNfaWithStates_1(2, 49, 16);
}
break;
default:
@@ -1608,18 +1340,18 @@
switch (curChar) {
case 101:
if ((active0 & 0x4000L) != 0L) {
- return jjStartNfaWithStates_1(3, 14, 30);
+ return jjStartNfaWithStates_1(3, 14, 16);
}
break;
case 108:
if ((active0 & 0x10000L) != 0L) {
- return jjStartNfaWithStates_1(3, 16, 30);
+ return jjStartNfaWithStates_1(3, 16, 16);
}
break;
case 115:
return jjMoveStringLiteralDfa4_1(active0, 0x8000L);
case 116:
- return jjMoveStringLiteralDfa4_1(active0, 0x180000000000L);
+ return jjMoveStringLiteralDfa4_1(active0, 0x80000000000L);
default:
break;
}
@@ -1637,16 +1369,14 @@
return 4;
}
switch (curChar) {
- case 97:
- return jjMoveStringLiteralDfa5_1(active0, 0x100000000000L);
case 101:
if ((active0 & 0x8000L) != 0L) {
- return jjStartNfaWithStates_1(4, 15, 30);
+ return jjStartNfaWithStates_1(4, 15, 16);
}
break;
case 121:
if ((active0 & 0x80000000000L) != 0L) {
- return jjStartNfaWithStates_1(4, 43, 30);
+ return jjStartNfaWithStates_1(4, 43, 16);
}
break;
default:
@@ -1655,104 +1385,6 @@
return jjStartNfa_1(3, active0);
}
- private int jjMoveStringLiteralDfa5_1(long old0, long active0) {
- if (((active0 &= old0)) == 0L) {
- return jjStartNfa_1(3, old0);
- }
- try {
- curChar = input_stream.readChar();
- } catch (java.io.IOException e) {
- jjStopStringLiteralDfa_1(4, active0);
- return 5;
- }
- switch (curChar) {
- case 110:
- return jjMoveStringLiteralDfa6_1(active0, 0x100000000000L);
- default:
- break;
- }
- return jjStartNfa_1(4, active0);
- }
-
- private int jjMoveStringLiteralDfa6_1(long old0, long active0) {
- if (((active0 &= old0)) == 0L) {
- return jjStartNfa_1(4, old0);
- }
- try {
- curChar = input_stream.readChar();
- } catch (java.io.IOException e) {
- jjStopStringLiteralDfa_1(5, active0);
- return 6;
- }
- switch (curChar) {
- case 99:
- return jjMoveStringLiteralDfa7_1(active0, 0x100000000000L);
- default:
- break;
- }
- return jjStartNfa_1(5, active0);
- }
-
- private int jjMoveStringLiteralDfa7_1(long old0, long active0) {
- if (((active0 &= old0)) == 0L) {
- return jjStartNfa_1(5, old0);
- }
- try {
- curChar = input_stream.readChar();
- } catch (java.io.IOException e) {
- jjStopStringLiteralDfa_1(6, active0);
- return 7;
- }
- switch (curChar) {
- case 101:
- return jjMoveStringLiteralDfa8_1(active0, 0x100000000000L);
- default:
- break;
- }
- return jjStartNfa_1(6, active0);
- }
-
- private int jjMoveStringLiteralDfa8_1(long old0, long active0) {
- if (((active0 &= old0)) == 0L) {
- return jjStartNfa_1(6, old0);
- }
- try {
- curChar = input_stream.readChar();
- } catch (java.io.IOException e) {
- jjStopStringLiteralDfa_1(7, active0);
- return 8;
- }
- switch (curChar) {
- case 111:
- return jjMoveStringLiteralDfa9_1(active0, 0x100000000000L);
- default:
- break;
- }
- return jjStartNfa_1(7, active0);
- }
-
- private int jjMoveStringLiteralDfa9_1(long old0, long active0) {
- if (((active0 &= old0)) == 0L) {
- return jjStartNfa_1(7, old0);
- }
- try {
- curChar = input_stream.readChar();
- } catch (java.io.IOException e) {
- jjStopStringLiteralDfa_1(8, active0);
- return 9;
- }
- switch (curChar) {
- case 102:
- if ((active0 & 0x100000000000L) != 0L) {
- return jjStartNfaWithStates_1(9, 44, 30);
- }
- break;
- default:
- break;
- }
- return jjStartNfa_1(8, active0);
- }
-
private int jjStartNfaWithStates_1(int pos, int kind, int state) {
jjmatchedKind = kind;
jjmatchedPos = pos;
@@ -1766,7 +1398,7 @@
private int jjMoveNfa_1(int startState, int curPos) {
int startsAt = 0;
- jjnewStateCnt = 30;
+ jjnewStateCnt = 29;
int i = 1;
jjstateSet[0] = startState;
int kind = 0x7fffffff;
@@ -1786,12 +1418,12 @@
{
jjCheckNAddStates(18, 22);
}
- } else if ((0x1800000000L & l) != 0L) {
- if (kind > 56) {
- kind = 56;
+ } else if (curChar == 36) {
+ if (kind > 55) {
+ kind = 55;
}
{
- jjCheckNAddTwoStates(28, 29);
+ jjCheckNAdd(16);
}
} else if (curChar == 39) {
jjCheckNAddStates(23, 25);
@@ -1801,24 +1433,6 @@
jjCheckNAdd(1);
}
break;
- case 30:
- if ((0x3ff00100fffc1ffL & l) != 0L) {
- if (kind > 57) {
- kind = 57;
- }
- {
- jjCheckNAdd(29);
- }
- }
- if ((0x3ff00100fffc1ffL & l) != 0L) {
- if (kind > 56) {
- kind = 56;
- }
- {
- jjCheckNAdd(28);
- }
- }
- break;
case 1:
if ((0x3ff000000000000L & l) == 0L) {
break;
@@ -1885,6 +1499,26 @@
}
break;
case 15:
+ if (curChar != 36) {
+ break;
+ }
+ if (kind > 55) {
+ kind = 55;
+ } {
+ jjCheckNAdd(16);
+ }
+ break;
+ case 16:
+ if ((0x3ff00100fffc1ffL & l) == 0L) {
+ break;
+ }
+ if (kind > 55) {
+ kind = 55;
+ } {
+ jjCheckNAdd(16);
+ }
+ break;
+ case 17:
if ((0x3ff000000000000L & l) == 0L) {
break;
}
@@ -1894,106 +1528,76 @@
jjCheckNAddStates(18, 22);
}
break;
- case 16:
+ case 18:
if ((0x3ff000000000000L & l) == 0L) {
break;
}
if (kind > 10) {
kind = 10;
} {
- jjCheckNAdd(16);
+ jjCheckNAdd(18);
}
break;
- case 17:
+ case 19:
if ((0x3ff000000000000L & l) != 0L) {
- jjCheckNAddTwoStates(17, 18);
+ jjCheckNAddTwoStates(19, 20);
}
break;
- case 18:
+ case 20:
if (curChar != 46) {
break;
}
if (kind > 11) {
kind = 11;
} {
- jjCheckNAddTwoStates(19, 20);
+ jjCheckNAddTwoStates(21, 22);
}
break;
- case 19:
+ case 21:
if ((0x3ff000000000000L & l) == 0L) {
break;
}
if (kind > 11) {
kind = 11;
} {
- jjCheckNAddTwoStates(19, 20);
+ jjCheckNAddTwoStates(21, 22);
}
break;
- case 21:
+ case 23:
if ((0x280000000000L & l) != 0L) {
- jjCheckNAdd(22);
+ jjCheckNAdd(24);
}
break;
- case 22:
+ case 24:
if ((0x3ff000000000000L & l) == 0L) {
break;
}
if (kind > 11) {
kind = 11;
} {
- jjCheckNAdd(22);
+ jjCheckNAdd(24);
}
break;
- case 23:
+ case 25:
if ((0x3ff000000000000L & l) != 0L) {
- jjCheckNAddTwoStates(23, 24);
+ jjCheckNAddTwoStates(25, 26);
}
break;
- case 25:
+ case 27:
if ((0x280000000000L & l) != 0L) {
- jjCheckNAdd(26);
+ jjCheckNAdd(28);
}
break;
- case 26:
+ case 28:
if ((0x3ff000000000000L & l) == 0L) {
break;
}
if (kind > 11) {
kind = 11;
} {
- jjCheckNAdd(26);
- }
- break;
- case 27:
- if ((0x1800000000L & l) == 0L) {
- break;
- }
- if (kind > 56) {
- kind = 56;
- } {
- jjCheckNAddTwoStates(28, 29);
- }
- break;
- case 28:
- if ((0x3ff00100fffc1ffL & l) == 0L) {
- break;
- }
- if (kind > 56) {
- kind = 56;
- } {
jjCheckNAdd(28);
}
break;
- case 29:
- if ((0x3ff00100fffc1ffL & l) == 0L) {
- break;
- }
- if (kind > 57) {
- kind = 57;
- } {
- jjCheckNAdd(29);
- }
- break;
default:
break;
}
@@ -2006,30 +1610,12 @@
if ((0x7fffffe87fffffeL & l) == 0L) {
break;
}
- if (kind > 56) {
- kind = 56;
+ if (kind > 55) {
+ kind = 55;
} {
- jjCheckNAddTwoStates(28, 29);
+ jjCheckNAdd(16);
}
break;
- case 30:
- if ((0x87fffffe87fffffeL & l) != 0L) {
- if (kind > 57) {
- kind = 57;
- }
- {
- jjCheckNAdd(29);
- }
- }
- if ((0x87fffffe87fffffeL & l) != 0L) {
- if (kind > 56) {
- kind = 56;
- }
- {
- jjCheckNAdd(28);
- }
- }
- break;
case 2:
if ((0x2000000020L & l) != 0L) {
jjAddStates(29, 30);
@@ -2065,35 +1651,25 @@
jjCheckNAddStates(23, 25);
}
break;
- case 20:
- if ((0x2000000020L & l) != 0L) {
- jjAddStates(31, 32);
- }
- break;
- case 24:
- if ((0x2000000020L & l) != 0L) {
- jjAddStates(33, 34);
- }
- break;
- case 28:
+ case 16:
if ((0x87fffffe87fffffeL & l) == 0L) {
break;
}
- if (kind > 56) {
- kind = 56;
+ if (kind > 55) {
+ kind = 55;
} {
- jjCheckNAdd(28);
+ jjCheckNAdd(16);
}
break;
- case 29:
- if ((0x87fffffe87fffffeL & l) == 0L) {
- break;
+ case 22:
+ if ((0x2000000020L & l) != 0L) {
+ jjAddStates(31, 32);
+ }
+ break;
+ case 26:
+ if ((0x2000000020L & l) != 0L) {
+ jjAddStates(33, 34);
}
- if (kind > 57) {
- kind = 57;
- } {
- jjCheckNAdd(29);
- }
break;
default:
break;
@@ -2111,30 +1687,12 @@
if (!jjCanMove_1(hiByte, i1, i2, l1, l2)) {
break;
}
- if (kind > 56) {
- kind = 56;
+ if (kind > 55) {
+ kind = 55;
} {
- jjCheckNAddTwoStates(28, 29);
+ jjCheckNAdd(16);
}
break;
- case 30:
- if (jjCanMove_2(hiByte, i1, i2, l1, l2)) {
- if (kind > 56) {
- kind = 56;
- }
- {
- jjCheckNAdd(28);
- }
- }
- if (jjCanMove_2(hiByte, i1, i2, l1, l2)) {
- if (kind > 57) {
- kind = 57;
- }
- {
- jjCheckNAdd(29);
- }
- }
- break;
case 6:
if (jjCanMove_0(hiByte, i1, i2, l1, l2)) {
jjAddStates(26, 28);
@@ -2145,24 +1703,14 @@
jjAddStates(23, 25);
}
break;
- case 28:
- if (!jjCanMove_2(hiByte, i1, i2, l1, l2)) {
- break;
- }
- if (kind > 56) {
- kind = 56;
- } {
- jjCheckNAdd(28);
- }
- break;
- case 29:
+ case 16:
if (!jjCanMove_2(hiByte, i1, i2, l1, l2)) {
break;
}
- if (kind > 57) {
- kind = 57;
+ if (kind > 55) {
+ kind = 55;
} {
- jjCheckNAdd(29);
+ jjCheckNAdd(16);
}
break;
default:
@@ -2180,7 +1728,7 @@
kind = 0x7fffffff;
}
++curPos;
- if ((i = jjnewStateCnt) == (startsAt = 30 - (jjnewStateCnt = startsAt))) {
+ if ((i = jjnewStateCnt) == (startsAt = 29 - (jjnewStateCnt = startsAt))) {
return curPos;
}
try {
@@ -2196,9 +1744,8 @@
"\175", null, null, null, null, "\164\162\165\145", "\146\141\154\163\145", "\156\165\154\154", "\56",
"\50", "\51", "\133", "\135", "\72", "\73", "\54", "\76", "\147\164", "\74", "\154\164", "\76\75",
"\147\145", "\74\75", "\154\145", "\75\75", "\145\161", "\41\75", "\156\145", "\41", "\156\157\164",
- "\46\46", "\141\156\144", "\174\174", "\157\162", "\145\155\160\164\171",
- "\151\156\163\164\141\156\143\145\157\146", "\52", "\53", "\55", "\77", "\57", "\144\151\166", "\45",
- "\155\157\144", "\53\75", "\75", "\55\76", null, null, null, null, null, null, };
+ "\46\46", "\141\156\144", "\174\174", "\157\162", "\145\155\160\164\171", "\52", "\53", "\55", "\77", "\57",
+ "\144\151\166", "\45", "\155\157\144", "\53\75", "\75", "\55\76", null, null, null, null, };
protected Token jjFillToken() {
final Token t;
@@ -2223,8 +1770,8 @@
return t;
}
- static final int[] jjnextStates = { 0, 1, 3, 4, 2, 0, 1, 4, 2, 0, 1, 4, 5, 2, 0, 1, 2, 6, 16, 17, 18, 23, 24, 11,
- 12, 14, 6, 7, 9, 3, 4, 21, 22, 25, 26, };
+ static final int[] jjnextStates = { 0, 1, 3, 4, 2, 0, 1, 4, 2, 0, 1, 4, 5, 2, 0, 1, 2, 6, 18, 19, 20, 25, 26, 11,
+ 12, 14, 6, 7, 9, 3, 4, 23, 24, 27, 28, };
private static final boolean jjCanMove_0(int hiByte, int i1, int i2, long l1, long l2) {
switch (hiByte) {
@@ -2473,7 +2020,8 @@
Token matchedToken;
int curPos = 0;
- EOFLoop: for (;;) {
+ EOFLoop:
+ for (;;) {
try {
curChar = input_stream.BeginToken();
} catch (Exception e) {
@@ -2504,8 +2052,8 @@
jjmatchedKind = 0x7fffffff;
jjmatchedPos = 0;
curPos = jjMoveStringLiteralDfa0_1();
- if (jjmatchedPos == 0 && jjmatchedKind > 61) {
- jjmatchedKind = 61;
+ if (jjmatchedPos == 0 && jjmatchedKind > 58) {
+ jjmatchedKind = 58;
}
break;
case 2:
@@ -2520,8 +2068,8 @@
jjmatchedKind = 0x7fffffff;
jjmatchedPos = 0;
curPos = jjMoveStringLiteralDfa0_2();
- if (jjmatchedPos == 0 && jjmatchedKind > 61) {
- jjmatchedKind = 61;
+ if (jjmatchedPos == 0 && jjmatchedKind > 58) {
+ jjmatchedKind = 58;
}
break;
}
@@ -2665,7 +2213,7 @@
private void ReInitRounds() {
int i;
jjround = 0x80000001;
- for (i = 30; i-- > 0;) {
+ for (i = 29; i-- > 0;) {
jjrounds[i] = 0x80000000;
}
}
@@ -2695,15 +2243,15 @@
/** Lex State array. */
public static final int[] jjnewLexState = { -1, -1, 1, 1, -1, -1, -1, -1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, };
- static final long[] jjtoToken = { 0x23ffffffffffef0fL, };
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, };
+ static final long[] jjtoToken = { 0x4ffffffffffef0fL, };
static final long[] jjtoSkip = { 0xf0L, };
static final long[] jjtoSpecial = { 0x0L, };
static final long[] jjtoMore = { 0x0L, };
protected SimpleCharStream input_stream;
- private final int[] jjrounds = new int[30];
- private final int[] jjstateSet = new int[2 * 30];
+ private final int[] jjrounds = new int[29];
+ private final int[] jjstateSet = new int[2 * 29];
private final StringBuilder jjimage = new StringBuilder();
private StringBuilder image = jjimage;
private int jjimageLen;
diff -Nru tomcat11-11.0.6/java/org/apache/el/parser/Node.java tomcat11-11.0.15/java/org/apache/el/parser/Node.java
--- tomcat11-11.0.6/java/org/apache/el/parser/Node.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/el/parser/Node.java 2025-12-02 16:54:08.000000000 +0000
@@ -29,10 +29,6 @@
/* All AST nodes must implement this interface. It provides basic
machinery for constructing the parent and child relationships
between nodes. */
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- */
@SuppressWarnings("all") // Ignore warnings in generated code
public interface Node {
diff -Nru tomcat11-11.0.6/java/org/apache/el/parser/NodeVisitor.java tomcat11-11.0.15/java/org/apache/el/parser/NodeVisitor.java
--- tomcat11-11.0.6/java/org/apache/el/parser/NodeVisitor.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/el/parser/NodeVisitor.java 2025-12-02 16:54:08.000000000 +0000
@@ -16,9 +16,6 @@
*/
package org.apache.el.parser;
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- */
public interface NodeVisitor {
void visit(Node node) throws Exception;
}
diff -Nru tomcat11-11.0.6/java/org/apache/el/parser/SimpleNode.java tomcat11-11.0.15/java/org/apache/el/parser/SimpleNode.java
--- tomcat11-11.0.6/java/org/apache/el/parser/SimpleNode.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/el/parser/SimpleNode.java 2025-12-02 16:54:08.000000000 +0000
@@ -28,10 +28,6 @@
import org.apache.el.lang.EvaluationContext;
import org.apache.el.util.MessageFactory;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- */
public abstract class SimpleNode implements Node {
/*
diff -Nru tomcat11-11.0.6/java/org/apache/el/util/MessageFactory.java tomcat11-11.0.15/java/org/apache/el/util/MessageFactory.java
--- tomcat11-11.0.6/java/org/apache/el/util/MessageFactory.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/el/util/MessageFactory.java 2025-12-02 16:54:08.000000000 +0000
@@ -22,9 +22,6 @@
import java.util.MissingResourceException;
import java.util.ResourceBundle;
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- */
public final class MessageFactory {
private static final ResourceBundle DEFAULT_BUNDLE = ResourceBundle.getBundle("org.apache.el.LocalStrings");
diff -Nru tomcat11-11.0.6/java/org/apache/el/util/ReflectionUtil.java tomcat11-11.0.15/java/org/apache/el/util/ReflectionUtil.java
--- tomcat11-11.0.6/java/org/apache/el/util/ReflectionUtil.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/el/util/ReflectionUtil.java 2025-12-02 16:54:08.000000000 +0000
@@ -30,11 +30,8 @@
import org.apache.el.lang.ELSupport;
import org.apache.el.lang.EvaluationContext;
-
/**
- * Utilities for Managing Serialization and Reflection
- *
- * @author Jacob Hookom [jacob@hookom.net]
+ * Utilities for Managing Serialization and Reflection.
*/
public class ReflectionUtil {
@@ -153,12 +150,20 @@
// Fast path: when no arguments exist, there can only be one matching method and no need for coercion.
if (paramCount == 0) {
+ Method result = null;
+ Throwable t = null;
try {
Method method = clazz.getMethod(methodName, paramTypes);
- return getMethod(clazz, base, method);
+ result = getMethod(clazz, base, method);
} catch (NoSuchMethodException | SecurityException e) {
- // Fall through to broader, slower logic
+ // Fall through
+ t = e;
+ }
+ if (result == null) {
+ throw new MethodNotFoundException(
+ MessageFactory.get("error.method.notfound", base, property, paramString(paramTypes)), t);
}
+ return result;
}
Method[] methods = clazz.getMethods();
@@ -494,9 +499,8 @@
/*
* This class duplicates code in jakarta.el.Util. When making changes keep the code in sync.
*/
- private record MatchResult(boolean varArgs, int exactCount, int assignableCount,
- int coercibleCount, int varArgsCount,
- boolean bridge) implements Comparable {
+ private record MatchResult(boolean varArgs, int exactCount, int assignableCount, int coercibleCount,
+ int varArgsCount, boolean bridge) implements Comparable {
@Override
public int compareTo(MatchResult o) {
@@ -532,8 +536,7 @@
((MatchResult) o).assignableCount() == this.assignableCount() &&
((MatchResult) o).coercibleCount() == this.coercibleCount() &&
((MatchResult) o).varArgsCount() == this.varArgsCount() &&
- ((MatchResult) o).varArgs() == this.varArgs() &&
- ((MatchResult) o).bridge() == this.bridge());
+ ((MatchResult) o).varArgs() == this.varArgs() && ((MatchResult) o).bridge() == this.bridge());
}
@Override
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/Constants.java tomcat11-11.0.15/java/org/apache/jasper/Constants.java
--- tomcat11-11.0.6/java/org/apache/jasper/Constants.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/Constants.java 2025-12-02 16:54:08.000000000 +0000
@@ -20,11 +20,6 @@
/**
* Some constants and other global data that are used by the compiler and the runtime.
- *
- * @author Anil K. Vijendran
- * @author Harish Prabandham
- * @author Shawn Bayern
- * @author Mark Roth
*/
public class Constants {
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/EmbeddedServletOptions.java tomcat11-11.0.15/java/org/apache/jasper/EmbeddedServletOptions.java
--- tomcat11-11.0.6/java/org/apache/jasper/EmbeddedServletOptions.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/EmbeddedServletOptions.java 2025-12-02 16:54:08.000000000 +0000
@@ -35,10 +35,6 @@
/**
* A class to hold all init parameters specific to the JSP engine.
- *
- * @author Anil K. Vijendran
- * @author Hans Bergsten
- * @author Pierre Delisle
*/
public final class EmbeddedServletOptions implements Options {
@@ -223,6 +219,8 @@
private boolean useInstanceManagerForTags = false;
+ private String useNonstandardTagOptimizations;
+
public String getProperty(String name) {
return settings.getProperty(name);
}
@@ -470,6 +468,11 @@
return useInstanceManagerForTags;
}
+ @Override
+ public String getUseNonstandardTagOptimizations() {
+ return useNonstandardTagOptimizations;
+ }
+
/**
* Create an EmbeddedServletOptions object using data available from ServletConfig and ServletContext.
*
@@ -652,6 +655,11 @@
this.classpath = classpath;
}
+ String useNonstandardTagOptimizations = config.getInitParameter("useNonstandardTagOptimizations");
+ if (useNonstandardTagOptimizations != null) {
+ this.useNonstandardTagOptimizations = useNonstandardTagOptimizations;
+ }
+
/*
* scratchdir
*/
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/JasperException.java tomcat11-11.0.15/java/org/apache/jasper/JasperException.java
--- tomcat11-11.0.6/java/org/apache/jasper/JasperException.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/JasperException.java 2025-12-02 16:54:08.000000000 +0000
@@ -20,8 +20,6 @@
/**
* Base class for all exceptions generated by the JSP engine. Makes it convenient to catch just this at the top-level.
- *
- * @author Anil K. Vijendran
*/
public class JasperException extends jakarta.servlet.ServletException {
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/JspC.java tomcat11-11.0.15/java/org/apache/jasper/JspC.java
--- tomcat11-11.0.6/java/org/apache/jasper/JspC.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/JspC.java 2025-12-02 16:54:08.000000000 +0000
@@ -86,11 +86,6 @@
* webXmlFragment="${build.dir}/generated_web.xml"
* outputDir="${webapp.dir}/${webapp.name}/WEB-INF/src/my/package" />
*
- *
- * @author Danno Ferrin
- * @author Pierre Delisle
- * @author Costin Manolache
- * @author Yoav Shapira
*/
public class JspC extends Task implements Options {
@@ -268,6 +263,8 @@
protected boolean fullstop = false;
protected String[] args;
+ protected String useNonstandardTagOptimizations;
+
public static void main(String[] arg) {
if (arg.length == 0) {
System.out.println(Localizer.getMessage("jspc.usage"));
@@ -787,7 +784,7 @@
}
try {
uriRoot = resolveFile(s).getCanonicalPath();
- } catch (Exception ex) {
+ } catch (Exception e) {
uriRoot = s;
}
}
@@ -996,6 +993,15 @@
}
/**
+ * Sets the set of custom tags to use nonstandard optimizations.
+ *
+ * @param useNonstandardTagOptimizations which tags to override
+ */
+ public void setUseNonstandardTagOptimizations(String useNonstandardTagOptimizations) {
+ this.useNonstandardTagOptimizations = useNonstandardTagOptimizations;
+ }
+
+ /**
* @return true if an exception will be thrown in case of a compilation error.
*/
public boolean getFailOnError() {
@@ -1403,7 +1409,7 @@
errorCount++;
log.error(Localizer.getMessage("jspc.error.compilation"), e);
}
- } catch (InterruptedException e) {
+ } catch (InterruptedException ignore) {
// Ignore
}
}
@@ -1507,8 +1513,8 @@
mapout.write(Localizer.getMessage("jspc.webinc.footer"));
}
mapout.close();
- } catch (IOException ioe) {
- // nothing to do if it fails since we are done with it
+ } catch (IOException ignore) {
+ // Nothing to do if it fails since we are done with it.
}
}
}
@@ -1680,7 +1686,7 @@
uriRoot = froot.getCanonicalPath();
}
}
- } catch (IOException ioe) {
+ } catch (IOException ignore) {
// Missing uriRoot will be handled in the caller.
}
}
@@ -1706,9 +1712,9 @@
FileInputStream fis = new FileInputStream(file);
try {
return webxmlEncoding != null ? new InputStreamReader(fis, webxmlEncoding) : new InputStreamReader(fis);
- } catch (IOException ex) {
+ } catch (IOException ioe) {
fis.close();
- throw ex;
+ throw ioe;
}
}
@@ -1716,12 +1722,17 @@
FileOutputStream fos = new FileOutputStream(file);
try {
return webxmlEncoding != null ? new OutputStreamWriter(fos, webxmlEncoding) : new OutputStreamWriter(fos);
- } catch (IOException ex) {
+ } catch (IOException ioe) {
fos.close();
- throw ex;
+ throw ioe;
}
}
+ @Override
+ public String getUseNonstandardTagOptimizations() {
+ return useNonstandardTagOptimizations;
+ }
+
private class ProcessFile implements Callable {
private final String file;
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/JspCompilationContext.java tomcat11-11.0.15/java/org/apache/jasper/JspCompilationContext.java
--- tomcat11-11.0.6/java/org/apache/jasper/JspCompilationContext.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/JspCompilationContext.java 2025-12-02 16:54:08.000000000 +0000
@@ -46,12 +46,6 @@
* A placeholder for various things that are used throughout the JSP engine. This is a per-request/per-context data
* structure. Some of the instance variables are set at different points. Most of the path-related stuff is here -
* mangling names, versions, dirs, loading resources and dealing with uris.
- *
- * @author Anil K. Vijendran
- * @author Harish Prabandham
- * @author Pierre Delisle
- * @author Costin Manolache
- * @author Kin-man Chung
*/
public class JspCompilationContext {
@@ -391,17 +385,17 @@
result = uc.getLastModified();
}
}
- } catch (IOException e) {
+ } catch (IOException ioe) {
if (log.isDebugEnabled()) {
- log.debug(Localizer.getMessage("jsp.error.lastModified", getJspFile()), e);
+ log.debug(Localizer.getMessage("jsp.error.lastModified", getJspFile()), ioe);
}
} finally {
if (uc != null) {
try {
uc.getInputStream().close();
- } catch (IOException e) {
+ } catch (IOException ioe) {
if (log.isDebugEnabled()) {
- log.debug(Localizer.getMessage("jsp.error.lastModified", getJspFile()), e);
+ log.debug(Localizer.getMessage("jsp.error.lastModified", getJspFile()), ioe);
}
result = -1;
}
@@ -589,7 +583,6 @@
jspCompiler.removeGeneratedFiles();
jspLoader = null;
jspCompiler.compile();
- jsw.setReload(true);
jsw.setCompilationException(null);
} catch (JasperException ex) {
// Cache compilation exception
@@ -602,11 +595,13 @@
} catch (FileNotFoundException fnfe) {
// Re-throw to let caller handle this - will result in a 404
throw fnfe;
- } catch (Exception ex) {
- JasperException je = new JasperException(Localizer.getMessage("jsp.error.unable.compile"), ex);
+ } catch (Exception e) {
+ JasperException je = new JasperException(Localizer.getMessage("jsp.error.unable.compile"), e);
// Cache compilation exception
jsw.setCompilationException(je);
throw je;
+ } finally {
+ jsw.setReload(true);
}
}
}
@@ -621,8 +616,8 @@
servletClass = jspLoader.loadClass(name);
} catch (ClassNotFoundException cex) {
throw new JasperException(Localizer.getMessage("jsp.error.unable.load"), cex);
- } catch (Exception ex) {
- throw new JasperException(Localizer.getMessage("jsp.error.unable.compile"), ex);
+ } catch (Exception e) {
+ throw new JasperException(Localizer.getMessage("jsp.error.unable.compile"), e);
}
removed = false;
return servletClass;
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/Options.java tomcat11-11.0.15/java/org/apache/jasper/Options.java
--- tomcat11-11.0.6/java/org/apache/jasper/Options.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/Options.java 2025-12-02 16:54:08.000000000 +0000
@@ -27,10 +27,6 @@
/**
* A class to hold all init parameters specific to the JSP engine.
- *
- * @author Anil K. Vijendran
- * @author Hans Bergsten
- * @author Pierre Delisle
*/
public interface Options {
@@ -342,4 +338,12 @@
default boolean getGeneratedJavaAddTimestamp() {
return true;
}
+
+ /**
+ * A string containing a comma-separated list of names to which custom tag implementations should be applied.
+ * Unknown or unused tag entries are harmless. Generally defined via an init parameter on the JspServlet.
+ *
+ * @return which tags to use
+ */
+ String getUseNonstandardTagOptimizations();
}
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/compiler/AntCompiler.java tomcat11-11.0.15/java/org/apache/jasper/compiler/AntCompiler.java
--- tomcat11-11.0.6/java/org/apache/jasper/compiler/AntCompiler.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/compiler/AntCompiler.java 2025-12-02 16:54:08.000000000 +0000
@@ -37,13 +37,6 @@
/**
* Main JSP compiler class. This class uses Ant for compiling.
- *
- * @author Anil K. Vijendran
- * @author Mandar Raje
- * @author Pierre Delisle
- * @author Kin-man Chung
- * @author Remy Maucherat
- * @author Mark Roth
*/
public class AntCompiler extends Compiler {
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/compiler/BeanRepository.java tomcat11-11.0.15/java/org/apache/jasper/compiler/BeanRepository.java
--- tomcat11-11.0.6/java/org/apache/jasper/compiler/BeanRepository.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/compiler/BeanRepository.java 2025-12-02 16:54:08.000000000 +0000
@@ -23,9 +23,6 @@
/**
* Repository of {page, request, session, application}-scoped beans
- *
- * @author Mandar Raje
- * @author Remy Maucherat
*/
public class BeanRepository {
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/compiler/Collector.java tomcat11-11.0.15/java/org/apache/jasper/compiler/Collector.java
--- tomcat11-11.0.6/java/org/apache/jasper/compiler/Collector.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/compiler/Collector.java 2025-12-02 16:54:08.000000000 +0000
@@ -20,11 +20,7 @@
/**
* Collect info about the page and nodes, and make them available through the PageInfo object.
- *
- * @author Kin-man Chung
- * @author Mark Roth
*/
-
class Collector {
/**
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/compiler/Compiler.java tomcat11-11.0.15/java/org/apache/jasper/compiler/Compiler.java
--- tomcat11-11.0.6/java/org/apache/jasper/compiler/Compiler.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/compiler/Compiler.java 2025-12-02 16:54:08.000000000 +0000
@@ -41,13 +41,6 @@
/**
* Main JSP compiler class. This class uses Ant for compiling.
- *
- * @author Anil K. Vijendran
- * @author Mandar Raje
- * @author Pierre Delisle
- * @author Kin-man Chung
- * @author Remy Maucherat
- * @author Mark Roth
*/
public abstract class Compiler {
@@ -427,8 +420,8 @@
if (jsw != null && (ctxt.getOptions().getModificationTestInterval() > 0)) {
- if (jsw.getLastModificationTest() +
- (ctxt.getOptions().getModificationTestInterval() * 1000L) > System.currentTimeMillis()) {
+ if (jsw.getLastModificationTest() + (ctxt.getOptions().getModificationTestInterval() * 1000L) > System
+ .currentTimeMillis()) {
return false;
}
jsw.setLastModificationTest(System.currentTimeMillis());
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/compiler/DefaultErrorHandler.java tomcat11-11.0.15/java/org/apache/jasper/compiler/DefaultErrorHandler.java
--- tomcat11-11.0.6/java/org/apache/jasper/compiler/DefaultErrorHandler.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/compiler/DefaultErrorHandler.java 2025-12-02 16:54:08.000000000 +0000
@@ -20,8 +20,6 @@
/**
* Default implementation of ErrorHandler interface.
- *
- * @author Jan Luehe
*/
class DefaultErrorHandler implements ErrorHandler {
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/compiler/ELFunctionMapper.java tomcat11-11.0.15/java/org/apache/jasper/compiler/ELFunctionMapper.java
--- tomcat11-11.0.6/java/org/apache/jasper/compiler/ELFunctionMapper.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/compiler/ELFunctionMapper.java 2025-12-02 16:54:08.000000000 +0000
@@ -30,8 +30,6 @@
/**
* This class generates functions mappers for the EL expressions in the page. Instead of a global mapper, a mapper is
* used for each call to EL evaluator, thus avoiding the prefix overlapping and redefinition issues.
- *
- * @author Kin-man Chung
*/
public class ELFunctionMapper {
@@ -187,7 +185,8 @@
// Generate declaration for the map statically
decName = getMapName();
- ss.append("private static org.apache.jasper.runtime.ProtectedFunctionMapper ").append(decName).append(";\n");
+ ss.append("private static org.apache.jasper.runtime.ProtectedFunctionMapper ").append(decName)
+ .append(";\n");
ds.append(" ").append(decName).append("= ");
ds.append("org.apache.jasper.runtime.ProtectedFunctionMapper");
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/compiler/ELNode.java tomcat11-11.0.15/java/org/apache/jasper/compiler/ELNode.java
--- tomcat11-11.0.6/java/org/apache/jasper/compiler/ELNode.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/compiler/ELNode.java 2025-12-02 16:54:08.000000000 +0000
@@ -27,10 +27,7 @@
/**
* This class defines internal representation for an EL Expression. It currently only defines functions. It can be
* expanded to define all the components of an EL expression, if need to.
- *
- * @author Kin-man Chung
*/
-
public abstract class ELNode {
public abstract void accept(Visitor v) throws JasperException;
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/compiler/ELParser.java tomcat11-11.0.15/java/org/apache/jasper/compiler/ELParser.java
--- tomcat11-11.0.6/java/org/apache/jasper/compiler/ELParser.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/compiler/ELParser.java 2025-12-02 16:54:08.000000000 +0000
@@ -25,10 +25,7 @@
/**
* This class implements a parser for EL expressions. It takes strings of the form xxx${..}yyy${..}zzz etc, and turn it
* into a ELNode.Nodes. Currently, it only handles text outside ${..} and functions in ${ ..}.
- *
- * @author Kin-man Chung
*/
-
public class ELParser {
private Token curToken; // current token
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/compiler/ErrorDispatcher.java tomcat11-11.0.15/java/org/apache/jasper/compiler/ErrorDispatcher.java
--- tomcat11-11.0.6/java/org/apache/jasper/compiler/ErrorDispatcher.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/compiler/ErrorDispatcher.java 2025-12-02 16:54:08.000000000 +0000
@@ -36,9 +36,6 @@
*
* In the case of a Java compilation error, the compiler error message is parsed into an array of JavacErrorDetail
* instances, which is passed on to the configured error handler.
- *
- * @author Jan Luehe
- * @author Kin-man Chung
*/
public class ErrorDispatcher {
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/compiler/ErrorHandler.java tomcat11-11.0.15/java/org/apache/jasper/compiler/ErrorHandler.java
--- tomcat11-11.0.6/java/org/apache/jasper/compiler/ErrorHandler.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/compiler/ErrorHandler.java 2025-12-02 16:54:08.000000000 +0000
@@ -22,14 +22,14 @@
* Interface for handling JSP parse and javac compilation errors. An implementation of this interface may be registered
* with the ErrorDispatcher by setting the XXX initialization parameter in the JSP page compiler and execution servlet
* in Catalina's web.xml file to the implementation's fully qualified class name.
- *
- * @author Jan Luehe
- * @author Kin-man Chung
*/
public interface ErrorHandler {
/**
* Processes the given JSP parse error.
+ *
+ * It is expected (and Jasper is coded based on this) that calls to this method will always result in a
+ * {@code JasperException} being thrown.
*
* @param fname Name of the JSP file in which the parse error occurred
* @param line Parse error line number
@@ -43,6 +43,9 @@
/**
* Processes the given JSP parse error.
+ *
+ * It is expected (and Jasper is coded based on this) that calls to this method will always result in a
+ * {@code JasperException} being thrown.
*
* @param msg Parse error message
* @param exception Parse exception
@@ -53,6 +56,9 @@
/**
* Processes the given javac compilation errors.
+ *
+ * It is expected (and Jasper is coded based on this) that calls to this method will always result in a
+ * {@code JasperException} being thrown.
*
* @param details Array of JavacErrorDetail instances corresponding to the compilation errors
*
@@ -62,6 +68,9 @@
/**
* Processes the given javac error report and exception.
+ *
+ * It is expected (and Jasper is coded based on this) that calls to this method will always result in a
+ * {@code JasperException} being thrown.
*
* @param errorReport Compilation error report
* @param exception Compilation exception
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/compiler/Generator.java tomcat11-11.0.15/java/org/apache/jasper/compiler/Generator.java
--- tomcat11-11.0.6/java/org/apache/jasper/compiler/Generator.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/compiler/Generator.java 2025-12-02 16:54:08.000000000 +0000
@@ -51,16 +51,13 @@
import org.apache.jasper.JspCompilationContext;
import org.apache.jasper.TrimSpacesOption;
import org.apache.jasper.compiler.Node.ChildInfoBase;
+import org.apache.jasper.compiler.Node.JspAttribute;
import org.apache.jasper.compiler.Node.NamedAttribute;
import org.apache.jasper.runtime.JspRuntimeLibrary;
import org.xml.sax.Attributes;
/**
- * Generate Java source from Nodes
- *
- * @author Anil K. Vijendran, Danno Ferrin, Mandar Raje, Rajiv Mordani, Pierre Delisle
- * @author Tomcat 4.1.x and Tomcat 5: Kin-man Chung, Jan Luehe, Shawn Bayern, Mark Roth, Denis Benoit
- * @author Tomcat 6.x: Jacob Hookom, Remy Maucherat
+ * Generate Java source from Nodes.
*/
class Generator {
@@ -70,6 +67,8 @@
private static final Pattern BLANK_LINE_PATTERN = Pattern.compile("(\\s*(\\n|\\r)+\\s*)");
+ private static final String CORE_LIBS_URI = "http://java.sun.com/jsp/jstl/core";
+
private final ServletWriter out;
private final ArrayList methodsBuffered;
@@ -102,6 +101,8 @@
private final ELInterpreter elInterpreter;
+ private final Set nonstandardCustomTagNames;
+
private final StringInterpreter stringInterpreter;
/**
@@ -1480,6 +1481,9 @@
@Override
public void visit(Node.CustomTag n) throws JasperException {
+ if (visitPotentiallyNonstandardCustomTag(n)) {
+ return;
+ }
// Use plugin to generate more efficient code if there is one.
if (n.useTagPlugin()) {
@@ -1736,7 +1740,7 @@
nvp = " + \" " + jspAttribute.getName() + "=\\\"\" + " + value + " + \"\\\"\"";
} else {
nvp = " + (java.lang.Boolean.valueOf(" + omit + ")?\"\":\" " + jspAttribute.getName() +
- "=\\\"\" + " + value + " + \"\\\"\")";
+ "=\\\"\" + " + value + " + \"\\\"\")";
}
} else {
value = attributeValue(jspAttribute, false, Object.class);
@@ -3028,6 +3032,216 @@
return varName;
}
+
+ /**
+ * Determines whether a tag should be handled via nonstandard code (typically faster). Considers both
+ * configuration and level of support within Tomcat.
+ *
+ * Note that Tomcat is free to ignore any case it cannot handle, as long as it reports it accurately to the
+ * caller by returning false. For example, the initial implementation for c:set excludes support for body
+ * content. c:set tags with body content will be generated with the standard code and tags without body content
+ * will be generated via non-standard code.
+ *
+ * @param n tag
+ * @param jspAttributes jsp attributes
+ *
+ * @return whether code was generated
+ *
+ * @throws JasperException unexpected error
+ */
+ private boolean visitPotentiallyNonstandardCustomTag(Node.CustomTag n) throws JasperException {
+ if (!nonstandardCustomTagNames.contains(n.getQName())) {
+ // tag is not configured, move along
+ return false;
+ }
+
+ // collect the attributes into one Map for further checks
+ Map jspAttributes = new HashMap<>();
+ if (n.getJspAttributes() != null) {
+ for (JspAttribute jspAttr : n.getJspAttributes()) {
+ jspAttributes.put(jspAttr.getLocalName(), jspAttr);
+ }
+ }
+ switch (n.qName) {
+ case "c:set":
+ // requires var and value, scope is optional, body is prohibited, value cannot be deferred
+ if (n.hasEmptyBody() && jspAttributes.containsKey("var") && jspAttributes.containsKey("value") &&
+ CORE_LIBS_URI.equals(n.getURI())) {
+ // verify value is not a deferred expression
+ String valueText = jspAttributes.get("value").getValue();
+ if (valueText.startsWith("#")) {
+ return false;
+ } else if (jspAttributes.size() == 2 ||
+ (jspAttributes.size() == 3 && jspAttributes.containsKey("scope"))) {
+ generateNonstandardSetLogic(n, jspAttributes);
+ return true;
+ }
+ }
+ break;
+ case "c:remove":
+ // requires var, scope is optional, body is prohibited
+ if (n.hasEmptyBody() && jspAttributes.containsKey("var") && CORE_LIBS_URI.equals(n.getURI()) &&
+ (jspAttributes.size() == 1 ||
+ (jspAttributes.size() == 2 && jspAttributes.containsKey("scope")))) {
+ generateNonstandardRemoveLogic(n, jspAttributes);
+ return true;
+
+ }
+ break;
+ default:
+ // This indicates someone configured a tag with no non-standard implementation.
+ // Harmless, fall back to the standard implementation.
+ }
+ return false;
+ }
+
+ private void generateNonstandardSetLogic(Node.CustomTag n, Map jspAttributes)
+ throws JasperException {
+ String baseVar = createTagVarName(n.getQName(), n.getPrefix(), n.getLocalName());
+ String tagMethod = "_jspx_meth_" + baseVar;
+ ServletWriter outSave = out;
+
+ // generate method call
+ out.printin(tagMethod);
+ out.print("(");
+ out.print("_jspx_page_context");
+ out.println(");");
+ GenBuffer genBuffer = new GenBuffer(n, n.getBody());
+ methodsBuffered.add(genBuffer);
+ out = genBuffer.getOut();
+
+ // Generate code for method declaration
+ methodNesting++;
+ out.println();
+ out.pushIndent();
+ out.printin("private void ");
+ out.print(tagMethod);
+ out.println("(jakarta.servlet.jsp.PageContext _jspx_page_context)");
+ out.printil(" throws java.lang.Throwable {");
+ out.pushIndent();
+ // Generated body of method
+ out.printil("// " + n.getQName());
+
+ JspAttribute varAttribute = jspAttributes.get("var");
+ Mark m = n.getStart();
+ out.printil("// " + m.getFile() + "(" + m.getLineNumber() + "," + m.getColumnNumber() + ") " +
+ varAttribute.getTagAttributeInfo());
+
+ JspAttribute valueAttribute = jspAttributes.get("value");
+ m = n.getStart();
+ out.printil("// " + m.getFile() + "(" + m.getLineNumber() + "," + m.getColumnNumber() + ") " +
+ valueAttribute.getTagAttributeInfo());
+
+ String varValue = varAttribute.getValue();
+
+ // get the scope constant at compile-time, where blank means page
+ String scopeValue = translateScopeToConstant(jspAttributes);
+
+ // translates the specified value attributes into EL-interpretation code using standard logic
+ String evaluatedAttribute = evaluateAttribute(getTagHandlerInfo(n), valueAttribute, n, null);
+
+ // call the multi-line logic equivalent of SetTag
+ out.printil("org.apache.jasper.runtime.JspRuntimeLibrary.nonstandardSetTag(_jspx_page_context, \"" +
+ varValue + "\", " + evaluatedAttribute + ", " + scopeValue + ");");
+
+ // Generate end of method
+ out.popIndent();
+ out.printil("}");
+ out.popIndent();
+
+ methodNesting--;
+ // restore previous writer
+ out = outSave;
+ }
+
+ /**
+ * Compile-time translation of the scope variable into the constant equivalent. Avoids runtime evaluation as
+ * performed by SetTag. Unspecified scope means page.
+ *
+ * @param jspAttributes attributes
+ *
+ * @return equivalent constant from PageContext
+ */
+ private String translateScopeToConstant(Map jspAttributes) {
+ String scopeValue;
+ JspAttribute scopeAttribute = jspAttributes.get("scope");
+ if (scopeAttribute == null) {
+ scopeValue = "jakarta.servlet.jsp.PageContext.PAGE_SCOPE";
+ } else {
+ switch (scopeAttribute.getValue()) {
+ case "":
+ case "page":
+ scopeValue = "jakarta.servlet.jsp.PageContext.PAGE_SCOPE";
+ break;
+ case "request":
+ scopeValue = "jakarta.servlet.jsp.PageContext.REQUEST_SCOPE";
+ break;
+ case "session":
+ scopeValue = "jakarta.servlet.jsp.PageContext.SESSION_SCOPE";
+ break;
+ case "application":
+ scopeValue = "jakarta.servlet.jsp.PageContext.APPLICATION_SCOPE";
+ break;
+ default:
+ throw new IllegalArgumentException(Localizer.getMessage("jsp.error.page.invalid.scope"));
+ }
+ }
+ return scopeValue;
+ }
+
+ /**
+ * Generates the code for a non-standard remove. Note that removes w/o a specified scope will remove from all
+ * scopes.
+ *
+ * @param n tag
+ * @param jspAttributes attributes
+ *
+ * @throws JasperException unspecified error
+ */
+ private void generateNonstandardRemoveLogic(Node.CustomTag n, Map jspAttributes)
+ throws JasperException {
+ String baseVar = createTagVarName(n.getQName(), n.getPrefix(), n.getLocalName());
+ String tagMethod = "_jspx_meth_" + baseVar;
+ ServletWriter outSave = out;
+
+ // generate method call
+ out.printin(tagMethod);
+ out.print("(");
+ out.print("_jspx_page_context");
+ out.println(");");
+ GenBuffer genBuffer = new GenBuffer(n, n.getBody());
+ methodsBuffered.add(genBuffer);
+ out = genBuffer.getOut();
+
+ // Generate code for method declaration
+ methodNesting++;
+ out.println();
+ out.pushIndent();
+ out.printin("private void ");
+ out.print(tagMethod);
+ out.println("(jakarta.servlet.jsp.PageContext pageContext)");
+ out.printil(" throws java.lang.Throwable {");
+ out.pushIndent();
+ // Generated body of method
+ String varValue = jspAttributes.get("var").getValue();
+ JspAttribute scope = jspAttributes.get("scope");
+ if (scope == null) {
+ // c:remove without a scope means remove from all scopes
+ out.printil("pageContext.removeAttribute(\"" + varValue + "\");");
+ } else {
+ // c:remove with a scope means remove only from the specified scope
+ String scopeValue = translateScopeToConstant(jspAttributes);
+ out.printil("pageContext.removeAttribute(\"" + varValue + "\", " + scopeValue + ");");
+ }
+ // Generate end of method
+ out.popIndent();
+ out.printil("}");
+ out.popIndent();
+
+ methodNesting--;
+ // restore previous writer
+ out = outSave;
+ }
}
private static void generateLocalVariables(ServletWriter out, ChildInfoBase n) {
@@ -3170,6 +3384,12 @@
}
timestampFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
timestampFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
+ String nonstandardOptionsList = ctxt.getOptions().getUseNonstandardTagOptimizations();
+ if (nonstandardOptionsList == null) {
+ nonstandardCustomTagNames = Collections.emptySet();
+ } else {
+ nonstandardCustomTagNames = new HashSet<>(Arrays.asList(nonstandardOptionsList.split(",")));
+ }
}
/**
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/compiler/ImplicitTagLibraryInfo.java tomcat11-11.0.15/java/org/apache/jasper/compiler/ImplicitTagLibraryInfo.java
--- tomcat11-11.0.6/java/org/apache/jasper/compiler/ImplicitTagLibraryInfo.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/compiler/ImplicitTagLibraryInfo.java 2025-12-02 16:54:08.000000000 +0000
@@ -44,8 +44,6 @@
/**
* Class responsible for generating an implicit tag library containing tag handlers corresponding to the tag files in
* "/WEB-INF/tags/" or a subdirectory of it.
- *
- * @author Jan Luehe
*/
class ImplicitTagLibraryInfo extends TagLibraryInfo {
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/compiler/JDTCompiler.java tomcat11-11.0.15/java/org/apache/jasper/compiler/JDTCompiler.java
--- tomcat11-11.0.6/java/org/apache/jasper/compiler/JDTCompiler.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/compiler/JDTCompiler.java 2025-12-02 16:54:08.000000000 +0000
@@ -35,6 +35,7 @@
import java.util.StringTokenizer;
import org.apache.jasper.JasperException;
+import org.apache.jasper.runtime.ExceptionUtils;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.eclipse.jdt.core.compiler.IProblem;
@@ -58,8 +59,6 @@
/**
* JDT class compiler. This compiler will load source dependencies from the context classloader, reducing dramatically
* disk access during the compilation process. Based on code from Cocoon2.
- *
- * @author Remy Maucherat
*/
public class JDTCompiler extends org.apache.jasper.compiler.Compiler {
@@ -113,8 +112,8 @@
}
result = new char[buf.length()];
buf.getChars(0, result.length, result, 0);
- } catch (IOException e) {
- log.error(Localizer.getMessage("jsp.error.compilation.source", sourceFile), e);
+ } catch (IOException ioe) {
+ log.error(Localizer.getMessage("jsp.error.compilation.source", sourceFile), ioe);
}
return result;
}
@@ -220,13 +219,20 @@
if (result.equals(targetClassName) || result.startsWith(targetClassName + '$')) {
return false;
}
- String resourceName = result.replace('.', '/') + ".class";
- try (InputStream is = classLoader.getResourceAsStream(resourceName)) {
- return is == null;
- } catch (IOException e) {
- // we are here, since close on is failed. That means it was not null
- return false;
+ /*
+ * This might look heavy-weight but, with only the ClassLoader API available, trying to load the
+ * resource as a class is the only reliable way found so far to differentiate between a class and a
+ * package. Other options, such as getResource(), fail for some edge cases on case insensitive file
+ * systems. As this code is only called at compile time, the performance impact is not a significant
+ * concern.
+ */
+ try {
+ classLoader.loadClass(result);
+ } catch (Throwable t) {
+ ExceptionUtils.handleThrowable(t);
+ return true;
}
+ return false;
}
@Override
@@ -326,10 +332,7 @@
} else if (opt.equals("23")) {
settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_23);
} else if (opt.equals("24")) {
- // Constant not available in latest ECJ version shipped with
- // Tomcat. May be supported in a snapshot build.
- // This is checked against the actual version below.
- settings.put(CompilerOptions.OPTION_Source, "24");
+ settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_24);
} else if (opt.equals("25")) {
// Constant not available in latest ECJ version shipped with
// Tomcat. May be supported in a snapshot build.
@@ -415,11 +418,8 @@
settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_23);
settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_23);
} else if (opt.equals("24")) {
- // Constant not available in latest ECJ version shipped with
- // Tomcat. May be supported in a snapshot build.
- // This is checked against the actual version below.
- settings.put(CompilerOptions.OPTION_TargetPlatform, "24");
- settings.put(CompilerOptions.OPTION_Compliance, "24");
+ settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_24);
+ settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_24);
} else if (opt.equals("25")) {
// Constant not available in latest ECJ version shipped with
// Tomcat. May be supported in a snapshot build.
@@ -476,8 +476,8 @@
}
}
}
- } catch (IOException exc) {
- log.error(Localizer.getMessage("jsp.error.compilation.jdt"), exc);
+ } catch (IOException ioe) {
+ log.error(Localizer.getMessage("jsp.error.compilation.jdt"), ioe);
}
}
};
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/compiler/JavaCompiler.java tomcat11-11.0.15/java/org/apache/jasper/compiler/JavaCompiler.java
--- tomcat11-11.0.6/java/org/apache/jasper/compiler/JavaCompiler.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/compiler/JavaCompiler.java 2025-12-02 16:54:08.000000000 +0000
@@ -42,7 +42,7 @@
private final Log log = LogFactory.getLog(JavaCompiler.class); // must not be static
@Override
- protected void generateClass(Map smaps) throws JasperException, IOException {
+ protected void generateClass(Map smaps) throws JasperException, IOException {
long t1 = 0;
if (log.isDebugEnabled()) {
@@ -51,14 +51,13 @@
javax.tools.JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
DiagnosticCollector diagnostics = new DiagnosticCollector<>();
- StandardJavaFileManager fileManager =
- compiler.getStandardFileManager(diagnostics, null, Charset.forName(ctxt.getOptions().getJavaEncoding()));
+ StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null,
+ Charset.forName(ctxt.getOptions().getJavaEncoding()));
Iterable extends JavaFileObject> compilationUnits =
fileManager.getJavaFileObjectsFromFiles(List.of(new File(ctxt.getServletJavaFileName())));
// Perform Java compilation using the appropriate options
- List compilerOptions =
- List.of("-classpath", ctxt.getClassPath(), "-source", ctxt.getOptions().getCompilerSourceVM(),
- "-target", ctxt.getOptions().getCompilerTargetVM());
+ List compilerOptions = List.of("-classpath", ctxt.getClassPath(), "-source",
+ ctxt.getOptions().getCompilerSourceVM(), "-target", ctxt.getOptions().getCompilerTargetVM());
Boolean result =
compiler.getTask(null, fileManager, diagnostics, compilerOptions, null, compilationUnits).call();
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/compiler/JavacErrorDetail.java tomcat11-11.0.15/java/org/apache/jasper/compiler/JavacErrorDetail.java
--- tomcat11-11.0.6/java/org/apache/jasper/compiler/JavacErrorDetail.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/compiler/JavacErrorDetail.java 2025-12-02 16:54:08.000000000 +0000
@@ -29,9 +29,6 @@
/**
* Class providing details about a javac compilation error.
- *
- * @author Jan Luehe
- * @author Kin-man Chung
*/
public class JavacErrorDetail {
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/compiler/JspConfig.java tomcat11-11.0.15/java/org/apache/jasper/compiler/JspConfig.java
--- tomcat11-11.0.6/java/org/apache/jasper/compiler/JspConfig.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/compiler/JspConfig.java 2025-12-02 16:54:08.000000000 +0000
@@ -30,11 +30,7 @@
/**
* Handles the jsp-config element in WEB_INF/web.xml. This is used for specifying the JSP configuration information on a
* JSP page
- *
- * @author Kin-man Chung
- * @author Remy Maucherat
*/
-
public class JspConfig {
// Logger
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/compiler/JspDocumentParser.java tomcat11-11.0.15/java/org/apache/jasper/compiler/JspDocumentParser.java
--- tomcat11-11.0.6/java/org/apache/jasper/compiler/JspDocumentParser.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/compiler/JspDocumentParser.java 2025-12-02 16:54:08.000000000 +0000
@@ -48,11 +48,7 @@
/**
* Class implementing a parser for a JSP document, that is, a JSP page in XML syntax.
- *
- * @author Jan Luehe
- * @author Kin-man Chung
*/
-
class JspDocumentParser extends DefaultHandler2 implements TagConstants {
private static final String LEXICAL_HANDLER_PROPERTY = "http://xml.org/sax/properties/lexical-handler";
@@ -169,7 +165,7 @@
jspDocParser.isValidating = true;
try {
source.getByteStream().close();
- } catch (IOException e2) {
+ } catch (IOException ioe) {
// ignore
}
source = JspUtil.getInputSource(path, jar, jspDocParser.ctxt);
@@ -177,7 +173,7 @@
} finally {
try {
source.getByteStream().close();
- } catch (IOException e) {
+ } catch (IOException ioe) {
// ignore
}
}
@@ -362,8 +358,8 @@
*
* The SAX does not call this method with all of the template text, but may invoke this method with chunks of it.
* This is a problem when we try to determine if the text contains only whitespaces, or when we are looking for an
- * EL expression string. Therefore, it is necessary to buffer and concatenate the chunks and process the concatenated
- * text later (at beginTag and endTag)
+ * EL expression string. Therefore, it is necessary to buffer and concatenate the chunks and process the
+ * concatenated text later (at beginTag and endTag)
*
* @param buf The characters
*
@@ -741,7 +737,8 @@
}
}
case INCLUDE_DIRECTIVE_ACTION -> {
- node = new Node.IncludeDirective(qName, nonTaglibAttrs, nonTaglibXmlnsAttrs, taglibAttrs, start, current);
+ node = new Node.IncludeDirective(qName, nonTaglibAttrs, nonTaglibXmlnsAttrs, taglibAttrs, start,
+ current);
processIncludeDirective(nonTaglibAttrs.getValue("file"), node);
}
case DECLARATION_ACTION -> {
@@ -788,7 +785,8 @@
node = new Node.JspOutput(qName, nonTaglibAttrs, nonTaglibXmlnsAttrs, taglibAttrs, start, current);
case TAG_DIRECTIVE_ACTION -> {
if (!isTagFile) {
- throw new SAXParseException(Localizer.getMessage("jsp.error.action.isnottagfile", localName), locator);
+ throw new SAXParseException(Localizer.getMessage("jsp.error.action.isnottagfile", localName),
+ locator);
}
node = new Node.TagDirective(qName, nonTaglibAttrs, nonTaglibXmlnsAttrs, taglibAttrs, start, current);
String imports = nonTaglibAttrs.getValue("import");
@@ -799,32 +797,38 @@
}
case ATTRIBUTE_DIRECTIVE_ACTION -> {
if (!isTagFile) {
- throw new SAXParseException(Localizer.getMessage("jsp.error.action.isnottagfile", localName), locator);
+ throw new SAXParseException(Localizer.getMessage("jsp.error.action.isnottagfile", localName),
+ locator);
}
- node = new Node.AttributeDirective(qName, nonTaglibAttrs, nonTaglibXmlnsAttrs, taglibAttrs, start, current);
+ node = new Node.AttributeDirective(qName, nonTaglibAttrs, nonTaglibXmlnsAttrs, taglibAttrs, start,
+ current);
}
case VARIABLE_DIRECTIVE_ACTION -> {
if (!isTagFile) {
- throw new SAXParseException(Localizer.getMessage("jsp.error.action.isnottagfile", localName), locator);
+ throw new SAXParseException(Localizer.getMessage("jsp.error.action.isnottagfile", localName),
+ locator);
}
- node = new Node.VariableDirective(qName, nonTaglibAttrs, nonTaglibXmlnsAttrs, taglibAttrs, start, current);
+ node = new Node.VariableDirective(qName, nonTaglibAttrs, nonTaglibXmlnsAttrs, taglibAttrs, start,
+ current);
}
case INVOKE_ACTION -> {
if (!isTagFile) {
- throw new SAXParseException(Localizer.getMessage("jsp.error.action.isnottagfile", localName), locator);
+ throw new SAXParseException(Localizer.getMessage("jsp.error.action.isnottagfile", localName),
+ locator);
}
node = new Node.InvokeAction(qName, nonTaglibAttrs, nonTaglibXmlnsAttrs, taglibAttrs, start, current);
}
case DOBODY_ACTION -> {
if (!isTagFile) {
- throw new SAXParseException(Localizer.getMessage("jsp.error.action.isnottagfile", localName), locator);
+ throw new SAXParseException(Localizer.getMessage("jsp.error.action.isnottagfile", localName),
+ locator);
}
node = new Node.DoBodyAction(qName, nonTaglibAttrs, nonTaglibXmlnsAttrs, taglibAttrs, start, current);
}
case ELEMENT_ACTION ->
node = new Node.JspElement(qName, nonTaglibAttrs, nonTaglibXmlnsAttrs, taglibAttrs, start, current);
- default ->
- throw new SAXParseException(Localizer.getMessage("jsp.error.xml.badStandardAction", localName), locator);
+ default -> throw new SAXParseException(Localizer.getMessage("jsp.error.xml.badStandardAction", localName),
+ locator);
}
return node;
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/compiler/JspReader.java tomcat11-11.0.15/java/org/apache/jasper/compiler/JspReader.java
--- tomcat11-11.0.6/java/org/apache/jasper/compiler/JspReader.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/compiler/JspReader.java 2025-12-02 16:54:08.000000000 +0000
@@ -31,18 +31,7 @@
/**
* JspReader is an input buffer for the JSP parser. It should allow unlimited lookahead and pushback. It also has a
* bunch of parsing utility methods for understanding html style content.
- *
- * @author Anil K. Vijendran
- * @author Anselm Baird-Smith
- * @author Harish Prabandham
- * @author Rajiv Mordani
- * @author Mandar Raje
- * @author Danno Ferrin
- * @author Kin-man Chung
- * @author Shawn Bayern
- * @author Mark Roth
*/
-
class JspReader {
/**
@@ -116,9 +105,9 @@
if (reader != null) {
try {
reader.close();
- } catch (Exception any) {
+ } catch (Exception e) {
if (log.isDebugEnabled()) {
- log.debug(Localizer.getMessage("jsp.error.file.close"), any);
+ log.debug(Localizer.getMessage("jsp.error.file.close"), e);
}
}
}
@@ -405,7 +394,8 @@
Boolean result;
Mark restart = null;
- skip: while ((result = indexOf(firstChar, ret)) != null) {
+ skip:
+ while ((result = indexOf(firstChar, ret)) != null) {
if (result.booleanValue()) {
if (restart != null) {
restart.init(current, true);
@@ -442,7 +432,8 @@
int ch;
int prev = 'x'; // Doesn't matter
char firstChar = limit.charAt(0);
- skip: for (ch = nextChar(ret); ch != -1; prev = ch, ch = nextChar(ret)) {
+ skip:
+ for (ch = nextChar(ret); ch != -1; prev = ch, ch = nextChar(ret)) {
if (ch == '\\' && prev == '\\') {
ch = 0; // Double \ is not an escape char anymore
} else if (prev == '\\') {
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/compiler/JspRuntimeContext.java tomcat11-11.0.15/java/org/apache/jasper/compiler/JspRuntimeContext.java
--- tomcat11-11.0.6/java/org/apache/jasper/compiler/JspRuntimeContext.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/compiler/JspRuntimeContext.java 2025-12-02 16:54:08.000000000 +0000
@@ -43,8 +43,6 @@
* Class for tracking JSP compile time file dependencies when the >%@include file="..."%< directive is used. A
* background thread periodically checks the files a JSP page is dependent upon. If a dependent file changes the JSP
* page which included it is recompiled. Only used if a web application context is a directory.
- *
- * @author Glenn L. Nielsen
*/
public final class JspRuntimeContext {
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/compiler/JspUtil.java tomcat11-11.0.15/java/org/apache/jasper/compiler/JspUtil.java
--- tomcat11-11.0.6/java/org/apache/jasper/compiler/JspUtil.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/compiler/JspUtil.java 2025-12-02 16:54:08.000000000 +0000
@@ -33,13 +33,6 @@
/**
* This class has all the utility method(s). Ideally should move all the bean containers here.
- *
- * @author Mandar Raje.
- * @author Rajiv Mordani.
- * @author Danno Ferrin
- * @author Pierre Delisle
- * @author Shawn Bayern
- * @author Mark Roth
*/
public class JspUtil {
@@ -793,7 +786,7 @@
} catch (IOException ioe) {
try {
in.close();
- } catch (IOException e) {
+ } catch (IOException ignore) {
// Ignore
}
throw ioe;
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/compiler/Localizer.java tomcat11-11.0.15/java/org/apache/jasper/compiler/Localizer.java
--- tomcat11-11.0.6/java/org/apache/jasper/compiler/Localizer.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/compiler/Localizer.java 2025-12-02 16:54:08.000000000 +0000
@@ -24,8 +24,6 @@
/**
* Class responsible for converting error codes to corresponding localized error messages.
- *
- * @author Jan Luehe
*/
public class Localizer {
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/compiler/Mark.java tomcat11-11.0.15/java/org/apache/jasper/compiler/Mark.java
--- tomcat11-11.0.6/java/org/apache/jasper/compiler/Mark.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/compiler/Mark.java 2025-12-02 16:54:08.000000000 +0000
@@ -23,8 +23,6 @@
/**
* Mark represents a point in the JSP input.
- *
- * @author Anil K. Vijendran
*/
public final class Mark {
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/compiler/Node.java tomcat11-11.0.15/java/org/apache/jasper/compiler/Node.java
--- tomcat11-11.0.6/java/org/apache/jasper/compiler/Node.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/compiler/Node.java 2025-12-02 16:54:08.000000000 +0000
@@ -42,13 +42,7 @@
/**
* An internal data representation of a JSP page or a JSP document (XML). Also included here is a visitor class for
* traversing nodes.
- *
- * @author Kin-man Chung
- * @author Jan Luehe
- * @author Shawn Bayern
- * @author Mark Roth
*/
-
public abstract class Node implements TagConstants {
private static final VariableInfo[] ZERO_VARIABLE_INFO = {};
@@ -346,8 +340,8 @@
}
/**
- * Selects and invokes a method in the visitor class based on the node type. This is abstract and should be overridden
- * by the extending classes.
+ * Selects and invokes a method in the visitor class based on the node type. This is abstract and should be
+ * overridden by the extending classes.
*
* @param v The visitor class
*/
@@ -1507,7 +1501,7 @@
case VariableInfo.AT_END -> this.atEndScriptingVars;
case VariableInfo.NESTED -> this.nestedScriptingVars;
default -> throw new IllegalArgumentException(
- Localizer.getMessage("jsp.error.page.invalid.varscope", Integer.valueOf(scope)));
+ Localizer.getMessage("jsp.error.page.invalid.varscope", Integer.valueOf(scope)));
};
}
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/compiler/PageDataImpl.java tomcat11-11.0.15/java/org/apache/jasper/compiler/PageDataImpl.java
--- tomcat11-11.0.6/java/org/apache/jasper/compiler/PageDataImpl.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/compiler/PageDataImpl.java 2025-12-02 16:54:08.000000000 +0000
@@ -36,8 +36,6 @@
* the XML view. This pass ignores any nodes other than JspRoot and TaglibDirective. During the second pass, the
* SecondPassVisitor produces the XML view, using the combined jsp:root attributes determined in the first pass and any
* remaining pages nodes (this pass ignores any JspRoot and TaglibDirective nodes).
- *
- * @author Jan Luehe
*/
class PageDataImpl extends PageData implements TagConstants {
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/compiler/PageInfo.java tomcat11-11.0.15/java/org/apache/jasper/compiler/PageInfo.java
--- tomcat11-11.0.6/java/org/apache/jasper/compiler/PageInfo.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/compiler/PageInfo.java 2025-12-02 16:54:08.000000000 +0000
@@ -35,10 +35,7 @@
/**
* A repository for various info about the translation unit under compilation.
- *
- * @author Kin-man Chung
*/
-
public class PageInfo {
private final List imports;
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/compiler/Parser.java tomcat11-11.0.15/java/org/apache/jasper/compiler/Parser.java
--- tomcat11-11.0.6/java/org/apache/jasper/compiler/Parser.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/compiler/Parser.java 2025-12-02 16:54:08.000000000 +0000
@@ -36,12 +36,7 @@
/**
* This class implements a parser for a JSP page (non-xml view). JSP page grammar is included here for reference. The
* token '#' that appears in the production indicates the current input token location in the production.
- *
- * @author Kin-man Chung
- * @author Shawn Bayern
- * @author Mark Roth
*/
-
class Parser implements TagConstants {
private final ParserController parserController;
@@ -245,8 +240,8 @@
buf.append(ch);
reader.nextChar();
ch = (char) reader.peekChar();
- } while (Character.isLetter(ch) || Character.isDigit(ch) ||
- ch == '.' || ch == '_' || ch == '-' || ch == ':');
+ } while (Character.isLetter(ch) || Character.isDigit(ch) || ch == '.' || ch == '_' || ch == '-' ||
+ ch == ':');
return buf.toString();
}
return null;
@@ -328,8 +323,8 @@
}
} catch (FileNotFoundException ex) {
err.jspError(start, "jsp.error.file.not.found", file);
- } catch (Exception ex) {
- err.jspError(start, ex.getMessage());
+ } catch (Exception e) {
+ err.jspError(start, e.getMessage());
}
}
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/compiler/ParserController.java tomcat11-11.0.15/java/org/apache/jasper/compiler/ParserController.java
--- tomcat11-11.0.6/java/org/apache/jasper/compiler/ParserController.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/compiler/ParserController.java 2025-12-02 16:54:08.000000000 +0000
@@ -36,9 +36,6 @@
* The same ParserController instance is used for a JSP page and any JSP segments included by it (via an include
* directive), where each segment may be provided in standard or XML syntax. This class selects and invokes the
* appropriate parser for the JSP page and its included segments.
- *
- * @author Pierre Delisle
- * @author Jan Luehe
*/
public class ParserController implements TagConstants {
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/compiler/ScriptingVariabler.java tomcat11-11.0.15/java/org/apache/jasper/compiler/ScriptingVariabler.java
--- tomcat11-11.0.6/java/org/apache/jasper/compiler/ScriptingVariabler.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/compiler/ScriptingVariabler.java 2025-12-02 16:54:08.000000000 +0000
@@ -28,8 +28,6 @@
/**
* Class responsible for determining the scripting variables that every custom action needs to declare.
- *
- * @author Jan Luehe
*/
class ScriptingVariabler {
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/compiler/ServletWriter.java tomcat11-11.0.15/java/org/apache/jasper/compiler/ServletWriter.java
--- tomcat11-11.0.6/java/org/apache/jasper/compiler/ServletWriter.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/compiler/ServletWriter.java 2025-12-02 16:54:08.000000000 +0000
@@ -20,9 +20,6 @@
/**
* This is what is used to generate servlets.
- *
- * @author Anil K. Vijendran
- * @author Kin-man Chung
*/
public class ServletWriter implements AutoCloseable {
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/compiler/SmapStratum.java tomcat11-11.0.15/java/org/apache/jasper/compiler/SmapStratum.java
--- tomcat11-11.0.6/java/org/apache/jasper/compiler/SmapStratum.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/compiler/SmapStratum.java 2025-12-02 16:54:08.000000000 +0000
@@ -21,9 +21,6 @@
/**
* Represents the line and file mappings associated with a JSR-045 "stratum".
- *
- * @author Jayson Falkner
- * @author Shawn Bayern
*/
public class SmapStratum {
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/compiler/SmapUtil.java tomcat11-11.0.15/java/org/apache/jasper/compiler/SmapUtil.java
--- tomcat11-11.0.6/java/org/apache/jasper/compiler/SmapUtil.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/compiler/SmapUtil.java 2025-12-02 16:54:08.000000000 +0000
@@ -39,12 +39,6 @@
/**
* Contains static utilities for generating SMAP data based on the current version of Jasper.
- *
- * @author Jayson Falkner
- * @author Shawn Bayern
- * @author Robert Field (inner SDEInstaller class)
- * @author Mark Roth
- * @author Kin-man Chung
*/
public class SmapUtil {
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/compiler/TagFileProcessor.java tomcat11-11.0.15/java/org/apache/jasper/compiler/TagFileProcessor.java
--- tomcat11-11.0.6/java/org/apache/jasper/compiler/TagFileProcessor.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/compiler/TagFileProcessor.java 2025-12-02 16:54:08.000000000 +0000
@@ -42,10 +42,7 @@
/**
* 1. Processes and extracts the directive info in a tag file. 2. Compiles and loads tag files used in a JSP file.
- *
- * @author Kin-man Chung
*/
-
public class TagFileProcessor {
private List tempVector;
@@ -441,7 +438,7 @@
Node.Nodes page = null;
try {
page = pc.parseTagFileDirectives(path, jar);
- } catch (IOException e) {
+ } catch (IOException ioe) {
err.jspError("jsp.error.file.not.found", path);
}
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/compiler/TagLibraryInfoImpl.java tomcat11-11.0.15/java/org/apache/jasper/compiler/TagLibraryInfoImpl.java
--- tomcat11-11.0.6/java/org/apache/jasper/compiler/TagLibraryInfoImpl.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/compiler/TagLibraryInfoImpl.java 2025-12-02 16:54:08.000000000 +0000
@@ -55,12 +55,6 @@
/**
* Implementation of the TagLibraryInfo class from the JSP spec.
- *
- * @author Anil K. Vijendran
- * @author Mandar Raje
- * @author Pierre Delisle
- * @author Kin-man Chung
- * @author Jan Luehe
*/
class TagLibraryInfoImpl extends TagLibraryInfo implements TagConstants {
@@ -152,7 +146,7 @@
if (urlConn != null) {
try {
urlConn.getInputStream().close();
- } catch (IOException e) {
+ } catch (IOException ignore) {
// Ignore
}
}
@@ -275,8 +269,8 @@
if (url.getProtocol().equals("war") && uri.endsWith(".jar")) {
url = UriUtil.warToJar(url);
}
- } catch (Exception ex) {
- err.jspError("jsp.error.tld.unable_to_get_jar", uri, ex.toString());
+ } catch (Exception e) {
+ err.jspError("jsp.error.tld.unable_to_get_jar", uri, e.toString());
}
if (uri.endsWith(".jar")) {
if (url == null) {
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/compiler/TagPluginManager.java tomcat11-11.0.15/java/org/apache/jasper/compiler/TagPluginManager.java
--- tomcat11-11.0.6/java/org/apache/jasper/compiler/TagPluginManager.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/compiler/TagPluginManager.java 2025-12-02 16:54:08.000000000 +0000
@@ -33,8 +33,6 @@
/**
* Manages tag plugin optimizations.
- *
- * @author Kin-man Chung
*/
public class TagPluginManager {
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/compiler/TldCache.java tomcat11-11.0.15/java/org/apache/jasper/compiler/TldCache.java
--- tomcat11-11.0.6/java/org/apache/jasper/compiler/TldCache.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/compiler/TldCache.java 2025-12-02 16:54:08.000000000 +0000
@@ -138,7 +138,7 @@
result[1] = jar.getLastModified(tldResourcePath.getEntryName());
}
}
- } catch (IOException e) {
+ } catch (IOException ignore) {
// Ignore (shouldn't happen)
}
return result;
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/compiler/Validator.java tomcat11-11.0.15/java/org/apache/jasper/compiler/Validator.java
--- tomcat11-11.0.6/java/org/apache/jasper/compiler/Validator.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/compiler/Validator.java 2025-12-02 16:54:08.000000000 +0000
@@ -50,11 +50,6 @@
/**
* Performs validation on the page elements. Attributes are checked for mandatory presence, entry value validity, and
* consistency. As a side effect, some page global value (such as those from page directives) are stored, for later use.
- *
- * @author Kin-man Chung
- * @author Jan Luehe
- * @author Shawn Bayern
- * @author Mark Roth
*/
class Validator {
@@ -962,7 +957,7 @@
}
for (int j = 0; tldAttrs != null && j < tldAttrs.length; j++) {
if (attrs.getLocalName(i).equals(tldAttrs[j].getName()) && (attrs.getURI(i) == null ||
- attrs.getURI(i).isEmpty() || attrs.getURI(i).equals(n.getURI()))) {
+ attrs.getURI(i).isEmpty() || attrs.getURI(i).equals(n.getURI()))) {
TagAttributeInfo tldAttr = tldAttrs[j];
if (tldAttr.canBeRequestTime() || tldAttr.isDeferredMethod() || tldAttr.isDeferredValue()) { // JSP
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/compiler/tagplugin/TagPluginContext.java tomcat11-11.0.15/java/org/apache/jasper/compiler/tagplugin/TagPluginContext.java
--- tomcat11-11.0.6/java/org/apache/jasper/compiler/tagplugin/TagPluginContext.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/compiler/tagplugin/TagPluginContext.java 2025-12-02 16:54:08.000000000 +0000
@@ -81,8 +81,8 @@
String getConstantAttribute(String attribute);
/**
- * Generate codes to evaluate value of an attribute in the custom tag The codes is a Java expression. NOTE: Currently
- * cannot handle attributes that are fragments.
+ * Generate codes to evaluate value of an attribute in the custom tag The codes is a Java expression. NOTE:
+ * Currently cannot handle attributes that are fragments.
*
* @param attribute The specified attribute
*/
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/el/ELContextImpl.java tomcat11-11.0.15/java/org/apache/jasper/el/ELContextImpl.java
--- tomcat11-11.0.6/java/org/apache/jasper/el/ELContextImpl.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/el/ELContextImpl.java 2025-12-02 16:54:08.000000000 +0000
@@ -36,9 +36,7 @@
import jakarta.el.VariableMapper;
/**
- * Implementation of ELContext
- *
- * @author Jacob Hookom
+ * Implementation of ELContext.
*/
public class ELContextImpl extends ELContext {
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/el/ELContextWrapper.java tomcat11-11.0.15/java/org/apache/jasper/el/ELContextWrapper.java
--- tomcat11-11.0.6/java/org/apache/jasper/el/ELContextWrapper.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/el/ELContextWrapper.java 2025-12-02 16:54:08.000000000 +0000
@@ -25,8 +25,6 @@
/**
* Simple ELContextWrapper for runtime evaluation of EL w/ dynamic FunctionMappers
- *
- * @author jhook
*/
public final class ELContextWrapper extends ELContext {
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/el/JasperELResolver.java tomcat11-11.0.15/java/org/apache/jasper/el/JasperELResolver.java
--- tomcat11-11.0.6/java/org/apache/jasper/el/JasperELResolver.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/el/JasperELResolver.java 2025-12-02 16:54:08.000000000 +0000
@@ -203,8 +203,8 @@
try {
method.setAccessible(true);
value = method.invoke(base, (Object[]) null);
- } catch (Exception ex) {
- Throwable thr = ExceptionUtils.unwrapInvocationTargetException(ex);
+ } catch (Exception e) {
+ Throwable thr = ExceptionUtils.unwrapInvocationTargetException(e);
ExceptionUtils.handleThrowable(thr);
}
}
@@ -222,8 +222,8 @@
context.setPropertyResolved(base, property);
try {
method.invoke(base, value);
- } catch (Exception ex) {
- Throwable thr = ExceptionUtils.unwrapInvocationTargetException(ex);
+ } catch (Exception e) {
+ Throwable thr = ExceptionUtils.unwrapInvocationTargetException(e);
ExceptionUtils.handleThrowable(thr);
}
}
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/el/JspValueExpression.java tomcat11-11.0.15/java/org/apache/jasper/el/JspValueExpression.java
--- tomcat11-11.0.6/java/org/apache/jasper/el/JspValueExpression.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/el/JspValueExpression.java 2025-12-02 16:54:08.000000000 +0000
@@ -28,9 +28,7 @@
import jakarta.el.ValueExpression;
/**
- * Wrapper for providing context to ValueExpressions
- *
- * @author Jacob Hookom
+ * Wrapper for providing context to ValueExpressions.
*/
public final class JspValueExpression extends ValueExpression implements Externalizable {
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/optimizations/ELInterpreterTagSetters.java tomcat11-11.0.15/java/org/apache/jasper/optimizations/ELInterpreterTagSetters.java
--- tomcat11-11.0.6/java/org/apache/jasper/optimizations/ELInterpreterTagSetters.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/optimizations/ELInterpreterTagSetters.java 2025-12-02 16:54:08.000000000 +0000
@@ -110,7 +110,9 @@
BigDecimal unused = new BigDecimal(m.group(2));
result = "new java.math.BigDecimal(\"" + m.group(2) + "\")";
} catch (NumberFormatException e) {
- log.debug(Localizer.getMessage("jsp.error.typeConversion", m.group(2), "BigDecimal"), e);
+ if (log.isDebugEnabled()) {
+ log.debug(Localizer.getMessage("jsp.error.typeConversion", m.group(2), "BigDecimal"), e);
+ }
// Continue and resolve the value at runtime
}
}
@@ -128,7 +130,9 @@
result = "Long.valueOf(\"" + m.group(2) + "\")";
}
} catch (NumberFormatException e) {
- log.debug(Localizer.getMessage("jsp.error.typeConversion", m.group(2), "Long"), e);
+ if (log.isDebugEnabled()) {
+ log.debug(Localizer.getMessage("jsp.error.typeConversion", m.group(2), "Long"), e);
+ }
// Continue and resolve the value at runtime
}
}
@@ -145,7 +149,9 @@
result = "Integer.valueOf(\"" + m.group(2) + "\")";
}
} catch (NumberFormatException e) {
- log.debug(Localizer.getMessage("jsp.error.typeConversion", m.group(2), "Integer"), e);
+ if (log.isDebugEnabled()) {
+ log.debug(Localizer.getMessage("jsp.error.typeConversion", m.group(2), "Integer"), e);
+ }
// Continue and resolve the value at runtime
}
}
@@ -163,7 +169,9 @@
result = "Short.valueOf(\"" + m.group(2) + "\")";
}
} catch (NumberFormatException e) {
- log.debug(Localizer.getMessage("jsp.error.typeConversion", m.group(2), "Short"), e);
+ if (log.isDebugEnabled()) {
+ log.debug(Localizer.getMessage("jsp.error.typeConversion", m.group(2), "Short"), e);
+ }
// Continue and resolve the value at runtime
}
}
@@ -181,7 +189,9 @@
result = "Byte.valueOf(\"" + m.group(2) + "\")";
}
} catch (NumberFormatException e) {
- log.debug(Localizer.getMessage("jsp.error.typeConversion", m.group(2), "Byte"), e);
+ if (log.isDebugEnabled()) {
+ log.debug(Localizer.getMessage("jsp.error.typeConversion", m.group(2), "Byte"), e);
+ }
// Continue and resolve the value at runtime
}
}
@@ -198,7 +208,9 @@
result = "Double.valueOf(\"" + m.group(2) + "\")";
}
} catch (NumberFormatException e) {
- log.debug(Localizer.getMessage("jsp.error.typeConversion", m.group(2), "Double"), e);
+ if (log.isDebugEnabled()) {
+ log.debug(Localizer.getMessage("jsp.error.typeConversion", m.group(2), "Double"), e);
+ }
// Continue and resolve the value at runtime
}
}
@@ -216,7 +228,9 @@
result = "Float.valueOf(\"" + m.group(2) + "\")";
}
} catch (NumberFormatException e) {
- log.debug(Localizer.getMessage("jsp.error.typeConversion", m.group(2), "Float"), e);
+ if (log.isDebugEnabled()) {
+ log.debug(Localizer.getMessage("jsp.error.typeConversion", m.group(2), "Float"), e);
+ }
// Continue and resolve the value at runtime
}
}
@@ -229,7 +243,9 @@
BigInteger unused = new BigInteger(m.group(2));
result = "new java.math.BigInteger(\"" + m.group(2) + "\")";
} catch (NumberFormatException e) {
- log.debug(Localizer.getMessage("jsp.error.typeConversion", m.group(2), "BigInteger"), e);
+ if (log.isDebugEnabled()) {
+ log.debug(Localizer.getMessage("jsp.error.typeConversion", m.group(2), "BigInteger"), e);
+ }
// Continue and resolve the value at runtime
}
}
@@ -242,8 +258,10 @@
Enum> enumValue = Enum.valueOf((Class extends Enum>) expectedType, m.group(2));
result = expectedType.getName() + "." + enumValue.name();
} catch (IllegalArgumentException iae) {
- log.debug(Localizer.getMessage("jsp.error.typeConversion", m.group(2),
- "Enum[" + expectedType.getName() + "]"), iae);
+ if (log.isDebugEnabled()) {
+ log.debug(Localizer.getMessage("jsp.error.typeConversion", m.group(2),
+ "Enum[" + expectedType.getName() + "]"), iae);
+ }
// Continue and resolve the value at runtime
}
}
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/optimizations/StringInterpreterEnum.java tomcat11-11.0.15/java/org/apache/jasper/optimizations/StringInterpreterEnum.java
--- tomcat11-11.0.6/java/org/apache/jasper/optimizations/StringInterpreterEnum.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/optimizations/StringInterpreterEnum.java 2025-12-02 16:54:08.000000000 +0000
@@ -37,7 +37,9 @@
Enum> enumValue = Enum.valueOf((Class extends Enum>) c, s);
return c.getName() + "." + enumValue.name();
} catch (IllegalArgumentException iae) {
- log.debug(Localizer.getMessage("jsp.error.typeConversion", s, "Enum[" + c.getName() + "]"), iae);
+ if (log.isDebugEnabled()) {
+ log.debug(Localizer.getMessage("jsp.error.typeConversion", s, "Enum[" + c.getName() + "]"), iae);
+ }
// Continue and resolve the value at runtime
}
}
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/runtime/BodyContentImpl.java tomcat11-11.0.15/java/org/apache/jasper/runtime/BodyContentImpl.java
--- tomcat11-11.0.6/java/org/apache/jasper/runtime/BodyContentImpl.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/runtime/BodyContentImpl.java 2025-12-02 16:54:08.000000000 +0000
@@ -27,11 +27,8 @@
import org.apache.jasper.compiler.Localizer;
/**
- * Write text to a character-output stream, buffering characters to provide efficient writing of single
- * characters, arrays, and strings. Provide support for discarding the output that has been buffered.
- *
- * @author Rajiv Mordani
- * @author Jan Luehe
+ * Write text to a character-output stream, buffering characters to provide efficient writing of single characters,
+ * arrays, and strings. Provide support for discarding the output that has been buffered.
*/
public class BodyContentImpl extends BodyContent {
@@ -370,7 +367,7 @@
this.writer = null;
try {
this.clear();
- } catch (IOException ex) {
+ } catch (IOException ignore) {
// ignore
}
}
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/runtime/HttpJspBase.java tomcat11-11.0.15/java/org/apache/jasper/runtime/HttpJspBase.java
--- tomcat11-11.0.6/java/org/apache/jasper/runtime/HttpJspBase.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/runtime/HttpJspBase.java 2025-12-02 16:54:08.000000000 +0000
@@ -31,8 +31,6 @@
/**
* This is the super class of all JSP-generated servlets.
- *
- * @author Anil K. Vijendran
*/
public abstract class HttpJspBase extends HttpServlet implements HttpJspPage {
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/runtime/JspApplicationContextImpl.java tomcat11-11.0.15/java/org/apache/jasper/runtime/JspApplicationContextImpl.java
--- tomcat11-11.0.6/java/org/apache/jasper/runtime/JspApplicationContextImpl.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/runtime/JspApplicationContextImpl.java 2025-12-02 16:54:08.000000000 +0000
@@ -33,9 +33,7 @@
import org.apache.jasper.el.JasperELResolver;
/**
- * Implementation of JspApplicationContext
- *
- * @author Jacob Hookom
+ * Implementation of JspApplicationContext.
*/
public class JspApplicationContextImpl implements JspApplicationContext {
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/runtime/JspContextWrapper.java tomcat11-11.0.15/java/org/apache/jasper/runtime/JspContextWrapper.java
--- tomcat11-11.0.6/java/org/apache/jasper/runtime/JspContextWrapper.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/runtime/JspContextWrapper.java 2025-12-02 16:54:08.000000000 +0000
@@ -57,10 +57,6 @@
* Implementation of a JSP Context Wrapper. The JSP Context Wrapper is a JspContext created and maintained by a tag
* handler implementation. It wraps the Invoking JSP Context, that is, the JspContext instance passed to the tag handler
* by the invoking page via setJspContext().
- *
- * @author Kin-man Chung
- * @author Jan Luehe
- * @author Jacob Hookom
*/
public class JspContextWrapper extends PageContext {
@@ -189,7 +185,7 @@
if (getSession() != null) {
try {
o = rootJspCtxt.getAttribute(name, SESSION_SCOPE);
- } catch (IllegalStateException ise) {
+ } catch (IllegalStateException ignore) {
// Session has been invalidated.
// Ignore and fall through to application scope.
}
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/runtime/JspFactoryImpl.java tomcat11-11.0.15/java/org/apache/jasper/runtime/JspFactoryImpl.java
--- tomcat11-11.0.6/java/org/apache/jasper/runtime/JspFactoryImpl.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/runtime/JspFactoryImpl.java 2025-12-02 16:54:08.000000000 +0000
@@ -31,8 +31,6 @@
/**
* Implementation of JspFactory.
- *
- * @author Anil K. Vijendran
*/
public class JspFactoryImpl extends JspFactory {
@@ -60,7 +58,7 @@
try {
pc.initialize(servlet, request, response, errorPageURL, needsSession, bufferSize, autoflush);
- } catch (IOException ioe) {
+ } catch (IOException ignore) {
// Implementation never throws IOE but can't change the signature
// since it is part of the JSP API
}
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/runtime/JspFragmentHelper.java tomcat11-11.0.15/java/org/apache/jasper/runtime/JspFragmentHelper.java
--- tomcat11-11.0.6/java/org/apache/jasper/runtime/JspFragmentHelper.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/runtime/JspFragmentHelper.java 2025-12-02 16:54:08.000000000 +0000
@@ -27,8 +27,6 @@
* JspFragments in a single page.
*
* The class also provides various utility methods for JspFragment implementations.
- *
- * @author Mark Roth
*/
public abstract class JspFragmentHelper extends JspFragment {
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/runtime/JspRuntimeLibrary.java tomcat11-11.0.15/java/org/apache/jasper/runtime/JspRuntimeLibrary.java
--- tomcat11-11.0.6/java/org/apache/jasper/runtime/JspRuntimeLibrary.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/runtime/JspRuntimeLibrary.java 2025-12-02 16:54:08.000000000 +0000
@@ -25,6 +25,7 @@
import java.nio.charset.StandardCharsets;
import java.util.Enumeration;
+import jakarta.el.VariableMapper;
import jakarta.servlet.RequestDispatcher;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
@@ -45,9 +46,6 @@
/**
* Bunch of util methods that are used by code generated for useBean, getProperty and setProperty.
- *
- * @author Mandar Raje
- * @author Shawn Bayern
*/
public class JspRuntimeLibrary {
@@ -280,8 +278,8 @@
} else {
return getValueFromPropertyEditorManager(t, propertyName, s);
}
- } catch (Exception ex) {
- throw new JasperException(ex);
+ } catch (Exception e) {
+ throw new JasperException(e);
}
}
@@ -347,10 +345,10 @@
}
}
}
- } catch (Exception ex) {
- Throwable thr = ExceptionUtils.unwrapInvocationTargetException(ex);
+ } catch (Exception e) {
+ Throwable thr = ExceptionUtils.unwrapInvocationTargetException(e);
ExceptionUtils.handleThrowable(thr);
- throw new JasperException(ex);
+ throw new JasperException(e);
}
if (!ignoreMethodNF && (method == null)) {
if (type == null) {
@@ -573,10 +571,10 @@
try {
Method method = getReadMethod(o.getClass(), prop);
value = method.invoke(o, (Object[]) null);
- } catch (Exception ex) {
- Throwable thr = ExceptionUtils.unwrapInvocationTargetException(ex);
+ } catch (Exception e) {
+ Throwable thr = ExceptionUtils.unwrapInvocationTargetException(e);
ExceptionUtils.handleThrowable(thr);
- throw new JasperException(ex);
+ throw new JasperException(e);
}
return value;
}
@@ -586,12 +584,12 @@
ProtectedFunctionMapper functionMapper) throws JasperException {
try {
Method method = getWriteMethod(bean.getClass(), prop);
- method.invoke(bean, PageContextImpl.proprietaryEvaluate(expression,
- method.getParameterTypes()[0], pageContext, functionMapper));
- } catch (Exception ex) {
- Throwable thr = ExceptionUtils.unwrapInvocationTargetException(ex);
+ method.invoke(bean, PageContextImpl.proprietaryEvaluate(expression, method.getParameterTypes()[0],
+ pageContext, functionMapper));
+ } catch (Exception e) {
+ Throwable thr = ExceptionUtils.unwrapInvocationTargetException(e);
ExceptionUtils.handleThrowable(thr);
- throw new JasperException(ex);
+ throw new JasperException(e);
}
}
@@ -599,10 +597,10 @@
try {
Method method = getWriteMethod(bean.getClass(), prop);
method.invoke(bean, value);
- } catch (Exception ex) {
- Throwable thr = ExceptionUtils.unwrapInvocationTargetException(ex);
+ } catch (Exception e) {
+ Throwable thr = ExceptionUtils.unwrapInvocationTargetException(e);
ExceptionUtils.handleThrowable(thr);
- throw new JasperException(ex);
+ throw new JasperException(e);
}
}
@@ -610,10 +608,10 @@
try {
Method method = getWriteMethod(bean.getClass(), prop);
method.invoke(bean, Integer.valueOf(value));
- } catch (Exception ex) {
- Throwable thr = ExceptionUtils.unwrapInvocationTargetException(ex);
+ } catch (Exception e) {
+ Throwable thr = ExceptionUtils.unwrapInvocationTargetException(e);
ExceptionUtils.handleThrowable(thr);
- throw new JasperException(ex);
+ throw new JasperException(e);
}
}
@@ -621,10 +619,10 @@
try {
Method method = getWriteMethod(bean.getClass(), prop);
method.invoke(bean, Short.valueOf(value));
- } catch (Exception ex) {
- Throwable thr = ExceptionUtils.unwrapInvocationTargetException(ex);
+ } catch (Exception e) {
+ Throwable thr = ExceptionUtils.unwrapInvocationTargetException(e);
ExceptionUtils.handleThrowable(thr);
- throw new JasperException(ex);
+ throw new JasperException(e);
}
}
@@ -632,10 +630,10 @@
try {
Method method = getWriteMethod(bean.getClass(), prop);
method.invoke(bean, Long.valueOf(value));
- } catch (Exception ex) {
- Throwable thr = ExceptionUtils.unwrapInvocationTargetException(ex);
+ } catch (Exception e) {
+ Throwable thr = ExceptionUtils.unwrapInvocationTargetException(e);
ExceptionUtils.handleThrowable(thr);
- throw new JasperException(ex);
+ throw new JasperException(e);
}
}
@@ -643,10 +641,10 @@
try {
Method method = getWriteMethod(bean.getClass(), prop);
method.invoke(bean, Double.valueOf(value));
- } catch (Exception ex) {
- Throwable thr = ExceptionUtils.unwrapInvocationTargetException(ex);
+ } catch (Exception e) {
+ Throwable thr = ExceptionUtils.unwrapInvocationTargetException(e);
ExceptionUtils.handleThrowable(thr);
- throw new JasperException(ex);
+ throw new JasperException(e);
}
}
@@ -654,10 +652,10 @@
try {
Method method = getWriteMethod(bean.getClass(), prop);
method.invoke(bean, Float.valueOf(value));
- } catch (Exception ex) {
- Throwable thr = ExceptionUtils.unwrapInvocationTargetException(ex);
+ } catch (Exception e) {
+ Throwable thr = ExceptionUtils.unwrapInvocationTargetException(e);
ExceptionUtils.handleThrowable(thr);
- throw new JasperException(ex);
+ throw new JasperException(e);
}
}
@@ -665,10 +663,10 @@
try {
Method method = getWriteMethod(bean.getClass(), prop);
method.invoke(bean, Character.valueOf(value));
- } catch (Exception ex) {
- Throwable thr = ExceptionUtils.unwrapInvocationTargetException(ex);
+ } catch (Exception e) {
+ Throwable thr = ExceptionUtils.unwrapInvocationTargetException(e);
ExceptionUtils.handleThrowable(thr);
- throw new JasperException(ex);
+ throw new JasperException(e);
}
}
@@ -676,10 +674,10 @@
try {
Method method = getWriteMethod(bean.getClass(), prop);
method.invoke(bean, Byte.valueOf(value));
- } catch (Exception ex) {
- Throwable thr = ExceptionUtils.unwrapInvocationTargetException(ex);
+ } catch (Exception e) {
+ Throwable thr = ExceptionUtils.unwrapInvocationTargetException(e);
ExceptionUtils.handleThrowable(thr);
- throw new JasperException(ex);
+ throw new JasperException(e);
}
}
@@ -687,10 +685,10 @@
try {
Method method = getWriteMethod(bean.getClass(), prop);
method.invoke(bean, Boolean.valueOf(value));
- } catch (Exception ex) {
- Throwable thr = ExceptionUtils.unwrapInvocationTargetException(ex);
+ } catch (Exception e) {
+ Throwable thr = ExceptionUtils.unwrapInvocationTargetException(e);
ExceptionUtils.handleThrowable(thr);
- throw new JasperException(ex);
+ throw new JasperException(e);
}
}
@@ -732,8 +730,8 @@
break;
}
}
- } catch (Exception ex) {
- throw new JasperException(ex);
+ } catch (Exception e) {
+ throw new JasperException(e);
}
}
if (result == null) {
@@ -770,8 +768,8 @@
break;
}
}
- } catch (Exception ex) {
- throw new JasperException(ex);
+ } catch (Exception e) {
+ throw new JasperException(e);
}
}
if (result == null) {
@@ -794,12 +792,12 @@
PropertyEditor pe = (PropertyEditor) propertyEditorClass.getConstructor().newInstance();
pe.setAsText(attrValue);
return pe.getValue();
- } catch (Exception ex) {
+ } catch (Exception e) {
if (attrValue.isEmpty()) {
return null;
} else {
throw new JasperException(Localizer.getMessage("jsp.error.beans.property.conversion", attrValue,
- attrClass.getName(), attrName, ex.getMessage()));
+ attrClass.getName(), attrName, e.getMessage()));
}
}
}
@@ -957,4 +955,30 @@
}
}
+
+ /**
+ * This method parallels the logic of {@code SetSupport.doEndTag()}.
+ *
+ * @param pageContext pageContext
+ * @param var name of the variable
+ * @param value value to store
+ * @param scope scope
+ */
+ public static void nonstandardSetTag(jakarta.servlet.jsp.PageContext pageContext, String var, Object value,
+ int scope) {
+ if (value == null) {
+ // matches SetTag and removes the key from the specified scope
+ pageContext.removeAttribute(var, scope);
+ } else {
+ if (scope == PageContext.PAGE_SCOPE) {
+ // matches SetTag and cleans up the VariableMapper
+ VariableMapper vm = pageContext.getELContext().getVariableMapper();
+ if (vm != null) {
+ vm.setVariable(var, null);
+ }
+ }
+ // does the all-important set of the correct scope
+ pageContext.setAttribute(var, value, scope);
+ }
+ }
}
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/runtime/JspWriterImpl.java tomcat11-11.0.15/java/org/apache/jasper/runtime/JspWriterImpl.java
--- tomcat11-11.0.6/java/org/apache/jasper/runtime/JspWriterImpl.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/runtime/JspWriterImpl.java 2025-12-02 16:54:08.000000000 +0000
@@ -27,11 +27,9 @@
import org.apache.jasper.compiler.Localizer;
/**
- * Write text to a character-output stream, buffering characters to provide efficient writing of single
- * characters, arrays, and strings. Provide support for discarding the output that has been buffered. This needs
- * revisiting when the buffering problems in the JSP spec are fixed -akv
- *
- * @author Anil K. Vijendran
+ * Write text to a character-output stream, buffering characters to provide efficient writing of single characters,
+ * arrays, and strings. Provide support for discarding the output that has been buffered. This needs revisiting when the
+ * buffering problems in the JSP spec are fixed -akv.
*/
public class JspWriterImpl extends JspWriter {
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/runtime/PageContextImpl.java tomcat11-11.0.15/java/org/apache/jasper/runtime/PageContextImpl.java
--- tomcat11-11.0.6/java/org/apache/jasper/runtime/PageContextImpl.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/runtime/PageContextImpl.java 2025-12-02 16:54:08.000000000 +0000
@@ -53,14 +53,6 @@
/**
* Implementation of the PageContext class from the JSP spec. Also doubles as a VariableResolver for the EL.
- *
- * @author Anil K. Vijendran
- * @author Larry Cable
- * @author Hans Bergsten
- * @author Pierre Delisle
- * @author Mark Roth
- * @author Jan Luehe
- * @author Jacob Hookom
*/
public class PageContextImpl extends PageContext {
@@ -172,8 +164,8 @@
out = baseOut;
try {
((JspWriterImpl) out).flushBuffer();
- } catch (IOException ex) {
- throw new IllegalStateException(Localizer.getMessage("jsp.error.flush"), ex);
+ } catch (IOException ioe) {
+ throw new IllegalStateException(Localizer.getMessage("jsp.error.flush"), ioe);
} finally {
servlet = null;
config = null;
@@ -312,7 +304,7 @@
if (session.getAttribute(name) != null) {
return SESSION_SCOPE;
}
- } catch (IllegalStateException ise) {
+ } catch (IllegalStateException ignore) {
// Session has been invalidated.
// Ignore and fall through to application scope.
}
@@ -344,7 +336,7 @@
if (session != null) {
try {
o = session.getAttribute(name);
- } catch (IllegalStateException ise) {
+ } catch (IllegalStateException ignore) {
// Session has been invalidated.
// Ignore and fall through to application scope.
}
@@ -384,7 +376,7 @@
if (session != null) {
try {
removeAttribute(name, SESSION_SCOPE);
- } catch (IllegalStateException ise) {
+ } catch (IllegalStateException ignore) {
// Session has been invalidated.
// Ignore and fall throw to application scope.
}
@@ -477,8 +469,8 @@
try {
out.clear();
baseOut.clear();
- } catch (IOException ex) {
- throw new IllegalStateException(Localizer.getMessage("jsp.error.attempt_to_clear_flushed_buffer"), ex);
+ } catch (IOException ioe) {
+ throw new IllegalStateException(Localizer.getMessage("jsp.error.attempt_to_clear_flushed_buffer"), ioe);
}
// Make sure that the response object is not the wrapper for include
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/runtime/ProtectedFunctionMapper.java tomcat11-11.0.15/java/org/apache/jasper/runtime/ProtectedFunctionMapper.java
--- tomcat11-11.0.6/java/org/apache/jasper/runtime/ProtectedFunctionMapper.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/runtime/ProtectedFunctionMapper.java 2025-12-02 16:54:08.000000000 +0000
@@ -22,9 +22,6 @@
/**
* Maps EL functions to their Java method counterparts. Keeps the actual Method objects protected so that JSP pages
* can't indirectly do reflection.
- *
- * @author Mark Roth
- * @author Kin-man Chung
*/
public final class ProtectedFunctionMapper extends jakarta.el.FunctionMapper {
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/runtime/ServletResponseWrapperInclude.java tomcat11-11.0.15/java/org/apache/jasper/runtime/ServletResponseWrapperInclude.java
--- tomcat11-11.0.6/java/org/apache/jasper/runtime/ServletResponseWrapperInclude.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/runtime/ServletResponseWrapperInclude.java 2025-12-02 16:54:08.000000000 +0000
@@ -28,10 +28,7 @@
/**
* ServletResponseWrapper used by the JSP 'include' action. This wrapper response object is passed to
* RequestDispatcher.include(), so that the output of the included resource is appended to that of the including page.
- *
- * @author Pierre Delisle
*/
-
public class ServletResponseWrapperInclude extends HttpServletResponseWrapper {
/**
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/runtime/TagHandlerPool.java tomcat11-11.0.15/java/org/apache/jasper/runtime/TagHandlerPool.java
--- tomcat11-11.0.6/java/org/apache/jasper/runtime/TagHandlerPool.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/runtime/TagHandlerPool.java 2025-12-02 16:54:08.000000000 +0000
@@ -27,8 +27,6 @@
/**
* Pool of tag handlers that can be reused.
- *
- * @author Jan Luehe
*/
public class TagHandlerPool {
@@ -69,7 +67,7 @@
if (maxSizeS != null) {
try {
maxSize = Integer.parseInt(maxSizeS);
- } catch (Exception ex) {
+ } catch (Exception e) {
// Ignore
}
}
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/servlet/JasperLoader.java tomcat11-11.0.15/java/org/apache/jasper/servlet/JasperLoader.java
--- tomcat11-11.0.6/java/org/apache/jasper/servlet/JasperLoader.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/servlet/JasperLoader.java 2025-12-02 16:54:08.000000000 +0000
@@ -24,9 +24,6 @@
/**
* Class loader for loading servlet class files (corresponding to JSP files) and tag handler class files (corresponding
* to tag files).
- *
- * @author Anil K. Vijendran
- * @author Harish Prabandham
*/
public class JasperLoader extends URLClassLoader {
@@ -110,7 +107,7 @@
if (url != null) {
try {
is = url.openStream();
- } catch (IOException e) {
+ } catch (IOException ignore) {
// Ignore
}
}
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/servlet/JspCServletContext.java tomcat11-11.0.15/java/org/apache/jasper/servlet/JspCServletContext.java
--- tomcat11-11.0.6/java/org/apache/jasper/servlet/JspCServletContext.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/servlet/JspCServletContext.java 2025-12-02 16:54:08.000000000 +0000
@@ -66,10 +66,7 @@
/**
* Simple ServletContext implementation without HTTP-specific methods.
- *
- * @author Peter Rossbach (pr@webapp.de)
*/
-
public class JspCServletContext implements ServletContext {
@@ -154,8 +151,8 @@
if (!webXmlParser.parseWebXml(url, webXml, false)) {
throw new JasperException(Localizer.getMessage("jspc.error.invalidWebXml"));
}
- } catch (IOException e) {
- throw new JasperException(e);
+ } catch (IOException ioe) {
+ throw new JasperException(ioe);
}
// if the application is metadata-complete then we can skip fragment processing
@@ -411,8 +408,8 @@
}
}
}
- } catch (IOException e) {
- log(e.getMessage(), e);
+ } catch (IOException ioe) {
+ log(ioe.getMessage(), ioe);
}
}
}
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/servlet/JspServlet.java tomcat11-11.0.15/java/org/apache/jasper/servlet/JspServlet.java
--- tomcat11-11.0.6/java/org/apache/jasper/servlet/JspServlet.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/servlet/JspServlet.java 2025-12-02 16:54:08.000000000 +0000
@@ -41,16 +41,9 @@
import org.apache.tomcat.util.security.Escape;
/**
- * The Jasper JSP engine. The servlet container is responsible for providing a URLClassLoader for the web
- * application context Jasper is being used in. Jasper will try to get the Tomcat ServletContext attribute for its
- * ServletContext class loader, if that fails, it uses the parent class loader. In either case, it must be a
- * URLClassLoader.
- *
- * @author Anil K. Vijendran
- * @author Harish Prabandham
- * @author Remy Maucherat
- * @author Kin-man Chung
- * @author Glenn Nielsen
+ * The Jasper JSP engine. The servlet container is responsible for providing a URLClassLoader for the web application
+ * context Jasper is being used in. Jasper will try to get the Tomcat ServletContext attribute for its ServletContext
+ * class loader, if that fails, it uses the parent class loader. In either case, it must be a URLClassLoader.
*/
public class JspServlet extends HttpServlet implements PeriodicEventListener {
@@ -88,8 +81,8 @@
Constructor> ctor = engineOptionsClass.getConstructor(ctorSig);
Object[] args = { config, context };
options = (Options) ctor.newInstance(args);
- } catch (Throwable e) {
- Throwable throwable = ExceptionUtils.unwrapInvocationTargetException(e);
+ } catch (Throwable t) {
+ Throwable throwable = ExceptionUtils.unwrapInvocationTargetException(t);
ExceptionUtils.handleThrowable(throwable);
// Need to localize this.
log.warn(Localizer.getMessage("jsp.warning.engineOptionsClass", engineOptionsName), throwable);
@@ -112,8 +105,8 @@
}
try {
serviceJspFile(null, null, jspFile, true);
- } catch (IOException e) {
- throw new ServletException(Localizer.getMessage("jsp.error.precompilation", jspFile), e);
+ } catch (IOException ioe) {
+ throw new ServletException(Localizer.getMessage("jsp.error.precompilation", jspFile), ioe);
}
}
@@ -288,9 +281,9 @@
serviceJspFile(request, response, jspUri, precompile);
} catch (RuntimeException | IOException | ServletException e) {
throw e;
- } catch (Throwable e) {
- ExceptionUtils.handleThrowable(e);
- throw new ServletException(e);
+ } catch (Throwable t) {
+ ExceptionUtils.handleThrowable(t);
+ throw new ServletException(t);
}
}
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/servlet/JspServletWrapper.java tomcat11-11.0.15/java/org/apache/jasper/servlet/JspServletWrapper.java
--- tomcat11-11.0.6/java/org/apache/jasper/servlet/JspServletWrapper.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/servlet/JspServletWrapper.java 2025-12-02 16:54:08.000000000 +0000
@@ -49,17 +49,9 @@
import org.apache.tomcat.Jar;
/**
- * The Jasper JSP engine. The servlet container is responsible for providing a URLClassLoader for the web
- * application context Jasper is being used in. Jasper will try to get the Tomcat ServletContext attribute for its
- * ServletContext class loader, if that fails, it uses the parent class loader. In either case, it must be a
- * URLClassLoader.
- *
- * @author Anil K. Vijendran
- * @author Harish Prabandham
- * @author Remy Maucherat
- * @author Kin-man Chung
- * @author Glenn Nielsen
- * @author Tim Fennell
+ * The Jasper JSP engine. The servlet container is responsible for providing a URLClassLoader for the web application
+ * context Jasper is being used in. Jasper will try to get the Tomcat ServletContext attribute for its ServletContext
+ * class loader, if that fails, it uses the parent class loader. In either case, it must be a URLClassLoader.
*/
public class JspServletWrapper {
@@ -402,11 +394,11 @@
throw handleJspException(ex);
}
throw ex;
- } catch (Exception ex) {
+ } catch (Exception e) {
if (options.getDevelopment()) {
- throw handleJspException(ex);
+ throw handleJspException(e);
}
- throw new JasperException(ex);
+ throw new JasperException(e);
}
try {
@@ -454,16 +446,16 @@
throw handleJspException(ex);
}
throw ex;
- } catch (IOException ex) {
+ } catch (IOException ioe) {
if (options.getDevelopment()) {
- throw new IOException(handleJspException(ex).getMessage(), ex);
+ throw new IOException(handleJspException(ioe).getMessage(), ioe);
}
- throw ex;
- } catch (Exception ex) {
+ throw ioe;
+ } catch (Exception e) {
if (options.getDevelopment()) {
- throw handleJspException(ex);
+ throw handleJspException(e);
}
- throw new JasperException(ex);
+ throw new JasperException(e);
}
}
@@ -513,7 +505,8 @@
* Attempts to construct a JasperException that contains helpful information about what went wrong. Uses the JSP
* compiler system to translate the line number in the generated servlet that originated the exception to a line
* number in the JSP. Then constructs an exception containing that information, and a snippet of the JSP to help
- * debugging. Please see BZ 37062 for more details.
+ * debugging. Please see BZ 37062 for more
+ * details.
*
*
* @param ex the exception that was the cause of the problem.
@@ -523,8 +516,9 @@
protected JasperException handleJspException(Exception ex) {
try {
Throwable realException = ex;
- if (ex instanceof ServletException) {
- realException = ((ServletException) ex).getRootCause();
+ // Unwrap Servlet exception once
+ if (ex instanceof ServletException servletException && servletException.getRootCause() != null) {
+ realException = servletException.getRootCause();
}
// Find the first stack frame that represents code generated by
@@ -563,8 +557,8 @@
throw new JasperException(ex);
}
- JavacErrorDetail detail = new JavacErrorDetail(jspFrame.getMethodName(), javaLineNumber,
- source.fileName(), source.lineNumber(), null, ctxt);
+ JavacErrorDetail detail = new JavacErrorDetail(jspFrame.getMethodName(), javaLineNumber, source.fileName(),
+ source.lineNumber(), null, ctxt);
if (options.getDisplaySourceFragment()) {
return new JasperException(
@@ -577,7 +571,7 @@
return new JasperException(
Localizer.getMessage("jsp.exception", detail.getJspFileName(), "" + source.lineNumber()), ex);
- } catch (Exception je) {
+ } catch (Exception e) {
// If anything goes wrong, just revert to the original behaviour
if (ex instanceof JasperException) {
return (JasperException) ex;
diff -Nru tomcat11-11.0.6/java/org/apache/jasper/tagplugins/jstl/core/Import.java tomcat11-11.0.15/java/org/apache/jasper/tagplugins/jstl/core/Import.java
--- tomcat11-11.0.6/java/org/apache/jasper/tagplugins/jstl/core/Import.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/jasper/tagplugins/jstl/core/Import.java 2025-12-02 16:54:08.000000000 +0000
@@ -158,7 +158,7 @@
ctxt.generateJavaSource(" try{");
ctxt.generateJavaSource(" " + tempReaderName + " = new java.io.InputStreamReader(" +
inputStreamName + ", " + charSetName + ");");
- ctxt.generateJavaSource(" }catch(Exception ex){");
+ ctxt.generateJavaSource(" }catch(Exception e){");
ctxt.generateJavaSource(" " + tempReaderName + " = new java.io.InputStreamReader(" +
inputStreamName + ", org.apache.jasper.tagplugins.jstl.Util.DEFAULT_ENCODING);");
ctxt.generateJavaSource(" }");
@@ -306,8 +306,7 @@
ctxt.generateJavaSource(" try{");
ctxt.generateJavaSource(" " + tempReaderName + " = new java.io.InputStreamReader(" +
inputStreamName + "," + charSetName + ");");
- ctxt.generateJavaSource(" }catch(Exception ex){");
- // ctxt.generateJavaSource(" throw new JspTagException(ex.toString());");
+ ctxt.generateJavaSource(" }catch(Exception e){");
ctxt.generateJavaSource(" " + tempReaderName + " = new java.io.InputStreamReader(" +
inputStreamName + ",org.apache.jasper.tagplugins.jstl.Util.DEFAULT_ENCODING);");
ctxt.generateJavaSource(" }");
diff -Nru tomcat11-11.0.6/java/org/apache/juli/AsyncFileHandler.java tomcat11-11.0.15/java/org/apache/juli/AsyncFileHandler.java
--- tomcat11-11.0.6/java/org/apache/juli/AsyncFileHandler.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/juli/AsyncFileHandler.java 2025-12-02 16:54:08.000000000 +0000
@@ -55,8 +55,8 @@
public static final int MAX_RECORDS = Integer
.parseInt(System.getProperty("org.apache.juli.AsyncMaxRecordCount", Integer.toString(DEFAULT_MAX_RECORDS)));
- private static final LoggerExecutorService LOGGER_SERVICE = new LoggerExecutorService(OVERFLOW_DROP_TYPE,
- MAX_RECORDS);
+ private static final LoggerExecutorService LOGGER_SERVICE =
+ new LoggerExecutorService(OVERFLOW_DROP_TYPE, MAX_RECORDS);
private final Object closeLock = new Object();
protected volatile boolean closed = false;
@@ -121,8 +121,8 @@
record.getSourceMethodName();
loggerService.execute(() -> {
/*
- * During Tomcat shutdown, the Handlers are closed before the executor queue is flushed therefore the
- * closed flag is ignored if the executor is shutting down.
+ * During Tomcat shutdown, the Handlers are closed before the executor queue is flushed therefore the closed
+ * flag is ignored if the executor is shutting down.
*/
if (!closed || loggerService.isTerminating()) {
publishInternal(record);
diff -Nru tomcat11-11.0.6/java/org/apache/juli/ClassLoaderLogManager.java tomcat11-11.0.15/java/org/apache/juli/ClassLoaderLogManager.java
--- tomcat11-11.0.6/java/org/apache/juli/ClassLoaderLogManager.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/juli/ClassLoaderLogManager.java 2025-12-02 16:54:08.000000000 +0000
@@ -78,7 +78,7 @@
* Map containing the classloader information, keyed per classloader. A weak hashmap is used to ensure no
* classloader reference is leaked from application redeployment.
*/
- protected final Map classLoaderLoggers = new WeakHashMap<>(); // Guarded by this
+ protected final Map classLoaderLoggers = new WeakHashMap<>(); // Guarded by this
/**
@@ -338,7 +338,7 @@
for (Handler handler : clLogInfo.handlers.values()) {
try {
handler.close();
- } catch (Exception e) {
+ } catch (Exception ignore) {
// Ignore
}
}
@@ -365,7 +365,7 @@
if (info == null) {
try {
readConfiguration(classLoader);
- } catch (IOException e) {
+ } catch (IOException ignore) {
// Ignore
}
info = classLoaderLoggers.get(classLoader);
@@ -407,9 +407,9 @@
if (configFileStr != null) {
try {
is = new FileInputStream(replace(configFileStr));
- } catch (IOException e) {
+ } catch (IOException ioe) {
System.err.println("Configuration error");
- e.printStackTrace();
+ ioe.printStackTrace();
}
}
// Try the default JVM configuration
@@ -417,9 +417,9 @@
File defaultFile = new File(new File(System.getProperty("java.home"), "conf"), "logging.properties");
try {
is = new FileInputStream(defaultFile);
- } catch (IOException e) {
+ } catch (IOException ioe) {
System.err.println("Configuration error");
- e.printStackTrace();
+ ioe.printStackTrace();
}
}
}
@@ -472,10 +472,10 @@
try (is) {
info.props.load(is);
- } catch (IOException e) {
+ } catch (IOException ioe) {
// Report error
System.err.println("Configuration error");
- e.printStackTrace();
+ ioe.printStackTrace();
}
// Ignore
@@ -606,7 +606,7 @@
protected static final class LogNode {
Logger logger;
- final Map children = new HashMap<>();
+ final Map children = new HashMap<>();
final LogNode parent;
@@ -672,8 +672,8 @@
protected static final class ClassLoaderLogInfo {
final LogNode rootNode;
- final Map loggers = new ConcurrentHashMap<>();
- final Map handlers = new HashMap<>();
+ final Map loggers = new ConcurrentHashMap<>();
+ final Map handlers = new HashMap<>();
final Properties props = new Properties();
ClassLoaderLogInfo(final LogNode rootNode) {
diff -Nru tomcat11-11.0.6/java/org/apache/juli/FileHandler.java tomcat11-11.0.15/java/org/apache/juli/FileHandler.java
--- tomcat11-11.0.6/java/org/apache/juli/FileHandler.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/juli/FileHandler.java 2025-12-02 16:54:08.000000000 +0000
@@ -84,8 +84,8 @@
public static final int DEFAULT_BUFFER_SIZE = -1;
- private static final ExecutorService DELETE_FILES_SERVICE = Executors
- .newSingleThreadExecutor(new ThreadFactory("FileHandlerLogFilesCleaner-"));
+ private static final ExecutorService DELETE_FILES_SERVICE =
+ Executors.newSingleThreadExecutor(new ThreadFactory("FileHandlerLogFilesCleaner-"));
// ------------------------------------------------------------ Constructor
@@ -364,7 +364,7 @@
if (encoding != null && !encoding.isEmpty()) {
try {
setEncoding(encoding);
- } catch (UnsupportedEncodingException ex) {
+ } catch (UnsupportedEncodingException ignore) {
// Ignore
}
}
@@ -377,7 +377,7 @@
if (filterName != null) {
try {
setFilter((Filter) cl.loadClass(filterName).getConstructor().newInstance());
- } catch (Exception e) {
+ } catch (Exception ignore) {
// Ignore
}
}
@@ -387,7 +387,7 @@
if (formatterName != null) {
try {
setFormatter((Formatter) cl.loadClass(formatterName).getConstructor().newInstance());
- } catch (Exception e) {
+ } catch (Exception ignore) {
// Ignore and fallback to defaults
setFormatter(new OneLineFormatter());
}
@@ -452,14 +452,14 @@
if (fos != null) {
try {
fos.close();
- } catch (IOException e1) {
+ } catch (IOException ignore) {
// Ignore
}
}
if (os != null) {
try {
os.close();
- } catch (IOException e1) {
+ } catch (IOException ignore) {
// Ignore
}
}
@@ -477,7 +477,7 @@
for (Path file : files) {
Files.delete(file);
}
- } catch (IOException e) {
+ } catch (IOException ioe) {
reportError("Unable to delete log files older than [" + maxDays + "] days", null,
ErrorManager.GENERIC_FAILURE);
}
@@ -493,8 +493,8 @@
try {
LocalDate dateFromFile = LocalDate.from(DateTimeFormatter.ISO_LOCAL_DATE.parse(date));
result = dateFromFile.isBefore(maxDaysOffset);
- } catch (DateTimeException e) {
- // no-op
+ } catch (DateTimeException ignore) {
+ // Unable to determine date from path. File will not be included.
}
}
return result;
diff -Nru tomcat11-11.0.6/java/org/apache/juli/JdkLoggerFormatter.java tomcat11-11.0.15/java/org/apache/juli/JdkLoggerFormatter.java
--- tomcat11-11.0.6/java/org/apache/juli/JdkLoggerFormatter.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/juli/JdkLoggerFormatter.java 2025-12-02 16:54:08.000000000 +0000
@@ -31,8 +31,6 @@
*
*
* Example: 1130122891846 Http11BaseProtocol I Initializing Coyote HTTP/1.1 on http-8800
- *
- * @author Costin Manolache
*/
public class JdkLoggerFormatter extends Formatter {
@@ -96,7 +94,7 @@
buf.append(" ".repeat(Math.max(0, 8 - buf.length())));
// Append the message
- buf.append(message);
+ buf.append(LogUtil.escape(message));
// Append stack trace if not null
if (t != null) {
@@ -106,7 +104,7 @@
java.io.PrintWriter pw = new java.io.PrintWriter(sw);
t.printStackTrace(pw);
pw.close();
- buf.append(sw);
+ buf.append(LogUtil.escape(sw.toString()));
}
buf.append(System.lineSeparator());
diff -Nru tomcat11-11.0.6/java/org/apache/juli/JsonFormatter.java tomcat11-11.0.15/java/org/apache/juli/JsonFormatter.java
--- tomcat11-11.0.6/java/org/apache/juli/JsonFormatter.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/juli/JsonFormatter.java 2025-12-02 16:54:08.000000000 +0000
@@ -20,9 +20,8 @@
import java.util.logging.LogRecord;
/**
- * Provides the same information as the one line format but using JSON formatting.
- * All the information of the LogRecord is included as a one line JSON document,
- * including the full stack trace of the associated exception if any.
+ * Provides the same information as the one line format but using JSON formatting. All the information of the LogRecord
+ * is included as a one line JSON document, including the full stack trace of the associated exception if any.
*
* The LogRecord is mapped as attributes:
*
@@ -32,9 +31,9 @@
*
class: the class from which the log originated
*
method: the method from which the log originated
*
message: the log message
- *
throwable: the full stack trace from an exception, if present, represented as an array of string
- * (the message first, then one string per stack trace element prefixed by a whitespace,
- * then moving on to the cause exception if any)
+ *
throwable: the full stack trace from an exception, if present, represented as an array of string (the message
+ * first, then one string per stack trace element prefixed by a whitespace, then moving on to the cause exception if
+ * any)
*
*/
public class JsonFormatter extends OneLineFormatter {
@@ -66,14 +65,7 @@
// Thread
sb.append("\"thread\": \"");
- final String threadName = Thread.currentThread().getName();
- if (threadName != null && threadName.startsWith(AsyncFileHandler.THREAD_PREFIX)) {
- // If using the async handler can't get the thread name from the
- // current thread.
- sb.append(getThreadName(record.getLongThreadID()));
- } else {
- sb.append(threadName);
- }
+ sb.append(resolveThreadName(record));
sb.append("\", ");
// Source
@@ -121,15 +113,16 @@
/**
- * Provides escaping of values so they can be included in a JSON document.
- * Escaping is based on the definition of JSON found in
- * RFC 8259.
+ * Provides escaping of values so they can be included in a JSON document. Escaping is based on the definition of
+ * JSON found in RFC 8259.
*/
public static class JSONFilter {
/**
* Escape the given string.
+ *
* @param input the string
+ *
* @return the escaped string
*/
public static String escape(String input) {
@@ -138,16 +131,17 @@
/**
* Escape the given char sequence.
- * @param input the char sequence
- * @param off the offset on which escaping will start
+ *
+ * @param input the char sequence
+ * @param off the offset on which escaping will start
* @param length the length which should be escaped
+ *
* @return the escaped char sequence corresponding to the specified range
*/
public static CharSequence escape(CharSequence input, int off, int length) {
/*
- * While any character MAY be escaped, only U+0000 to U+001F (control
- * characters), U+0022 (quotation mark) and U+005C (reverse solidus)
- * MUST be escaped.
+ * While any character MAY be escaped, only U+0000 to U+001F (control characters), U+0022 (quotation mark)
+ * and U+005C (reverse solidus) MUST be escaped.
*/
StringBuilder escaped = null;
int lastUnescapedStart = off;
diff -Nru tomcat11-11.0.6/java/org/apache/juli/LogUtil.java tomcat11-11.0.15/java/org/apache/juli/LogUtil.java
--- tomcat11-11.0.6/java/org/apache/juli/LogUtil.java 1970-01-01 00:00:00.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/juli/LogUtil.java 2025-12-02 16:54:08.000000000 +0000
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.juli;
+
+public class LogUtil {
+
+ private LogUtil() {
+ // Utility class. Hide default constructor
+ }
+
+
+ /**
+ * Escape a string so it can be displayed in a readable format. Characters that may not be printable in some/all of
+ * the contexts in which log messages will be viewed will be escaped using Java \\uNNNN escaping.
+ *
+ * All control characters are escaped apart from horizontal tab (\\u0009), new line (\\u000a) and carriage return
+ * (\\u000d).
+ *
+ * @param input The string to escape
+ *
+ * @return The escaped form of the input string
+ */
+ @SuppressWarnings("null") // sb is not null when used
+ public static String escape(final String input) {
+ final int len = input.length();
+ int i = 0;
+ int lastControl = -1;
+ StringBuilder sb = null;
+ while (i < len) {
+ char c = input.charAt(i);
+ if (Character.getType(c) == Character.CONTROL) {
+ if (!(c == '\t' || c == '\n' || c == '\r')) {
+ if (lastControl == -1) {
+ sb = new StringBuilder(len + 20);
+ }
+ sb.append(input.substring(lastControl + 1, i));
+ sb.append(String.format("\\u%1$04x", Integer.valueOf(c)));
+ lastControl = i;
+ }
+ }
+ i++;
+ }
+ if (lastControl == -1) {
+ return input;
+ } else {
+ sb.append(input.substring(lastControl + 1, len));
+ return sb.toString();
+ }
+ }
+}
diff -Nru tomcat11-11.0.6/java/org/apache/juli/OneLineFormatter.java tomcat11-11.0.15/java/org/apache/juli/OneLineFormatter.java
--- tomcat11-11.0.6/java/org/apache/juli/OneLineFormatter.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/juli/OneLineFormatter.java 2025-12-02 16:54:08.000000000 +0000
@@ -25,7 +25,6 @@
import java.lang.management.ThreadMXBean;
import java.util.LinkedHashMap;
import java.util.Map;
-import java.util.Map.Entry;
import java.util.logging.Formatter;
import java.util.logging.LogManager;
import java.util.logging.LogRecord;
@@ -42,8 +41,8 @@
private static final Object threadMxBeanLock = new Object();
private static volatile ThreadMXBean threadMxBean = null;
private static final int THREAD_NAME_CACHE_SIZE = 10000;
- private static final ThreadLocal threadNameCache = ThreadLocal
- .withInitial(() -> new ThreadNameCache(THREAD_NAME_CACHE_SIZE));
+ private static final ThreadLocal threadNameCache =
+ ThreadLocal.withInitial(() -> new ThreadNameCache(THREAD_NAME_CACHE_SIZE));
/* Timestamp format */
private static final String DEFAULT_TIME_FORMAT = "dd-MMM-yyyy HH:mm:ss.SSS";
@@ -51,12 +50,12 @@
/**
* The size of our global date format cache
*/
- private static final int globalCacheSize = 30;
+ private static final int GLOBAL_CACHE_SIZE = 30;
/**
* The size of our thread local date format cache
*/
- private static final int localCacheSize = 5;
+ private static final int LOCAL_CACHE_SIZE = 5;
/**
* Thread local date format cache.
@@ -100,9 +99,9 @@
cachedTimeFormat = timeFormat;
}
- final DateFormatCache globalDateCache = new DateFormatCache(globalCacheSize, cachedTimeFormat, null);
- localDateCache = ThreadLocal
- .withInitial(() -> new DateFormatCache(localCacheSize, cachedTimeFormat, globalDateCache));
+ final DateFormatCache globalDateCache = new DateFormatCache(GLOBAL_CACHE_SIZE, cachedTimeFormat, null);
+ localDateCache =
+ ThreadLocal.withInitial(() -> new DateFormatCache(LOCAL_CACHE_SIZE, cachedTimeFormat, globalDateCache));
}
@@ -130,14 +129,7 @@
// Thread
sb.append(' ');
sb.append('[');
- final String threadName = Thread.currentThread().getName();
- if (threadName != null && threadName.startsWith(AsyncFileHandler.THREAD_PREFIX)) {
- // If using the async handler can't get the thread name from the
- // current thread.
- sb.append(getThreadName(record.getLongThreadID()));
- } else {
- sb.append(threadName);
- }
+ sb.append(resolveThreadName(record));
sb.append(']');
// Source
@@ -148,7 +140,7 @@
// Message
sb.append(' ');
- sb.append(formatMessage(record));
+ sb.append(LogUtil.escape(formatMessage(record)));
// New line for next record
sb.append(System.lineSeparator());
@@ -159,12 +151,23 @@
PrintWriter pw = new IndentingPrintWriter(sw);
record.getThrown().printStackTrace(pw);
pw.close();
- sb.append(sw.getBuffer());
+ sb.append(LogUtil.escape(sw.toString()));
}
return sb.toString();
}
+ protected String resolveThreadName(LogRecord record) {
+ final String threadName = Thread.currentThread().getName();
+ if (threadName != null && threadName.startsWith(AsyncFileHandler.THREAD_PREFIX)) {
+ // If using the async handler can't get the thread name from the
+ // current thread.
+ return getThreadName(record.getLongThreadID());
+ } else {
+ return threadName;
+ }
+ }
+
protected void addTimestamp(StringBuilder buf, long timestamp) {
String cachedTimeStamp = localDateCache.get().getFormat(timestamp);
if (millisHandling == MillisHandling.NONE) {
@@ -212,10 +215,11 @@
* LogRecord has threadID but no thread name.
*
* @param logRecordThreadId the thread id
+ *
* @return the thread name
*/
protected static String getThreadName(long logRecordThreadId) {
- Map cache = threadNameCache.get();
+ Map cache = threadNameCache.get();
String result = cache.get(Long.valueOf(logRecordThreadId));
if (result != null) {
@@ -245,7 +249,7 @@
/*
* This is an LRU cache.
*/
- private static class ThreadNameCache extends LinkedHashMap {
+ private static class ThreadNameCache extends LinkedHashMap {
@Serial
private static final long serialVersionUID = 1L;
@@ -258,7 +262,7 @@
}
@Override
- protected boolean removeEldestEntry(Entry eldest) {
+ protected boolean removeEldestEntry(Map.Entry eldest) {
return (size() > cacheSize);
}
}
@@ -283,6 +287,10 @@
private enum MillisHandling {
- NONE, APPEND, REPLACE_S, REPLACE_SS, REPLACE_SSS,
+ NONE,
+ APPEND,
+ REPLACE_S,
+ REPLACE_SS,
+ REPLACE_SSS,
}
}
diff -Nru tomcat11-11.0.6/java/org/apache/juli/VerbatimFormatter.java tomcat11-11.0.15/java/org/apache/juli/VerbatimFormatter.java
--- tomcat11-11.0.6/java/org/apache/juli/VerbatimFormatter.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/juli/VerbatimFormatter.java 2025-12-02 16:54:08.000000000 +0000
@@ -20,9 +20,9 @@
import java.util.logging.LogRecord;
/**
- * Outputs just the log message with no additional elements. Stack traces are not logged. Log messages are separated
- * by System.lineSeparator(). This is intended for use by access logs and the like that need complete
- * control over the output format.
+ * Outputs just the log message with no additional elements and no escaping. Stack traces are not logged. Log messages
+ * are separated by System.lineSeparator(). This is intended for use by access logs and the like that need
+ * complete control over the output format.
*/
public class VerbatimFormatter extends Formatter {
@@ -31,5 +31,4 @@
// Timestamp + New line for next record
return record.getMessage() + System.lineSeparator();
}
-
}
diff -Nru tomcat11-11.0.6/java/org/apache/juli/logging/Log.java tomcat11-11.0.15/java/org/apache/juli/logging/Log.java
--- tomcat11-11.0.6/java/org/apache/juli/logging/Log.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/juli/logging/Log.java 2025-12-02 16:54:08.000000000 +0000
@@ -17,14 +17,11 @@
package org.apache.juli.logging;
/**
- *
* A simple logging interface abstracting logging APIs. In order to be instantiated successfully by {@link LogFactory},
* classes that implement this interface must have a constructor that takes a single String parameter representing the
* "name" of this Log.
- *
*
* The six logging levels used by Log are (in order):
- *
*
*
trace (the least serious)
*
debug
@@ -36,11 +33,9 @@
*
* The mapping of these log levels to the concepts used by the underlying logging system is implementation dependent.
* The implementation should ensure, though, that this ordering behaves as expected.
- *
*
* Performance is often a logging concern. By examining the appropriate property, a component can avoid expensive
* operations (producing information to be logged).
- *
*
* For example,
* if (log.isDebugEnabled()) {
@@ -48,21 +43,12 @@
* log.debug(theResult);
* }
*
- *
*
* Configuration of the underlying logging system will generally be done external to the Logging APIs, through whatever
* mechanism is supported by that system.
- *
- *
- * @author Scott Sanders
- * @author Rod Waldhoff
*/
public interface Log {
-
- // ----------------------------------------------------- Logging Properties
-
-
/**
*
* Is debug logging currently enabled?
diff -Nru tomcat11-11.0.6/java/org/apache/juli/logging/LogConfigurationException.java tomcat11-11.0.15/java/org/apache/juli/logging/LogConfigurationException.java
--- tomcat11-11.0.6/java/org/apache/juli/logging/LogConfigurationException.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/juli/logging/LogConfigurationException.java 2025-12-02 16:54:08.000000000 +0000
@@ -24,8 +24,6 @@
* An exception that is thrown only if a suitable LogFactory or Log instance cannot be created
* by the corresponding factory methods.
*
* Factory for creating {@link Log} instances, with discovery and configuration features similar to that employed by
* standard Java APIs such as JAXP.
- *
*
* IMPLEMENTATION NOTE - This implementation is heavily based on the SAXParserFactory and
* DocumentBuilderFactory implementations (corresponding to the JAXP pluggability APIs) found in Apache Xerces.
- *
- *
- * @author Craig R. McClanahan
- * @author Costin Manolache
- * @author Richard A. Sitze
*/
@ServiceConsumer(value = Log.class)
public class LogFactory {
diff -Nru tomcat11-11.0.6/java/org/apache/naming/ContextAccessController.java tomcat11-11.0.15/java/org/apache/naming/ContextAccessController.java
--- tomcat11-11.0.6/java/org/apache/naming/ContextAccessController.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/naming/ContextAccessController.java 2025-12-02 16:54:08.000000000 +0000
@@ -21,8 +21,6 @@
/**
* Handles the access control on the JNDI contexts.
- *
- * @author Remy Maucherat
*/
public class ContextAccessController {
@@ -45,7 +43,7 @@
/**
* Set a security token for a Catalina context. Can be set only once.
*
- * @param name Name of the Catalina context
+ * @param name Name of the Catalina context
* @param token Security token
*/
public static void setSecurityToken(Object name, Object token) {
@@ -58,7 +56,7 @@
/**
* Remove a security token for a context.
*
- * @param name Name of the Catalina context
+ * @param name Name of the Catalina context
* @param token Security token
*/
public static void unsetSecurityToken(Object name, Object token) {
@@ -71,15 +69,13 @@
/**
* Check a submitted security token.
*
- * @param name Name of the Catalina context
+ * @param name Name of the Catalina context
* @param token Submitted security token
*
- * @return true if the submitted token is equal to the token
- * in the repository or if no token is present in the repository.
- * Otherwise, false
+ * @return true if the submitted token is equal to the token in the repository or if no token is
+ * present in the repository. Otherwise, false
*/
- public static boolean checkSecurityToken
- (Object name, Object token) {
+ public static boolean checkSecurityToken(Object name, Object token) {
Object refToken = securityTokens.get(name);
return (refToken == null || refToken.equals(token));
}
@@ -88,7 +84,7 @@
/**
* Allow writing to a context.
*
- * @param name Name of the Catalina context
+ * @param name Name of the Catalina context
* @param token Security token
*/
public static void setWritable(Object name, Object token) {
diff -Nru tomcat11-11.0.6/java/org/apache/naming/ContextBindings.java tomcat11-11.0.15/java/org/apache/naming/ContextBindings.java
--- tomcat11-11.0.6/java/org/apache/naming/ContextBindings.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/naming/ContextBindings.java 2025-12-02 16:54:08.000000000 +0000
@@ -29,12 +29,9 @@
*
Calling thread with a NamingContext
*
Calling thread with object bound to the same naming context
*
Thread context class loader with a NamingContext
- *
Thread context class loader with object bound to the same
- * NamingContext
+ *
Thread context class loader with object bound to the same NamingContext
*
* The objects are typically Catalina Server or Context objects.
- *
- * @author Remy Maucherat
*/
public class ContextBindings {
@@ -81,8 +78,8 @@
/**
* Binds an object and a naming context.
*
- * @param obj Object to bind with naming context
- * @param context Associated naming context instance
+ * @param obj Object to bind with naming context
+ * @param context Associated naming context instance
*/
public static void bindContext(Object obj, Context context) {
bindContext(obj, context, null);
@@ -92,9 +89,9 @@
/**
* Binds an object and a naming context.
*
- * @param obj Object to bind with naming context
- * @param context Associated naming context instance
- * @param token Security token
+ * @param obj Object to bind with naming context
+ * @param context Associated naming context instance
+ * @param token Security token
*/
public static void bindContext(Object obj, Context context, Object token) {
if (ContextAccessController.checkSecurityToken(obj, token)) {
@@ -119,7 +116,7 @@
/**
* Retrieve a naming context.
*
- * @param obj Object bound to the required naming context
+ * @param obj Object bound to the required naming context
*/
static Context getContext(Object obj) {
return objectBindings.get(obj);
@@ -132,15 +129,13 @@
* @param obj Object bound to the required naming context
* @param token Security token
*
- * @throws NamingException If no naming context is bound to the provided
- * object
+ * @throws NamingException If no naming context is bound to the provided object
*/
public static void bindThread(Object obj, Object token) throws NamingException {
if (ContextAccessController.checkSecurityToken(obj, token)) {
Context context = objectBindings.get(obj);
if (context == null) {
- throw new NamingException(
- sm.getString("contextBindings.unknownContext", obj));
+ throw new NamingException(sm.getString("contextBindings.unknownContext", obj));
}
Thread currentThread = Thread.currentThread();
threadBindings.put(currentThread, context);
@@ -169,28 +164,24 @@
*
* @return The naming context bound to the current thread.
*
- * @throws NamingException If no naming context is bound to the current
- * thread
+ * @throws NamingException If no naming context is bound to the current thread
*/
public static Context getThread() throws NamingException {
Context context = threadBindings.get(Thread.currentThread());
if (context == null) {
- throw new NamingException
- (sm.getString("contextBindings.noContextBoundToThread"));
+ throw new NamingException(sm.getString("contextBindings.noContextBoundToThread"));
}
return context;
}
/**
- * Retrieves the name of the object bound to the naming context that is also
- * bound to the current thread.
+ * Retrieves the name of the object bound to the naming context that is also bound to the current thread.
*/
static String getThreadName() throws NamingException {
Object obj = threadObjectBindings.get(Thread.currentThread());
if (obj == null) {
- throw new NamingException
- (sm.getString("contextBindings.noContextBoundToThread"));
+ throw new NamingException(sm.getString("contextBindings.noContextBoundToThread"));
}
return obj.toString();
}
@@ -199,8 +190,7 @@
/**
* Tests if current thread is bound to a naming context.
*
- * @return true if the current thread is bound to a naming
- * context, otherwise false
+ * @return true if the current thread is bound to a naming context, otherwise false
*/
public static boolean isThreadBound() {
return threadBindings.containsKey(Thread.currentThread());
@@ -210,20 +200,17 @@
/**
* Binds a naming context to a class loader.
*
- * @param obj Object bound to the required naming context
- * @param token Security token
- * @param classLoader The class loader to bind to the naming context
+ * @param obj Object bound to the required naming context
+ * @param token Security token
+ * @param classLoader The class loader to bind to the naming context
*
- * @throws NamingException If no naming context is bound to the provided
- * object
+ * @throws NamingException If no naming context is bound to the provided object
*/
- public static void bindClassLoader(Object obj, Object token,
- ClassLoader classLoader) throws NamingException {
+ public static void bindClassLoader(Object obj, Object token, ClassLoader classLoader) throws NamingException {
if (ContextAccessController.checkSecurityToken(obj, token)) {
Context context = objectBindings.get(obj);
if (context == null) {
- throw new NamingException
- (sm.getString("contextBindings.unknownContext", obj));
+ throw new NamingException(sm.getString("contextBindings.unknownContext", obj));
}
clBindings.put(classLoader, context);
clObjectBindings.put(classLoader, obj);
@@ -234,12 +221,11 @@
/**
* Unbinds a naming context and a class loader.
*
- * @param obj Object bound to the required naming context
- * @param token Security token
- * @param classLoader The class loader bound to the naming context
+ * @param obj Object bound to the required naming context
+ * @param token Security token
+ * @param classLoader The class loader bound to the naming context
*/
- public static void unbindClassLoader(Object obj, Object token,
- ClassLoader classLoader) {
+ public static void unbindClassLoader(Object obj, Object token, ClassLoader classLoader) {
if (ContextAccessController.checkSecurityToken(obj, token)) {
Object o = clObjectBindings.get(classLoader);
if (o == null || !o.equals(obj)) {
@@ -254,8 +240,7 @@
/**
* Retrieves the naming context bound to a class loader.
*
- * @return the naming context bound to current class loader or one of its
- * parents
+ * @return the naming context bound to current class loader or one of its parents
*
* @throws NamingException If no naming context was bound
*/
@@ -273,8 +258,8 @@
/**
- * Retrieves the name of the object bound to the naming context that is also
- * bound to the thread context class loader.
+ * Retrieves the name of the object bound to the naming context that is also bound to the thread context class
+ * loader.
*/
static String getClassLoaderName() throws NamingException {
ClassLoader cl = Thread.currentThread().getContextClassLoader();
@@ -285,16 +270,15 @@
return obj.toString();
}
} while ((cl = cl.getParent()) != null);
- throw new NamingException (sm.getString("contextBindings.noContextBoundToCL"));
+ throw new NamingException(sm.getString("contextBindings.noContextBoundToCL"));
}
/**
* Tests if the thread context class loader is bound to a context.
*
- * @return true if the thread context class loader or one of
- * its parents is bound to a naming context, otherwise
- * false
+ * @return true if the thread context class loader or one of its parents is bound to a naming context,
+ * otherwise false
*/
public static boolean isClassLoaderBound() {
ClassLoader cl = Thread.currentThread().getContextClassLoader();
diff -Nru tomcat11-11.0.6/java/org/apache/naming/EjbRef.java tomcat11-11.0.15/java/org/apache/naming/EjbRef.java
--- tomcat11-11.0.6/java/org/apache/naming/EjbRef.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/naming/EjbRef.java 2025-12-02 16:54:08.000000000 +0000
@@ -22,8 +22,6 @@
/**
* Represents a reference address to an EJB.
- *
- * @author Remy Maucherat
*/
public class EjbRef extends AbstractRef {
@@ -34,8 +32,7 @@
/**
* Default factory for this reference.
*/
- public static final String DEFAULT_FACTORY =
- org.apache.naming.factory.Constants.DEFAULT_EJB_FACTORY;
+ public static final String DEFAULT_FACTORY = org.apache.naming.factory.Constants.DEFAULT_EJB_FACTORY;
/**
@@ -60,9 +57,9 @@
* EJB Reference.
*
* @param ejbType EJB type
- * @param home Home interface classname
- * @param remote Remote interface classname
- * @param link EJB link
+ * @param home Home interface classname
+ * @param remote Remote interface classname
+ * @param link EJB link
*/
public EjbRef(String ejbType, String home, String remote, String link) {
this(ejbType, home, remote, link, null, null);
@@ -72,16 +69,14 @@
/**
* EJB Reference.
*
- * @param ejbType EJB type
- * @param home Home interface classname
- * @param remote Remote interface classname
- * @param link EJB link
- * @param factory The possibly null class name of the object's factory.
- * @param factoryLocation The possibly null location from which to load
- * the factory (e.g. URL)
+ * @param ejbType EJB type
+ * @param home Home interface classname
+ * @param remote Remote interface classname
+ * @param link EJB link
+ * @param factory The possibly null class name of the object's factory.
+ * @param factoryLocation The possibly null location from which to load the factory (e.g. URL)
*/
- public EjbRef(String ejbType, String home, String remote, String link,
- String factory, String factoryLocation) {
+ public EjbRef(String ejbType, String home, String remote, String link, String factory, String factoryLocation) {
super(home, factory, factoryLocation);
StringRefAddr refAddr;
if (ejbType != null) {
diff -Nru tomcat11-11.0.6/java/org/apache/naming/HandlerRef.java tomcat11-11.0.15/java/org/apache/naming/HandlerRef.java
--- tomcat11-11.0.6/java/org/apache/naming/HandlerRef.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/naming/HandlerRef.java 2025-12-02 16:54:08.000000000 +0000
@@ -22,8 +22,6 @@
/**
* Represents a reference handler for a web service.
- *
- * @author Fabien Carrion
*/
public class HandlerRef extends AbstractRef {
@@ -34,56 +32,55 @@
/**
* Default factory for this reference.
*/
- public static final String DEFAULT_FACTORY =
- org.apache.naming.factory.Constants.DEFAULT_HANDLER_FACTORY;
+ public static final String DEFAULT_FACTORY = org.apache.naming.factory.Constants.DEFAULT_HANDLER_FACTORY;
/**
* HandlerName address type.
*/
- public static final String HANDLER_NAME = "handlername";
+ public static final String HANDLER_NAME = "handlername";
/**
* Handler Classname address type.
*/
- public static final String HANDLER_CLASS = "handlerclass";
+ public static final String HANDLER_CLASS = "handlerclass";
/**
* Handler Classname address type.
*/
- public static final String HANDLER_LOCALPART = "handlerlocalpart";
+ public static final String HANDLER_LOCALPART = "handlerlocalpart";
/**
* Handler Classname address type.
*/
- public static final String HANDLER_NAMESPACE = "handlernamespace";
+ public static final String HANDLER_NAMESPACE = "handlernamespace";
/**
* Handler Classname address type.
*/
- public static final String HANDLER_PARAMNAME = "handlerparamname";
+ public static final String HANDLER_PARAMNAME = "handlerparamname";
/**
* Handler Classname address type.
*/
- public static final String HANDLER_PARAMVALUE = "handlerparamvalue";
+ public static final String HANDLER_PARAMVALUE = "handlerparamvalue";
/**
* Handler SoapRole address type.
*/
- public static final String HANDLER_SOAPROLE = "handlersoaprole";
+ public static final String HANDLER_SOAPROLE = "handlersoaprole";
/**
* Handler PortName address type.
*/
- public static final String HANDLER_PORTNAME = "handlerportname";
+ public static final String HANDLER_PORTNAME = "handlerportname";
public HandlerRef(String refname, String handlerClass) {
@@ -91,8 +88,7 @@
}
- public HandlerRef(String refname, String handlerClass,
- String factory, String factoryLocation) {
+ public HandlerRef(String refname, String handlerClass, String factory, String factoryLocation) {
super(refname, factory, factoryLocation);
StringRefAddr refAddr;
if (refname != null) {
diff -Nru tomcat11-11.0.6/java/org/apache/naming/LocalStrings.properties tomcat11-11.0.15/java/org/apache/naming/LocalStrings.properties
--- tomcat11-11.0.6/java/org/apache/naming/LocalStrings.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/naming/LocalStrings.properties 2025-12-02 16:54:08.000000000 +0000
@@ -21,8 +21,8 @@
contextBindings.unknownContext=Unknown context name : [{0}]
namingContext.alreadyBound=Name [{0}] is already bound in this Context
-namingContext.contextExpected=Name is not bound to a Context
-namingContext.failResolvingReference=Unexpected exception resolving reference
+namingContext.contextExpected=Name [{0}] is not bound to a Context
+namingContext.failResolvingReference=Unexpected exception resolving reference with name [{0}]
namingContext.invalidName=Name is not valid
namingContext.nameNotBound=Name [{0}] is not bound in this Context. Unable to find [{1}].
namingContext.noAbsoluteName=Cannot generate an absolute name for this namespace
diff -Nru tomcat11-11.0.6/java/org/apache/naming/LocalStrings_cs.properties tomcat11-11.0.15/java/org/apache/naming/LocalStrings_cs.properties
--- tomcat11-11.0.6/java/org/apache/naming/LocalStrings_cs.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/naming/LocalStrings_cs.properties 2025-12-02 16:54:08.000000000 +0000
@@ -16,4 +16,3 @@
# Do not edit this file directly.
# To edit translations see: https://tomcat.apache.org/getinvolved.html#Translations
-namingContext.contextExpected=Jméno není svázáno s kontextem
diff -Nru tomcat11-11.0.6/java/org/apache/naming/LocalStrings_de.properties tomcat11-11.0.15/java/org/apache/naming/LocalStrings_de.properties
--- tomcat11-11.0.6/java/org/apache/naming/LocalStrings_de.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/naming/LocalStrings_de.properties 2025-12-02 16:54:08.000000000 +0000
@@ -18,7 +18,5 @@
contextBindings.unknownContext=Unbekannter Kontext-Name: [{0}]
-namingContext.contextExpected=Ein Name ist nicht an den Context gebunden
-
selectorContext.methodUsingName=Aufruf der Methode [{0}] mit Namen [{1}]
selectorContext.noJavaUrl=Auf diesen Kontext muss durch eine java:-URL zugegriffen werden
diff -Nru tomcat11-11.0.6/java/org/apache/naming/LocalStrings_es.properties tomcat11-11.0.15/java/org/apache/naming/LocalStrings_es.properties
--- tomcat11-11.0.6/java/org/apache/naming/LocalStrings_es.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/naming/LocalStrings_es.properties 2025-12-02 16:54:08.000000000 +0000
@@ -21,8 +21,7 @@
contextBindings.unknownContext=Contexto [{0}] desconocido
namingContext.alreadyBound=El nombre [{0}] este ya asociado en este Contexto
-namingContext.contextExpected=El nombre no esta asociado a ningun Contexto
-namingContext.failResolvingReference=Excepción inesperada resolviendo referencia
+namingContext.contextExpected=El nombre [{0}] no está vinculado a un Contexto
namingContext.invalidName=Nombre no valido
namingContext.nameNotBound=El nombre [{0}] no este asociado a este contexto
namingContext.noAbsoluteName=No se puede generar un nombre absoluto para este espacio de nombres
diff -Nru tomcat11-11.0.6/java/org/apache/naming/LocalStrings_fr.properties tomcat11-11.0.15/java/org/apache/naming/LocalStrings_fr.properties
--- tomcat11-11.0.6/java/org/apache/naming/LocalStrings_fr.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/naming/LocalStrings_fr.properties 2025-12-02 16:54:08.000000000 +0000
@@ -21,8 +21,8 @@
contextBindings.unknownContext=Nom de Contexte inconnu : [{0}]
namingContext.alreadyBound=Le Nom [{0}] est déjà lié à ce Contexte
-namingContext.contextExpected=Le Nom n'est pas lié à un Contexte
-namingContext.failResolvingReference=Une erreur s est produite durant la résolution de la référence
+namingContext.contextExpected=Le nom [{0}] n''est pas associé à un Context
+namingContext.failResolvingReference=Erreur inattendue lors de la résolution de la référence avec le nom [{0}]
namingContext.invalidName=Le Nom est invalide
namingContext.nameNotBound=Le Nom [{0}] n''est pas lié à ce Contexte
namingContext.noAbsoluteName=Impossible de générer un nom absolu pour cet espace de nommage (namespace)
diff -Nru tomcat11-11.0.6/java/org/apache/naming/LocalStrings_ja.properties tomcat11-11.0.15/java/org/apache/naming/LocalStrings_ja.properties
--- tomcat11-11.0.6/java/org/apache/naming/LocalStrings_ja.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/naming/LocalStrings_ja.properties 2025-12-02 16:54:08.000000000 +0000
@@ -21,8 +21,8 @@
contextBindings.unknownContext=未知のコンテキスト名です: [{0}]
namingContext.alreadyBound=名前 [{0}] は既にこのコンテキストにバインドされています
-namingContext.contextExpected=名前がコンテキストにバインドされていません
-namingContext.failResolvingReference=参照の解決中に予測しない例外が発生しました
+namingContext.contextExpected=名前 [{0}] はコンテキストにバインドされていません
+namingContext.failResolvingReference=名前 [{0}] の参照を解決中に予期しない例外が発生しました
namingContext.invalidName=名前は無効です
namingContext.nameNotBound=名前 [{0}] はこのコンテキストにバインドされていません
namingContext.noAbsoluteName=この名前空間に絶対名を生成できません
diff -Nru tomcat11-11.0.6/java/org/apache/naming/LocalStrings_ko.properties tomcat11-11.0.15/java/org/apache/naming/LocalStrings_ko.properties
--- tomcat11-11.0.6/java/org/apache/naming/LocalStrings_ko.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/naming/LocalStrings_ko.properties 2025-12-02 16:54:08.000000000 +0000
@@ -21,8 +21,6 @@
contextBindings.unknownContext=알 수 없는 컨텍스트 이름: [{0}]
namingContext.alreadyBound=Name [{0}]이(가) 이미 이 컨텍스트에 바인딩 되어 있습니다.
-namingContext.contextExpected=Name이 컨텍스트에 바인딩 되지 않았습니다.
-namingContext.failResolvingReference=참조를 결정하는 중 예기치 않은 예외 발생
namingContext.invalidName=Name이 유효하지 않습니다.
namingContext.nameNotBound=Name [{0}]은(는) 이 컨텍스트에 바인딩되지 않았습니다. [{1}]을(를) 찾을 수 없습니다.
namingContext.noAbsoluteName=이 네임스페이스를 위한 절대 이름을 생성할 수 없습니다.
diff -Nru tomcat11-11.0.6/java/org/apache/naming/LocalStrings_ru.properties tomcat11-11.0.15/java/org/apache/naming/LocalStrings_ru.properties
--- tomcat11-11.0.6/java/org/apache/naming/LocalStrings_ru.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/naming/LocalStrings_ru.properties 2025-12-02 16:54:08.000000000 +0000
@@ -16,7 +16,5 @@
# Do not edit this file directly.
# To edit translations see: https://tomcat.apache.org/getinvolved.html#Translations
-namingContext.contextExpected=Имя не привязано к контексту
-
selectorContext.methodUsingName=Вызов метода [{0}] с именем [{1}]
selectorContext.methodUsingString=Вызов метода [{0}] для строки [{1}]
diff -Nru tomcat11-11.0.6/java/org/apache/naming/LocalStrings_zh_CN.properties tomcat11-11.0.15/java/org/apache/naming/LocalStrings_zh_CN.properties
--- tomcat11-11.0.6/java/org/apache/naming/LocalStrings_zh_CN.properties 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/naming/LocalStrings_zh_CN.properties 2025-12-02 16:54:08.000000000 +0000
@@ -21,8 +21,6 @@
contextBindings.unknownContext=未知.上下文名:[{0}]
namingContext.alreadyBound=名称[{0}]已在此上下文中绑定
-namingContext.contextExpected=上下文Context未绑定名称name
-namingContext.failResolvingReference=解析引用时意外异常
namingContext.invalidName=名称无效
namingContext.nameNotBound=名称[{0}]未在此上下文中绑定。找不到[{1}]。
namingContext.noAbsoluteName=无法为此命名空间生成绝对名称
diff -Nru tomcat11-11.0.6/java/org/apache/naming/NameParserImpl.java tomcat11-11.0.15/java/org/apache/naming/NameParserImpl.java
--- tomcat11-11.0.6/java/org/apache/naming/NameParserImpl.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/naming/NameParserImpl.java 2025-12-02 16:54:08.000000000 +0000
@@ -23,19 +23,15 @@
/**
* Parses names.
- *
- * @author Remy Maucherat
*/
-public class NameParserImpl
- implements NameParser {
+public class NameParserImpl implements NameParser {
// ----------------------------------------------------- NameParser Methods
@Override
- public Name parse(String name)
- throws NamingException {
+ public Name parse(String name) throws NamingException {
return new CompositeName(name);
}
diff -Nru tomcat11-11.0.6/java/org/apache/naming/NamingContext.java tomcat11-11.0.15/java/org/apache/naming/NamingContext.java
--- tomcat11-11.0.6/java/org/apache/naming/NamingContext.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/naming/NamingContext.java 2025-12-02 16:54:08.000000000 +0000
@@ -44,8 +44,6 @@
/**
* Catalina JNDI Context implementation.
- *
- * @author Remy Maucherat
*/
public class NamingContext implements Context {
@@ -68,7 +66,7 @@
/**
* Builds a naming context.
*
- * @param env The environment to use to construct the naming context
+ * @param env The environment to use to construct the naming context
* @param name The name of the associated Catalina Context
*/
public NamingContext(Hashtable env, String name) {
@@ -79,17 +77,16 @@
/**
* Builds a naming context.
*
- * @param env The environment to use to construct the naming context
- * @param name The name of the associated Catalina Context
+ * @param env The environment to use to construct the naming context
+ * @param name The name of the associated Catalina Context
* @param bindings The initial bindings for the naming context
*/
- public NamingContext(Hashtable env, String name,
- HashMap bindings) {
+ public NamingContext(Hashtable env, String name, HashMap bindings) {
this.env = new Hashtable<>();
this.name = name;
// Populating the environment hashtable
- if (env != null ) {
+ if (env != null) {
Enumeration envEntries = env.keys();
while (envEntries.hasMoreElements()) {
String entryName = envEntries.nextElement();
@@ -128,13 +125,14 @@
/**
- * Determines if an attempt to write to a read-only context results in an
- * exception or if the request is ignored.
+ * Determines if an attempt to write to a read-only context results in an exception or if the request is ignored.
*/
private boolean exceptionOnFailedWrite = true;
+
public boolean getExceptionOnFailedWrite() {
return exceptionOnFailedWrite;
}
+
public void setExceptionOnFailedWrite(boolean exceptionOnFailedWrite) {
this.exceptionOnFailedWrite = exceptionOnFailedWrite;
}
@@ -143,43 +141,37 @@
// -------------------------------------------------------- Context Methods
@Override
- public Object lookup(Name name)
- throws NamingException {
+ public Object lookup(Name name) throws NamingException {
return lookup(name, true);
}
@Override
- public Object lookup(String name)
- throws NamingException {
+ public Object lookup(String name) throws NamingException {
return lookup(new CompositeName(name), true);
}
@Override
- public void bind(Name name, Object obj)
- throws NamingException {
+ public void bind(Name name, Object obj) throws NamingException {
bind(name, obj, false);
}
@Override
- public void bind(String name, Object obj)
- throws NamingException {
+ public void bind(String name, Object obj) throws NamingException {
bind(new CompositeName(name), obj);
}
@Override
- public void rebind(Name name, Object obj)
- throws NamingException {
+ public void rebind(Name name, Object obj) throws NamingException {
bind(name, obj, true);
}
@Override
- public void rebind(String name, Object obj)
- throws NamingException {
+ public void rebind(String name, Object obj) throws NamingException {
rebind(new CompositeName(name), obj);
}
@@ -195,23 +187,20 @@
name = name.getSuffix(1);
}
if (name.isEmpty()) {
- throw new NamingException
- (sm.getString("namingContext.invalidName"));
+ throw new NamingException(sm.getString("namingContext.invalidName"));
}
NamingEntry entry = bindings.get(name.get(0));
if (entry == null) {
- throw new NameNotFoundException
- (sm.getString("namingContext.nameNotBound", name, name.get(0)));
+ throw new NameNotFoundException(sm.getString("namingContext.nameNotBound", name, name.get(0)));
}
if (name.size() > 1) {
if (entry.type == NamingEntry.CONTEXT) {
((Context) entry.value).unbind(name.getSuffix(1));
} else {
- throw new NamingException
- (sm.getString("namingContext.contextExpected"));
+ throw new NamingException(sm.getString("namingContext.contextExpected", name.get(0)));
}
} else {
bindings.remove(name.get(0));
@@ -221,15 +210,13 @@
@Override
- public void unbind(String name)
- throws NamingException {
+ public void unbind(String name) throws NamingException {
unbind(new CompositeName(name));
}
@Override
- public void rename(Name oldName, Name newName)
- throws NamingException {
+ public void rename(Name oldName, Name newName) throws NamingException {
Object value = lookup(oldName);
bind(newName, value);
unbind(oldName);
@@ -237,15 +224,13 @@
@Override
- public void rename(String oldName, String newName)
- throws NamingException {
+ public void rename(String oldName, String newName) throws NamingException {
rename(new CompositeName(oldName), new CompositeName(newName));
}
@Override
- public NamingEnumeration list(Name name)
- throws NamingException {
+ public NamingEnumeration list(Name name) throws NamingException {
// Removing empty parts
while ((!name.isEmpty()) && (name.get(0).isEmpty())) {
name = name.getSuffix(1);
@@ -257,28 +242,24 @@
NamingEntry entry = bindings.get(name.get(0));
if (entry == null) {
- throw new NameNotFoundException
- (sm.getString("namingContext.nameNotBound", name, name.get(0)));
+ throw new NameNotFoundException(sm.getString("namingContext.nameNotBound", name, name.get(0)));
}
if (entry.type != NamingEntry.CONTEXT) {
- throw new NamingException
- (sm.getString("namingContext.contextExpected"));
+ throw new NamingException(sm.getString("namingContext.contextExpected", name.get(0)));
}
return ((Context) entry.value).list(name.getSuffix(1));
}
@Override
- public NamingEnumeration list(String name)
- throws NamingException {
+ public NamingEnumeration list(String name) throws NamingException {
return list(new CompositeName(name));
}
@Override
- public NamingEnumeration listBindings(Name name)
- throws NamingException {
+ public NamingEnumeration listBindings(Name name) throws NamingException {
// Removing empty parts
while ((!name.isEmpty()) && (name.get(0).isEmpty())) {
name = name.getSuffix(1);
@@ -290,21 +271,18 @@
NamingEntry entry = bindings.get(name.get(0));
if (entry == null) {
- throw new NameNotFoundException
- (sm.getString("namingContext.nameNotBound", name, name.get(0)));
+ throw new NameNotFoundException(sm.getString("namingContext.nameNotBound", name, name.get(0)));
}
if (entry.type != NamingEntry.CONTEXT) {
- throw new NamingException
- (sm.getString("namingContext.contextExpected"));
+ throw new NamingException(sm.getString("namingContext.contextExpected", name.get(0)));
}
return ((Context) entry.value).listBindings(name.getSuffix(1));
}
@Override
- public NamingEnumeration listBindings(String name)
- throws NamingException {
+ public NamingEnumeration listBindings(String name) throws NamingException {
return listBindings(new CompositeName(name));
}
@@ -320,31 +298,27 @@
name = name.getSuffix(1);
}
if (name.isEmpty()) {
- throw new NamingException
- (sm.getString("namingContext.invalidName"));
+ throw new NamingException(sm.getString("namingContext.invalidName"));
}
NamingEntry entry = bindings.get(name.get(0));
if (entry == null) {
- throw new NameNotFoundException
- (sm.getString("namingContext.nameNotBound", name, name.get(0)));
+ throw new NameNotFoundException(sm.getString("namingContext.nameNotBound", name, name.get(0)));
}
if (name.size() > 1) {
if (entry.type == NamingEntry.CONTEXT) {
((Context) entry.value).destroySubcontext(name.getSuffix(1));
} else {
- throw new NamingException
- (sm.getString("namingContext.contextExpected"));
+ throw new NamingException(sm.getString("namingContext.contextExpected", name.get(0)));
}
} else {
if (entry.type == NamingEntry.CONTEXT) {
((Context) entry.value).close();
bindings.remove(name.get(0));
} else {
- throw new NotContextException
- (sm.getString("namingContext.contextExpected"));
+ throw new NotContextException(sm.getString("namingContext.contextExpected", name.get(0)));
}
}
@@ -352,8 +326,7 @@
@Override
- public void destroySubcontext(String name)
- throws NamingException {
+ public void destroySubcontext(String name) throws NamingException {
destroySubcontext(new CompositeName(name));
}
@@ -374,29 +347,25 @@
@Override
- public Context createSubcontext(String name)
- throws NamingException {
+ public Context createSubcontext(String name) throws NamingException {
return createSubcontext(new CompositeName(name));
}
@Override
- public Object lookupLink(Name name)
- throws NamingException {
+ public Object lookupLink(Name name) throws NamingException {
return lookup(name, false);
}
@Override
- public Object lookupLink(String name)
- throws NamingException {
+ public Object lookupLink(String name) throws NamingException {
return lookup(new CompositeName(name), false);
}
@Override
- public NameParser getNameParser(Name name)
- throws NamingException {
+ public NameParser getNameParser(Name name) throws NamingException {
while ((!name.isEmpty()) && (name.get(0).isEmpty())) {
name = name.getSuffix(1);
@@ -410,8 +379,7 @@
if (obj instanceof Context) {
return ((Context) obj).getNameParser(name.getSuffix(1));
} else {
- throw new NotContextException
- (sm.getString("namingContext.contextExpected"));
+ throw new NotContextException(sm.getString("namingContext.contextExpected", name.get(0)));
}
}
@@ -421,8 +389,7 @@
@Override
- public NameParser getNameParser(String name)
- throws NamingException {
+ public NameParser getNameParser(String name) throws NamingException {
return getNameParser(new CompositeName(name));
}
@@ -447,7 +414,7 @@
@Override
- public Object removeFromEnvironment(String propName){
+ public Object removeFromEnvironment(String propName) {
return env.remove(propName);
}
@@ -468,10 +435,8 @@
@Override
- public String getNameInNamespace()
- throws NamingException {
- throw new OperationNotSupportedException
- (sm.getString("namingContext.noAbsoluteName"));
+ public String getNameInNamespace() throws NamingException {
+ throw new OperationNotSupportedException(sm.getString("namingContext.noAbsoluteName"));
}
@@ -496,13 +461,14 @@
/**
* Retrieves the named object.
*
- * @param name the name of the object to look up
+ * @param name the name of the object to look up
* @param resolveLinks If true, the links will be resolved
+ *
* @return the object bound to name
+ *
* @exception NamingException if a naming exception is encountered
*/
- protected Object lookup(Name name, boolean resolveLinks)
- throws NamingException {
+ protected Object lookup(Name name, boolean resolveLinks) throws NamingException {
// Removing empty parts
while ((!name.isEmpty()) && (name.get(0).isEmpty())) {
@@ -516,16 +482,14 @@
NamingEntry entry = bindings.get(name.get(0));
if (entry == null) {
- throw new NameNotFoundException
- (sm.getString("namingContext.nameNotBound", name, name.get(0)));
+ throw new NameNotFoundException(sm.getString("namingContext.nameNotBound", name, name.get(0)));
}
if (name.size() > 1) {
// If the size of the name is greater than 1, then we go through a
// number of sub contexts.
if (entry.type != NamingEntry.CONTEXT) {
- throw new NamingException
- (sm.getString("namingContext.contextExpected"));
+ throw new NamingException(sm.getString("namingContext.contextExpected", name.get(0)));
}
return ((Context) entry.value).lookup(name.getSuffix(1));
} else {
@@ -556,21 +520,20 @@
}
if (entry.value instanceof ResourceRef) {
boolean singleton = Boolean.parseBoolean(
- (String) ((ResourceRef) entry.value).get(
- ResourceRef.SINGLETON).getContent());
+ (String) ((ResourceRef) entry.value).get(ResourceRef.SINGLETON).getContent());
if (singleton) {
entry.type = NamingEntry.ENTRY;
entry.value = obj;
}
}
if (obj == null) {
- throw new NamingException(sm.getString("namingContext.failResolvingReference"));
+ throw new NamingException(sm.getString("namingContext.failResolvingReference", name));
}
return obj;
} catch (NamingException e) {
throw e;
} catch (Exception e) {
- String msg = sm.getString("namingContext.failResolvingReference");
+ String msg = sm.getString("namingContext.failResolvingReference", name);
log.warn(msg, e);
NamingException ne = new NamingException(msg);
ne.initCause(e);
@@ -585,20 +548,18 @@
/**
- * Binds a name to an object. All intermediate contexts and the target
- * context (that named by all but terminal atomic component of the name)
- * must already exist.
+ * Binds a name to an object. All intermediate contexts and the target context (that named by all but terminal
+ * atomic component of the name) must already exist.
*
- * @param name the name to bind; may not be empty
- * @param obj the object to bind; possibly null
+ * @param name the name to bind; may not be empty
+ * @param obj the object to bind; possibly null
* @param rebind if true, then perform a rebind (ie, overwrite)
- * @exception NameAlreadyBoundException if name is already bound
- * @exception javax.naming.directory.InvalidAttributesException if object
- * did not supply all mandatory attributes
- * @exception NamingException if a naming exception is encountered
+ *
+ * @exception NameAlreadyBoundException if name is already bound
+ * @exception javax.naming.directory.InvalidAttributesException if object did not supply all mandatory attributes
+ * @exception NamingException if a naming exception is encountered
*/
- protected void bind(Name name, Object obj, boolean rebind)
- throws NamingException {
+ protected void bind(Name name, Object obj, boolean rebind) throws NamingException {
if (!checkWritable()) {
return;
@@ -608,16 +569,14 @@
name = name.getSuffix(1);
}
if (name.isEmpty()) {
- throw new NamingException
- (sm.getString("namingContext.invalidName"));
+ throw new NamingException(sm.getString("namingContext.invalidName"));
}
NamingEntry entry = bindings.get(name.get(0));
if (name.size() > 1) {
if (entry == null) {
- throw new NameNotFoundException(sm.getString(
- "namingContext.nameNotBound", name, name.get(0)));
+ throw new NameNotFoundException(sm.getString("namingContext.nameNotBound", name, name.get(0)));
}
if (entry.type == NamingEntry.CONTEXT) {
if (rebind) {
@@ -626,34 +585,26 @@
((Context) entry.value).bind(name.getSuffix(1), obj);
}
} else {
- throw new NamingException
- (sm.getString("namingContext.contextExpected"));
+ throw new NamingException(sm.getString("namingContext.contextExpected", name.get(0)));
}
} else {
if ((!rebind) && (entry != null)) {
- throw new NameAlreadyBoundException
- (sm.getString("namingContext.alreadyBound", name.get(0)));
+ throw new NameAlreadyBoundException(sm.getString("namingContext.alreadyBound", name.get(0)));
} else {
// Getting the type of the object and wrapping it within a new
// NamingEntry
- Object toBind =
- NamingManager.getStateToBind(obj, name, this, env);
+ Object toBind = NamingManager.getStateToBind(obj, name, this, env);
if (toBind instanceof Context) {
- entry = new NamingEntry(name.get(0), toBind,
- NamingEntry.CONTEXT);
+ entry = new NamingEntry(name.get(0), toBind, NamingEntry.CONTEXT);
} else if (toBind instanceof LinkRef) {
- entry = new NamingEntry(name.get(0), toBind,
- NamingEntry.LINK_REF);
+ entry = new NamingEntry(name.get(0), toBind, NamingEntry.LINK_REF);
} else if (toBind instanceof Reference) {
- entry = new NamingEntry(name.get(0), toBind,
- NamingEntry.REFERENCE);
+ entry = new NamingEntry(name.get(0), toBind, NamingEntry.REFERENCE);
} else if (toBind instanceof Referenceable) {
toBind = ((Referenceable) toBind).getReference();
- entry = new NamingEntry(name.get(0), toBind,
- NamingEntry.REFERENCE);
+ entry = new NamingEntry(name.get(0), toBind, NamingEntry.REFERENCE);
} else {
- entry = new NamingEntry(name.get(0), toBind,
- NamingEntry.ENTRY);
+ entry = new NamingEntry(name.get(0), toBind, NamingEntry.ENTRY);
}
bindings.put(name.get(0), entry);
}
@@ -672,9 +623,11 @@
/**
* Throws a naming exception is Context is not writable.
+ *
* @return true if the Context is writable
- * @throws NamingException if the Context is not writable and
- * exceptionOnFailedWrite is true
+ *
+ * @throws NamingException if the Context is not writable and exceptionOnFailedWrite is
+ * true
*/
protected boolean checkWritable() throws NamingException {
if (isWritable()) {
diff -Nru tomcat11-11.0.6/java/org/apache/naming/NamingContextBindingsEnumeration.java tomcat11-11.0.15/java/org/apache/naming/NamingContextBindingsEnumeration.java
--- tomcat11-11.0.6/java/org/apache/naming/NamingContextBindingsEnumeration.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/naming/NamingContextBindingsEnumeration.java 2025-12-02 16:54:08.000000000 +0000
@@ -26,18 +26,14 @@
/**
* Naming enumeration implementation.
- *
- * @author Remy Maucherat
*/
-public class NamingContextBindingsEnumeration
- implements NamingEnumeration {
+public class NamingContextBindingsEnumeration implements NamingEnumeration {
// ----------------------------------------------------------- Constructors
- public NamingContextBindingsEnumeration(Iterator entries,
- Context ctx) {
+ public NamingContextBindingsEnumeration(Iterator entries, Context ctx) {
iterator = entries;
this.ctx = ctx;
}
@@ -61,22 +57,19 @@
@Override
- public Binding next()
- throws NamingException {
+ public Binding next() throws NamingException {
return nextElementInternal();
}
@Override
- public boolean hasMore()
- throws NamingException {
+ public boolean hasMore() throws NamingException {
return iterator.hasNext();
}
@Override
- public void close()
- throws NamingException {
+ public void close() throws NamingException {
}
@@ -100,8 +93,7 @@
Object value;
// If the entry is a reference, resolve it
- if (entry.type == NamingEntry.REFERENCE
- || entry.type == NamingEntry.LINK_REF) {
+ if (entry.type == NamingEntry.REFERENCE || entry.type == NamingEntry.LINK_REF) {
try {
value = ctx.lookup(new CompositeName(entry.name));
} catch (NamingException e) {
diff -Nru tomcat11-11.0.6/java/org/apache/naming/NamingContextEnumeration.java tomcat11-11.0.15/java/org/apache/naming/NamingContextEnumeration.java
--- tomcat11-11.0.6/java/org/apache/naming/NamingContextEnumeration.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/naming/NamingContextEnumeration.java 2025-12-02 16:54:08.000000000 +0000
@@ -24,11 +24,8 @@
/**
* Naming enumeration implementation.
- *
- * @author Remy Maucherat
*/
-public class NamingContextEnumeration
- implements NamingEnumeration {
+public class NamingContextEnumeration implements NamingEnumeration {
// ----------------------------------------------------------- Constructors
@@ -52,22 +49,19 @@
@Override
- public NameClassPair next()
- throws NamingException {
+ public NameClassPair next() throws NamingException {
return nextElement();
}
@Override
- public boolean hasMore()
- throws NamingException {
+ public boolean hasMore() throws NamingException {
return iterator.hasNext();
}
@Override
- public void close()
- throws NamingException {
+ public void close() throws NamingException {
}
diff -Nru tomcat11-11.0.6/java/org/apache/naming/NamingEntry.java tomcat11-11.0.15/java/org/apache/naming/NamingEntry.java
--- tomcat11-11.0.6/java/org/apache/naming/NamingEntry.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/naming/NamingEntry.java 2025-12-02 16:54:08.000000000 +0000
@@ -19,8 +19,6 @@
/**
* Represents a binding in a NamingContext.
- *
- * @author Remy Maucherat
*/
public class NamingEntry {
@@ -38,8 +36,7 @@
/**
- * The type instance variable is used to avoid using RTTI when doing
- * lookups.
+ * The type instance variable is used to avoid using RTTI when doing lookups.
*/
public int type;
public final String name;
diff -Nru tomcat11-11.0.6/java/org/apache/naming/ResourceEnvRef.java tomcat11-11.0.15/java/org/apache/naming/ResourceEnvRef.java
--- tomcat11-11.0.6/java/org/apache/naming/ResourceEnvRef.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/naming/ResourceEnvRef.java 2025-12-02 16:54:08.000000000 +0000
@@ -20,8 +20,6 @@
/**
* Represents a reference address to a resource environment.
- *
- * @author Remy Maucherat
*/
public class ResourceEnvRef extends AbstractRef {
@@ -32,8 +30,7 @@
/**
* Default factory for this reference.
*/
- public static final String DEFAULT_FACTORY =
- org.apache.naming.factory.Constants.DEFAULT_RESOURCE_ENV_FACTORY;
+ public static final String DEFAULT_FACTORY = org.apache.naming.factory.Constants.DEFAULT_RESOURCE_ENV_FACTORY;
/**
diff -Nru tomcat11-11.0.6/java/org/apache/naming/ResourceLinkRef.java tomcat11-11.0.15/java/org/apache/naming/ResourceLinkRef.java
--- tomcat11-11.0.6/java/org/apache/naming/ResourceLinkRef.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/naming/ResourceLinkRef.java 2025-12-02 16:54:08.000000000 +0000
@@ -22,8 +22,6 @@
/**
* Represents a reference address to a resource.
- *
- * @author Remy Maucherat
*/
public class ResourceLinkRef extends AbstractRef {
@@ -34,8 +32,7 @@
/**
* Default factory for this reference.
*/
- public static final String DEFAULT_FACTORY =
- org.apache.naming.factory.Constants.DEFAULT_RESOURCE_LINK_FACTORY;
+ public static final String DEFAULT_FACTORY = org.apache.naming.factory.Constants.DEFAULT_RESOURCE_LINK_FACTORY;
/**
@@ -47,14 +44,12 @@
/**
* ResourceLink Reference.
*
- * @param resourceClass Resource class
- * @param globalName Global name
- * @param factory The possibly null class name of the object's factory.
- * @param factoryLocation The possibly null location from which to load the
- * factory (e.g. URL)
+ * @param resourceClass Resource class
+ * @param globalName Global name
+ * @param factory The possibly null class name of the object's factory.
+ * @param factoryLocation The possibly null location from which to load the factory (e.g. URL)
*/
- public ResourceLinkRef(String resourceClass, String globalName,
- String factory, String factoryLocation) {
+ public ResourceLinkRef(String resourceClass, String globalName, String factory, String factoryLocation) {
super(resourceClass, factory, factoryLocation);
if (globalName != null) {
add(new StringRefAddr(GLOBALNAME, globalName));
diff -Nru tomcat11-11.0.6/java/org/apache/naming/ResourceRef.java tomcat11-11.0.15/java/org/apache/naming/ResourceRef.java
--- tomcat11-11.0.6/java/org/apache/naming/ResourceRef.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/naming/ResourceRef.java 2025-12-02 16:54:08.000000000 +0000
@@ -22,8 +22,6 @@
/**
* Represents a reference address to a resource.
- *
- * @author Remy Maucherat
*/
public class ResourceRef extends AbstractRef {
@@ -34,8 +32,7 @@
/**
* Default factory for this reference.
*/
- public static final String DEFAULT_FACTORY =
- org.apache.naming.factory.Constants.DEFAULT_RESOURCE_FACTORY;
+ public static final String DEFAULT_FACTORY = org.apache.naming.factory.Constants.DEFAULT_RESOURCE_FACTORY;
/**
@@ -66,14 +63,13 @@
* Resource Reference.
*
* @param resourceClass Resource class
- * @param description Description of the resource
- * @param scope Resource scope
- * @param auth Resource authentication
- * @param singleton Is this resource a singleton (every lookup should return
- * the same instance rather than a new instance)?
+ * @param description Description of the resource
+ * @param scope Resource scope
+ * @param auth Resource authentication
+ * @param singleton Is this resource a singleton (every lookup should return the same instance rather than a new
+ * instance)?
*/
- public ResourceRef(String resourceClass, String description,
- String scope, String auth, boolean singleton) {
+ public ResourceRef(String resourceClass, String description, String scope, String auth, boolean singleton) {
this(resourceClass, description, scope, auth, singleton, null, null);
}
@@ -81,19 +77,17 @@
/**
* Resource Reference.
*
- * @param resourceClass Resource class
- * @param description Description of the resource
- * @param scope Resource scope
- * @param auth Resource authentication
- * @param singleton Is this resource a singleton (every lookup should return
- * the same instance rather than a new instance)?
- * @param factory The possibly null class name of the object's factory.
- * @param factoryLocation The possibly null location from which to load the
- * factory (e.g. URL)
- */
- public ResourceRef(String resourceClass, String description,
- String scope, String auth, boolean singleton,
- String factory, String factoryLocation) {
+ * @param resourceClass Resource class
+ * @param description Description of the resource
+ * @param scope Resource scope
+ * @param auth Resource authentication
+ * @param singleton Is this resource a singleton (every lookup should return the same instance rather than a
+ * new instance)?
+ * @param factory The possibly null class name of the object's factory.
+ * @param factoryLocation The possibly null location from which to load the factory (e.g. URL)
+ */
+ public ResourceRef(String resourceClass, String description, String scope, String auth, boolean singleton,
+ String factory, String factoryLocation) {
super(resourceClass, factory, factoryLocation);
StringRefAddr refAddr;
if (description != null) {
diff -Nru tomcat11-11.0.6/java/org/apache/naming/SelectorContext.java tomcat11-11.0.15/java/org/apache/naming/SelectorContext.java
--- tomcat11-11.0.6/java/org/apache/naming/SelectorContext.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/naming/SelectorContext.java 2025-12-02 16:54:08.000000000 +0000
@@ -31,8 +31,6 @@
/**
* Catalina JNDI Context implementation.
- *
- * @author Remy Maucherat
*/
public class SelectorContext implements Context {
@@ -65,6 +63,7 @@
/**
* Builds a Catalina selector context using the given environment.
+ *
* @param env The environment
*/
public SelectorContext(Hashtable env) {
@@ -75,12 +74,11 @@
/**
* Builds a Catalina selector context using the given environment.
- * @param env The environment
- * @param initialContext true if this is the main
- * initial context
+ *
+ * @param env The environment
+ * @param initialContext true if this is the main initial context
*/
- public SelectorContext(Hashtable env,
- boolean initialContext) {
+ public SelectorContext(Hashtable env, boolean initialContext) {
this.env = env;
this.initialContext = initialContext;
}
@@ -114,12 +112,10 @@
@Override
- public Object lookup(Name name)
- throws NamingException {
+ public Object lookup(Name name) throws NamingException {
if (log.isTraceEnabled()) {
- log.trace(sm.getString("selectorContext.methodUsingName", "lookup",
- name));
+ log.trace(sm.getString("selectorContext.methodUsingName", "lookup", name));
}
// Strip the URL header
@@ -130,12 +126,10 @@
@Override
- public Object lookup(String name)
- throws NamingException {
+ public Object lookup(String name) throws NamingException {
if (log.isTraceEnabled()) {
- log.trace(sm.getString("selectorContext.methodUsingString", "lookup",
- name));
+ log.trace(sm.getString("selectorContext.methodUsingString", "lookup", name));
}
// Strip the URL header
@@ -146,68 +140,58 @@
@Override
- public void bind(Name name, Object obj)
- throws NamingException {
+ public void bind(Name name, Object obj) throws NamingException {
getBoundContext().bind(parseName(name), obj);
}
@Override
- public void bind(String name, Object obj)
- throws NamingException {
+ public void bind(String name, Object obj) throws NamingException {
getBoundContext().bind(parseName(name), obj);
}
@Override
- public void rebind(Name name, Object obj)
- throws NamingException {
+ public void rebind(Name name, Object obj) throws NamingException {
getBoundContext().rebind(parseName(name), obj);
}
@Override
- public void rebind(String name, Object obj)
- throws NamingException {
+ public void rebind(String name, Object obj) throws NamingException {
getBoundContext().rebind(parseName(name), obj);
}
@Override
- public void unbind(Name name)
- throws NamingException {
+ public void unbind(Name name) throws NamingException {
getBoundContext().unbind(parseName(name));
}
@Override
- public void unbind(String name)
- throws NamingException {
+ public void unbind(String name) throws NamingException {
getBoundContext().unbind(parseName(name));
}
@Override
- public void rename(Name oldName, Name newName)
- throws NamingException {
+ public void rename(Name oldName, Name newName) throws NamingException {
getBoundContext().rename(parseName(oldName), parseName(newName));
}
@Override
- public void rename(String oldName, String newName)
- throws NamingException {
+ public void rename(String oldName, String newName) throws NamingException {
getBoundContext().rename(parseName(oldName), parseName(newName));
}
@Override
- public NamingEnumeration list(Name name)
- throws NamingException {
+ public NamingEnumeration list(Name name) throws NamingException {
if (log.isTraceEnabled()) {
- log.trace(sm.getString("selectorContext.methodUsingName", "list",
- name));
+ log.trace(sm.getString("selectorContext.methodUsingName", "list", name));
}
return getBoundContext().list(parseName(name));
@@ -215,12 +199,10 @@
@Override
- public NamingEnumeration list(String name)
- throws NamingException {
+ public NamingEnumeration list(String name) throws NamingException {
if (log.isTraceEnabled()) {
- log.trace(sm.getString("selectorContext.methodUsingString", "list",
- name));
+ log.trace(sm.getString("selectorContext.methodUsingString", "list", name));
}
return getBoundContext().list(parseName(name));
@@ -228,12 +210,10 @@
@Override
- public NamingEnumeration listBindings(Name name)
- throws NamingException {
+ public NamingEnumeration listBindings(Name name) throws NamingException {
if (log.isTraceEnabled()) {
- log.trace(sm.getString("selectorContext.methodUsingName",
- "listBindings", name));
+ log.trace(sm.getString("selectorContext.methodUsingName", "listBindings", name));
}
return getBoundContext().listBindings(parseName(name));
@@ -241,12 +221,10 @@
@Override
- public NamingEnumeration listBindings(String name)
- throws NamingException {
+ public NamingEnumeration listBindings(String name) throws NamingException {
if (log.isTraceEnabled()) {
- log.trace(sm.getString("selectorContext.methodUsingString",
- "listBindings", name));
+ log.trace(sm.getString("selectorContext.methodUsingString", "listBindings", name));
}
return getBoundContext().listBindings(parseName(name));
@@ -254,40 +232,34 @@
@Override
- public void destroySubcontext(Name name)
- throws NamingException {
+ public void destroySubcontext(Name name) throws NamingException {
getBoundContext().destroySubcontext(parseName(name));
}
@Override
- public void destroySubcontext(String name)
- throws NamingException {
+ public void destroySubcontext(String name) throws NamingException {
getBoundContext().destroySubcontext(parseName(name));
}
@Override
- public Context createSubcontext(Name name)
- throws NamingException {
+ public Context createSubcontext(Name name) throws NamingException {
return getBoundContext().createSubcontext(parseName(name));
}
@Override
- public Context createSubcontext(String name)
- throws NamingException {
+ public Context createSubcontext(String name) throws NamingException {
return getBoundContext().createSubcontext(parseName(name));
}
@Override
- public Object lookupLink(Name name)
- throws NamingException {
+ public Object lookupLink(Name name) throws NamingException {
if (log.isTraceEnabled()) {
- log.trace(sm.getString("selectorContext.methodUsingName",
- "lookupLink", name));
+ log.trace(sm.getString("selectorContext.methodUsingName", "lookupLink", name));
}
return getBoundContext().lookupLink(parseName(name));
@@ -295,12 +267,10 @@
@Override
- public Object lookupLink(String name)
- throws NamingException {
+ public Object lookupLink(String name) throws NamingException {
if (log.isTraceEnabled()) {
- log.trace(sm.getString("selectorContext.methodUsingString",
- "lookupLink", name));
+ log.trace(sm.getString("selectorContext.methodUsingString", "lookupLink", name));
}
return getBoundContext().lookupLink(parseName(name));
@@ -308,65 +278,56 @@
@Override
- public NameParser getNameParser(Name name)
- throws NamingException {
+ public NameParser getNameParser(Name name) throws NamingException {
return getBoundContext().getNameParser(parseName(name));
}
@Override
- public NameParser getNameParser(String name)
- throws NamingException {
+ public NameParser getNameParser(String name) throws NamingException {
return getBoundContext().getNameParser(parseName(name));
}
@Override
- public Name composeName(Name name, Name prefix)
- throws NamingException {
+ public Name composeName(Name name, Name prefix) throws NamingException {
Name prefixClone = (Name) prefix.clone();
return prefixClone.addAll(name);
}
@Override
- public String composeName(String name, String prefix)
- throws NamingException {
+ public String composeName(String name, String prefix) throws NamingException {
return prefix + "/" + name;
}
@Override
- public Object addToEnvironment(String propName, Object propVal)
- throws NamingException {
+ public Object addToEnvironment(String propName, Object propVal) throws NamingException {
return getBoundContext().addToEnvironment(propName, propVal);
}
@Override
- public Object removeFromEnvironment(String propName)
- throws NamingException {
+ public Object removeFromEnvironment(String propName) throws NamingException {
return getBoundContext().removeFromEnvironment(propName);
}
@Override
- public Hashtable,?> getEnvironment()
- throws NamingException {
+ public Hashtable,?> getEnvironment() throws NamingException {
return getBoundContext().getEnvironment();
}
@Override
- public void close()
- throws NamingException {
+ public void close() throws NamingException {
getBoundContext().close();
}
@Override
- public String getNameInNamespace()
- throws NamingException {
+ public String getNameInNamespace() throws NamingException {
return prefix;
}
@@ -376,12 +337,12 @@
/**
* Get the bound context.
- * @return the Context bound with either the current thread or
- * the current classloader
+ *
+ * @return the Context bound with either the current thread or the current classloader
+ *
* @throws NamingException Bindings exception
*/
- protected Context getBoundContext()
- throws NamingException {
+ protected Context getBoundContext() throws NamingException {
if (initialContext) {
String ICName = IC_PREFIX;
@@ -411,13 +372,14 @@
/**
* Strips the URL header.
+ *
* @param name The name
+ *
* @return the parsed name
- * @throws NamingException if there is no "java:" header or if no
- * naming context has been bound to this thread
+ *
+ * @throws NamingException if there is no "java:" header or if no naming context has been bound to this thread
*/
- protected String parseName(String name)
- throws NamingException {
+ protected String parseName(String name) throws NamingException {
if ((!initialContext) && (name.startsWith(prefix))) {
return name.substring(prefixLength);
@@ -425,8 +387,7 @@
if (initialContext) {
return name;
} else {
- throw new NamingException
- (sm.getString("selectorContext.noJavaUrl"));
+ throw new NamingException(sm.getString("selectorContext.noJavaUrl"));
}
}
@@ -435,16 +396,16 @@
/**
* Strips the URL header.
+ *
* @param name The name
+ *
* @return the parsed name
- * @throws NamingException if there is no "java:" header or if no
- * naming context has been bound to this thread
+ *
+ * @throws NamingException if there is no "java:" header or if no naming context has been bound to this thread
*/
- protected Name parseName(Name name)
- throws NamingException {
+ protected Name parseName(Name name) throws NamingException {
- if (!initialContext && !name.isEmpty() &&
- name.get(0).startsWith(prefix)) {
+ if (!initialContext && !name.isEmpty() && name.get(0).startsWith(prefix)) {
if (name.get(0).equals(prefix)) {
return name.getSuffix(1);
} else {
@@ -456,8 +417,7 @@
if (initialContext) {
return name;
} else {
- throw new NamingException(
- sm.getString("selectorContext.noJavaUrl"));
+ throw new NamingException(sm.getString("selectorContext.noJavaUrl"));
}
}
diff -Nru tomcat11-11.0.6/java/org/apache/naming/ServiceRef.java tomcat11-11.0.15/java/org/apache/naming/ServiceRef.java
--- tomcat11-11.0.6/java/org/apache/naming/ServiceRef.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/naming/ServiceRef.java 2025-12-02 16:54:08.000000000 +0000
@@ -24,8 +24,6 @@
/**
* Represents a reference web service.
- *
- * @author Fabien Carrion
*/
public class ServiceRef extends AbstractRef {
@@ -36,20 +34,19 @@
/**
* Default factory for this reference.
*/
- public static final String DEFAULT_FACTORY =
- org.apache.naming.factory.Constants.DEFAULT_SERVICE_FACTORY;
+ public static final String DEFAULT_FACTORY = org.apache.naming.factory.Constants.DEFAULT_SERVICE_FACTORY;
/**
* Service Classname address type.
*/
- public static final String SERVICE_INTERFACE = "serviceInterface";
+ public static final String SERVICE_INTERFACE = "serviceInterface";
/**
* ServiceQname address type.
*/
- public static final String SERVICE_NAMESPACE = "service namespace";
+ public static final String SERVICE_NAMESPACE = "service namespace";
public static final String SERVICE_LOCAL_PART = "service local part";
@@ -78,23 +75,19 @@
/**
- * The list to save the handler Reference objects, because they can't be
- * saved in the addrs vector.
+ * The list to save the handler Reference objects, because they can't be saved in the addrs vector.
*/
private final List handlers = new CopyOnWriteArrayList<>();
- public ServiceRef(String refname, String serviceInterface, String[] serviceQname,
- String wsdl, String jaxrpcmapping) {
- this(refname, serviceInterface, serviceQname, wsdl, jaxrpcmapping,
- null, null);
+ public ServiceRef(String refname, String serviceInterface, String[] serviceQname, String wsdl,
+ String jaxrpcmapping) {
+ this(refname, serviceInterface, serviceQname, wsdl, jaxrpcmapping, null, null);
}
- public ServiceRef(@SuppressWarnings("unused") String refname,
- String serviceInterface, String[] serviceQname,
- String wsdl, String jaxrpcmapping,
- String factory, String factoryLocation) {
+ public ServiceRef(@SuppressWarnings("unused") String refname, String serviceInterface, String[] serviceQname,
+ String wsdl, String jaxrpcmapping, String factory, String factoryLocation) {
super(serviceInterface, factory, factoryLocation);
StringRefAddr refAddr;
if (serviceInterface != null) {
@@ -122,6 +115,7 @@
/**
* Add and Get Handlers classes.
+ *
* @return the handler
*/
public HandlerRef getHandler() {
diff -Nru tomcat11-11.0.6/java/org/apache/naming/StringManager.java tomcat11-11.0.15/java/org/apache/naming/StringManager.java
--- tomcat11-11.0.6/java/org/apache/naming/StringManager.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/naming/StringManager.java 2025-12-02 16:54:08.000000000 +0000
@@ -24,27 +24,18 @@
import java.util.ResourceBundle;
/**
- * An internationalization / localization helper class which reduces
- * the bother of handling ResourceBundles and takes care of the
- * common cases of message formatting which otherwise require the
- * creation of Object arrays and such.
+ * An internationalization / localization helper class which reduces the bother of handling ResourceBundles and takes
+ * care of the common cases of message formatting which otherwise require the creation of Object arrays and such.
+ *
+ * The StringManager operates on a package basis. One StringManager per package can be created and accessed via the
+ * getManager method call.
+ *
+ * The StringManager will look for a ResourceBundle named by the package name given plus the suffix of "LocalStrings".
+ * In practice, this means that the localized information will be contained in a LocalStrings.properties file located in
+ * the package directory of the classpath.
+ *
+ * Please see the documentation for java.util.ResourceBundle for more information.
*
- *
The StringManager operates on a package basis. One StringManager
- * per package can be created and accessed via the getManager method
- * call.
- *
- *
The StringManager will look for a ResourceBundle named by
- * the package name given plus the suffix of "LocalStrings". In
- * practice, this means that the localized information will be contained
- * in a LocalStrings.properties file located in the package
- * directory of the classpath.
- *
- *
Please see the documentation for java.util.ResourceBundle for
- * more information.
- *
- * @author James Duncan Davidson [duncan@eng.sun.com]
- * @author James Todd [gonzo@eng.sun.com]
- * @author Mel Martinez [mmartinez@g1440.com]
* @see java.util.ResourceBundle
*/
public class StringManager {
@@ -56,10 +47,8 @@
private final Locale locale;
/**
- * Creates a new StringManager for a given package. This is a
- * private method and all access to it is arbitrated by the
- * static getManager method call so that only one StringManager
- * per package will be created.
+ * Creates a new StringManager for a given package. This is a private method and all access to it is arbitrated by
+ * the static getManager method call so that only one StringManager per package will be created.
*
* @param packageName Name of package to create StringManager for.
*/
@@ -75,9 +64,8 @@
ClassLoader cl = Thread.currentThread().getContextClassLoader();
if (cl != null) {
try {
- tempBundle = ResourceBundle.getBundle(
- bundleName, Locale.getDefault(), cl);
- } catch (MissingResourceException ex2) {
+ tempBundle = ResourceBundle.getBundle(bundleName, Locale.getDefault(), cl);
+ } catch (MissingResourceException ignore) {
// Ignore
}
}
@@ -92,19 +80,17 @@
}
/**
- * Get a string from the underlying resource bundle or return
- * null if the String is not found.
+ * Get a string from the underlying resource bundle or return null if the String is not found.
*
- * @param key to desired resource String
- * @return resource String matching key from underlying
- * bundle or null if not found.
- * @throws IllegalArgumentException if key is null.
+ * @param key to desired resource String
+ *
+ * @return resource String matching key from underlying bundle or null if not found.
+ *
+ * @throws IllegalArgumentException if key is null.
*/
public String getString(String key) {
if (key == null) {
- String msg = "key may not have a null value";
-
- throw new IllegalArgumentException(msg);
+ throw new IllegalArgumentException("key may not have a null value");
}
String str = null;
@@ -114,17 +100,17 @@
if (bundle != null) {
str = bundle.getString(key);
}
- } catch (MissingResourceException mre) {
- //bad: shouldn't mask an exception the following way:
- // str = "[cannot find message associated with key '" + key + "' due to " + mre + "]";
- // because it hides the fact that the String was missing
- // from the calling code.
- //good: could just throw the exception (or wrap it in another)
- // but that would probably cause much havoc on existing
- // code.
- //better: consistent with container pattern to
- // simply return null. Calling code can then do
- // a null check.
+ } catch (MissingResourceException ignore) {
+ // bad: shouldn't mask an exception the following way:
+ // str = "[cannot find message associated with key '" + key + "' due to " + mre + "]";
+ // because it hides the fact that the String was missing
+ // from the calling code.
+ // good: could just throw the exception (or wrap it in another)
+ // but that would probably cause much havoc on existing
+ // code.
+ // better: consistent with container pattern to
+ // simply return null. Calling code can then do
+ // a null check.
// str is already set to null
}
@@ -132,14 +118,12 @@
}
/**
- * Get a string from the underlying resource bundle and format
- * it with the given set of arguments.
+ * Get a string from the underlying resource bundle and format it with the given set of arguments.
*
* @param key The key for the required message
* @param args The values to insert into the message
*
- * @return The request string formatted with the provided arguments or the
- * key if the key was not found.
+ * @return The request string formatted with the provided arguments or the key if the key was not found.
*/
public String getString(final String key, final Object... args) {
String value = getString(key);
@@ -156,12 +140,11 @@
// STATIC SUPPORT METHODS
// --------------------------------------------------------------
- private static final Map managers = new HashMap<>();
+ private static final Map managers = new HashMap<>();
/**
- * Get the StringManager for a particular package. If a manager for
- * a package already exists, it will be reused, else a new
- * StringManager will be created and returned.
+ * Get the StringManager for a particular package. If a manager for a package already exists, it will be reused,
+ * else a new StringManager will be created and returned.
*
* @param packageName The package name
*
diff -Nru tomcat11-11.0.6/java/org/apache/naming/TransactionRef.java tomcat11-11.0.15/java/org/apache/naming/TransactionRef.java
--- tomcat11-11.0.6/java/org/apache/naming/TransactionRef.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/naming/TransactionRef.java 2025-12-02 16:54:08.000000000 +0000
@@ -20,8 +20,6 @@
/**
* Represents a reference address to a transaction.
- *
- * @author Remy Maucherat
*/
public class TransactionRef extends AbstractRef {
@@ -32,8 +30,7 @@
/**
* Default factory for this reference.
*/
- public static final String DEFAULT_FACTORY =
- org.apache.naming.factory.Constants.DEFAULT_TRANSACTION_FACTORY;
+ public static final String DEFAULT_FACTORY = org.apache.naming.factory.Constants.DEFAULT_TRANSACTION_FACTORY;
/**
@@ -47,7 +44,7 @@
/**
* Resource Reference.
*
- * @param factory The factory class
+ * @param factory The factory class
* @param factoryLocation The factory location
*/
public TransactionRef(String factory, String factoryLocation) {
diff -Nru tomcat11-11.0.6/java/org/apache/naming/factory/BeanFactory.java tomcat11-11.0.15/java/org/apache/naming/factory/BeanFactory.java
--- tomcat11-11.0.6/java/org/apache/naming/factory/BeanFactory.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/naming/factory/BeanFactory.java 2025-12-02 16:54:08.000000000 +0000
@@ -37,10 +37,11 @@
/**
* Object factory for any Resource conforming to the JavaBean spec.
+ *
+ * This factory can be configured in a <Context> element in your conf/server.xml
+ * configuration file. An example of factory configuration is:
+ *
*
- *
This factory can be configured in a <Context> element
- * in your conf/server.xml
- * configuration file. An example of factory configuration is:
- *
- * @author Aner Perez [aner at ncstech.com]
*/
public class BeanFactory implements ObjectFactory {
@@ -68,11 +67,13 @@
/**
* Create a new Bean instance.
*
- * @param obj The reference object describing the Bean
- * @param name the bound name
- * @param nameCtx unused
+ * @param obj The reference object describing the Bean
+ * @param name the bound name
+ * @param nameCtx unused
* @param environment unused
+ *
* @return the object instance
+ *
* @throws NamingException if an error occur creating the instance
*/
@Override
@@ -92,7 +93,7 @@
} else {
beanClass = Class.forName(beanClassName);
}
- } catch(ClassNotFoundException cnfe) {
+ } catch (ClassNotFoundException cnfe) {
NamingException ne = new NamingException(sm.getString("beanFactory.classNotFound", beanClassName));
ne.initCause(cnfe);
throw ne;
@@ -117,14 +118,12 @@
ra = e.nextElement();
String propName = ra.getType();
- if (propName.equals(Constants.FACTORY) ||
- propName.equals("scope") || propName.equals("auth") ||
- propName.equals("forceString") ||
- propName.equals("singleton")) {
+ if (propName.equals(Constants.FACTORY) || propName.equals("scope") || propName.equals("auth") ||
+ propName.equals("forceString") || propName.equals("singleton")) {
continue;
}
- value = (String)ra.getContent();
+ value = (String) ra.getContent();
Object[] valueArray = new Object[1];
@@ -162,12 +161,12 @@
setProp = bean.getClass().getMethod(setterName, String.class);
valueArray[0] = value;
} catch (NoSuchMethodException nsme) {
- throw new NamingException(sm.getString(
- "beanFactory.noStringConversion", propName, propType.getName()));
+ throw new NamingException(sm.getString("beanFactory.noStringConversion", propName,
+ propType.getName()));
}
} else {
- throw new NamingException(sm.getString(
- "beanFactory.noStringConversion", propName, propType.getName()));
+ throw new NamingException(
+ sm.getString("beanFactory.noStringConversion", propName, propType.getName()));
}
if (setProp != null) {
diff -Nru tomcat11-11.0.6/java/org/apache/naming/factory/Constants.java tomcat11-11.0.15/java/org/apache/naming/factory/Constants.java
--- tomcat11-11.0.6/java/org/apache/naming/factory/Constants.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/naming/factory/Constants.java 2025-12-02 16:54:08.000000000 +0000
@@ -37,8 +37,7 @@
public static final String DEFAULT_HANDLER_FACTORY = Package + ".HandlerFactory";
- public static final String DBCP_DATASOURCE_FACTORY =
- "org.apache.tomcat.dbcp.dbcp2.BasicDataSourceFactory";
+ public static final String DBCP_DATASOURCE_FACTORY = "org.apache.tomcat.dbcp.dbcp2.BasicDataSourceFactory";
public static final String OPENEJB_EJB_FACTORY = Package + ".OpenEjbFactory";
diff -Nru tomcat11-11.0.6/java/org/apache/naming/factory/DataSourceLinkFactory.java tomcat11-11.0.15/java/org/apache/naming/factory/DataSourceLinkFactory.java
--- tomcat11-11.0.6/java/org/apache/naming/factory/DataSourceLinkFactory.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/naming/factory/DataSourceLinkFactory.java 2025-12-02 16:54:08.000000000 +0000
@@ -31,10 +31,10 @@
import javax.sql.DataSource;
-
/**
- *
Object factory for resource links for shared data sources.
- *
+ *
+ * Object factory for resource links for shared data sources.
+ *
*/
public class DataSourceLinkFactory extends ResourceLinkFactory {
@@ -46,14 +46,15 @@
@Override
public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable,?> environment)
- throws NamingException {
+ throws NamingException {
Object result = super.getObjectInstance(obj, name, nameCtx, environment);
// Can we process this request?
- if (result!=null) {
+ if (result != null) {
Reference ref = (Reference) obj;
RefAddr userAttr = ref.get("username");
RefAddr passAttr = ref.get("password");
- if (userAttr != null && passAttr != null && userAttr.getContent() != null && passAttr.getContent() != null) {
+ if (userAttr != null && passAttr != null && userAttr.getContent() != null &&
+ passAttr.getContent() != null) {
result = wrapDataSource(result, userAttr.getContent().toString(), passAttr.getContent().toString());
}
}
@@ -62,34 +63,32 @@
protected Object wrapDataSource(Object datasource, String username, String password) throws NamingException {
try {
- DataSourceHandler handler =
- new DataSourceHandler((DataSource)datasource, username, password);
- return Proxy.newProxyInstance(datasource.getClass().getClassLoader(),
- datasource.getClass().getInterfaces(), handler);
- }catch (Exception x) {
- Exception exception = x;
- if (exception instanceof InvocationTargetException) {
- Throwable cause = exception.getCause();
+ DataSourceHandler handler = new DataSourceHandler((DataSource) datasource, username, password);
+ return Proxy.newProxyInstance(datasource.getClass().getClassLoader(), datasource.getClass().getInterfaces(),
+ handler);
+ } catch (Exception e) {
+ if (e instanceof InvocationTargetException) {
+ Throwable cause = e.getCause();
if (cause instanceof VirtualMachineError) {
throw (VirtualMachineError) cause;
}
if (cause instanceof Exception) {
- exception = (Exception) cause;
+ e = (Exception) cause;
}
}
- if (exception instanceof NamingException) {
- throw (NamingException) exception;
+ if (e instanceof NamingException) {
+ throw (NamingException) e;
} else {
- NamingException nx = new NamingException(exception.getMessage());
- nx.initCause(exception);
+ NamingException nx = new NamingException(e.getMessage());
+ nx.initCause(e);
throw nx;
}
}
}
/**
- * Simple wrapper class that will allow a user to configure a ResourceLink for a data source
- * so that when {@link javax.sql.DataSource#getConnection()} is called, it will invoke
+ * Simple wrapper class that will allow a user to configure a ResourceLink for a data source so that when
+ * {@link javax.sql.DataSource#getConnection()} is called, it will invoke
* {@link javax.sql.DataSource#getConnection(String, String)} with the preconfigured username and password.
*/
public static class DataSourceHandler implements InvocationHandler {
@@ -97,6 +96,7 @@
private final String username;
private final String password;
private final Method getConnection;
+
public DataSourceHandler(DataSource ds, String username, String password) throws Exception {
this.ds = ds;
this.username = username;
@@ -107,17 +107,16 @@
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
- if ("getConnection".equals(method.getName()) && (args==null || args.length==0)) {
- args = new String[] {username,password};
+ if ("getConnection".equals(method.getName()) && (args == null || args.length == 0)) {
+ args = new String[] { username, password };
method = getConnection;
} else if ("unwrap".equals(method.getName())) {
- return unwrap((Class>)args[0]);
+ return unwrap((Class>) args[0]);
}
try {
- return method.invoke(ds,args);
- }catch (Throwable t) {
- if (t instanceof InvocationTargetException
- && t.getCause() != null) {
+ return method.invoke(ds, args);
+ } catch (Throwable t) {
+ if (t instanceof InvocationTargetException && t.getCause() != null) {
throw t.getCause();
} else {
throw t;
@@ -136,7 +135,5 @@
}
-
-
}
diff -Nru tomcat11-11.0.6/java/org/apache/naming/factory/EjbFactory.java tomcat11-11.0.15/java/org/apache/naming/factory/EjbFactory.java
--- tomcat11-11.0.6/java/org/apache/naming/factory/EjbFactory.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/naming/factory/EjbFactory.java 2025-12-02 16:54:08.000000000 +0000
@@ -27,8 +27,6 @@
/**
* Object factory for EJBs.
- *
- * @author Remy Maucherat
*/
public class EjbFactory extends FactoryBase {
@@ -43,12 +41,10 @@
protected ObjectFactory getDefaultFactory(Reference ref) throws NamingException {
ObjectFactory factory;
- String javaxEjbFactoryClassName = System.getProperty(
- "jakarta.ejb.Factory", Constants.OPENEJB_EJB_FACTORY);
+ String javaxEjbFactoryClassName = System.getProperty("jakarta.ejb.Factory", Constants.OPENEJB_EJB_FACTORY);
try {
- factory = (ObjectFactory)
- Class.forName(javaxEjbFactoryClassName).getConstructor().newInstance();
- } catch(Throwable t) {
+ factory = (ObjectFactory) Class.forName(javaxEjbFactoryClassName).getConstructor().newInstance();
+ } catch (Throwable t) {
if (t instanceof VirtualMachineError) {
throw (VirtualMachineError) t;
}
diff -Nru tomcat11-11.0.6/java/org/apache/naming/factory/FactoryBase.java tomcat11-11.0.15/java/org/apache/naming/factory/FactoryBase.java
--- tomcat11-11.0.6/java/org/apache/naming/factory/FactoryBase.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/naming/factory/FactoryBase.java 2025-12-02 16:54:08.000000000 +0000
@@ -28,16 +28,16 @@
import org.apache.naming.StringManager;
/**
- * Abstract base class that provides common functionality required by
- * subclasses. This class exists primarily to reduce code duplication.
+ * Abstract base class that provides common functionality required by subclasses. This class exists primarily to reduce
+ * code duplication.
*/
public abstract class FactoryBase implements ObjectFactory {
private static final StringManager sm = StringManager.getManager(FactoryBase.class);
@Override
- public final Object getObjectInstance(Object obj, Name name, Context nameCtx,
- Hashtable,?> environment) throws Exception {
+ public final Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable,?> environment)
+ throws Exception {
if (isReferenceTypeSupported(obj)) {
Reference ref = (Reference) obj;
@@ -61,14 +61,14 @@
} else {
factoryClass = Class.forName(factoryClassName);
}
- } catch(ClassNotFoundException e) {
+ } catch (ClassNotFoundException e) {
NamingException ex = new NamingException(sm.getString("factoryBase.factoryClassError"));
ex.initCause(e);
throw ex;
}
try {
factory = (ObjectFactory) factoryClass.getConstructor().newInstance();
- } catch(Throwable t) {
+ } catch (Throwable t) {
if (t instanceof VirtualMachineError) {
throw (VirtualMachineError) t;
}
@@ -93,37 +93,33 @@
/**
- * Determines if this factory supports processing the provided reference
- * object.
+ * Determines if this factory supports processing the provided reference object.
*
- * @param obj The object to be processed
+ * @param obj The object to be processed
*
- * @return true if this factory can process the object,
- * otherwise false
+ * @return true if this factory can process the object, otherwise false
*/
protected abstract boolean isReferenceTypeSupported(Object obj);
/**
- * If a default factory is available for the given reference type, create
- * the default factory.
+ * If a default factory is available for the given reference type, create the default factory.
*
- * @param ref The reference object to be processed
+ * @param ref The reference object to be processed
*
- * @return The default factory for the given reference object or
- * null if no default factory exists.
+ * @return The default factory for the given reference object or null if no default factory exists.
*
- * @throws NamingException If the default factory cannot be created
+ * @throws NamingException If the default factory cannot be created
*/
- protected abstract ObjectFactory getDefaultFactory(Reference ref)
- throws NamingException;
+ protected abstract ObjectFactory getDefaultFactory(Reference ref) throws NamingException;
/**
* If this reference is a link to another JNDI object, obtain that object.
*
- * @param ref The reference object to be processed
+ * @param ref The reference object to be processed
+ *
+ * @return The linked object or null if linked objects are not supported by or not configured for this
+ * reference object
*
- * @return The linked object or null if linked objects are
- * not supported by or not configured for this reference object
* @throws NamingException Error accessing linked object
*/
protected abstract Object getLinked(Reference ref) throws NamingException;
diff -Nru tomcat11-11.0.6/java/org/apache/naming/factory/LookupFactory.java tomcat11-11.0.15/java/org/apache/naming/factory/LookupFactory.java
--- tomcat11-11.0.6/java/org/apache/naming/factory/LookupFactory.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/naming/factory/LookupFactory.java 2025-12-02 16:54:08.000000000 +0000
@@ -45,16 +45,18 @@
/**
* Create a new Resource env instance.
*
- * @param obj The reference object describing the DataSource
- * @param name the bound name
- * @param nameCtx unused
+ * @param obj The reference object describing the DataSource
+ * @param name the bound name
+ * @param nameCtx unused
* @param environment unused
+ *
* @return the object instance
+ *
* @throws Exception if an error occur creating the instance
*/
@Override
- public Object getObjectInstance(Object obj, Name name, Context nameCtx,
- Hashtable, ?> environment) throws Exception {
+ public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable,?> environment)
+ throws Exception {
String lookupName = null;
Object result = null;
@@ -86,8 +88,7 @@
try {
factoryClass = tcl.loadClass(factoryClassName);
} catch (ClassNotFoundException e) {
- NamingException ex = new NamingException(
- sm.getString("lookupFactory.loadFailed"));
+ NamingException ex = new NamingException(sm.getString("lookupFactory.loadFailed"));
ex.initCause(e);
throw ex;
}
@@ -95,8 +96,7 @@
try {
factoryClass = Class.forName(factoryClassName);
} catch (ClassNotFoundException e) {
- NamingException ex = new NamingException(
- sm.getString("lookupFactory.loadFailed"));
+ NamingException ex = new NamingException(sm.getString("lookupFactory.loadFailed"));
ex.initCause(e);
throw ex;
}
@@ -105,8 +105,7 @@
try {
factory = (ObjectFactory) factoryClass.getConstructor().newInstance();
} catch (Throwable t) {
- NamingException ex = new NamingException(
- sm.getString("lookupFactory.createFailed"));
+ NamingException ex = new NamingException(sm.getString("lookupFactory.createFailed"));
ex.initCause(t);
throw ex;
}
@@ -125,8 +124,8 @@
Class> clazz = Class.forName(ref.getClassName());
if (result != null && !clazz.isAssignableFrom(result.getClass())) {
- String msg = sm.getString("lookupFactory.typeMismatch",
- name, ref.getClassName(), lookupName, result.getClass().getName());
+ String msg = sm.getString("lookupFactory.typeMismatch", name, ref.getClassName(), lookupName,
+ result.getClass().getName());
NamingException ne = new NamingException(msg);
log.warn(msg, ne);
// Close the resource we no longer need if we know how to do so
diff -Nru tomcat11-11.0.6/java/org/apache/naming/factory/MailSessionFactory.java tomcat11-11.0.15/java/org/apache/naming/factory/MailSessionFactory.java
--- tomcat11-11.0.6/java/org/apache/naming/factory/MailSessionFactory.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/naming/factory/MailSessionFactory.java 2025-12-02 16:54:08.000000000 +0000
@@ -31,19 +31,20 @@
import jakarta.mail.Session;
/**
- *
Factory class that creates a JNDI named JavaMail Session factory,
- * which can be used for managing inbound and outbound electronic mail
- * messages via JavaMail APIs. All messaging environment properties
- * described in the JavaMail Specification may be passed to the Session
- * factory; however the following properties are the most commonly used:
+ *
+ * Factory class that creates a JNDI named JavaMail Session factory, which can be used for managing inbound and outbound
+ * electronic mail messages via JavaMail APIs. All messaging environment properties described in the JavaMail
+ * Specification may be passed to the Session factory; however the following properties are the most commonly used:
+ *
*
- *
mail.smtp.host - Hostname for outbound transport
- * connections. Defaults to localhost if not specified.
+ *
mail.smtp.host - Hostname for outbound transport connections. Defaults to localhost
+ * if not specified.
*
+ *
+ * This factory can be configured in a <Context> element in your conf/server.xml
+ * configuration file. An example of factory configuration is:
+ *
*
- *
This factory can be configured in a
- * <Context> element in your conf/server.xml
- * configuration file. An example of factory configuration is:
- *
- * @author Craig R. McClanahan
*/
public class MailSessionFactory implements ObjectFactory {
@@ -64,8 +63,7 @@
@Override
- public Object getObjectInstance(Object refObj, Name name, Context context,
- Hashtable,?> env) throws Exception {
+ public Object getObjectInstance(Object refObj, Name name, Context context, Hashtable,?> env) throws Exception {
// Return null if we cannot create an object of the requested type
final Reference ref = (Reference) refObj;
@@ -98,18 +96,18 @@
Authenticator auth = null;
if (password != null) {
String user = props.getProperty("mail.smtp.user");
- if(user == null) {
+ if (user == null) {
user = props.getProperty("mail.user");
}
- if(user != null) {
+ if (user != null) {
final PasswordAuthentication pa = new PasswordAuthentication(user, password);
auth = new Authenticator() {
- @Override
- protected PasswordAuthentication getPasswordAuthentication() {
- return pa;
- }
- };
+ @Override
+ protected PasswordAuthentication getPasswordAuthentication() {
+ return pa;
+ }
+ };
}
}
diff -Nru tomcat11-11.0.6/java/org/apache/naming/factory/OpenEjbFactory.java tomcat11-11.0.15/java/org/apache/naming/factory/OpenEjbFactory.java
--- tomcat11-11.0.6/java/org/apache/naming/factory/OpenEjbFactory.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/naming/factory/OpenEjbFactory.java 2025-12-02 16:54:08.000000000 +0000
@@ -29,37 +29,26 @@
/**
* Object factory for EJBs.
- *
- * @author Jacek Laskowski
- * @author Remy Maucherat
*/
public class OpenEjbFactory implements ObjectFactory {
-
- // -------------------------------------------------------------- Constants
-
-
- protected static final String DEFAULT_OPENEJB_FACTORY =
- "org.openejb.client.LocalInitialContextFactory";
-
-
- // -------------------------------------------------- ObjectFactory Methods
-
+ protected static final String DEFAULT_OPENEJB_FACTORY = "org.openejb.client.LocalInitialContextFactory";
/**
* Create a new EJB instance using OpenEJB.
*
- * @param obj The reference object describing the DataSource
- * @param name the bound name
- * @param nameCtx unused
+ * @param obj The reference object describing the DataSource
+ * @param name the bound name
+ * @param nameCtx unused
* @param environment unused
+ *
* @return the object instance
+ *
* @throws Exception if an error occur creating the instance
*/
@Override
- public Object getObjectInstance(Object obj, Name name, Context nameCtx,
- Hashtable,?> environment)
- throws Exception {
+ public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable,?> environment)
+ throws Exception {
Object beanObj = null;
@@ -80,12 +69,8 @@
String ejbLink = linkRefAddr.getContent().toString();
beanObj = (new InitialContext(env)).lookup(ejbLink);
}
-
}
return beanObj;
-
}
-
-
}
diff -Nru tomcat11-11.0.6/java/org/apache/naming/factory/ResourceEnvFactory.java tomcat11-11.0.15/java/org/apache/naming/factory/ResourceEnvFactory.java
--- tomcat11-11.0.6/java/org/apache/naming/factory/ResourceEnvFactory.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/naming/factory/ResourceEnvFactory.java 2025-12-02 16:54:08.000000000 +0000
@@ -23,8 +23,6 @@
/**
* Object factory for Resources env.
- *
- * @author Remy Maucherat
*/
public class ResourceEnvFactory extends FactoryBase {
diff -Nru tomcat11-11.0.6/java/org/apache/naming/factory/ResourceFactory.java tomcat11-11.0.15/java/org/apache/naming/factory/ResourceFactory.java
--- tomcat11-11.0.6/java/org/apache/naming/factory/ResourceFactory.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/naming/factory/ResourceFactory.java 2025-12-02 16:54:08.000000000 +0000
@@ -25,8 +25,6 @@
/**
* Object factory for Resources.
- *
- * @author Remy Maucherat
*/
public class ResourceFactory extends FactoryBase {
@@ -44,11 +42,10 @@
if (ref.getClassName().equals("javax.sql.DataSource")) {
String javaxSqlDataSourceFactoryClassName =
- System.getProperty("javax.sql.DataSource.Factory",
- Constants.DBCP_DATASOURCE_FACTORY);
+ System.getProperty("javax.sql.DataSource.Factory", Constants.DBCP_DATASOURCE_FACTORY);
try {
- factory = (ObjectFactory) Class.forName(
- javaxSqlDataSourceFactoryClassName).getConstructor().newInstance();
+ factory = (ObjectFactory) Class.forName(javaxSqlDataSourceFactoryClassName).getConstructor()
+ .newInstance();
} catch (Exception e) {
NamingException ex = new NamingException(sm.getString("resourceFactory.factoryCreationError"));
ex.initCause(e);
@@ -56,12 +53,11 @@
}
} else if (ref.getClassName().equals("jakarta.mail.Session")) {
String javaxMailSessionFactoryClassName =
- System.getProperty("jakarta.mail.Session.Factory",
- "org.apache.naming.factory.MailSessionFactory");
+ System.getProperty("jakarta.mail.Session.Factory", "org.apache.naming.factory.MailSessionFactory");
try {
- factory = (ObjectFactory) Class.forName(
- javaxMailSessionFactoryClassName).getConstructor().newInstance();
- } catch(Throwable t) {
+ factory =
+ (ObjectFactory) Class.forName(javaxMailSessionFactoryClassName).getConstructor().newInstance();
+ } catch (Throwable t) {
if (t instanceof VirtualMachineError) {
throw (VirtualMachineError) t;
}
diff -Nru tomcat11-11.0.6/java/org/apache/naming/factory/ResourceLinkFactory.java tomcat11-11.0.15/java/org/apache/naming/factory/ResourceLinkFactory.java
--- tomcat11-11.0.6/java/org/apache/naming/factory/ResourceLinkFactory.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/naming/factory/ResourceLinkFactory.java 2025-12-02 16:54:08.000000000 +0000
@@ -31,9 +31,9 @@
import org.apache.naming.StringManager;
/**
- *
Object factory for resource links.
- *
- * @author Remy Maucherat
+ *
+ * Object factory for resource links.
+ *
*/
public class ResourceLinkFactory implements ObjectFactory {
@@ -46,8 +46,7 @@
*/
private static Context globalContext = null;
- private static final Map> globalResourceRegistrations =
- new ConcurrentHashMap<>();
+ private static final Map> globalResourceRegistrations = new ConcurrentHashMap<>();
// --------------------------------------------------------- Public Methods
@@ -61,8 +60,7 @@
}
- public static void registerGlobalResourceAccess(Context globalContext, String localName,
- String globalName) {
+ public static void registerGlobalResourceAccess(Context globalContext, String localName, String globalName) {
validateGlobalContext(globalContext);
ClassLoader cl = Thread.currentThread().getContextClassLoader();
// Web application initialization is single threaded so this is
@@ -89,8 +87,7 @@
private static void validateGlobalContext(Context globalContext) {
- if (ResourceLinkFactory.globalContext != null &&
- ResourceLinkFactory.globalContext != globalContext) {
+ if (ResourceLinkFactory.globalContext != null && ResourceLinkFactory.globalContext != globalContext) {
throw new SecurityException(sm.getString("resourceLinkFactory.invalidGlobalContext"));
}
}
@@ -114,15 +111,17 @@
/**
* Create a new resource instance.
*
- * @param name the bound name
- * @param nameCtx unused
+ * @param name the bound name
+ * @param nameCtx unused
* @param environment unused
+ *
* @return the object instance
+ *
* @throws NamingException if an error occur creating the instance
*/
@Override
- public Object getObjectInstance(Object obj, Name name, Context nameCtx,
- Hashtable,?> environment) throws NamingException {
+ public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable,?> environment)
+ throws NamingException {
if (!(obj instanceof ResourceLinkRef ref)) {
return null;
@@ -144,19 +143,18 @@
// Check the expected type
String expectedClassName = ref.getClassName();
if (expectedClassName == null) {
- throw new IllegalArgumentException(
- sm.getString("resourceLinkFactory.nullType", name, globalName));
+ throw new IllegalArgumentException(sm.getString("resourceLinkFactory.nullType", name, globalName));
}
try {
- Class> expectedClazz = Class.forName(
- expectedClassName, true, Thread.currentThread().getContextClassLoader());
+ Class> expectedClazz =
+ Class.forName(expectedClassName, true, Thread.currentThread().getContextClassLoader());
if (!expectedClazz.isAssignableFrom(result.getClass())) {
- throw new IllegalArgumentException(sm.getString("resourceLinkFactory.wrongType",
- name, globalName, expectedClassName, result.getClass().getName()));
+ throw new IllegalArgumentException(sm.getString("resourceLinkFactory.wrongType", name, globalName,
+ expectedClassName, result.getClass().getName()));
}
} catch (ClassNotFoundException e) {
- throw new IllegalArgumentException(sm.getString("resourceLinkFactory.unknownType",
- name, globalName, expectedClassName), e);
+ throw new IllegalArgumentException(
+ sm.getString("resourceLinkFactory.unknownType", name, globalName, expectedClassName), e);
}
return result;
}
diff -Nru tomcat11-11.0.6/java/org/apache/naming/factory/SendMailFactory.java tomcat11-11.0.15/java/org/apache/naming/factory/SendMailFactory.java
--- tomcat11-11.0.6/java/org/apache/naming/factory/SendMailFactory.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/naming/factory/SendMailFactory.java 2025-12-02 16:54:08.000000000 +0000
@@ -34,13 +34,13 @@
import org.apache.tomcat.util.ExceptionUtils;
/**
- * Factory class that creates a JNDI named javamail MimePartDataSource
- * object which can be used for sending email using SMTP.
+ * Factory class that creates a JNDI named javamail MimePartDataSource object which can be used for sending email using
+ * SMTP.
*
- * Can be configured in the Context scope
- * of your server.xml configuration file.
+ * Can be configured in the Context scope of your server.xml configuration file.
*
- *
- * @author Glenn Nielsen Rich Catlett
*/
-
-public class SendMailFactory implements ObjectFactory
-{
+public class SendMailFactory implements ObjectFactory {
// The class name for the javamail MimeMessageDataSource
- protected static final String DataSourceClassName =
- "jakarta.mail.internet.MimePartDataSource";
+ protected static final String DataSourceClassName = "jakarta.mail.internet.MimePartDataSource";
@Override
- public Object getObjectInstance(Object refObj, Name name, Context ctx,
- Hashtable,?> env) throws Exception {
- final Reference ref = (Reference)refObj;
+ public Object getObjectInstance(Object refObj, Name name, Context ctx, Hashtable,?> env) throws Exception {
+ final Reference ref = (Reference) refObj;
if (ref.getClassName().equals(DataSourceClassName)) {
// set up the smtp session that will send the message
@@ -85,8 +79,7 @@
// set property
props.put(refaddr.getType(), refaddr.getContent());
}
- MimeMessage message = new MimeMessage(
- Session.getInstance(props));
+ MimeMessage message = new MimeMessage(Session.getInstance(props));
try {
RefAddr fromAddr = ref.get("mail.from");
String from = null;
diff -Nru tomcat11-11.0.6/java/org/apache/naming/factory/TransactionFactory.java tomcat11-11.0.15/java/org/apache/naming/factory/TransactionFactory.java
--- tomcat11-11.0.6/java/org/apache/naming/factory/TransactionFactory.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/naming/factory/TransactionFactory.java 2025-12-02 16:54:08.000000000 +0000
@@ -23,8 +23,6 @@
/**
* Object factory for User transactions.
- *
- * @author Remy Maucherat
*/
public class TransactionFactory extends FactoryBase {
diff -Nru tomcat11-11.0.6/java/org/apache/naming/java/javaURLContextFactory.java tomcat11-11.0.15/java/org/apache/naming/java/javaURLContextFactory.java
--- tomcat11-11.0.6/java/org/apache/naming/java/javaURLContextFactory.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/naming/java/javaURLContextFactory.java 2025-12-02 16:54:08.000000000 +0000
@@ -31,22 +31,15 @@
/**
* Context factory for the "java:" namespace.
*
- * Important note : This factory MUST be associated with the "java" URL
- * prefix, which can be done by either :
+ * Important note : This factory MUST be associated with the "java" URL prefix, which can be done by either :
*
- *
Adding a
- * java.naming.factory.url.pkgs=org.apache.naming property
- * to the JNDI properties file
- *
Setting an environment variable named Context.URL_PKG_PREFIXES with
- * its value including the org.apache.naming package name.
- * More detail about this can be found in the JNDI documentation :
+ *
Adding a java.naming.factory.url.pkgs=org.apache.naming property to the JNDI properties file
+ *
Setting an environment variable named Context.URL_PKG_PREFIXES with its value including the org.apache.naming
+ * package name. More detail about this can be found in the JNDI documentation :
* {@link javax.naming.spi.NamingManager#getURLContext(String, java.util.Hashtable)}.
*
- *
- * @author Remy Maucherat
*/
-public class javaURLContextFactory
- implements ObjectFactory, InitialContextFactory {
+public class javaURLContextFactory implements ObjectFactory, InitialContextFactory {
// ----------------------------------------------------------- Constructors
@@ -75,22 +68,22 @@
/**
* Create a new Context's instance.
- * @param obj unused
- * @param name unused
- * @param nameCtx unused
+ *
+ * @param obj unused
+ * @param name unused
+ * @param nameCtx unused
* @param environment the environment used
- * @return a selector context if the thread or classloader are bound, and
- * null otherwise
+ *
+ * @return a selector context if the thread or classloader are bound, and null otherwise
+ *
* @throws NamingException not thrown by this implementationm
*/
@SuppressWarnings("unchecked")
@Override
- public Object getObjectInstance(Object obj, Name name, Context nameCtx,
- Hashtable,?> environment)
- throws NamingException {
- if ((ContextBindings.isThreadBound()) ||
- (ContextBindings.isClassLoaderBound())) {
- return new SelectorContext((Hashtable)environment);
+ public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable,?> environment)
+ throws NamingException {
+ if ((ContextBindings.isThreadBound()) || (ContextBindings.isClassLoaderBound())) {
+ return new SelectorContext((Hashtable) environment);
}
return null;
}
@@ -98,28 +91,26 @@
/**
* Get a new (writable) initial context.
+ *
* @param environment the environment used
- * @return a selector context if the thread or classloader are bound, and
- * a shared writable context otherwise
+ *
+ * @return a selector context if the thread or classloader are bound, and a shared writable context otherwise
+ *
* @throws NamingException not thrown by this implementationm
*/
@SuppressWarnings("unchecked")
@Override
- public Context getInitialContext(Hashtable,?> environment)
- throws NamingException {
- if (ContextBindings.isThreadBound() ||
- (ContextBindings.isClassLoaderBound())) {
+ public Context getInitialContext(Hashtable,?> environment) throws NamingException {
+ if (ContextBindings.isThreadBound() || (ContextBindings.isClassLoaderBound())) {
// Redirect the request to the bound initial context
- return new SelectorContext(
- (Hashtable)environment, true);
+ return new SelectorContext((Hashtable) environment, true);
}
// If the thread is not bound, return a shared writable context
if (initialContext == null) {
- synchronized(javaURLContextFactory.class) {
+ synchronized (javaURLContextFactory.class) {
if (initialContext == null) {
- initialContext = new NamingContext(
- (Hashtable)environment, MAIN);
+ initialContext = new NamingContext((Hashtable) environment, MAIN);
}
}
}
diff -Nru tomcat11-11.0.6/java/org/apache/tomcat/ContextBind.java tomcat11-11.0.15/java/org/apache/tomcat/ContextBind.java
--- tomcat11-11.0.6/java/org/apache/tomcat/ContextBind.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/tomcat/ContextBind.java 2025-12-02 16:54:08.000000000 +0000
@@ -19,53 +19,40 @@
public interface ContextBind {
/**
- * Change the current thread context class loader to the web application
- * class loader. If no web application class loader is defined, or if the
- * current thread is already using the web application class loader then no
- * change will be made. If the class loader is changed and a
- * {@link org.apache.catalina.ThreadBindingListener} is configured then
- * {@link org.apache.catalina.ThreadBindingListener#bind()} will be called
- * after the change has been made.
- *
- * @param originalClassLoader The current class loader if known to save this
- * method having to look it up
- *
- * @return If the class loader has been changed by the method it will return
- * the thread context class loader in use when the method was called. If
- * no change was made then this method returns null.
+ * Change the current thread context class loader to the web application class loader. If no web application class
+ * loader is defined, or if the current thread is already using the web application class loader then no change will
+ * be made. If the class loader is changed and a {@link org.apache.catalina.ThreadBindingListener} is configured
+ * then {@link org.apache.catalina.ThreadBindingListener#bind()} will be called after the change has been made.
+ *
+ * @param originalClassLoader The current class loader if known to save this method having to look it up
+ *
+ * @return If the class loader has been changed by the method it will return the thread context class loader in use
+ * when the method was called. If no change was made then this method returns null.
*/
ClassLoader bind(ClassLoader originalClassLoader);
/**
- * Restore the current thread context class loader to the original class
- * loader in used before {@link #bind(boolean, ClassLoader)} was called. If
- * no original class loader is passed to this method then no change will be
- * made. If the class loader is changed and a
- * {@link org.apache.catalina.ThreadBindingListener} is configured then
- * {@link org.apache.catalina.ThreadBindingListener#unbind()} will be called
- * before the change is made.
+ * Restore the current thread context class loader to the original class loader in used before
+ * {@link #bind(boolean, ClassLoader)} was called. If no original class loader is passed to this method then no
+ * change will be made. If the class loader is changed and a {@link org.apache.catalina.ThreadBindingListener} is
+ * configured then {@link org.apache.catalina.ThreadBindingListener#unbind()} will be called before the change is
+ * made.
*
- * @param originalClassLoader
- * The class loader to restore as the thread context class loader
+ * @param originalClassLoader The class loader to restore as the thread context class loader
*/
void unbind(ClassLoader originalClassLoader);
/**
- * Change the current thread context class loader to the web application
- * class loader. If no web application class loader is defined, or if the
- * current thread is already using the web application class loader then no
- * change will be made. If the class loader is changed and a
- * {@link org.apache.catalina.ThreadBindingListener} is configured then
- * {@link org.apache.catalina.ThreadBindingListener#bind()} will be called
- * after the change has been made.
+ * Change the current thread context class loader to the web application class loader. If no web application class
+ * loader is defined, or if the current thread is already using the web application class loader then no change will
+ * be made. If the class loader is changed and a {@link org.apache.catalina.ThreadBindingListener} is configured
+ * then {@link org.apache.catalina.ThreadBindingListener#bind()} will be called after the change has been made.
*
* @param usePrivilegedAction Unused
- * @param originalClassLoader The current class loader if known to save this
- * method having to look it up
+ * @param originalClassLoader The current class loader if known to save this method having to look it up
*
- * @return If the class loader has been changed by the method it will return
- * the thread context class loader in use when the method was called. If
- * no change was made then this method returns null.
+ * @return If the class loader has been changed by the method it will return the thread context class loader in use
+ * when the method was called. If no change was made then this method returns null.
*
* @deprecated Unused. Will be removed in Tomcat 12 onwards.
*/
@@ -73,17 +60,14 @@
ClassLoader bind(boolean usePrivilegedAction, ClassLoader originalClassLoader);
/**
- * Restore the current thread context class loader to the original class
- * loader in used before {@link #bind(boolean, ClassLoader)} was called. If
- * no original class loader is passed to this method then no change will be
- * made. If the class loader is changed and a
- * {@link org.apache.catalina.ThreadBindingListener} is configured then
- * {@link org.apache.catalina.ThreadBindingListener#unbind()} will be called
- * before the change is made.
+ * Restore the current thread context class loader to the original class loader in used before
+ * {@link #bind(boolean, ClassLoader)} was called. If no original class loader is passed to this method then no
+ * change will be made. If the class loader is changed and a {@link org.apache.catalina.ThreadBindingListener} is
+ * configured then {@link org.apache.catalina.ThreadBindingListener#unbind()} will be called before the change is
+ * made.
*
* @param usePrivilegedAction Unused
- * @param originalClassLoader The class loader to restore as the thread
- * context class loader
+ * @param originalClassLoader The class loader to restore as the thread context class loader
*
* @deprecated Unused. Will be removed in Tomcat 12 onwards.
*/
diff -Nru tomcat11-11.0.6/java/org/apache/tomcat/InstanceManager.java tomcat11-11.0.15/java/org/apache/tomcat/InstanceManager.java
--- tomcat11-11.0.6/java/org/apache/tomcat/InstanceManager.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/tomcat/InstanceManager.java 2025-12-02 16:54:08.000000000 +0000
@@ -22,28 +22,24 @@
public interface InstanceManager {
- Object newInstance(Class> clazz) throws IllegalAccessException, InvocationTargetException,
- NamingException, InstantiationException, IllegalArgumentException,
- NoSuchMethodException, SecurityException;
-
- Object newInstance(String className) throws IllegalAccessException, InvocationTargetException,
- NamingException, InstantiationException, ClassNotFoundException,
- IllegalArgumentException, NoSuchMethodException, SecurityException;
-
- Object newInstance(String fqcn, ClassLoader classLoader) throws IllegalAccessException,
- InvocationTargetException, NamingException, InstantiationException,
- ClassNotFoundException, IllegalArgumentException, NoSuchMethodException,
- SecurityException;
+ Object newInstance(Class> clazz) throws IllegalAccessException, InvocationTargetException, NamingException,
+ InstantiationException, IllegalArgumentException, NoSuchMethodException, SecurityException;
- void newInstance(Object o)
- throws IllegalAccessException, InvocationTargetException, NamingException;
+ Object newInstance(String className)
+ throws IllegalAccessException, InvocationTargetException, NamingException, InstantiationException,
+ ClassNotFoundException, IllegalArgumentException, NoSuchMethodException, SecurityException;
+
+ Object newInstance(String fqcn, ClassLoader classLoader)
+ throws IllegalAccessException, InvocationTargetException, NamingException, InstantiationException,
+ ClassNotFoundException, IllegalArgumentException, NoSuchMethodException, SecurityException;
+
+ void newInstance(Object o) throws IllegalAccessException, InvocationTargetException, NamingException;
void destroyInstance(Object o) throws IllegalAccessException, InvocationTargetException;
/**
- * Called by the component using the InstanceManager periodically to perform
- * any regular maintenance that might be required. By default, this method
- * is a NO-OP.
+ * Called by the component using the InstanceManager periodically to perform any regular maintenance that might be
+ * required. By default, this method is a NO-OP.
*/
default void backgroundProcess() {
// NO-OP by default
diff -Nru tomcat11-11.0.6/java/org/apache/tomcat/InstanceManagerBindings.java tomcat11-11.0.15/java/org/apache/tomcat/InstanceManagerBindings.java
--- tomcat11-11.0.6/java/org/apache/tomcat/InstanceManagerBindings.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/tomcat/InstanceManagerBindings.java 2025-12-02 16:54:08.000000000 +0000
@@ -21,14 +21,16 @@
public final class InstanceManagerBindings {
- private static final Map bindings = new ConcurrentHashMap<>();
+ private static final Map bindings = new ConcurrentHashMap<>();
public static void bind(ClassLoader classLoader, InstanceManager instanceManager) {
bindings.put(classLoader, instanceManager);
}
+
public static void unbind(ClassLoader classLoader) {
bindings.remove(classLoader);
}
+
public static InstanceManager get(ClassLoader classLoader) {
return bindings.get(classLoader);
}
diff -Nru tomcat11-11.0.6/java/org/apache/tomcat/InstrumentableClassLoader.java tomcat11-11.0.15/java/org/apache/tomcat/InstrumentableClassLoader.java
--- tomcat11-11.0.6/java/org/apache/tomcat/InstrumentableClassLoader.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/tomcat/InstrumentableClassLoader.java 2025-12-02 16:54:08.000000000 +0000
@@ -19,58 +19,46 @@
import java.lang.instrument.ClassFileTransformer;
/**
- * Specifies a class loader capable of being decorated with
- * {@link ClassFileTransformer}s. These transformers can instrument
- * (or weave) the byte code of classes loaded through this class loader
- * to alter their behavior. Currently only
- * {@link org.apache.catalina.loader.WebappClassLoaderBase} implements this
- * interface. This allows web application frameworks or JPA providers
- * bundled with a web application to instrument web application classes
- * as necessary.
+ * Specifies a class loader capable of being decorated with {@link ClassFileTransformer}s. These transformers can
+ * instrument (or weave) the byte code of classes loaded through this class loader to alter their behavior. Currently
+ * only {@link org.apache.catalina.loader.WebappClassLoaderBase} implements this interface. This allows web application
+ * frameworks or JPA providers bundled with a web application to instrument web application classes as necessary.
*
- * You should always program against the methods of this interface
- * (whether using reflection or otherwise). The methods in
- * {@code WebappClassLoaderBase} are protected by the default security
- * manager if one is in use.
+ * You should always program against the methods of this interface (whether using reflection or otherwise). The methods
+ * in {@code WebappClassLoaderBase} are protected by the default security manager if one is in use.
*
* @since 8.0, 7.0.64
*/
public interface InstrumentableClassLoader {
/**
- * Adds the specified class file transformer to this class loader. The
- * transformer will then be able to instrument the bytecode of any
- * classes loaded by this class loader after the invocation of this
- * method.
+ * Adds the specified class file transformer to this class loader. The transformer will then be able to instrument
+ * the bytecode of any classes loaded by this class loader after the invocation of this method.
*
* @param transformer The transformer to add to the class loader
+ *
* @throws IllegalArgumentException if the {@literal transformer} is null.
*/
void addTransformer(ClassFileTransformer transformer);
/**
- * Removes the specified class file transformer from this class loader.
- * It will no longer be able to instrument the byte code of any classes
- * loaded by the class loader after the invocation of this method.
- * However, any classes already instrumented by this transformer before
- * this method call will remain in their instrumented state.
+ * Removes the specified class file transformer from this class loader. It will no longer be able to instrument the
+ * byte code of any classes loaded by the class loader after the invocation of this method. However, any classes
+ * already instrumented by this transformer before this method call will remain in their instrumented state.
*
* @param transformer The transformer to remove
*/
void removeTransformer(ClassFileTransformer transformer);
/**
- * Returns a copy of this class loader without any class file
- * transformers. This is a tool often used by Java Persistence API
- * providers to inspect entity classes in the absence of any
- * instrumentation, something that can't be guaranteed within the
- * context of a {@link ClassFileTransformer}'s
- * {@link ClassFileTransformer#transform(ClassLoader, String, Class,
- * java.security.ProtectionDomain, byte[]) transform} method.
+ * Returns a copy of this class loader without any class file transformers. This is a tool often used by Java
+ * Persistence API providers to inspect entity classes in the absence of any instrumentation, something that can't
+ * be guaranteed within the context of a {@link ClassFileTransformer}'s
+ * {@link ClassFileTransformer#transform(ClassLoader, String, Class, java.security.ProtectionDomain, byte[])
+ * transform} method.
*
- * The returned class loader's resource cache will have been cleared
- * so that classes already instrumented will not be retained or
- * returned.
+ * The returned class loader's resource cache will have been cleared so that classes already instrumented will not
+ * be retained or returned.
*
* @return the transformer-free copy of this class loader.
*/
diff -Nru tomcat11-11.0.6/java/org/apache/tomcat/Jar.java tomcat11-11.0.15/java/org/apache/tomcat/Jar.java
--- tomcat11-11.0.6/java/org/apache/tomcat/Jar.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/tomcat/Jar.java 2025-12-02 16:54:08.000000000 +0000
@@ -22,15 +22,12 @@
import java.util.jar.Manifest;
/**
- * Provides an abstraction for use by the various classes that need to scan
- * JARs. The classes provided by the JRE for accessing JARs
- * ({@link java.util.jar.JarFile} and {@link java.util.jar.JarInputStream}) have
- * significantly different performance characteristics depending on the form of
- * the URL used to access the JAR. For file based JAR {@link java.net.URL}s,
- * {@link java.util.jar.JarFile} is faster but for non-file based
- * {@link java.net.URL}s, {@link java.util.jar.JarFile} creates a copy of the
- * JAR in the temporary directory so {@link java.util.jar.JarInputStream} is
- * faster.
+ * Provides an abstraction for use by the various classes that need to scan JARs. The classes provided by the JRE for
+ * accessing JARs ({@link java.util.jar.JarFile} and {@link java.util.jar.JarInputStream}) have significantly different
+ * performance characteristics depending on the form of the URL used to access the JAR. For file based JAR
+ * {@link java.net.URL}s, {@link java.util.jar.JarFile} is faster but for non-file based {@link java.net.URL}s,
+ * {@link java.util.jar.JarFile} creates a copy of the JAR in the temporary directory so
+ * {@link java.util.jar.JarInputStream} is faster.
*/
public interface Jar extends AutoCloseable {
@@ -40,12 +37,11 @@
URL getJarFileURL();
/**
- * Obtain an {@link InputStream} for a given entry in a JAR. The caller is
- * responsible for closing the stream.
+ * Obtain an {@link InputStream} for a given entry in a JAR. The caller is responsible for closing the stream.
*
- * @param name Entry to obtain an {@link InputStream} for
- * @return An {@link InputStream} for the specified entry or null if
- * the entry does not exist
+ * @param name Entry to obtain an {@link InputStream} for
+ *
+ * @return An {@link InputStream} for the specified entry or null if the entry does not exist
*
* @throws IOException if an I/O error occurs while processing the JAR file
*/
@@ -54,11 +50,10 @@
/**
* Obtain the last modified time for the given resource in the JAR.
*
- * @param name Entry to obtain the modification time for
+ * @param name Entry to obtain the modification time for
*
- * @return The time (in the same format as
- * {@link System#currentTimeMillis()}) that the resource was last
- * modified. Returns -1 if the entry does not exist
+ * @return The time (in the same format as {@link System#currentTimeMillis()}) that the resource was last modified.
+ * Returns -1 if the entry does not exist
*
* @throws IOException if an I/O error occurs while processing the JAR file
*/
@@ -67,10 +62,9 @@
/**
* Determine if the given resource in present in the JAR.
*
- * @param name Entry to look for
+ * @param name Entry to look for
*
- * @return {@code true} if the entry is present in the JAR, otherwise
- * {@code false}
+ * @return {@code true} if the entry is present in the JAR, otherwise {@code false}
*
* @throws IOException if an I/O error occurs while processing the JAR file
*/
@@ -90,26 +84,24 @@
/**
* Obtains the name of the current entry.
*
- * @return The entry name
+ * @return The entry name
*/
String getEntryName();
/**
* Obtains the input stream for the current entry.
*
- * @return The input stream
- * @throws IOException If the stream cannot be obtained
+ * @return The input stream
+ *
+ * @throws IOException If the stream cannot be obtained
*/
InputStream getEntryInputStream() throws IOException;
/**
- * Obtain, in String form, the URL for an entry in this JAR. Note that for
- * JARs nested in WAR files, the Tomcat specific war:file:... form will not
- * be used, rather the jar:jar:file:... form (that the JRE does not
- * understand will be used). Note that this means that any code using these
- * URLs will need to understand the jar:jar:file:... form and use the
- * {@link org.apache.tomcat.util.scan.JarFactory} to ensure resources are
- * accessed correctly.
+ * Obtain, in String form, the URL for an entry in this JAR. Note that for JARs nested in WAR files, the Tomcat
+ * specific war:file:... form will not be used, rather the jar:jar:file:... form (that the JRE does not understand
+ * will be used). Note that this means that any code using these URLs will need to understand the jar:jar:file:...
+ * form and use the {@link org.apache.tomcat.util.scan.JarFactory} to ensure resources are accessed correctly.
*
* @param entry The entry to generate the URL for
*
@@ -127,10 +119,9 @@
Manifest getManifest() throws IOException;
/**
- * Resets the internal pointer used to track JAR entries to the beginning of
- * the JAR.
+ * Resets the internal pointer used to track JAR entries to the beginning of the JAR.
*
- * @throws IOException If the pointer cannot be reset
+ * @throws IOException If the pointer cannot be reset
*/
void reset() throws IOException;
}
diff -Nru tomcat11-11.0.6/java/org/apache/tomcat/JarScanFilter.java tomcat11-11.0.15/java/org/apache/tomcat/JarScanFilter.java
--- tomcat11-11.0.6/java/org/apache/tomcat/JarScanFilter.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/tomcat/JarScanFilter.java 2025-12-02 16:54:08.000000000 +0000
@@ -19,18 +19,18 @@
public interface JarScanFilter {
/**
- * @param jarScanType The type of JAR scan currently being performed
- * @param jarName The name of the JAR file (without any path
- * information) to be checked to see if it should
- * be included in the results or not
- * @return true if the JAR should be returned in the results,
- * false if it should be excluded
+ * @param jarScanType The type of JAR scan currently being performed
+ * @param jarName The name of the JAR file (without any path information) to be checked to see if it should be
+ * included in the results or not
+ *
+ * @return true if the JAR should be returned in the results, false if it should be
+ * excluded
*/
boolean check(JarScanType jarScanType, String jarName);
/**
- * @return true if all of the scans should be skipped which
- * can improve startup performance. The default is false.
+ * @return true if all of the scans should be skipped which can improve startup performance. The
+ * default is false.
*/
default boolean isSkipAll() {
return false;
diff -Nru tomcat11-11.0.6/java/org/apache/tomcat/JarScanner.java tomcat11-11.0.15/java/org/apache/tomcat/JarScanner.java
--- tomcat11-11.0.6/java/org/apache/tomcat/JarScanner.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/tomcat/JarScanner.java 2025-12-02 16:54:08.000000000 +0000
@@ -19,25 +19,21 @@
import jakarta.servlet.ServletContext;
/**
- * Scans a web application and classloader hierarchy for JAR files. Uses
- * include TLD scanning and web-fragment.xml scanning. Uses a call-back
- * mechanism so the caller can process each JAR found.
+ * Scans a web application and classloader hierarchy for JAR files. Uses include TLD scanning and web-fragment.xml
+ * scanning. Uses a call-back mechanism so the caller can process each JAR found.
*/
public interface JarScanner {
/**
- * Scan the provided ServletContext and classloader for JAR files. Each JAR
- * file found will be passed to the callback handler to be processed.
+ * Scan the provided ServletContext and classloader for JAR files. Each JAR file found will be passed to the
+ * callback handler to be processed.
*
- * @param scanType The type of JAR scan to perform. This is passed to
- * the filter which uses it to determine how to
- * filter the results
- * @param context The ServletContext - used to locate and access
- * WEB-INF/lib
- * @param callback The handler to process any JARs found
+ * @param scanType The type of JAR scan to perform. This is passed to the filter which uses it to determine how to
+ * filter the results
+ * @param context The ServletContext - used to locate and access WEB-INF/lib
+ * @param callback The handler to process any JARs found
*/
- void scan(JarScanType scanType, ServletContext context,
- JarScannerCallback callback);
+ void scan(JarScanType scanType, ServletContext context, JarScannerCallback callback);
JarScanFilter getJarScanFilter();
diff -Nru tomcat11-11.0.6/java/org/apache/tomcat/JarScannerCallback.java tomcat11-11.0.15/java/org/apache/tomcat/JarScannerCallback.java
--- tomcat11-11.0.6/java/org/apache/tomcat/JarScannerCallback.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/tomcat/JarScannerCallback.java 2025-12-02 16:54:08.000000000 +0000
@@ -20,35 +20,31 @@
import java.io.IOException;
/**
- * This interface is implemented by clients of the {@link JarScanner} to enable
- * them to receive notification of a discovered JAR.
+ * This interface is implemented by clients of the {@link JarScanner} to enable them to receive notification of a
+ * discovered JAR.
*/
public interface JarScannerCallback {
/**
- * A JAR was found and may be accessed for further processing via the
- * provided URL connection. The caller is responsible for closing the JAR.
+ * A JAR was found and may be accessed for further processing via the provided URL connection. The caller is
+ * responsible for closing the JAR.
*
* @param jar The JAR to process
* @param webappPath The path, if any, to the JAR within the web application
- * @param isWebapp Indicates if the JAR was found within a web
- * application. If false the JAR should
+ * @param isWebapp Indicates if the JAR was found within a web application. If false the JAR should
* be treated as being provided by the container
*
* @throws IOException if an I/O error occurs while scanning the JAR
*/
- void scan(Jar jar, String webappPath, boolean isWebapp)
- throws IOException;
+ void scan(Jar jar, String webappPath, boolean isWebapp) throws IOException;
/**
- * A directory was found that is to be treated as an unpacked JAR. The
- * directory may be accessed for further processing via the provided file.
+ * A directory was found that is to be treated as an unpacked JAR. The directory may be accessed for further
+ * processing via the provided file.
*
* @param file The directory containing the unpacked JAR.
- * @param webappPath The path, if any, to the file within the web
- * application
- * @param isWebapp Indicates if the JAR was found within a web
- * application. If false the JAR should
+ * @param webappPath The path, if any, to the file within the web application
+ * @param isWebapp Indicates if the JAR was found within a web application. If false the JAR should
* be treated as being provided by the container
*
* @throws IOException if an I/O error occurs while scanning the JAR
@@ -56,10 +52,9 @@
void scan(File file, String webappPath, boolean isWebapp) throws IOException;
/**
- * A directory structure was found within the web application at
- * /WEB-INF/classes that should be handled as an unpacked JAR. Note that all
- * resource access must be via the ServletContext to ensure that any
- * additional resources are visible.
+ * A directory structure was found within the web application at /WEB-INF/classes that should be handled as an
+ * unpacked JAR. Note that all resource access must be via the ServletContext to ensure that any additional
+ * resources are visible.
*
* @throws IOException if an I/O error occurs while scanning WEB-INF/classes
*/
diff -Nru tomcat11-11.0.6/java/org/apache/tomcat/SimpleInstanceManager.java tomcat11-11.0.15/java/org/apache/tomcat/SimpleInstanceManager.java
--- tomcat11-11.0.6/java/org/apache/tomcat/SimpleInstanceManager.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/tomcat/SimpleInstanceManager.java 2025-12-02 16:54:08.000000000 +0000
@@ -29,30 +29,28 @@
}
@Override
- public Object newInstance(Class> clazz) throws IllegalAccessException,
- InvocationTargetException, NamingException, InstantiationException, NoSuchMethodException {
+ public Object newInstance(Class> clazz) throws IllegalAccessException, InvocationTargetException, NamingException,
+ InstantiationException, NoSuchMethodException {
return prepareInstance(clazz.getConstructor().newInstance());
}
@Override
- public Object newInstance(String className) throws IllegalAccessException,
- InvocationTargetException, NamingException, InstantiationException,
- ClassNotFoundException, NoSuchMethodException {
+ public Object newInstance(String className) throws IllegalAccessException, InvocationTargetException,
+ NamingException, InstantiationException, ClassNotFoundException, NoSuchMethodException {
Class> clazz = Thread.currentThread().getContextClassLoader().loadClass(className);
return prepareInstance(clazz.getConstructor().newInstance());
}
@Override
- public Object newInstance(String fqcn, ClassLoader classLoader) throws IllegalAccessException,
- InvocationTargetException, NamingException, InstantiationException,
- ClassNotFoundException, NoSuchMethodException {
+ public Object newInstance(String fqcn, ClassLoader classLoader)
+ throws IllegalAccessException, InvocationTargetException, NamingException, InstantiationException,
+ ClassNotFoundException, NoSuchMethodException {
Class> clazz = classLoader.loadClass(fqcn);
return prepareInstance(clazz.getConstructor().newInstance());
}
@Override
- public void newInstance(Object o) throws IllegalAccessException, InvocationTargetException,
- NamingException {
+ public void newInstance(Object o) throws IllegalAccessException, InvocationTargetException, NamingException {
// NO-OP
}
diff -Nru tomcat11-11.0.6/java/org/apache/tomcat/buildutil/CheckEol.java tomcat11-11.0.15/java/org/apache/tomcat/buildutil/CheckEol.java
--- tomcat11-11.0.6/java/org/apache/tomcat/buildutil/CheckEol.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/tomcat/buildutil/CheckEol.java 2025-12-02 16:54:08.000000000 +0000
@@ -31,13 +31,10 @@
import org.apache.tools.ant.types.FileSet;
/**
- * Ant task that checks that all the files in the given fileset have end-of-line
- * delimiters that are appropriate.
- *
+ * Ant task that checks that all the files in the given fileset have end-of-line delimiters that are appropriate.
*
- * The goal is to check whether we have problems with Subversion's svn:eol-style
- * property or Git's autocrlf setting when files are committed on one OS and then
- * checked on another one.
+ * The goal is to check whether we have problems with Subversion's svn:eol-style property or Git's autocrlf setting when
+ * files are committed on one OS and then checked on another one.
*/
public class CheckEol extends Task {
@@ -52,8 +49,8 @@
*
* @param fs The fileset to be checked.
*/
- public void addFileset( FileSet fs ) {
- filesets.add( fs );
+ public void addFileset(FileSet fs) {
+ filesets.add(fs);
}
/**
@@ -61,12 +58,12 @@
*
* @param mode The line ending mode (either LF or CRLF)
*/
- public void setMode( String mode ) {
- this.mode = Mode.valueOf( mode.toUpperCase(Locale.ENGLISH) );
+ public void setMode(String mode) {
+ this.mode = Mode.valueOf(mode.toUpperCase(Locale.ENGLISH));
}
private Mode getMode() {
- if ( mode != null ) {
+ if (mode != null) {
return mode;
} else {
if ("\n".equals(System.lineSeparator())) {
@@ -82,14 +79,13 @@
/**
* Perform the check
*
- * @throws BuildException if an error occurs during execution of
- * this task.
+ * @throws BuildException if an error occurs during execution of this task.
*/
@Override
public void execute() throws BuildException {
Mode mode = getMode();
- if ( mode == null ) {
+ if (mode == null) {
log("Line ends check skipped, because OS line ends setting is neither LF nor CRLF.", Project.MSG_VERBOSE);
return;
}
@@ -107,25 +103,21 @@
log("Checking line ends in " + files.length + " file(s)");
for (String filename : files) {
File file = new File(basedir, filename);
- log("Checking file '" + file + "' for correct line ends",
- Project.MSG_DEBUG);
+ log("Checking file '" + file + "' for correct line ends", Project.MSG_DEBUG);
try {
check(file, errors, mode);
- } catch (IOException e) {
- throw new BuildException("Could not check file '"
- + file.getAbsolutePath() + "'", e);
+ } catch (IOException ioe) {
+ throw new BuildException("Could not check file '" + file.getAbsolutePath() + "'", ioe);
}
count++;
}
}
}
if (count > 0) {
- log("Done line ends check in " + count + " file(s), "
- + errors.size() + " error(s) found.");
+ log("Done line ends check in " + count + " file(s), " + errors.size() + " error(s) found.");
}
if (!errors.isEmpty()) {
- String message = "The following files have wrong line ends: "
- + errors;
+ String message = "The following files have wrong line ends: " + errors;
// We need to explicitly write the message to the log, because
// long BuildException messages may be trimmed. E.g. I observed
// this problem with Eclipse IDE 3.7.
@@ -135,7 +127,8 @@
}
private enum Mode {
- LF, CRLF
+ LF,
+ CRLF
}
private record CheckFailure(File file, int line, String value) {
@@ -146,8 +139,7 @@
}
private void check(File file, List errors, Mode mode) throws IOException {
- try (FileInputStream fis = new FileInputStream(file);
- BufferedInputStream is = new BufferedInputStream(fis)) {
+ try (FileInputStream fis = new FileInputStream(file); BufferedInputStream is = new BufferedInputStream(fis)) {
int line = 1;
int prev = -1;
int ch;
diff -Nru tomcat11-11.0.6/java/org/apache/tomcat/buildutil/MimeTypeMappings.java tomcat11-11.0.15/java/org/apache/tomcat/buildutil/MimeTypeMappings.java
--- tomcat11-11.0.6/java/org/apache/tomcat/buildutil/MimeTypeMappings.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/tomcat/buildutil/MimeTypeMappings.java 2025-12-02 16:54:08.000000000 +0000
@@ -49,7 +49,7 @@
digester.parse(globalWebXml);
Map webXmlMimeMappings = webXmlDefaultFragment.getMimeMappings();
- SortedMap sortedWebXmlMimeMappings = new TreeMap<>(webXmlMimeMappings);
+ SortedMap sortedWebXmlMimeMappings = new TreeMap<>(webXmlMimeMappings);
File f = new File("java/org/apache/catalina/startup/MimeTypeMappings.properties");
try (FileOutputStream fos = new FileOutputStream(f);
@@ -59,7 +59,7 @@
w.write(System.lineSeparator());
- for (Map.Entry mapping : sortedWebXmlMimeMappings.entrySet()) {
+ for (Map.Entry mapping : sortedWebXmlMimeMappings.entrySet()) {
w.write(mapping.getKey());
w.write("=");
w.write(mapping.getValue());
diff -Nru tomcat11-11.0.6/java/org/apache/tomcat/buildutil/RepeatableArchive.java tomcat11-11.0.15/java/org/apache/tomcat/buildutil/RepeatableArchive.java
--- tomcat11-11.0.6/java/org/apache/tomcat/buildutil/RepeatableArchive.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/tomcat/buildutil/RepeatableArchive.java 2025-12-02 16:54:08.000000000 +0000
@@ -41,11 +41,9 @@
/**
* Ant task to assist with repeatable builds.
*
- * While originally written to address an issue with Javadoc output, this task
- * takes a generic approach that could be used with any archive. The task takes
- * a set of zip (or jar, war etc) files as its input and sets the last modified
- * time of every file in the archive to be the same as the last modified time
- * of the archive.
+ * While originally written to address an issue with Javadoc output, this task takes a generic approach that could be
+ * used with any archive. The task takes a set of zip (or jar, war etc) files as its input and sets the last modified
+ * time of every file in the archive to be the same as the last modified time of the archive.
*/
public class RepeatableArchive extends Task {
diff -Nru tomcat11-11.0.6/java/org/apache/tomcat/buildutil/Txt2Html.java tomcat11-11.0.15/java/org/apache/tomcat/buildutil/Txt2Html.java
--- tomcat11-11.0.6/java/org/apache/tomcat/buildutil/Txt2Html.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/tomcat/buildutil/Txt2Html.java 2025-12-02 16:54:08.000000000 +0000
@@ -35,17 +35,12 @@
import org.apache.tools.ant.types.FileSet;
/**
- * Ant task to convert a given set of files from Text to HTML.
- * Inserts an HTML header including pre tags and replaces special characters
- * with their HTML escaped equivalents.
- *
- *
This task is currently used by the ant script to build our examples
- *
- * @author Mark Roth
+ * Ant task to convert a given set of files from Text to HTML. Inserts an HTML header including pre tags and replaces
+ * special characters with their HTML escaped equivalents.
+ *
+ * This task is currently used by the ant script to build our examples
*/
-public class Txt2Html
- extends Task
-{
+public class Txt2Html extends Task {
/** The directory to contain the resulting files */
private File todir;
@@ -54,14 +49,13 @@
private final List filesets = new ArrayList<>();
/**
- * The encoding of the source files (.java and .jsp). Once they use
- * UTF-8, this will need to be updated.
+ * The encoding of the source files (.java and .jsp). Once they use UTF-8, this will need to be updated.
*/
private static final String SOURCE_ENCODING = "ISO-8859-1";
/**
- * Line terminator to be used for separating lines of the generated
- * HTML page, to be independent of the "line.separator" system property.
+ * Line terminator to be used for separating lines of the generated HTML page, to be independent of the
+ * "line.separator" system property.
*/
private static final String LINE_SEPARATOR = "\r\n";
@@ -70,7 +64,7 @@
*
* @param todir The directory
*/
- public void setTodir( File todir ) {
+ public void setTodir(File todir) {
this.todir = todir;
}
@@ -79,20 +73,17 @@
*
* @param fs The fileset to be converted.
*/
- public void addFileset( FileSet fs ) {
- filesets.add( fs );
+ public void addFileset(FileSet fs) {
+ filesets.add(fs);
}
/**
* Perform the conversion
*
- * @throws BuildException if an error occurs during execution of
- * this task.
+ * @throws BuildException if an error occurs during execution of this task.
*/
@Override
- public void execute()
- throws BuildException
- {
+ public void execute() throws BuildException {
int count = 0;
// Step through each file and convert.
@@ -103,23 +94,21 @@
for (String file : files) {
File from = new File(basedir, file);
File to = new File(todir, file + ".html");
- if (!to.exists() ||
- (from.lastModified() > to.lastModified())) {
- log("Converting file '" + from.getAbsolutePath() +
- "' to '" + to.getAbsolutePath(), Project.MSG_VERBOSE);
+ if (!to.exists() || (from.lastModified() > to.lastModified())) {
+ log("Converting file '" + from.getAbsolutePath() + "' to '" + to.getAbsolutePath(),
+ Project.MSG_VERBOSE);
try {
convert(from, to);
- } catch (IOException e) {
- throw new BuildException("Could not convert '" +
- from.getAbsolutePath() + "' to '" +
- to.getAbsolutePath() + "'", e);
+ } catch (IOException ioe) {
+ throw new BuildException(
+ "Could not convert '" + from.getAbsolutePath() + "' to '" + to.getAbsolutePath() + "'",
+ ioe);
}
count++;
}
}
- if( count > 0 ) {
- log( "Converted " + count + " file" + (count > 1 ? "s" : "") +
- " to " + todir.getAbsolutePath() );
+ if (count > 0) {
+ log("Converted " + count + " file" + (count > 1 ? "s" : "") + " to " + todir.getAbsolutePath());
}
}
}
@@ -128,45 +117,44 @@
* Perform the actual copy and conversion
*
* @param from The input file
- * @param to The output file
+ * @param to The output file
+ *
* @throws IOException Thrown if an error occurs during the conversion
*/
- private void convert( File from, File to )
- throws IOException
- {
+ private void convert(File from, File to) throws IOException {
// Open files:
- try (BufferedReader in = new BufferedReader(new InputStreamReader(
- new FileInputStream(from), SOURCE_ENCODING))) {
- try (PrintWriter out = new PrintWriter(new OutputStreamWriter(
- new FileOutputStream(to), StandardCharsets.UTF_8))) {
+ try (BufferedReader in =
+ new BufferedReader(new InputStreamReader(new FileInputStream(from), SOURCE_ENCODING))) {
+ try (PrintWriter out =
+ new PrintWriter(new OutputStreamWriter(new FileOutputStream(to), StandardCharsets.UTF_8))) {
// Output header:
- out.print(""
- + "Source Code
" );
+ out.print("" +
+ "Source Code
");
// Convert, line-by-line:
String line;
- while( (line = in.readLine()) != null ) {
+ while ((line = in.readLine()) != null) {
StringBuilder result = new StringBuilder();
int len = line.length();
- for( int i = 0; i < len; i++ ) {
- char c = line.charAt( i );
- switch( c ) {
+ for (int i = 0; i < len; i++) {
+ char c = line.charAt(i);
+ switch (c) {
case '&':
- result.append( "&" );
+ result.append("&");
break;
case '<':
- result.append( "<" );
+ result.append("<");
break;
default:
- result.append( c );
+ result.append(c);
}
}
- out.print( result.toString() + LINE_SEPARATOR );
+ out.print(result.toString() + LINE_SEPARATOR);
}
// Output footer:
- out.print( "
" );
+ out.print("
");
}
}
@@ -174,4 +162,3 @@
}
-
diff -Nru tomcat11-11.0.6/java/org/apache/tomcat/buildutil/translate/BackportEnglish.java tomcat11-11.0.15/java/org/apache/tomcat/buildutil/translate/BackportEnglish.java
--- tomcat11-11.0.6/java/org/apache/tomcat/buildutil/translate/BackportEnglish.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/tomcat/buildutil/translate/BackportEnglish.java 2025-12-02 16:54:08.000000000 +0000
@@ -21,11 +21,9 @@
import java.util.Set;
/**
- * Generates a set of English property files to back-port updates to a previous
- * version. Where a key exists in the source and target versions the value is
- * copied from the source to the target, overwriting the value in the target.
- * The expectation is that the changes will be manually reviewed before
- * committing them.
+ * Generates a set of English property files to back-port updates to a previous version. Where a key exists in the
+ * source and target versions the value is copied from the source to the target, overwriting the value in the target.
+ * The expectation is that the changes will be manually reviewed before committing them.
*/
public class BackportEnglish extends BackportBase {
diff -Nru tomcat11-11.0.6/java/org/apache/tomcat/buildutil/translate/BackportTranslations.java tomcat11-11.0.15/java/org/apache/tomcat/buildutil/translate/BackportTranslations.java
--- tomcat11-11.0.6/java/org/apache/tomcat/buildutil/translate/BackportTranslations.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/tomcat/buildutil/translate/BackportTranslations.java 2025-12-02 16:54:08.000000000 +0000
@@ -20,10 +20,8 @@
import java.util.Properties;
/**
- * Generates a set of translated property files to back-port updates to a
- * previous version. If the source and target use the same value for the English
- * key then any translated value for that key is copied from the source to the
- * target.
+ * Generates a set of translated property files to back-port updates to a previous version. If the source and target use
+ * the same value for the English key then any translated value for that key is copied from the source to the target.
*/
public class BackportTranslations extends BackportBase {
@@ -53,8 +51,7 @@
}
for (Object key : targetEnglish.keySet()) {
- if (sourceTranslated.containsKey(key) &&
- targetEnglish.get(key).equals(sourceEnglish.get(key))) {
+ if (sourceTranslated.containsKey(key) && targetEnglish.get(key).equals(sourceEnglish.get(key))) {
targetTranslated.put(key, sourceTranslated.get(key));
}
diff -Nru tomcat11-11.0.6/java/org/apache/tomcat/buildutil/translate/Import.java tomcat11-11.0.15/java/org/apache/tomcat/buildutil/translate/Import.java
--- tomcat11-11.0.6/java/org/apache/tomcat/buildutil/translate/Import.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/tomcat/buildutil/translate/Import.java 2025-12-02 16:54:08.000000000 +0000
@@ -68,7 +68,8 @@
if (w != null) {
w.close();
}
- File outFile = new File(currentPkg.replace('.', File.separatorChar), Constants.L10N_PREFIX + language + Constants.L10N_SUFFIX);
+ File outFile = new File(currentPkg.replace('.', File.separatorChar),
+ Constants.L10N_PREFIX + language + Constants.L10N_SUFFIX);
FileOutputStream fos = new FileOutputStream(outFile);
w = new OutputStreamWriter(fos, StandardCharsets.UTF_8);
org.apache.tomcat.buildutil.Utils.insertLicense(w);
diff -Nru tomcat11-11.0.6/java/org/apache/tomcat/buildutil/translate/Utils.java tomcat11-11.0.15/java/org/apache/tomcat/buildutil/translate/Utils.java
--- tomcat11-11.0.6/java/org/apache/tomcat/buildutil/translate/Utils.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/tomcat/buildutil/translate/Utils.java 2025-12-02 16:54:08.000000000 +0000
@@ -64,13 +64,21 @@
try (FileInputStream fis = new FileInputStream(f);
Reader r = new InputStreamReader(fis, StandardCharsets.UTF_8)) {
props.load(r);
- } catch (IOException e) {
- e.printStackTrace();
+ } catch (IOException ioe) {
+ ioe.printStackTrace();
}
return props;
}
+ /*
+ * This is the formatting applied when exporting values from Tomcat to POE.
+ *
+ * The values have been read from Tomcat's property files (so the input is the actual value with none of the
+ * escaping required to represent that value in a property file) and are being written back out in a single file to
+ * be imported into POEditor. The padding for blank lines needs to be added followed by the common formatting
+ * required to convert a property value to the representation of that value in a file.
+ */
static String formatValueExport(String in) {
String result;
@@ -84,6 +92,14 @@
}
+ /*
+ * This is the formatting applied when importing values to Tomcat from POE.
+ *
+ * The values have been read from POE's property files (so the input is the actual value with none of the escaping
+ * required to represent that value in a property file) and are being written back out to individual files in
+ * Tomcat. The padding for blank lines needs to be removed followed by the common formatting required to convert a
+ * property value to the representation of that value in a file.
+ */
static String formatValueImport(String in) {
String result;
@@ -98,9 +114,8 @@
/*
- * Values containing "[{n}]" and "'" need to have the "'" escaped as "''".
- * POEditor attempts to do this automatically but does it for any value
- * containing "{" or "}" leading to some unnecessary escaping. This method
+ * Values containing "[{n}]" and "'" need to have the "'" escaped as "''". POEditor attempts to do this
+ * automatically but does it for any value containing "{" or "}" leading to some unnecessary escaping. This method
* undoes the unnecessary escaping.
*/
static String fixUnnecessaryEscaping(String key, String value) {
@@ -112,8 +127,13 @@
/*
- * Common formatting to convert a String for storage as a value in a
- * property file.
+ * Common formatting to convert a String value for storage as a value in a property file. Values that contain
+ * line-breaks need the line-break in the value to be replaced with the correct representation of a line-break in a
+ * property file. Leading space needs to be escaped with a '\' and horizontal tabs need to be converted to "\t".
+ *
+ * Note that a single '\' needs to be escaped both in a Java string and in a property file so if a property value
+ * needs to contain a single `\` (e.g. to escape white space at the start of a line) that will appear as "\\\\" in
+ * the Java code.
*/
static String formatValueCommon(String in) {
String result = in.replace("\n", "\\n\\\n");
diff -Nru tomcat11-11.0.6/java/org/apache/tomcat/dbcp/dbcp2/ObjectNameWrapper.java tomcat11-11.0.15/java/org/apache/tomcat/dbcp/dbcp2/ObjectNameWrapper.java
--- tomcat11-11.0.6/java/org/apache/tomcat/dbcp/dbcp2/ObjectNameWrapper.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/tomcat/dbcp/dbcp2/ObjectNameWrapper.java 2025-12-02 16:54:08.000000000 +0000
@@ -42,7 +42,9 @@
return ManagementFactory.getPlatformMBeanServer();
} catch (final LinkageError | Exception e) {
// ignore - JMX not available
- log.debug("Failed to get platform MBeanServer", e);
+ if (log.isDebugEnabled()) {
+ log.debug("Failed to get platform MBeanServer", e);
+ }
return null;
}
}
diff -Nru tomcat11-11.0.6/java/org/apache/tomcat/jni/AprStatus.java tomcat11-11.0.15/java/org/apache/tomcat/jni/AprStatus.java
--- tomcat11-11.0.6/java/org/apache/tomcat/jni/AprStatus.java 1970-01-01 00:00:00.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/tomcat/jni/AprStatus.java 2025-12-02 16:54:08.000000000 +0000
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomcat.jni;
+
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+/**
+ * Holds APR status without the need to load other classes.
+ */
+public class AprStatus {
+ private static volatile boolean aprInitialized = false;
+ private static volatile boolean aprAvailable = false;
+ private static volatile boolean useOpenSSL = true;
+ private static volatile boolean instanceCreated = false;
+ private static volatile int openSSLVersion = 0;
+ private static ReentrantReadWriteLock statusLock = new ReentrantReadWriteLock();
+
+ public static boolean isAprInitialized() {
+ return aprInitialized;
+ }
+
+ public static boolean isAprAvailable() {
+ return aprAvailable;
+ }
+
+ public static boolean getUseOpenSSL() {
+ return useOpenSSL;
+ }
+
+ public static boolean isInstanceCreated() {
+ return instanceCreated;
+ }
+
+ public static void setAprInitialized(boolean aprInitialized) {
+ AprStatus.aprInitialized = aprInitialized;
+ }
+
+ public static void setAprAvailable(boolean aprAvailable) {
+ AprStatus.aprAvailable = aprAvailable;
+ }
+
+ public static void setUseOpenSSL(boolean useOpenSSL) {
+ AprStatus.useOpenSSL = useOpenSSL;
+ }
+
+ public static void setInstanceCreated(boolean instanceCreated) {
+ AprStatus.instanceCreated = instanceCreated;
+ }
+
+ /**
+ * @return the openSSLVersion
+ */
+ public static int getOpenSSLVersion() {
+ return openSSLVersion;
+ }
+
+ /**
+ * @param openSSLVersion the openSSLVersion to set
+ */
+ public static void setOpenSSLVersion(int openSSLVersion) {
+ AprStatus.openSSLVersion = openSSLVersion;
+ }
+
+ /**
+ * Code that changes the status of the APR library MUST hold the write lock while making any changes.
+ *
+ * Code that needs the status to be consistent for an operation must hold the read lock for the duration of that
+ * operation.
+ *
+ * @return The read/write lock for APR library status
+ */
+ public static ReentrantReadWriteLock getStatusLock() {
+ return statusLock;
+ }
+}
diff -Nru tomcat11-11.0.6/java/org/apache/tomcat/jni/Buffer.java tomcat11-11.0.15/java/org/apache/tomcat/jni/Buffer.java
--- tomcat11-11.0.6/java/org/apache/tomcat/jni/Buffer.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/tomcat/jni/Buffer.java 2025-12-02 16:54:08.000000000 +0000
@@ -19,8 +19,7 @@
import java.nio.ByteBuffer;
/**
- * Provides utilities related to the use of directly allocated
- * {@link ByteBuffer} instances with native code.
+ * Provides utilities related to the use of directly allocated {@link ByteBuffer} instances with native code.
*/
public class Buffer {
diff -Nru tomcat11-11.0.6/java/org/apache/tomcat/jni/CertificateVerifier.java tomcat11-11.0.15/java/org/apache/tomcat/jni/CertificateVerifier.java
--- tomcat11-11.0.6/java/org/apache/tomcat/jni/CertificateVerifier.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/tomcat/jni/CertificateVerifier.java 2025-12-02 16:54:08.000000000 +0000
@@ -22,13 +22,14 @@
public interface CertificateVerifier {
/**
- * Returns {@code true} if the passed in certificate chain could be verified and so the handshake
- * should be successful, {@code false} otherwise.
+ * Returns {@code true} if the passed in certificate chain could be verified and so the handshake should be
+ * successful, {@code false} otherwise.
*
- * @param ssl the SSL instance
- * @param x509 the {@code X509} certificate chain
- * @param authAlgorithm the auth algorithm
- * @return verified {@code true} if verified successful, {@code false} otherwise
+ * @param ssl the SSL instance
+ * @param x509 the {@code X509} certificate chain
+ * @param authAlgorithm the auth algorithm
+ *
+ * @return verified {@code true} if verified successful, {@code false} otherwise
*/
boolean verify(long ssl, byte[][] x509, String authAlgorithm);
}
diff -Nru tomcat11-11.0.6/java/org/apache/tomcat/jni/FileInfo.java tomcat11-11.0.15/java/org/apache/tomcat/jni/FileInfo.java
--- tomcat11-11.0.6/java/org/apache/tomcat/jni/FileInfo.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/tomcat/jni/FileInfo.java 2025-12-02 16:54:08.000000000 +0000
@@ -17,10 +17,9 @@
package org.apache.tomcat.jni;
/**
- * Tomcat Native 1.2.33 and earlier won't initialise unless this class is
- * present. This dummy class ensures initialisation gets as far as being able to
- * check the version of the Tomcat Native library and reporting a version error
- * if 1.2.33 or earlier is present.
+ * Tomcat Native 1.2.33 and earlier won't initialise unless this class is present. This dummy class ensures
+ * initialisation gets as far as being able to check the version of the Tomcat Native library and reporting a version
+ * error if 1.2.33 or earlier is present.
*/
public class FileInfo {
diff -Nru tomcat11-11.0.6/java/org/apache/tomcat/jni/Library.java tomcat11-11.0.15/java/org/apache/tomcat/jni/Library.java
--- tomcat11-11.0.6/java/org/apache/tomcat/jni/Library.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/tomcat/jni/Library.java 2025-12-02 16:54:08.000000000 +0000
@@ -21,7 +21,7 @@
public final class Library {
/* Default library names - use 2.x in preference to 1.x if both are available */
- private static final String [] NAMES = {"tcnative-2", "libtcnative-2", "tcnative-1", "libtcnative-1"};
+ private static final String[] NAMES = { "tcnative-2", "libtcnative-2", "tcnative-1", "libtcnative-1" };
/* System property used to define CATALINA_HOME */
private static final String CATALINA_HOME_PROP = "catalina.home";
/*
@@ -56,7 +56,7 @@
}
if (!loaded) {
String path = System.getProperty("java.library.path");
- String [] paths = path.split(File.pathSeparator);
+ String[] paths = path.split(File.pathSeparator);
for (String value : NAMES) {
try {
System.loadLibrary(value);
@@ -88,12 +88,11 @@
names.append(name);
names.append(", ");
}
- throw new LibraryNotFoundError(names.substring(0, names.length() -2), err.toString());
+ throw new LibraryNotFoundError(names.substring(0, names.length() - 2), err.toString());
}
}
- private Library(String libraryName)
- {
+ private Library(String libraryName) {
System.loadLibrary(libraryName);
}
@@ -101,43 +100,45 @@
* Create Tomcat Native's global APR pool. This has to be the first call to TCN library.
*/
private static native boolean initialize();
+
/**
* Destroys Tomcat Native's global APR pool. This has to be the last call to TCN library. This will destroy any APR
* root pools that have not been explicitly destroyed.
*/
public static native void terminate();
+
/* Internal function for loading APR Features */
private static native int version(int what);
/* TCN_MAJOR_VERSION */
- public static int TCN_MAJOR_VERSION = 0;
+ public static int TCN_MAJOR_VERSION = 0;
/* TCN_MINOR_VERSION */
- public static int TCN_MINOR_VERSION = 0;
+ public static int TCN_MINOR_VERSION = 0;
/* TCN_PATCH_VERSION */
- public static int TCN_PATCH_VERSION = 0;
+ public static int TCN_PATCH_VERSION = 0;
/* TCN_IS_DEV_VERSION */
public static int TCN_IS_DEV_VERSION = 0;
/* APR_MAJOR_VERSION */
- public static int APR_MAJOR_VERSION = 0;
+ public static int APR_MAJOR_VERSION = 0;
/* APR_MINOR_VERSION */
- public static int APR_MINOR_VERSION = 0;
+ public static int APR_MINOR_VERSION = 0;
/* APR_PATCH_VERSION */
- public static int APR_PATCH_VERSION = 0;
+ public static int APR_PATCH_VERSION = 0;
/* APR_IS_DEV_VERSION */
public static int APR_IS_DEV_VERSION = 0;
/* TCN_VERSION_STRING */
public static native String versionString();
+
/* APR_VERSION_STRING */
public static native String aprVersionString();
/**
- * Setup any APR internal data structures. This MUST be the first function
- * called for any APR library.
+ * Setup any APR internal data structures. This MUST be the first function called for any APR library.
+ *
* @param libraryName the name of the library to load
*
- * @return {@code true} if the native code was initialized successfully
- * otherwise {@code false}
+ * @return {@code true} if the native code was initialized successfully otherwise {@code false}
*
* @throws Exception if a problem occurred during initialization
*/
@@ -148,18 +149,17 @@
} else {
_instance = new Library(libraryName);
}
- TCN_MAJOR_VERSION = version(0x01);
- TCN_MINOR_VERSION = version(0x02);
- TCN_PATCH_VERSION = version(0x03);
+ TCN_MAJOR_VERSION = version(0x01);
+ TCN_MINOR_VERSION = version(0x02);
+ TCN_PATCH_VERSION = version(0x03);
TCN_IS_DEV_VERSION = version(0x04);
- APR_MAJOR_VERSION = version(0x11);
- APR_MINOR_VERSION = version(0x12);
- APR_PATCH_VERSION = version(0x13);
+ APR_MAJOR_VERSION = version(0x11);
+ APR_MINOR_VERSION = version(0x12);
+ APR_PATCH_VERSION = version(0x13);
APR_IS_DEV_VERSION = version(0x14);
if (APR_MAJOR_VERSION < 1) {
- throw new UnsatisfiedLinkError("Unsupported APR Version (" +
- aprVersionString() + ")");
+ throw new UnsatisfiedLinkError("Unsupported APR Version (" + aprVersionString() + ")");
}
}
return initialize();
diff -Nru tomcat11-11.0.6/java/org/apache/tomcat/jni/LibraryNotFoundError.java tomcat11-11.0.15/java/org/apache/tomcat/jni/LibraryNotFoundError.java
--- tomcat11-11.0.6/java/org/apache/tomcat/jni/LibraryNotFoundError.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/tomcat/jni/LibraryNotFoundError.java 2025-12-02 16:54:08.000000000 +0000
@@ -26,17 +26,15 @@
private final String libraryNames;
/**
- * @param libraryNames A list of the file names of the native libraries that
- * failed to load
- * @param errors A list of the error messages received when trying to load
- * each of the libraries
+ * @param libraryNames A list of the file names of the native libraries that failed to load
+ * @param errors A list of the error messages received when trying to load each of the libraries
*/
- public LibraryNotFoundError(String libraryNames, String errors){
+ public LibraryNotFoundError(String libraryNames, String errors) {
super(errors);
this.libraryNames = libraryNames;
}
- public String getLibraryNames(){
+ public String getLibraryNames() {
return libraryNames;
}
}
diff -Nru tomcat11-11.0.6/java/org/apache/tomcat/jni/Pool.java tomcat11-11.0.15/java/org/apache/tomcat/jni/Pool.java
--- tomcat11-11.0.6/java/org/apache/tomcat/jni/Pool.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/tomcat/jni/Pool.java 2025-12-02 16:54:08.000000000 +0000
@@ -17,26 +17,23 @@
package org.apache.tomcat.jni;
/**
- * Provides access to APR memory pools which are used to manage memory
- * allocations for natively created instances.
+ * Provides access to APR memory pools which are used to manage memory allocations for natively created instances.
*/
public class Pool {
/**
* Create a new pool.
*
- * @param parent The parent pool. If this is 0, the new pool is a root pool.
- * If it is non-zero, the new pool will inherit all of its
- * parent pool's attributes, except the apr_pool_t will be a
- * sub-pool.
+ * @param parent The parent pool. If this is 0, the new pool is a root pool. If it is non-zero, the new pool will
+ * inherit all of its parent pool's attributes, except the apr_pool_t will be a sub-pool.
*
* @return The pool we have just created.
- */
+ */
public static native long create(long parent);
/**
- * Destroy the pool. This takes similar action as apr_pool_clear() and then
- * frees all the memory. This will actually free the memory.
+ * Destroy the pool. This takes similar action as apr_pool_clear() and then frees all the memory. This will actually
+ * free the memory.
*
* @param pool The pool to destroy
*/
diff -Nru tomcat11-11.0.6/java/org/apache/tomcat/jni/SSL.java tomcat11-11.0.15/java/org/apache/tomcat/jni/SSL.java
--- tomcat11-11.0.6/java/org/apache/tomcat/jni/SSL.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/tomcat/jni/SSL.java 2025-12-02 16:54:08.000000000 +0000
@@ -21,55 +21,56 @@
/*
* Type definitions mostly from mod_ssl
*/
- public static final int UNSET = -1;
+ public static final int UNSET = -1;
/*
* Define the certificate algorithm types
*/
public static final int SSL_ALGO_UNKNOWN = 0;
- public static final int SSL_ALGO_RSA = (1<<0);
- public static final int SSL_ALGO_DSA = (1<<1);
- public static final int SSL_ALGO_ALL = (SSL_ALGO_RSA|SSL_ALGO_DSA);
-
- public static final int SSL_AIDX_RSA = 0;
- public static final int SSL_AIDX_DSA = 1;
- public static final int SSL_AIDX_ECC = 3;
- public static final int SSL_AIDX_MAX = 4;
+ public static final int SSL_ALGO_RSA = (1 << 0);
+ public static final int SSL_ALGO_DSA = (1 << 1);
+ public static final int SSL_ALGO_ALL = (SSL_ALGO_RSA | SSL_ALGO_DSA);
+
+ public static final int SSL_AIDX_RSA = 0;
+ public static final int SSL_AIDX_DSA = 1;
+ public static final int SSL_AIDX_ECC = 3;
+ public static final int SSL_AIDX_MAX = 4;
/*
* Define IDs for the temporary RSA keys and DH params
*/
- public static final int SSL_TMP_KEY_RSA_512 = 0;
+ public static final int SSL_TMP_KEY_RSA_512 = 0;
public static final int SSL_TMP_KEY_RSA_1024 = 1;
public static final int SSL_TMP_KEY_RSA_2048 = 2;
public static final int SSL_TMP_KEY_RSA_4096 = 3;
- public static final int SSL_TMP_KEY_DH_512 = 4;
- public static final int SSL_TMP_KEY_DH_1024 = 5;
- public static final int SSL_TMP_KEY_DH_2048 = 6;
- public static final int SSL_TMP_KEY_DH_4096 = 7;
- public static final int SSL_TMP_KEY_MAX = 8;
+ public static final int SSL_TMP_KEY_DH_512 = 4;
+ public static final int SSL_TMP_KEY_DH_1024 = 5;
+ public static final int SSL_TMP_KEY_DH_2048 = 6;
+ public static final int SSL_TMP_KEY_DH_4096 = 7;
+ public static final int SSL_TMP_KEY_MAX = 8;
/*
* Define the SSL options
*/
- public static final int SSL_OPT_NONE = 0;
- public static final int SSL_OPT_RELSET = (1<<0);
- public static final int SSL_OPT_STDENVVARS = (1<<1);
- public static final int SSL_OPT_EXPORTCERTDATA = (1<<3);
- public static final int SSL_OPT_FAKEBASICAUTH = (1<<4);
- public static final int SSL_OPT_STRICTREQUIRE = (1<<5);
- public static final int SSL_OPT_OPTRENEGOTIATE = (1<<6);
- public static final int SSL_OPT_ALL = (SSL_OPT_STDENVVARS|SSL_OPT_EXPORTCERTDATA|SSL_OPT_FAKEBASICAUTH|SSL_OPT_STRICTREQUIRE|SSL_OPT_OPTRENEGOTIATE);
+ public static final int SSL_OPT_NONE = 0;
+ public static final int SSL_OPT_RELSET = (1 << 0);
+ public static final int SSL_OPT_STDENVVARS = (1 << 1);
+ public static final int SSL_OPT_EXPORTCERTDATA = (1 << 3);
+ public static final int SSL_OPT_FAKEBASICAUTH = (1 << 4);
+ public static final int SSL_OPT_STRICTREQUIRE = (1 << 5);
+ public static final int SSL_OPT_OPTRENEGOTIATE = (1 << 6);
+ public static final int SSL_OPT_ALL = (SSL_OPT_STDENVVARS | SSL_OPT_EXPORTCERTDATA | SSL_OPT_FAKEBASICAUTH |
+ SSL_OPT_STRICTREQUIRE | SSL_OPT_OPTRENEGOTIATE);
/*
* Define the SSL Protocol options
*/
- public static final int SSL_PROTOCOL_NONE = 0;
- public static final int SSL_PROTOCOL_SSLV2 = (1<<0);
- public static final int SSL_PROTOCOL_SSLV3 = (1<<1);
- public static final int SSL_PROTOCOL_TLSV1 = (1<<2);
- public static final int SSL_PROTOCOL_TLSV1_1 = (1<<3);
- public static final int SSL_PROTOCOL_TLSV1_2 = (1<<4);
- public static final int SSL_PROTOCOL_TLSV1_3 = (1<<5);
+ public static final int SSL_PROTOCOL_NONE = 0;
+ public static final int SSL_PROTOCOL_SSLV2 = (1 << 0);
+ public static final int SSL_PROTOCOL_SSLV3 = (1 << 1);
+ public static final int SSL_PROTOCOL_TLSV1 = (1 << 2);
+ public static final int SSL_PROTOCOL_TLSV1_1 = (1 << 3);
+ public static final int SSL_PROTOCOL_TLSV1_2 = (1 << 4);
+ public static final int SSL_PROTOCOL_TLSV1_3 = (1 << 5);
public static final int SSL_PROTOCOL_ALL =
(SSL_PROTOCOL_TLSV1 | SSL_PROTOCOL_TLSV1_1 | SSL_PROTOCOL_TLSV1_2 | SSL_PROTOCOL_TLSV1_3);
@@ -77,154 +78,159 @@
/*
* Define the SSL verify levels
*/
- public static final int SSL_CVERIFY_UNSET = UNSET;
- public static final int SSL_CVERIFY_NONE = 0;
- public static final int SSL_CVERIFY_OPTIONAL = 1;
- public static final int SSL_CVERIFY_REQUIRE = 2;
+ public static final int SSL_CVERIFY_UNSET = UNSET;
+ public static final int SSL_CVERIFY_NONE = 0;
+ public static final int SSL_CVERIFY_OPTIONAL = 1;
+ public static final int SSL_CVERIFY_REQUIRE = 2;
public static final int SSL_CVERIFY_OPTIONAL_NO_CA = 3;
- /* Use either SSL_VERIFY_NONE or SSL_VERIFY_PEER, the last 2 options
- * are 'ored' with SSL_VERIFY_PEER if they are desired
+ /*
+ * Use either SSL_VERIFY_NONE or SSL_VERIFY_PEER, the last 2 options are 'ored' with SSL_VERIFY_PEER if they are
+ * desired
*/
- public static final int SSL_VERIFY_NONE = 0;
- public static final int SSL_VERIFY_PEER = 1;
+ public static final int SSL_VERIFY_NONE = 0;
+ public static final int SSL_VERIFY_PEER = 1;
public static final int SSL_VERIFY_FAIL_IF_NO_PEER_CERT = 2;
- public static final int SSL_VERIFY_CLIENT_ONCE = 4;
- public static final int SSL_VERIFY_PEER_STRICT = (SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT);
+ public static final int SSL_VERIFY_CLIENT_ONCE = 4;
+ public static final int SSL_VERIFY_PEER_STRICT = (SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT);
- public static final int SSL_OP_MICROSOFT_SESS_ID_BUG = 0x00000001;
- public static final int SSL_OP_NETSCAPE_CHALLENGE_BUG = 0x00000002;
+ public static final int SSL_OP_MICROSOFT_SESS_ID_BUG = 0x00000001;
+ public static final int SSL_OP_NETSCAPE_CHALLENGE_BUG = 0x00000002;
public static final int SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG = 0x00000008;
- public static final int SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG = 0x00000010;
- public static final int SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER = 0x00000020;
- public static final int SSL_OP_MSIE_SSLV2_RSA_PADDING = 0x00000040;
- public static final int SSL_OP_SSLEAY_080_CLIENT_DH_BUG = 0x00000080;
- public static final int SSL_OP_TLS_D5_BUG = 0x00000100;
- public static final int SSL_OP_TLS_BLOCK_PADDING_BUG = 0x00000200;
-
- /* Disable SSL 3.0/TLS 1.0 CBC vulnerability workaround that was added
- * in OpenSSL 0.9.6d. Usually (depending on the application protocol)
- * the workaround is not needed. Unfortunately some broken SSL/TLS
- * implementations cannot handle it at all, which is why we include
- * it in SSL_OP_ALL. */
- public static final int SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS = 0x00000800;
-
- /* SSL_OP_ALL: various bug workarounds that should be rather harmless.
- * This used to be 0x000FFFFFL before 0.9.7. */
- public static final int SSL_OP_ALL = 0x00000FFF;
+ public static final int SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG = 0x00000010;
+ public static final int SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER = 0x00000020;
+ public static final int SSL_OP_MSIE_SSLV2_RSA_PADDING = 0x00000040;
+ public static final int SSL_OP_SSLEAY_080_CLIENT_DH_BUG = 0x00000080;
+ public static final int SSL_OP_TLS_D5_BUG = 0x00000100;
+ public static final int SSL_OP_TLS_BLOCK_PADDING_BUG = 0x00000200;
+
+ /*
+ * Disable SSL 3.0/TLS 1.0 CBC vulnerability workaround that was added in OpenSSL 0.9.6d. Usually (depending on the
+ * application protocol) the workaround is not needed. Unfortunately some broken SSL/TLS implementations cannot
+ * handle it at all, which is why we include it in SSL_OP_ALL.
+ */
+ public static final int SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS = 0x00000800;
+
+ /*
+ * SSL_OP_ALL: various bug workarounds that should be rather harmless. This used to be 0x000FFFFFL before 0.9.7.
+ */
+ public static final int SSL_OP_ALL = 0x00000FFF;
/* As server, disallow session resumption on renegotiation */
public static final int SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION = 0x00010000;
/* Don't use compression even if supported */
- public static final int SSL_OP_NO_COMPRESSION = 0x00020000;
+ public static final int SSL_OP_NO_COMPRESSION = 0x00020000;
/* Permit unsafe legacy renegotiation */
- public static final int SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION = 0x00040000;
+ public static final int SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION = 0x00040000;
/* If set, always create a new key when using tmp_eddh parameters */
- public static final int SSL_OP_SINGLE_ECDH_USE = 0x00080000;
+ public static final int SSL_OP_SINGLE_ECDH_USE = 0x00080000;
/* If set, always create a new key when using tmp_dh parameters */
- public static final int SSL_OP_SINGLE_DH_USE = 0x00100000;
- /* Set to always use the tmp_rsa key when doing RSA operations,
- * even when this violates protocol specs */
- public static final int SSL_OP_EPHEMERAL_RSA = 0x00200000;
- /* Set on servers to choose the cipher according to the server's
- * preferences */
- public static final int SSL_OP_CIPHER_SERVER_PREFERENCE = 0x00400000;
- /* If set, a server will allow a client to issue an SSLv3.0 version number
- * as latest version supported in the premaster secret, even when TLSv1.0
- * (version 3.1) was announced in the client hello. Normally this is
- * forbidden to prevent version rollback attacks. */
- public static final int SSL_OP_TLS_ROLLBACK_BUG = 0x00800000;
-
- public static final int SSL_OP_NO_SSLv2 = 0x01000000;
- public static final int SSL_OP_NO_SSLv3 = 0x02000000;
- public static final int SSL_OP_NO_TLSv1 = 0x04000000;
- public static final int SSL_OP_NO_TLSv1_2 = 0x08000000;
- public static final int SSL_OP_NO_TLSv1_1 = 0x10000000;
-
- public static final int SSL_OP_NO_TICKET = 0x00004000;
-
- public static final int SSL_OP_NETSCAPE_CA_DN_BUG = 0x20000000;
- public static final int SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG = 0x40000000;
-
- public static final int SSL_CRT_FORMAT_UNDEF = 0;
- public static final int SSL_CRT_FORMAT_ASN1 = 1;
- public static final int SSL_CRT_FORMAT_TEXT = 2;
- public static final int SSL_CRT_FORMAT_PEM = 3;
+ public static final int SSL_OP_SINGLE_DH_USE = 0x00100000;
+ /*
+ * Set to always use the tmp_rsa key when doing RSA operations, even when this violates protocol specs
+ */
+ public static final int SSL_OP_EPHEMERAL_RSA = 0x00200000;
+ /*
+ * Set on servers to choose the cipher according to the server's preferences
+ */
+ public static final int SSL_OP_CIPHER_SERVER_PREFERENCE = 0x00400000;
+ /*
+ * If set, a server will allow a client to issue an SSLv3.0 version number as latest version supported in the
+ * premaster secret, even when TLSv1.0 (version 3.1) was announced in the client hello. Normally this is forbidden
+ * to prevent version rollback attacks.
+ */
+ public static final int SSL_OP_TLS_ROLLBACK_BUG = 0x00800000;
+
+ public static final int SSL_OP_NO_SSLv2 = 0x01000000;
+ public static final int SSL_OP_NO_SSLv3 = 0x02000000;
+ public static final int SSL_OP_NO_TLSv1 = 0x04000000;
+ public static final int SSL_OP_NO_TLSv1_2 = 0x08000000;
+ public static final int SSL_OP_NO_TLSv1_1 = 0x10000000;
+
+ public static final int SSL_OP_NO_TICKET = 0x00004000;
+
+ public static final int SSL_OP_NETSCAPE_CA_DN_BUG = 0x20000000;
+ public static final int SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG = 0x40000000;
+
+ public static final int SSL_CRT_FORMAT_UNDEF = 0;
+ public static final int SSL_CRT_FORMAT_ASN1 = 1;
+ public static final int SSL_CRT_FORMAT_TEXT = 2;
+ public static final int SSL_CRT_FORMAT_PEM = 3;
public static final int SSL_CRT_FORMAT_NETSCAPE = 4;
- public static final int SSL_CRT_FORMAT_PKCS12 = 5;
- public static final int SSL_CRT_FORMAT_SMIME = 6;
- public static final int SSL_CRT_FORMAT_ENGINE = 7;
-
- public static final int SSL_MODE_CLIENT = 0;
- public static final int SSL_MODE_SERVER = 1;
- public static final int SSL_MODE_COMBINED = 2;
-
- public static final int SSL_CONF_FLAG_CMDLINE = 0x0001;
- public static final int SSL_CONF_FLAG_FILE = 0x0002;
- public static final int SSL_CONF_FLAG_CLIENT = 0x0004;
- public static final int SSL_CONF_FLAG_SERVER = 0x0008;
- public static final int SSL_CONF_FLAG_SHOW_ERRORS = 0x0010;
- public static final int SSL_CONF_FLAG_CERTIFICATE = 0x0020;
-
- public static final int SSL_CONF_TYPE_UNKNOWN = 0x0000;
- public static final int SSL_CONF_TYPE_STRING = 0x0001;
- public static final int SSL_CONF_TYPE_FILE = 0x0002;
- public static final int SSL_CONF_TYPE_DIR = 0x0003;
+ public static final int SSL_CRT_FORMAT_PKCS12 = 5;
+ public static final int SSL_CRT_FORMAT_SMIME = 6;
+ public static final int SSL_CRT_FORMAT_ENGINE = 7;
+
+ public static final int SSL_MODE_CLIENT = 0;
+ public static final int SSL_MODE_SERVER = 1;
+ public static final int SSL_MODE_COMBINED = 2;
+
+ public static final int SSL_CONF_FLAG_CMDLINE = 0x0001;
+ public static final int SSL_CONF_FLAG_FILE = 0x0002;
+ public static final int SSL_CONF_FLAG_CLIENT = 0x0004;
+ public static final int SSL_CONF_FLAG_SERVER = 0x0008;
+ public static final int SSL_CONF_FLAG_SHOW_ERRORS = 0x0010;
+ public static final int SSL_CONF_FLAG_CERTIFICATE = 0x0020;
+
+ public static final int SSL_CONF_TYPE_UNKNOWN = 0x0000;
+ public static final int SSL_CONF_TYPE_STRING = 0x0001;
+ public static final int SSL_CONF_TYPE_FILE = 0x0002;
+ public static final int SSL_CONF_TYPE_DIR = 0x0003;
- public static final int SSL_SHUTDOWN_TYPE_UNSET = 0;
+ public static final int SSL_SHUTDOWN_TYPE_UNSET = 0;
public static final int SSL_SHUTDOWN_TYPE_STANDARD = 1;
- public static final int SSL_SHUTDOWN_TYPE_UNCLEAN = 2;
+ public static final int SSL_SHUTDOWN_TYPE_UNCLEAN = 2;
public static final int SSL_SHUTDOWN_TYPE_ACCURATE = 3;
- public static final int SSL_INFO_SESSION_ID = 0x0001;
- public static final int SSL_INFO_CIPHER = 0x0002;
- public static final int SSL_INFO_CIPHER_USEKEYSIZE = 0x0003;
- public static final int SSL_INFO_CIPHER_ALGKEYSIZE = 0x0004;
- public static final int SSL_INFO_CIPHER_VERSION = 0x0005;
- public static final int SSL_INFO_CIPHER_DESCRIPTION = 0x0006;
- public static final int SSL_INFO_PROTOCOL = 0x0007;
-
- /* To obtain the CountryName of the Client Certificate Issuer
- * use the SSL_INFO_CLIENT_I_DN + SSL_INFO_DN_COUNTRYNAME
- */
- public static final int SSL_INFO_CLIENT_S_DN = 0x0010;
- public static final int SSL_INFO_CLIENT_I_DN = 0x0020;
- public static final int SSL_INFO_SERVER_S_DN = 0x0040;
- public static final int SSL_INFO_SERVER_I_DN = 0x0080;
-
- public static final int SSL_INFO_DN_COUNTRYNAME = 0x0001;
- public static final int SSL_INFO_DN_STATEORPROVINCENAME = 0x0002;
- public static final int SSL_INFO_DN_LOCALITYNAME = 0x0003;
- public static final int SSL_INFO_DN_ORGANIZATIONNAME = 0x0004;
+ public static final int SSL_INFO_SESSION_ID = 0x0001;
+ public static final int SSL_INFO_CIPHER = 0x0002;
+ public static final int SSL_INFO_CIPHER_USEKEYSIZE = 0x0003;
+ public static final int SSL_INFO_CIPHER_ALGKEYSIZE = 0x0004;
+ public static final int SSL_INFO_CIPHER_VERSION = 0x0005;
+ public static final int SSL_INFO_CIPHER_DESCRIPTION = 0x0006;
+ public static final int SSL_INFO_PROTOCOL = 0x0007;
+
+ /*
+ * To obtain the CountryName of the Client Certificate Issuer use the SSL_INFO_CLIENT_I_DN + SSL_INFO_DN_COUNTRYNAME
+ */
+ public static final int SSL_INFO_CLIENT_S_DN = 0x0010;
+ public static final int SSL_INFO_CLIENT_I_DN = 0x0020;
+ public static final int SSL_INFO_SERVER_S_DN = 0x0040;
+ public static final int SSL_INFO_SERVER_I_DN = 0x0080;
+
+ public static final int SSL_INFO_DN_COUNTRYNAME = 0x0001;
+ public static final int SSL_INFO_DN_STATEORPROVINCENAME = 0x0002;
+ public static final int SSL_INFO_DN_LOCALITYNAME = 0x0003;
+ public static final int SSL_INFO_DN_ORGANIZATIONNAME = 0x0004;
public static final int SSL_INFO_DN_ORGANIZATIONALUNITNAME = 0x0005;
- public static final int SSL_INFO_DN_COMMONNAME = 0x0006;
- public static final int SSL_INFO_DN_TITLE = 0x0007;
- public static final int SSL_INFO_DN_INITIALS = 0x0008;
- public static final int SSL_INFO_DN_GIVENNAME = 0x0009;
- public static final int SSL_INFO_DN_SURNAME = 0x000A;
- public static final int SSL_INFO_DN_DESCRIPTION = 0x000B;
- public static final int SSL_INFO_DN_UNIQUEIDENTIFIER = 0x000C;
- public static final int SSL_INFO_DN_EMAILADDRESS = 0x000D;
-
- public static final int SSL_INFO_CLIENT_M_VERSION = 0x0101;
- public static final int SSL_INFO_CLIENT_M_SERIAL = 0x0102;
- public static final int SSL_INFO_CLIENT_V_START = 0x0103;
- public static final int SSL_INFO_CLIENT_V_END = 0x0104;
- public static final int SSL_INFO_CLIENT_A_SIG = 0x0105;
- public static final int SSL_INFO_CLIENT_A_KEY = 0x0106;
- public static final int SSL_INFO_CLIENT_CERT = 0x0107;
- public static final int SSL_INFO_CLIENT_V_REMAIN = 0x0108;
-
- public static final int SSL_INFO_SERVER_M_VERSION = 0x0201;
- public static final int SSL_INFO_SERVER_M_SERIAL = 0x0202;
- public static final int SSL_INFO_SERVER_V_START = 0x0203;
- public static final int SSL_INFO_SERVER_V_END = 0x0204;
- public static final int SSL_INFO_SERVER_A_SIG = 0x0205;
- public static final int SSL_INFO_SERVER_A_KEY = 0x0206;
- public static final int SSL_INFO_SERVER_CERT = 0x0207;
- /* Return client certificate chain.
- * Add certificate chain number to that flag (0 ... verify depth)
+ public static final int SSL_INFO_DN_COMMONNAME = 0x0006;
+ public static final int SSL_INFO_DN_TITLE = 0x0007;
+ public static final int SSL_INFO_DN_INITIALS = 0x0008;
+ public static final int SSL_INFO_DN_GIVENNAME = 0x0009;
+ public static final int SSL_INFO_DN_SURNAME = 0x000A;
+ public static final int SSL_INFO_DN_DESCRIPTION = 0x000B;
+ public static final int SSL_INFO_DN_UNIQUEIDENTIFIER = 0x000C;
+ public static final int SSL_INFO_DN_EMAILADDRESS = 0x000D;
+
+ public static final int SSL_INFO_CLIENT_M_VERSION = 0x0101;
+ public static final int SSL_INFO_CLIENT_M_SERIAL = 0x0102;
+ public static final int SSL_INFO_CLIENT_V_START = 0x0103;
+ public static final int SSL_INFO_CLIENT_V_END = 0x0104;
+ public static final int SSL_INFO_CLIENT_A_SIG = 0x0105;
+ public static final int SSL_INFO_CLIENT_A_KEY = 0x0106;
+ public static final int SSL_INFO_CLIENT_CERT = 0x0107;
+ public static final int SSL_INFO_CLIENT_V_REMAIN = 0x0108;
+
+ public static final int SSL_INFO_SERVER_M_VERSION = 0x0201;
+ public static final int SSL_INFO_SERVER_M_SERIAL = 0x0202;
+ public static final int SSL_INFO_SERVER_V_START = 0x0203;
+ public static final int SSL_INFO_SERVER_V_END = 0x0204;
+ public static final int SSL_INFO_SERVER_A_SIG = 0x0205;
+ public static final int SSL_INFO_SERVER_A_KEY = 0x0206;
+ public static final int SSL_INFO_SERVER_CERT = 0x0207;
+ /*
+ * Return client certificate chain. Add certificate chain number to that flag (0 ... verify depth)
*/
- public static final int SSL_INFO_CLIENT_CERT_CHAIN = 0x0400;
+ public static final int SSL_INFO_CLIENT_CERT_CHAIN = 0x0400;
/* Only support OFF and SERVER for now */
public static final long SSL_SESS_CACHE_OFF = 0x0000;
@@ -240,12 +246,12 @@
public static native String versionString();
/**
- * Initialize OpenSSL support.
- * This function needs to be called once for the
- * lifetime of JVM. Library.init() has to be called before.
- * @param engine Support for external a Crypto Device ("engine"),
- * usually
- * a hardware accelerator card for crypto operations.
+ * Initialize OpenSSL support. This function needs to be called once for the lifetime of JVM. Library.init() has to
+ * be called before.
+ *
+ * @param engine Support for external a Crypto Device ("engine"), usually a hardware accelerator card for crypto
+ * operations.
+ *
* @return APR status code
*/
public static native int initialize(String engine);
@@ -253,9 +259,11 @@
/**
* Get the status of FIPS Mode.
*
- * @return FIPS_mode return code. It is 0 if OpenSSL is not
- * in FIPS mode, 1 if OpenSSL is in FIPS Mode.
+ * @return FIPS_mode return code. It is 0 if OpenSSL is not in FIPS mode, 1 if OpenSSL is
+ * in FIPS Mode.
+ *
* @throws Exception If tcnative was not compiled with FIPS Mode available.
+ *
* @see OpenSSL method FIPS_mode()
*/
public static native int fipsModeGet() throws Exception;
@@ -266,8 +274,10 @@
* @param mode 1 - enable, 0 - disable
*
* @return FIPS_mode_set return code
- * @throws Exception If tcnative was not compiled with FIPS Mode available,
- * or if {@code FIPS_mode_set()} call returned an error value.
+ *
+ * @throws Exception If tcnative was not compiled with FIPS Mode available, or if {@code FIPS_mode_set()} call
+ * returned an error value.
+ *
* @see OpenSSL method FIPS_mode_set()
*/
public static native int fipsModeSet(int mode) throws Exception;
@@ -275,15 +285,16 @@
/**
* Sets global random filename.
*
- * @param filename Filename to use.
- * If set it will be used for SSL initialization
- * and all contexts where explicitly not set.
+ * @param filename Filename to use. If set it will be used for SSL initialization and all contexts where explicitly
+ * not set.
*/
public static native void randSet(String filename);
/**
* Return the handshake completed count.
+ *
* @param ssl SSL pointer
+ *
* @return the count
*/
public static native int getHandshakeCount(long ssl);
@@ -295,84 +306,101 @@
public static final int SSL_SENT_SHUTDOWN = 1;
public static final int SSL_RECEIVED_SHUTDOWN = 2;
- public static final int SSL_ERROR_NONE = 0;
- public static final int SSL_ERROR_SSL = 1;
- public static final int SSL_ERROR_WANT_READ = 2;
- public static final int SSL_ERROR_WANT_WRITE = 3;
+ public static final int SSL_ERROR_NONE = 0;
+ public static final int SSL_ERROR_SSL = 1;
+ public static final int SSL_ERROR_WANT_READ = 2;
+ public static final int SSL_ERROR_WANT_WRITE = 3;
public static final int SSL_ERROR_WANT_X509_LOOKUP = 4;
- public static final int SSL_ERROR_SYSCALL = 5; /* look at error stack/return value/errno */
- public static final int SSL_ERROR_ZERO_RETURN = 6;
- public static final int SSL_ERROR_WANT_CONNECT = 7;
- public static final int SSL_ERROR_WANT_ACCEPT = 8;
+ public static final int SSL_ERROR_SYSCALL = 5; /* look at error stack/return value/errno */
+ public static final int SSL_ERROR_ZERO_RETURN = 6;
+ public static final int SSL_ERROR_WANT_CONNECT = 7;
+ public static final int SSL_ERROR_WANT_ACCEPT = 8;
/**
* SSL_new
- * @param ctx Server or Client context to use.
- * @param server if true configure SSL instance to use accept handshake routines
- * if false configure SSL instance to use connect handshake routines
+ *
+ * @param ctx Server or Client context to use.
+ * @param server if true configure SSL instance to use accept handshake routines if false configure SSL instance to
+ * use connect handshake routines
+ *
* @return pointer to SSL instance (SSL *)
*/
public static native long newSSL(long ctx, boolean server);
/**
* BIO_ctrl_pending.
+ *
* @param bio BIO pointer (BIO *)
+ *
* @return the pending bytes count
*/
public static native int pendingWrittenBytesInBIO(long bio);
/**
* SSL_pending.
+ *
* @param ssl SSL pointer (SSL *)
+ *
* @return the pending bytes count
*/
public static native int pendingReadableBytesInSSL(long ssl);
/**
* BIO_write.
- * @param bio BIO pointer
+ *
+ * @param bio BIO pointer
* @param wbuf Buffer pointer
* @param wlen Write length
+ *
* @return the bytes count written
*/
public static native int writeToBIO(long bio, long wbuf, int wlen);
/**
* BIO_read.
- * @param bio BIO pointer
+ *
+ * @param bio BIO pointer
* @param rbuf Buffer pointer
* @param rlen Read length
+ *
* @return the bytes count read
*/
public static native int readFromBIO(long bio, long rbuf, int rlen);
/**
* SSL_write.
- * @param ssl the SSL instance (SSL *)
+ *
+ * @param ssl the SSL instance (SSL *)
* @param wbuf Buffer pointer
* @param wlen Write length
+ *
* @return the bytes count written
*/
public static native int writeToSSL(long ssl, long wbuf, int wlen);
/**
* SSL_read
- * @param ssl the SSL instance (SSL *)
+ *
+ * @param ssl the SSL instance (SSL *)
* @param rbuf Buffer pointer
* @param rlen Read length
+ *
* @return the bytes count read
*/
public static native int readFromSSL(long ssl, long rbuf, int rlen);
/**
* SSL_get_shutdown
+ *
* @param ssl the SSL instance (SSL *)
+ *
* @return the operation status
*/
public static native int getShutdown(long ssl);
/**
* SSL_free
+ *
* @param ssl the SSL instance (SSL *)
*/
public static native void freeSSL(long ssl);
@@ -382,86 +410,106 @@
*
* Warning: you must explicitly free this resource by calling freeBIO
*
- * While the SSL's internal/application data BIO will be freed when freeSSL is called on
- * the provided SSL instance, you must call freeBIO on the returned network BIO.
+ * While the SSL's internal/application data BIO will be freed when freeSSL is called on the provided SSL instance,
+ * you must call freeBIO on the returned network BIO.
*
* @param ssl the SSL instance (SSL *)
+ *
* @return pointer to the Network BIO (BIO *)
*/
public static native long makeNetworkBIO(long ssl);
/**
* BIO_free
+ *
* @param bio BIO pointer
*/
public static native void freeBIO(long bio);
/**
* SSL_shutdown
+ *
* @param ssl the SSL instance (SSL *)
+ *
* @return the operation status
*/
public static native int shutdownSSL(long ssl);
/**
- * Get the error number representing the last error OpenSSL encountered on
- * this thread.
+ * Get the error number representing the last error OpenSSL encountered on this thread.
+ *
* @return the last error number
*/
public static native int getLastErrorNumber();
/**
* SSL_get_cipher.
+ *
* @param ssl the SSL instance (SSL *)
+ *
* @return the cipher name
*/
public static native String getCipherForSSL(long ssl);
/**
* SSL_get_version
+ *
* @param ssl the SSL instance (SSL *)
+ *
* @return the SSL version in use
*/
public static native String getVersion(long ssl);
/**
* SSL_do_handshake
+ *
* @param ssl the SSL instance (SSL *)
+ *
* @return the handshake status
*/
public static native int doHandshake(long ssl);
/**
* SSL_renegotiate
+ *
* @param ssl the SSL instance (SSL *)
+ *
* @return the operation status
*/
public static native int renegotiate(long ssl);
/**
* SSL_renegotiate_pending
+ *
* @param ssl the SSL instance (SSL *)
+ *
* @return the operation status
*/
public static native int renegotiatePending(long ssl);
/**
* SSL_verify_client_post_handshake
+ *
* @param ssl the SSL instance (SSL *)
+ *
* @return the operation status
*/
public static native int verifyClientPostHandshake(long ssl);
/**
* Is post handshake authentication in progress on this connection?
+ *
* @param ssl the SSL instance (SSL *)
+ *
* @return the operation status
*/
public static native int getPostHandshakeAuthInProgress(long ssl);
/**
* SSL_in_init.
+ *
* @param ssl the SSL instance (SSL *)
+ *
* @return the status
*/
public static native int isInInit(long ssl);
@@ -472,52 +520,59 @@
/**
* SSL_get0_alpn_selected
+ *
* @param ssl the SSL instance (SSL *)
+ *
* @return the ALPN protocol negotiated
*/
public static native String getAlpnSelected(long ssl);
/**
* Get the peer certificate chain or {@code null} if none was sent.
+ *
* @param ssl the SSL instance (SSL *)
+ *
* @return the certificate chain bytes
*/
public static native byte[][] getPeerCertChain(long ssl);
/**
* Get the peer certificate or {@code null} if none was sent.
+ *
* @param ssl the SSL instance (SSL *)
+ *
* @return the certificate bytes
*/
public static native byte[] getPeerCertificate(long ssl);
/**
* Get the error number representing for the given {@code errorNumber}.
+ *
* @param errorNumber The error code
+ *
* @return an error message
*/
public static native String getErrorString(long errorNumber);
/**
* SSL_get_time
+ *
* @param ssl the SSL instance (SSL *)
+ *
* @return returns the time at which the session ssl was established. The time is given in seconds since the Epoch
*/
public static native long getTime(long ssl);
/**
- * Set Type of Client Certificate verification and Maximum depth of CA Certificates
- * in Client Certificate verification.
- *
- * This directive sets the Certificate verification level for the Client
- * Authentication. Notice that this directive can be used both in per-server
- * and per-directory context. In per-server context it applies to the client
- * authentication process used in the standard SSL handshake when a connection
- * is established. In per-directory context it forces an SSL renegotiation with
- * the reconfigured client verification level after the HTTP request was read
- * but before the HTTP response is sent.
- *
+ * Set Type of Client Certificate verification and Maximum depth of CA Certificates in Client Certificate
+ * verification.
+ * This directive sets the Certificate verification level for the Client Authentication. Notice that this directive
+ * can be used both in per-server and per-directory context. In per-server context it applies to the client
+ * authentication process used in the standard SSL handshake when a connection is established. In per-directory
+ * context it forces an SSL renegotiation with the reconfigured client verification level after the HTTP request was
+ * read but before the HTTP response is sent.
* The following levels are available for level:
+ *
*
* SSL_CVERIFY_NONE - No client Certificate is required at all
* SSL_CVERIFY_OPTIONAL - The client may present a valid Certificate
@@ -525,66 +580,68 @@
* SSL_CVERIFY_OPTIONAL_NO_CA - The client may present a valid Certificate
* but it need not to be (successfully) verifiable
*
+ *
*
- * The depth actually is the maximum number of intermediate certificate issuers,
- * i.e. the number of CA certificates which are max allowed to be followed while
- * verifying the client certificate. A depth of 0 means that self-signed client
- * certificates are accepted only, the default depth of 1 means the client
- * certificate can be self-signed or has to be signed by a CA which is directly
- * known to the server (i.e. the CA's certificate is under
+ * The depth actually is the maximum number of intermediate certificate issuers, i.e. the number of CA certificates
+ * which are max allowed to be followed while verifying the client certificate. A depth of 0 means that self-signed
+ * client certificates are accepted only, the default depth of 1 means the client certificate can be self-signed or
+ * has to be signed by a CA which is directly known to the server (i.e. the CA's certificate is under
* {@code setCACertificatePath}, etc).
*
- * @param ssl the SSL instance (SSL *)
+ * @param ssl the SSL instance (SSL *)
* @param level Type of Client Certificate verification.
- * @param depth Maximum depth of CA Certificates in Client Certificate
- * verification.
+ * @param depth Maximum depth of CA Certificates in Client Certificate verification.
*/
public static native void setVerify(long ssl, int level, int depth);
/**
* Set OpenSSL Option.
- * @param ssl the SSL instance (SSL *)
- * @param options See SSL.SSL_OP_* for option flags.
+ *
+ * @param ssl the SSL instance (SSL *)
+ * @param options See SSL.SSL_OP_* for option flags.
*/
public static native void setOptions(long ssl, int options);
/**
* Get OpenSSL Option.
+ *
* @param ssl the SSL instance (SSL *)
- * @return options See SSL.SSL_OP_* for option flags.
+ *
+ * @return options See SSL.SSL_OP_* for option flags.
*/
public static native int getOptions(long ssl);
/**
* Returns all cipher suites that are enabled for negotiation in an SSL handshake.
+ *
* @param ssl the SSL instance (SSL *)
+ *
* @return ciphers
*/
public static native String[] getCiphers(long ssl);
/**
- * Returns the cipher suites available for negotiation in SSL handshake.
- *
- * This complex directive uses a colon-separated cipher-spec string consisting
- * of OpenSSL cipher specifications to configure the Cipher Suite the client
- * is permitted to negotiate in the SSL handshake phase. Notice that this
- * directive can be used both in per-server and per-directory context.
- * In per-server context it applies to the standard SSL handshake when a
- * connection is established. In per-directory context it forces an SSL
- * renegotiation with the reconfigured Cipher Suite after the HTTP request
- * was read but before the HTTP response is sent.
- * @param ssl the SSL instance (SSL *)
+ * Returns the cipher suites available for negotiation in SSL handshake.
+ * This complex directive uses a colon-separated cipher-spec string consisting of OpenSSL cipher specifications to
+ * configure the Cipher Suite the client is permitted to negotiate in the SSL handshake phase. Notice that this
+ * directive can be used both in per-server and per-directory context. In per-server context it applies to the
+ * standard SSL handshake when a connection is established. In per-directory context it forces an SSL renegotiation
+ * with the reconfigured Cipher Suite after the HTTP request was read but before the HTTP response is sent.
+ *
+ * @param ssl the SSL instance (SSL *)
* @param ciphers an SSL cipher specification
+ *
* @return true if the operation was successful
+ *
* @throws Exception An error occurred
*/
- public static native boolean setCipherSuites(long ssl, String ciphers)
- throws Exception;
+ public static native boolean setCipherSuites(long ssl, String ciphers) throws Exception;
/**
* Returns the ID of the session as byte array representation.
*
* @param ssl the SSL instance (SSL *)
+ *
* @return the session as byte array representation obtained via SSL_SESSION_get_id.
*/
public static native byte[] getSessionId(long ssl);
diff -Nru tomcat11-11.0.6/java/org/apache/tomcat/jni/SSLConf.java tomcat11-11.0.15/java/org/apache/tomcat/jni/SSLConf.java
--- tomcat11-11.0.6/java/org/apache/tomcat/jni/SSLConf.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/tomcat/jni/SSLConf.java 2025-12-02 16:54:08.000000000 +0000
@@ -21,10 +21,10 @@
/**
* Create a new SSL_CONF context.
*
- * @param pool The pool to use.
- * @param flags The SSL_CONF flags to use. It can be any combination of
- * the following:
- *
+ * @param pool The pool to use.
+ * @param flags The SSL_CONF flags to use. It can be any combination of the following:
+ *
+ *
*
- * @return The Java representation of a pointer to the newly created
- * SSL_CONF Context
+ * @return The Java representation of a pointer to the newly created SSL_CONF Context
*
* @throws Exception If the SSL_CONF context could not be created
*
* @see OpenSSL SSL_CONF_CTX_new
- * @see OpenSSL SSL_CONF_CTX_set_flags
+ * @see OpenSSL
+ * SSL_CONF_CTX_set_flags
*/
public static native long make(long pool, int flags) throws Exception;
@@ -55,13 +55,12 @@
/**
* Check a command with an SSL_CONF context.
*
- * @param cctx SSL_CONF context to use.
- * @param name command name.
+ * @param cctx SSL_CONF context to use.
+ * @param name command name.
* @param value command value.
*
- * @return The result of the check based on the {@code SSL_CONF_cmd_value_type}
- * call. Unknown types will result in an exception, as well as
- * file and directory types with invalid file or directory names.
+ * @return The result of the check based on the {@code SSL_CONF_cmd_value_type} call. Unknown types will result in
+ * an exception, as well as file and directory types with invalid file or directory names.
*
* @throws Exception If the check fails.
*
@@ -70,22 +69,22 @@
public static native int check(long cctx, String name, String value) throws Exception;
/**
- * Assign an SSL context to an SSL_CONF context.
- * All following calls to {@link #apply(long, String, String)} will be
+ * Assign an SSL context to an SSL_CONF context. All following calls to {@link #apply(long, String, String)} will be
* applied to this SSL context.
*
* @param cctx SSL_CONF context to use.
- * @param ctx SSL context to assign to the given SSL_CONF context.
+ * @param ctx SSL context to assign to the given SSL_CONF context.
*
- * @see OpenSSL SSL_CONF_CTX_set_ssl_ctx
+ * @see OpenSSL
+ * SSL_CONF_CTX_set_ssl_ctx
*/
public static native void assign(long cctx, long ctx);
/**
* Apply a command to an SSL_CONF context.
*
- * @param cctx SSL_CONF context to use.
- * @param name command name.
+ * @param cctx SSL_CONF context to use.
+ * @param name command name.
* @param value command value.
*
* @return The result of the native {@code SSL_CONF_cmd} call
@@ -103,7 +102,8 @@
*
* @return The result of the native {@code SSL_CONF_CTX_finish} call
*
- * @see OpenSSL SSL_CONF_CTX_finish
+ * @see OpenSSL
+ * SSL_CONF_CTX_finish
*/
public static native int finish(long cctx);
diff -Nru tomcat11-11.0.6/java/org/apache/tomcat/jni/SSLContext.java tomcat11-11.0.15/java/org/apache/tomcat/jni/SSLContext.java
--- tomcat11-11.0.6/java/org/apache/tomcat/jni/SSLContext.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/tomcat/jni/SSLContext.java 2025-12-02 16:54:08.000000000 +0000
@@ -22,16 +22,15 @@
public final class SSLContext {
- public static final byte[] DEFAULT_SESSION_ID_CONTEXT =
- new byte[] { 'd', 'e', 'f', 'a', 'u', 'l', 't' };
+ public static final byte[] DEFAULT_SESSION_ID_CONTEXT = new byte[] { 'd', 'e', 'f', 'a', 'u', 'l', 't' };
/**
* Create a new SSL context.
*
- * @param pool The pool to use.
- * @param protocol The SSL protocol to use. It can be any combination of
- * the following:
- *
+ * @param pool The pool to use.
+ * @param protocol The SSL protocol to use. It can be any combination of the following:
+ *
+ *
*
- * @return The Java representation of a pointer to the newly created SSL
- * Context
+ * @return The Java representation of a pointer to the newly created SSL Context
*
* @throws Exception If the SSL Context could not be created
*/
@@ -56,149 +56,140 @@
/**
* Free the resources used by the Context
+ *
* @param ctx Server or Client context to free.
+ *
* @return APR Status code.
*/
public static native int free(long ctx);
/**
* Set OpenSSL Option.
- * @param ctx Server or Client context to use.
- * @param options See SSL.SSL_OP_* for option flags.
+ *
+ * @param ctx Server or Client context to use.
+ * @param options See SSL.SSL_OP_* for option flags.
*/
public static native void setOptions(long ctx, int options);
/**
* Get OpenSSL Option.
+ *
* @param ctx Server or Client context to use.
- * @return options See SSL.SSL_OP_* for option flags.
+ *
+ * @return options See SSL.SSL_OP_* for option flags.
*/
public static native int getOptions(long ctx);
/**
* Clears OpenSSL Options.
- * @param ctx Server or Client context to use.
- * @param options See SSL.SSL_OP_* for option flags.
+ *
+ * @param ctx Server or Client context to use.
+ * @param options See SSL.SSL_OP_* for option flags.
*/
public static native void clearOptions(long ctx, int options);
/**
* Returns all cipher suites that are enabled for negotiation in an SSL handshake.
+ *
* @param ctx Server or Client context to use.
+ *
* @return ciphers
*/
public static native String[] getCiphers(long ctx);
/**
- * Cipher Suite available for negotiation in SSL handshake.
- *
- * This complex directive uses a colon-separated cipher-spec string consisting
- * of OpenSSL cipher specifications to configure the Cipher Suite the client
- * is permitted to negotiate in the SSL handshake phase. Notice that this
- * directive can be used both in per-server and per-directory context.
- * In per-server context it applies to the standard SSL handshake when a
- * connection is established. In per-directory context it forces an SSL
- * renegotiation with the reconfigured Cipher Suite after the HTTP request
- * was read but before the HTTP response is sent.
- * @param ctx Server or Client context to use.
+ * Cipher Suite available for negotiation in SSL handshake.
+ * This complex directive uses a colon-separated cipher-spec string consisting of OpenSSL cipher specifications to
+ * configure the Cipher Suite the client is permitted to negotiate in the SSL handshake phase. Notice that this
+ * directive can be used both in per-server and per-directory context. In per-server context it applies to the
+ * standard SSL handshake when a connection is established. In per-directory context it forces an SSL renegotiation
+ * with the reconfigured Cipher Suite after the HTTP request was read but before the HTTP response is sent.
+ *
+ * @param ctx Server or Client context to use.
* @param ciphers An OpenSSL cipher specification.
+ *
* @return true if the operation was successful
+ *
* @throws Exception An error occurred
*/
- public static native boolean setCipherSuite(long ctx, String ciphers)
- throws Exception;
+ public static native boolean setCipherSuite(long ctx, String ciphers) throws Exception;
/**
- * Set File of concatenated PEM-encoded CA CRLs or
- * directory of PEM-encoded CA Certificates for Client Auth
- *
- * This directive sets the all-in-one file where you can assemble the
- * Certificate Revocation Lists (CRL) of Certification Authorities (CA)
- * whose clients you deal with. These are used for Client Authentication.
- * Such a file is simply the concatenation of the various PEM-encoded CRL
- * files, in order of preference.
- *
- * The files in this directory have to be PEM-encoded and are accessed through
- * hash filenames. So usually you can't just place the Certificate files there:
- * you also have to create symbolic links named hash-value.N. And you should
- * always make sure this directory contains the appropriate symbolic links.
- * Use the Makefile which comes with mod_ssl to accomplish this task.
- * @param ctx Server or Client context to use.
+ * Set File of concatenated PEM-encoded CA CRLs or directory of PEM-encoded CA Certificates for Client Auth
+ * This directive sets the all-in-one file where you can assemble the Certificate Revocation Lists (CRL) of
+ * Certification Authorities (CA) whose clients you deal with. These are used for Client Authentication. Such a file
+ * is simply the concatenation of the various PEM-encoded CRL files, in order of preference.
+ * The files in this directory have to be PEM-encoded and are accessed through hash filenames. So usually you can't
+ * just place the Certificate files there: you also have to create symbolic links named hash-value.N. And you should
+ * always make sure this directory contains the appropriate symbolic links. Use the Makefile which comes with
+ * mod_ssl to accomplish this task.
+ *
+ * @param ctx Server or Client context to use.
* @param file File of concatenated PEM-encoded CA CRLs for Client Auth.
* @param path Directory of PEM-encoded CA Certificates for Client Auth.
+ *
* @return true if the operation was successful
+ *
* @throws Exception An error occurred
*/
- public static native boolean setCARevocation(long ctx, String file,
- String path)
- throws Exception;
+ public static native boolean setCARevocation(long ctx, String file, String path) throws Exception;
/**
- * Set File of PEM-encoded Server CA Certificates
- *
- * This directive sets the optional all-in-one file where you can assemble the
- * certificates of Certification Authorities (CA) which form the certificate
- * chain of the server certificate. This starts with the issuing CA certificate
- * of the server certificate and can range up to the root CA certificate.
- * Such a file is simply the concatenation of the various PEM-encoded CA
- * Certificate files, usually in certificate chain order.
- *
- * But be careful: Providing the certificate chain works only if you are using
- * a single (either RSA or DSA) based server certificate. If you are using a
- * coupled RSA+DSA certificate pair, this will work only if actually both
- * certificates use the same certificate chain. Else the browsers will be
- * confused in this situation.
- * @param ctx Server or Client context to use.
- * @param file File of PEM-encoded Server CA Certificates.
- * @param skipfirst Skip first certificate if chain file is inside
- * certificate file.
+ * Set File of PEM-encoded Server CA Certificates
+ * This directive sets the optional all-in-one file where you can assemble the certificates of Certification
+ * Authorities (CA) which form the certificate chain of the server certificate. This starts with the issuing CA
+ * certificate of the server certificate and can range up to the root CA certificate. Such a file is simply the
+ * concatenation of the various PEM-encoded CA Certificate files, usually in certificate chain order.
+ * But be careful: Providing the certificate chain works only if you are using a single (either RSA or DSA) based
+ * server certificate. If you are using a coupled RSA+DSA certificate pair, this will work only if actually both
+ * certificates use the same certificate chain. Else the browsers will be confused in this situation.
+ *
+ * @param ctx Server or Client context to use.
+ * @param file File of PEM-encoded Server CA Certificates.
+ * @param skipfirst Skip first certificate if chain file is inside certificate file.
+ *
* @return true if the operation was successful
*/
- public static native boolean setCertificateChainFile(long ctx, String file,
- boolean skipfirst);
+ public static native boolean setCertificateChainFile(long ctx, String file, boolean skipfirst);
/**
- * Set Certificate
- *
- * Point setCertificateFile at a PEM encoded certificate. If
- * the certificate is encrypted, then you will be prompted for a
- * pass phrase. Note that a kill -HUP will prompt again. A test
- * certificate can be generated with 'make certificate' under
- * built time. Keep in mind that if you've both a RSA and a DSA
- * certificate you can configure both in parallel (to also allow
- * the use of DSA ciphers, etc.)
- *
- * If the key is not combined with the certificate, use key param
- * to point at the key file. Keep in mind that if
- * you've both a RSA and a DSA private key you can configure
- * both in parallel (to also allow the use of DSA ciphers, etc.)
- * @param ctx Server or Client context to use.
- * @param cert Certificate file.
- * @param key Private Key file to use if not in cert.
- * @param password Certificate password. If null and certificate
- * is encrypted, password prompt will be displayed.
- * @param idx Certificate index SSL_AIDX_RSA or SSL_AIDX_DSA.
+ * Set Certificate
+ * Point setCertificateFile at a PEM encoded certificate. If the certificate is encrypted, then you will be prompted
+ * for a pass phrase. Note that a kill -HUP will prompt again. A test certificate can be generated with 'make
+ * certificate' under built time. Keep in mind that if you've both a RSA and a DSA certificate you can configure
+ * both in parallel (to also allow the use of DSA ciphers, etc.)
+ * If the key is not combined with the certificate, use key param to point at the key file. Keep in mind that if
+ * you've both a RSA and a DSA private key you can configure both in parallel (to also allow the use of DSA ciphers,
+ * etc.)
+ *
+ * @param ctx Server or Client context to use.
+ * @param cert Certificate file.
+ * @param key Private Key file to use if not in cert.
+ * @param password Certificate password. If null and certificate is encrypted, password prompt will be displayed.
+ * @param idx Certificate index SSL_AIDX_RSA or SSL_AIDX_DSA.
+ *
* @return true if the operation was successful
+ *
* @throws Exception An error occurred
*/
- public static native boolean setCertificate(long ctx, String cert,
- String key, String password,
- int idx)
- throws Exception;
+ public static native boolean setCertificate(long ctx, String cert, String key, String password, int idx)
+ throws Exception;
/**
- * Set the size of the internal session cache.
- * http://www.openssl.org/docs/ssl/SSL_CTX_sess_set_cache_size.html
- * @param ctx Server or Client context to use.
+ * Set the size of the internal session cache. http://www.openssl.org/docs/ssl/SSL_CTX_sess_set_cache_size.html
+ *
+ * @param ctx Server or Client context to use.
* @param size The cache size
+ *
* @return the value set
*/
public static native long setSessionCacheSize(long ctx, long size);
/**
- * Get the size of the internal session cache.
- * http://www.openssl.org/docs/ssl/SSL_CTX_sess_get_cache_size.html
+ * Get the size of the internal session cache. http://www.openssl.org/docs/ssl/SSL_CTX_sess_get_cache_size.html
+ *
* @param ctx Server or Client context to use.
+ *
* @return the size
*/
public static native long getSessionCacheSize(long ctx);
@@ -206,8 +197,10 @@
/**
* Set the timeout for the internal session cache in seconds.
* http://www.openssl.org/docs/ssl/SSL_CTX_set_timeout.html
- * @param ctx Server or Client context to use.
+ *
+ * @param ctx Server or Client context to use.
* @param timeoutSeconds Timeout value
+ *
* @return the value set
*/
public static native long setSessionCacheTimeout(long ctx, long timeoutSeconds);
@@ -215,90 +208,98 @@
/**
* Get the timeout for the internal session cache in seconds.
* http://www.openssl.org/docs/ssl/SSL_CTX_set_timeout.html
+ *
* @param ctx Server or Client context to use.
+ *
* @return the timeout
*/
public static native long getSessionCacheTimeout(long ctx);
/**
* Set the mode of the internal session cache and return the previous used mode.
- * @param ctx Server or Client context to use.
+ *
+ * @param ctx Server or Client context to use.
* @param mode The mode to set
+ *
* @return the value set
*/
public static native long setSessionCacheMode(long ctx, long mode);
/**
* Get the mode of the current used internal session cache.
+ *
* @param ctx Server or Client context to use.
+ *
* @return the value set
*/
public static native long getSessionCacheMode(long ctx);
/*
- * Session resumption statistics methods.
- * http://www.openssl.org/docs/ssl/SSL_CTX_sess_number.html
+ * Session resumption statistics methods. http://www.openssl.org/docs/ssl/SSL_CTX_sess_number.html
*/
public static native long sessionAccept(long ctx);
+
public static native long sessionAcceptGood(long ctx);
+
public static native long sessionAcceptRenegotiate(long ctx);
+
public static native long sessionCacheFull(long ctx);
+
public static native long sessionCbHits(long ctx);
+
public static native long sessionConnect(long ctx);
+
public static native long sessionConnectGood(long ctx);
+
public static native long sessionConnectRenegotiate(long ctx);
+
public static native long sessionHits(long ctx);
+
public static native long sessionMisses(long ctx);
+
public static native long sessionNumber(long ctx);
+
public static native long sessionTimeouts(long ctx);
/**
* Set TLS session keys. This allows us to share keys across TFEs.
- * @param ctx Server or Client context to use.
+ *
+ * @param ctx Server or Client context to use.
* @param keys Some session keys
*/
public static native void setSessionTicketKeys(long ctx, byte[] keys);
/**
- * Set File and Directory of concatenated PEM-encoded CA Certificates
- * for Client Auth
- *
- * This directive sets the all-in-one file where you can assemble the
- * Certificates of Certification Authorities (CA) whose clients you deal with.
- * These are used for Client Authentication. Such a file is simply the
- * concatenation of the various PEM-encoded Certificate files, in order of
- * preference. This can be used alternatively and/or additionally to
- * path.
- *
- * The files in this directory have to be PEM-encoded and are accessed through
- * hash filenames. So usually you can't just place the Certificate files there:
- * you also have to create symbolic links named hash-value.N. And you should
- * always make sure this directory contains the appropriate symbolic links.
- * Use the Makefile which comes with mod_ssl to accomplish this task.
- * @param ctx Server or Client context to use.
- * @param file File of concatenated PEM-encoded CA Certificates for
- * Client Auth.
+ * Set File and Directory of concatenated PEM-encoded CA Certificates for Client Auth
+ * This directive sets the all-in-one file where you can assemble the Certificates of Certification Authorities (CA)
+ * whose clients you deal with. These are used for Client Authentication. Such a file is simply the concatenation of
+ * the various PEM-encoded Certificate files, in order of preference. This can be used alternatively and/or
+ * additionally to path.
+ * The files in this directory have to be PEM-encoded and are accessed through hash filenames. So usually you can't
+ * just place the Certificate files there: you also have to create symbolic links named hash-value.N. And you should
+ * always make sure this directory contains the appropriate symbolic links. Use the Makefile which comes with
+ * mod_ssl to accomplish this task.
+ *
+ * @param ctx Server or Client context to use.
+ * @param file File of concatenated PEM-encoded CA Certificates for Client Auth.
* @param path Directory of PEM-encoded CA Certificates for Client Auth.
+ *
* @return true if the operation was successful
+ *
* @throws Exception An error occurred
*/
- public static native boolean setCACertificate(long ctx, String file,
- String path)
- throws Exception;
+ public static native boolean setCACertificate(long ctx, String file, String path) throws Exception;
/**
- * Set Type of Client Certificate verification and Maximum depth of CA Certificates
- * in Client Certificate verification.
- *
- * This directive sets the Certificate verification level for the Client
- * Authentication. Notice that this directive can be used both in per-server
- * and per-directory context. In per-server context it applies to the client
- * authentication process used in the standard SSL handshake when a connection
- * is established. In per-directory context it forces an SSL renegotiation with
- * the reconfigured client verification level after the HTTP request was read
- * but before the HTTP response is sent.
- *
+ * Set Type of Client Certificate verification and Maximum depth of CA Certificates in Client Certificate
+ * verification.
+ * This directive sets the Certificate verification level for the Client Authentication. Notice that this directive
+ * can be used both in per-server and per-directory context. In per-server context it applies to the client
+ * authentication process used in the standard SSL handshake when a connection is established. In per-directory
+ * context it forces an SSL renegotiation with the reconfigured client verification level after the HTTP request was
+ * read but before the HTTP response is sent.
* The following levels are available for level:
+ *
*
* SSL_CVERIFY_NONE - No client Certificate is required at all
* SSL_CVERIFY_OPTIONAL - The client may present a valid Certificate
@@ -306,34 +307,30 @@
* SSL_CVERIFY_OPTIONAL_NO_CA - The client may present a valid Certificate
* but it need not to be (successfully) verifiable
*
+ *
*
- * The depth actually is the maximum number of intermediate certificate issuers,
- * i.e. the number of CA certificates which are max allowed to be followed while
- * verifying the client certificate. A depth of 0 means that self-signed client
- * certificates are accepted only, the default depth of 1 means the client
- * certificate can be self-signed or has to be signed by a CA which is directly
- * known to the server (i.e. the CA's certificate is under
+ * The depth actually is the maximum number of intermediate certificate issuers, i.e. the number of CA certificates
+ * which are max allowed to be followed while verifying the client certificate. A depth of 0 means that self-signed
+ * client certificates are accepted only, the default depth of 1 means the client certificate can be self-signed or
+ * has to be signed by a CA which is directly known to the server (i.e. the CA's certificate is under
* setCACertificatePath), etc.
- * @param ctx Server or Client context to use.
+ *
+ * @param ctx Server or Client context to use.
* @param level Type of Client Certificate verification.
- * @param depth Maximum depth of CA Certificates in Client Certificate
- * verification.
+ * @param depth Maximum depth of CA Certificates in Client Certificate verification.
*/
public static native void setVerify(long ctx, int level, int depth);
/**
- * When tc-native encounters a SNI extension in the TLS handshake it will
- * call this method to determine which OpenSSL SSLContext to use for the
- * connection.
- *
- * @param currentCtx The OpenSSL SSLContext that the handshake started to
- * use. This will be the default OpenSSL SSLContext for
- * the endpoint associated with the socket.
- * @param sniHostName The host name requested by the client
- *
- * @return The Java representation of the pointer to the OpenSSL SSLContext
- * to use for the given host or zero if no SSLContext could be
- * identified
+ * When tc-native encounters a SNI extension in the TLS handshake it will call this method to determine which
+ * OpenSSL SSLContext to use for the connection.
+ *
+ * @param currentCtx The OpenSSL SSLContext that the handshake started to use. This will be the default OpenSSL
+ * SSLContext for the endpoint associated with the socket.
+ * @param sniHostName The host name requested by the client
+ *
+ * @return The Java representation of the pointer to the OpenSSL SSLContext to use for the given host or zero if no
+ * SSLContext could be identified
*/
public static long sniCallBack(long currentCtx, String sniHostName) {
SNICallBack sniCallBack = sniCallBacks.get(Long.valueOf(currentCtx));
@@ -347,50 +344,47 @@
}
/**
- * A map of default SSL Contexts to SNICallBack instances (in Tomcat these
- * are instances of AprEndpoint) that will be used to determine the SSL
- * Context to use bases on the SNI host name. It is structured this way
- * since a Tomcat instance may have several TLS enabled endpoints that each
- * have different SSL Context mappings for the same host name.
+ * A map of default SSL Contexts to SNICallBack instances (in Tomcat these are instances of AprEndpoint) that will
+ * be used to determine the SSL Context to use bases on the SNI host name. It is structured this way since a Tomcat
+ * instance may have several TLS enabled endpoints that each have different SSL Context mappings for the same host
+ * name.
*/
private static final Map sniCallBacks = new ConcurrentHashMap<>();
/**
- * Interface implemented by components that will receive the call back to
- * select an OpenSSL SSLContext based on the host name requested by the
- * client.
+ * Interface implemented by components that will receive the call back to select an OpenSSL SSLContext based on the
+ * host name requested by the client.
*/
public interface SNICallBack {
/**
- * This callback is made during the TLS handshake when the client uses
- * the SNI extension to request a specific TLS host.
+ * This callback is made during the TLS handshake when the client uses the SNI extension to request a specific
+ * TLS host.
*
- * @param sniHostName The host name requested by the client - must be in
- * lower case
+ * @param sniHostName The host name requested by the client - must be in lower case
*
- * @return The Java representation of the pointer to the OpenSSL
- * SSLContext to use for the given host or zero if no SSLContext
- * could be identified
+ * @return The Java representation of the pointer to the OpenSSL SSLContext to use for the given host or zero if
+ * no SSLContext could be identified
*/
long getSslContext(String sniHostName);
}
/**
- * Allow to hook {@link CertificateVerifier} into the handshake processing.
- * This will call {@code SSL_CTX_set_cert_verify_callback} and so replace the default verification
- * callback used by openssl
- * @param ctx Server or Client context to use.
+ * Allow to hook {@link CertificateVerifier} into the handshake processing. This will call
+ * {@code SSL_CTX_set_cert_verify_callback} and so replace the default verification callback used by openssl
+ *
+ * @param ctx Server or Client context to use.
* @param verifier the verifier to call during handshake.
*/
public static native void setCertVerifyCallback(long ctx, CertificateVerifier verifier);
/**
* Set application layer protocol for application layer protocol negotiation extension
- * @param ctx Server context to use.
- * @param alpnProtos protocols in priority order
- * @param selectorFailureBehavior see {@link SSL#SSL_SELECTOR_FAILURE_NO_ADVERTISE}
- * and {@link SSL#SSL_SELECTOR_FAILURE_CHOOSE_MY_LAST_PROTOCOL}
+ *
+ * @param ctx Server context to use.
+ * @param alpnProtos protocols in priority order
+ * @param selectorFailureBehavior see {@link SSL#SSL_SELECTOR_FAILURE_NO_ADVERTISE} and
+ * {@link SSL#SSL_SELECTOR_FAILURE_CHOOSE_MY_LAST_PROTOCOL}
*/
public static native void setAlpnProtos(long ctx, String[] alpnProtos, int selectorFailureBehavior);
@@ -398,42 +392,45 @@
* Set the context within which session be reused (server side only)
* http://www.openssl.org/docs/ssl/SSL_CTX_set_session_id_context.html
*
- * @param ctx Server context to use.
- * @param sidCtx can be any kind of binary data, it is therefore possible to use e.g. the name
- * of the application and/or the hostname and/or service name
+ * @param ctx Server context to use.
+ * @param sidCtx can be any kind of binary data, it is therefore possible to use e.g. the name of the application
+ * and/or the hostname and/or service name
+ *
* @return {@code true} if success, {@code false} otherwise.
*/
public static native boolean setSessionIdContext(long ctx, byte[] sidCtx);
/**
- * Set CertificateRaw
- *
+ * Set CertificateRaw
* Use keystore a certificate and key to fill the BIOP
- * @param ctx Server or Client context to use.
- * @param cert Byte array with the certificate in DER encoding.
- * @param key Byte array with the Private Key file in PEM format.
+ *
+ * @param ctx Server or Client context to use.
+ * @param cert Byte array with the certificate in DER encoding.
+ * @param key Byte array with the Private Key file in PEM format.
* @param sslAidxRsa Certificate index SSL_AIDX_RSA or SSL_AIDX_DSA.
+ *
* @return {@code true} if success, {@code false} otherwise.
*/
public static native boolean setCertificateRaw(long ctx, byte[] cert, byte[] key, int sslAidxRsa);
/**
- * Add a certificate to the certificate chain. Certs should be added in
- * order starting with the issuer of the host certs and working up the
- * certificate chain to the CA.
- *
- *
+ * Add a certificate to the certificate chain. Certs should be added in order starting with the issuer of the host
+ * certs and working up the certificate chain to the CA.
* Use keystore a certificate chain to fill the BIOP
- * @param ctx Server or Client context to use.
+ *
+ * @param ctx Server or Client context to use.
* @param cert Byte array with the certificate in DER encoding.
+ *
* @return {@code true} if success, {@code false} otherwise.
*/
public static native boolean addChainCertificateRaw(long ctx, byte[] cert);
/**
* Add a CA certificate we accept as issuer for peer certs
- * @param ctx Server or Client context to use.
+ *
+ * @param ctx Server or Client context to use.
* @param cert Byte array with the certificate in DER encoding.
+ *
* @return {@code true} if success, {@code false} otherwise.
*/
public static native boolean addClientCACertificateRaw(long ctx, byte[] cert);
diff -Nru tomcat11-11.0.6/java/org/apache/tomcat/jni/Sockaddr.java tomcat11-11.0.15/java/org/apache/tomcat/jni/Sockaddr.java
--- tomcat11-11.0.6/java/org/apache/tomcat/jni/Sockaddr.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/tomcat/jni/Sockaddr.java 2025-12-02 16:54:08.000000000 +0000
@@ -17,10 +17,9 @@
package org.apache.tomcat.jni;
/**
- * Tomcat Native 1.2.33 and earlier won't initialise unless this class is
- * present. This dummy class ensures initialisation gets as far as being able to
- * check the version of the Tomcat Native library and reporting a version error
- * if 1.2.33 or earlier is present.
+ * Tomcat Native 1.2.33 and earlier won't initialise unless this class is present. This dummy class ensures
+ * initialisation gets as far as being able to check the version of the Tomcat Native library and reporting a version
+ * error if 1.2.33 or earlier is present.
*/
public class Sockaddr {
diff -Nru tomcat11-11.0.6/java/org/apache/tomcat/util/Diagnostics.java tomcat11-11.0.15/java/org/apache/tomcat/util/Diagnostics.java
--- tomcat11-11.0.6/java/org/apache/tomcat/util/Diagnostics.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/tomcat/util/Diagnostics.java 2025-12-02 16:54:08.000000000 +0000
@@ -76,34 +76,25 @@
private static final Log log = LogFactory.getLog(Diagnostics.class);
- private static final SimpleDateFormat timeformat =
- new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+ private static final SimpleDateFormat timeformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
/* Some platform MBeans */
- private static final ClassLoadingMXBean classLoadingMXBean =
- ManagementFactory.getClassLoadingMXBean();
- private static final CompilationMXBean compilationMXBean =
- ManagementFactory.getCompilationMXBean();
- private static final OperatingSystemMXBean operatingSystemMXBean =
- ManagementFactory.getOperatingSystemMXBean();
- private static final RuntimeMXBean runtimeMXBean =
- ManagementFactory.getRuntimeMXBean();
- private static final ThreadMXBean threadMXBean =
- ManagementFactory.getThreadMXBean();
+ private static final ClassLoadingMXBean classLoadingMXBean = ManagementFactory.getClassLoadingMXBean();
+ private static final CompilationMXBean compilationMXBean = ManagementFactory.getCompilationMXBean();
+ private static final OperatingSystemMXBean operatingSystemMXBean = ManagementFactory.getOperatingSystemMXBean();
+ private static final RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();
+ private static final ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
// XXX Not sure whether the following MBeans should better
// be retrieved on demand, i.e. whether they can change
// dynamically in the MBeanServer.
private static final PlatformLoggingMXBean loggingMXBean =
- ManagementFactory.getPlatformMXBean(PlatformLoggingMXBean.class);
- private static final MemoryMXBean memoryMXBean =
- ManagementFactory.getMemoryMXBean();
+ ManagementFactory.getPlatformMXBean(PlatformLoggingMXBean.class);
+ private static final MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
private static final List garbageCollectorMXBeans =
- ManagementFactory.getGarbageCollectorMXBeans();
- private static final List memoryManagerMXBeans =
- ManagementFactory.getMemoryManagerMXBeans();
- private static final List memoryPoolMXBeans =
- ManagementFactory.getMemoryPoolMXBeans();
+ ManagementFactory.getGarbageCollectorMXBeans();
+ private static final List memoryManagerMXBeans = ManagementFactory.getMemoryManagerMXBeans();
+ private static final List memoryPoolMXBeans = ManagementFactory.getMemoryPoolMXBeans();
/**
* Check whether thread contention monitoring is enabled.
@@ -146,8 +137,8 @@
threadMXBean.setThreadCpuTimeEnabled(enable);
boolean checkValue = threadMXBean.isThreadCpuTimeEnabled();
if (enable != checkValue) {
- log.error(sm.getString("diagnostics.setPropertyFail", "threadCpuTimeEnabled",
- Boolean.valueOf(enable), Boolean.valueOf(checkValue)));
+ log.error(sm.getString("diagnostics.setPropertyFail", "threadCpuTimeEnabled", Boolean.valueOf(enable),
+ Boolean.valueOf(checkValue)));
}
}
@@ -167,8 +158,8 @@
classLoadingMXBean.setVerbose(verbose);
boolean checkValue = classLoadingMXBean.isVerbose();
if (verbose != checkValue) {
- log.error(sm.getString("diagnostics.setPropertyFail", "verboseClassLoading",
- Boolean.valueOf(verbose), Boolean.valueOf(checkValue)));
+ log.error(sm.getString("diagnostics.setPropertyFail", "verboseClassLoading", Boolean.valueOf(verbose),
+ Boolean.valueOf(checkValue)));
}
}
@@ -176,15 +167,14 @@
* Set logger level
*
* @param loggerName the name of the logger
- * @param levelName the level to set
+ * @param levelName the level to set
*/
public static void setLoggerLevel(String loggerName, String levelName) {
loggingMXBean.setLoggerLevel(loggerName, levelName);
String checkValue = loggingMXBean.getLoggerLevel(loggerName);
if (!checkValue.equals(levelName)) {
String propertyName = "loggerLevel[" + loggerName + "]";
- log.error(sm.getString("diagnostics.setPropertyFail", propertyName,
- levelName, checkValue));
+ log.error(sm.getString("diagnostics.setPropertyFail", propertyName, levelName, checkValue));
}
}
@@ -197,8 +187,8 @@
memoryMXBean.setVerbose(verbose);
boolean checkValue = memoryMXBean.isVerbose();
if (verbose != checkValue) {
- log.error(sm.getString("diagnostics.setPropertyFail", "verboseGarbageCollection",
- Boolean.valueOf(verbose), Boolean.valueOf(checkValue)));
+ log.error(sm.getString("diagnostics.setPropertyFail", "verboseGarbageCollection", Boolean.valueOf(verbose),
+ Boolean.valueOf(checkValue)));
}
}
@@ -215,7 +205,7 @@
* @param name name of the MemoryPoolMXBean or "all"
*/
public static void resetPeakUsage(String name) {
- for (MemoryPoolMXBean mbean: memoryPoolMXBeans) {
+ for (MemoryPoolMXBean mbean : memoryPoolMXBeans) {
if (name.equals("all") || name.equals(mbean.getName())) {
mbean.resetPeakUsage();
}
@@ -225,12 +215,13 @@
/**
* Set usage threshold in MemoryPoolMXBean
*
- * @param name name of the MemoryPoolMXBean
+ * @param name name of the MemoryPoolMXBean
* @param threshold the threshold to set
+ *
* @return true if setting the threshold succeeded
*/
public static boolean setUsageThreshold(String name, long threshold) {
- for (MemoryPoolMXBean mbean: memoryPoolMXBeans) {
+ for (MemoryPoolMXBean mbean : memoryPoolMXBeans) {
if (name.equals(mbean.getName())) {
try {
mbean.setUsageThreshold(threshold);
@@ -247,12 +238,13 @@
/**
* Set collection usage threshold in MemoryPoolMXBean
*
- * @param name name of the MemoryPoolMXBean
+ * @param name name of the MemoryPoolMXBean
* @param threshold the collection threshold to set
+ *
* @return true if setting the threshold succeeded
*/
public static boolean setCollectionUsageThreshold(String name, long threshold) {
- for (MemoryPoolMXBean mbean: memoryPoolMXBeans) {
+ for (MemoryPoolMXBean mbean : memoryPoolMXBeans) {
if (name.equals(mbean.getName())) {
try {
mbean.setCollectionUsageThreshold(threshold);
@@ -270,6 +262,7 @@
* Formats the thread dump header for one thread.
*
* @param ti the ThreadInfo describing the thread
+ *
* @return the formatted thread dump header
*/
private static String getThreadDumpHeader(ThreadInfo ti) {
@@ -297,6 +290,7 @@
* Formats the thread dump for one thread.
*
* @param ti the ThreadInfo describing the thread
+ *
* @return the formatted thread dump
*/
private static String getThreadDump(ThreadInfo ti) {
@@ -318,14 +312,15 @@
if (ti.getLockName() != null) {
sb.append(INDENT2 + "- waiting on (a ").append(ti.getLockName()).append(")");
if (ti.getLockOwnerName() != null) {
- sb.append(" owned by ").append(ti.getLockOwnerName()).append(" Id=").append(ti.getLockOwnerId());
+ sb.append(" owned by ").append(ti.getLockOwnerName()).append(" Id=")
+ .append(ti.getLockOwnerId());
}
sb.append(CRLF);
}
start = false;
}
if (monitorDepths[i] != null) {
- MonitorInfo mi = (MonitorInfo)monitorDepths[i];
+ MonitorInfo mi = (MonitorInfo) monitorDepths[i];
sb.append(INDENT2 + "- locked (a ").append(mi.toString()).append(")").append(" index ");
sb.append(mi.getLockedStackDepth()).append(" frame ").append(mi.getLockedStackFrame().toString());
sb.append(CRLF);
@@ -339,6 +334,7 @@
* Formats the thread dump for a list of threads.
*
* @param tinfos the ThreadInfo array describing the thread list
+ *
* @return the formatted thread dump
*/
private static String getThreadDump(ThreadInfo[] tinfos) {
@@ -351,17 +347,14 @@
}
/**
- * Check if any threads are deadlocked. If any, print
- * the thread dump for those threads.
+ * Check if any threads are deadlocked. If any, print the thread dump for those threads.
*
- * @return a deadlock message and the formatted thread dump
- * of the deadlocked threads
+ * @return a deadlock message and the formatted thread dump of the deadlocked threads
*/
public static String findDeadlock() {
long[] ids = threadMXBean.findDeadlockedThreads();
if (ids != null) {
- ThreadInfo[] tinfos = threadMXBean.getThreadInfo(threadMXBean.findDeadlockedThreads(),
- true, true);
+ ThreadInfo[] tinfos = threadMXBean.getThreadInfo(threadMXBean.findDeadlockedThreads(), true, true);
if (tinfos != null) {
return sm.getString("diagnostics.deadlockFound") + CRLF + getThreadDump(tinfos);
}
@@ -370,8 +363,7 @@
}
/**
- * Retrieves a formatted JVM thread dump.
- * The default StringManager will be used.
+ * Retrieves a formatted JVM thread dump. The default StringManager will be used.
*
* @return the formatted JVM thread dump
*/
@@ -380,29 +372,27 @@
}
/**
- * Retrieves a formatted JVM thread dump.
- * The given list of locales will be used
- * to retrieve a StringManager.
+ * Retrieves a formatted JVM thread dump. The given list of locales will be used to retrieve a StringManager.
*
* @param requestedLocales list of locales to use
+ *
* @return the formatted JVM thread dump
*/
public static String getThreadDump(Enumeration requestedLocales) {
- return getThreadDump(
- StringManager.getManager(PACKAGE, requestedLocales));
+ return getThreadDump(StringManager.getManager(PACKAGE, requestedLocales));
}
/**
- * Retrieve a JVM thread dump formatted
- * using the given StringManager.
+ * Retrieve a JVM thread dump formatted using the given StringManager.
*
* @param requestedSm the StringManager to use
+ *
* @return the formatted JVM thread dump
*/
public static String getThreadDump(StringManager requestedSm) {
StringBuilder sb = new StringBuilder();
- synchronized(timeformat) {
+ synchronized (timeformat) {
sb.append(timeformat.format(new Date()));
}
sb.append(CRLF);
@@ -428,8 +418,10 @@
/**
* Format contents of a MemoryUsage object.
- * @param name a text prefix used in formatting
+ *
+ * @param name a text prefix used in formatting
* @param usage the MemoryUsage object to format
+ *
* @return the formatted contents
*/
private static String formatMemoryUsage(String name, MemoryUsage usage) {
@@ -445,8 +437,7 @@
}
/**
- * Retrieves a formatted JVM information text.
- * The default StringManager will be used.
+ * Retrieves a formatted JVM information text. The default StringManager will be used.
*
* @return the formatted JVM information text
*/
@@ -455,11 +446,10 @@
}
/**
- * Retrieves a formatted JVM information text.
- * The given list of locales will be used
- * to retrieve a StringManager.
+ * Retrieves a formatted JVM information text. The given list of locales will be used to retrieve a StringManager.
*
* @param requestedLocales list of locales to use
+ *
* @return the formatted JVM information text
*/
public static String getVMInfo(Enumeration requestedLocales) {
@@ -467,17 +457,17 @@
}
/**
- * Retrieve a JVM information text formatted
- * using the given StringManager.
+ * Retrieve a JVM information text formatted using the given StringManager.
*
* @param requestedSm the StringManager to use
+ *
* @return the formatted JVM information text
*/
@SuppressWarnings("deprecation")
public static String getVMInfo(StringManager requestedSm) {
StringBuilder sb = new StringBuilder();
- synchronized(timeformat) {
+ synchronized (timeformat) {
sb.append(timeformat.format(new Date()));
}
sb.append(CRLF);
@@ -502,19 +492,25 @@
sb.append(INDENT1 + "name: ").append(operatingSystemMXBean.getName()).append(CRLF);
sb.append(INDENT1 + "version: ").append(operatingSystemMXBean.getVersion()).append(CRLF);
sb.append(INDENT1 + "architecture: ").append(operatingSystemMXBean.getArch()).append(CRLF);
- sb.append(INDENT1 + "availableProcessors: ").append(operatingSystemMXBean.getAvailableProcessors()).append(CRLF);
+ sb.append(INDENT1 + "availableProcessors: ").append(operatingSystemMXBean.getAvailableProcessors())
+ .append(CRLF);
sb.append(INDENT1 + "systemLoadAverage: ").append(operatingSystemMXBean.getSystemLoadAverage()).append(CRLF);
sb.append(CRLF);
sb.append(requestedSm.getString("diagnostics.vmInfoThreadMxBean"));
sb.append(":" + CRLF);
- sb.append(INDENT1 + "isCurrentThreadCpuTimeSupported: ").append(threadMXBean.isCurrentThreadCpuTimeSupported()).append(CRLF);
+ sb.append(INDENT1 + "isCurrentThreadCpuTimeSupported: ").append(threadMXBean.isCurrentThreadCpuTimeSupported())
+ .append(CRLF);
sb.append(INDENT1 + "isThreadCpuTimeSupported: ").append(threadMXBean.isThreadCpuTimeSupported()).append(CRLF);
sb.append(INDENT1 + "isThreadCpuTimeEnabled: ").append(threadMXBean.isThreadCpuTimeEnabled()).append(CRLF);
- sb.append(INDENT1 + "isObjectMonitorUsageSupported: ").append(threadMXBean.isObjectMonitorUsageSupported()).append(CRLF);
- sb.append(INDENT1 + "isSynchronizerUsageSupported: ").append(threadMXBean.isSynchronizerUsageSupported()).append(CRLF);
- sb.append(INDENT1 + "isThreadContentionMonitoringSupported: ").append(threadMXBean.isThreadContentionMonitoringSupported()).append(CRLF);
- sb.append(INDENT1 + "isThreadContentionMonitoringEnabled: ").append(threadMXBean.isThreadContentionMonitoringEnabled()).append(CRLF);
+ sb.append(INDENT1 + "isObjectMonitorUsageSupported: ").append(threadMXBean.isObjectMonitorUsageSupported())
+ .append(CRLF);
+ sb.append(INDENT1 + "isSynchronizerUsageSupported: ").append(threadMXBean.isSynchronizerUsageSupported())
+ .append(CRLF);
+ sb.append(INDENT1 + "isThreadContentionMonitoringSupported: ")
+ .append(threadMXBean.isThreadContentionMonitoringSupported()).append(CRLF);
+ sb.append(INDENT1 + "isThreadContentionMonitoringEnabled: ")
+ .append(threadMXBean.isThreadContentionMonitoringEnabled()).append(CRLF);
sb.append(CRLF);
sb.append(requestedSm.getString("diagnostics.vmInfoThreadCounts"));
@@ -527,7 +523,7 @@
sb.append(requestedSm.getString("diagnostics.vmInfoStartup"));
sb.append(":" + CRLF);
- for (String arg: runtimeMXBean.getInputArguments()) {
+ for (String arg : runtimeMXBean.getInputArguments()) {
sb.append(INDENT1).append(arg).append(CRLF);
}
sb.append(CRLF);
@@ -553,30 +549,31 @@
sb.append(":" + CRLF);
sb.append(INDENT1 + "name: ").append(compilationMXBean.getName()).append(CRLF);
sb.append(INDENT1 + "totalCompilationTime: ").append(compilationMXBean.getTotalCompilationTime()).append(CRLF);
- sb.append(INDENT1 + "isCompilationTimeMonitoringSupported: ").append(compilationMXBean.isCompilationTimeMonitoringSupported()).append(CRLF);
+ sb.append(INDENT1 + "isCompilationTimeMonitoringSupported: ")
+ .append(compilationMXBean.isCompilationTimeMonitoringSupported()).append(CRLF);
sb.append(CRLF);
- for (MemoryManagerMXBean mbean: memoryManagerMXBeans) {
+ for (MemoryManagerMXBean mbean : memoryManagerMXBeans) {
sb.append(requestedSm.getString("diagnostics.vmInfoMemoryManagers", mbean.getName()));
sb.append(":" + CRLF);
sb.append(INDENT1 + "isValid: ").append(mbean.isValid()).append(CRLF);
sb.append(INDENT1 + "mbean.getMemoryPoolNames: " + CRLF);
String[] names = mbean.getMemoryPoolNames();
Arrays.sort(names);
- for (String name: names) {
+ for (String name : names) {
sb.append(INDENT2).append(name).append(CRLF);
}
sb.append(CRLF);
}
- for (GarbageCollectorMXBean mbean: garbageCollectorMXBeans) {
+ for (GarbageCollectorMXBean mbean : garbageCollectorMXBeans) {
sb.append(requestedSm.getString("diagnostics.vmInfoGarbageCollectors", mbean.getName()));
sb.append(":" + CRLF);
sb.append(INDENT1 + "isValid: ").append(mbean.isValid()).append(CRLF);
sb.append(INDENT1 + "mbean.getMemoryPoolNames: " + CRLF);
String[] names = mbean.getMemoryPoolNames();
Arrays.sort(names);
- for (String name: names) {
+ for (String name : names) {
sb.append(INDENT2).append(name).append(CRLF);
}
sb.append(INDENT1 + "getCollectionCount: ").append(mbean.getCollectionCount()).append(CRLF);
@@ -587,12 +584,13 @@
sb.append(requestedSm.getString("diagnostics.vmInfoMemory"));
sb.append(":" + CRLF);
sb.append(INDENT1 + "isVerbose: ").append(memoryMXBean.isVerbose()).append(CRLF);
- sb.append(INDENT1 + "getObjectPendingFinalizationCount: ").append(memoryMXBean.getObjectPendingFinalizationCount()).append(CRLF);
+ sb.append(INDENT1 + "getObjectPendingFinalizationCount: ")
+ .append(memoryMXBean.getObjectPendingFinalizationCount()).append(CRLF);
sb.append(formatMemoryUsage("heap", memoryMXBean.getHeapMemoryUsage()));
sb.append(formatMemoryUsage("non-heap", memoryMXBean.getNonHeapMemoryUsage()));
sb.append(CRLF);
- for (MemoryPoolMXBean mbean: memoryPoolMXBeans) {
+ for (MemoryPoolMXBean mbean : memoryPoolMXBeans) {
sb.append(requestedSm.getString("diagnostics.vmInfoMemoryPools", mbean.getName()));
sb.append(":" + CRLF);
sb.append(INDENT1 + "isValid: ").append(mbean.isValid()).append(CRLF);
@@ -600,7 +598,7 @@
sb.append(INDENT1 + "mbean.getMemoryManagerNames: " + CRLF);
String[] names = mbean.getMemoryManagerNames();
Arrays.sort(names);
- for (String name: names) {
+ for (String name : names) {
sb.append(INDENT2).append(name).append(CRLF);
}
sb.append(INDENT1 + "isUsageThresholdSupported: ").append(mbean.isUsageThresholdSupported()).append(CRLF);
@@ -609,9 +607,11 @@
} catch (UnsupportedOperationException ex) {
// IGNORE
}
- sb.append(INDENT1 + "isCollectionUsageThresholdSupported: ").append(mbean.isCollectionUsageThresholdSupported()).append(CRLF);
+ sb.append(INDENT1 + "isCollectionUsageThresholdSupported: ")
+ .append(mbean.isCollectionUsageThresholdSupported()).append(CRLF);
try {
- sb.append(INDENT1 + "isCollectionUsageThresholdExceeded: ").append(mbean.isCollectionUsageThresholdExceeded()).append(CRLF);
+ sb.append(INDENT1 + "isCollectionUsageThresholdExceeded: ")
+ .append(mbean.isCollectionUsageThresholdExceeded()).append(CRLF);
} catch (UnsupportedOperationException ex) {
// IGNORE
}
@@ -626,12 +626,14 @@
// IGNORE
}
try {
- sb.append(INDENT1 + "getCollectionUsageThreshold: ").append(mbean.getCollectionUsageThreshold()).append(CRLF);
+ sb.append(INDENT1 + "getCollectionUsageThreshold: ").append(mbean.getCollectionUsageThreshold())
+ .append(CRLF);
} catch (UnsupportedOperationException ex) {
// IGNORE
}
try {
- sb.append(INDENT1 + "getCollectionUsageThresholdCount: ").append(mbean.getCollectionUsageThresholdCount()).append(CRLF);
+ sb.append(INDENT1 + "getCollectionUsageThresholdCount: ")
+ .append(mbean.getCollectionUsageThresholdCount()).append(CRLF);
} catch (UnsupportedOperationException ex) {
// IGNORE
}
@@ -647,7 +649,7 @@
Map props = runtimeMXBean.getSystemProperties();
ArrayList keys = new ArrayList<>(props.keySet());
Collections.sort(keys);
- for (String prop: keys) {
+ for (String prop : keys) {
sb.append(INDENT1).append(prop).append(": ").append(props.get(prop)).append(CRLF);
}
sb.append(CRLF);
@@ -656,7 +658,7 @@
sb.append(":" + CRLF);
List loggers = loggingMXBean.getLoggerNames();
Collections.sort(loggers);
- for (String logger: loggers) {
+ for (String logger : loggers) {
sb.append(INDENT1).append(logger).append(": level=").append(loggingMXBean.getLoggerLevel(logger));
sb.append(", parent=").append(loggingMXBean.getParentLoggerName(logger)).append(CRLF);
}
diff -Nru tomcat11-11.0.6/java/org/apache/tomcat/util/ExceptionUtils.java tomcat11-11.0.15/java/org/apache/tomcat/util/ExceptionUtils.java
--- tomcat11-11.0.6/java/org/apache/tomcat/util/ExceptionUtils.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/tomcat/util/ExceptionUtils.java 2025-12-02 16:54:08.000000000 +0000
@@ -25,8 +25,8 @@
public class ExceptionUtils {
/**
- * Checks whether the supplied Throwable is one that needs to be
- * rethrown and swallows all others.
+ * Checks whether the supplied Throwable is one that needs to be rethrown and swallows all others.
+ *
* @param t the Throwable to check
*/
public static void handleThrowable(Throwable t) {
@@ -41,11 +41,11 @@
}
/**
- * Checks whether the supplied Throwable is an instance of
- * InvocationTargetException and returns the throwable that is
- * wrapped by it, if there is any.
+ * Checks whether the supplied Throwable is an instance of InvocationTargetException and returns the
+ * throwable that is wrapped by it, if there is any.
*
* @param t the Throwable to check
+ *
* @return t or t.getCause()
*/
public static Throwable unwrapInvocationTargetException(Throwable t) {
@@ -57,10 +57,9 @@
/**
- * NO-OP method provided to enable simple preloading of this class. Since
- * the class is used extensively in error handling, it is prudent to
- * preload it to avoid any failure to load this class masking the true
- * problem during error handling.
+ * NO-OP method provided to enable simple preloading of this class. Since the class is used extensively in error
+ * handling, it is prudent to preload it to avoid any failure to load this class masking the true problem during
+ * error handling.
*/
public static void preload() {
// NO-OP
diff -Nru tomcat11-11.0.6/java/org/apache/tomcat/util/IntrospectionUtils.java tomcat11-11.0.15/java/org/apache/tomcat/util/IntrospectionUtils.java
--- tomcat11-11.0.6/java/org/apache/tomcat/util/IntrospectionUtils.java 2025-04-01 15:26:55.000000000 +0000
+++ tomcat11-11.0.15/java/org/apache/tomcat/util/IntrospectionUtils.java 2025-12-02 16:54:08.000000000 +0000
@@ -37,29 +37,28 @@
private static final StringManager sm = StringManager.getManager(IntrospectionUtils.class);
/**
- * Find a method with the right name If found, call the method ( if param is
- * int or boolean we'll convert value to the right type before) - that means
- * you can have setDebug(1).
- * @param o The object to set a property on
- * @param name The property name
+ * Find a method with the right name If found, call the method ( if param is int or boolean we'll convert value to
+ * the right type before) - that means you can have setDebug(1).
+ *
+ * @param o The object to set a property on
+ * @param name The property name
* @param value The property value
+ *
* @return true if operation was successful
*/
public static boolean setProperty(Object o, String name, String value) {
return setProperty(o, name, value, true, null);
}
- public static boolean setProperty(Object o, String name, String value,
- boolean invokeSetProperty) {
+ public static boolean setProperty(Object o, String name, String value, boolean invokeSetProperty) {
return setProperty(o, name, value, invokeSetProperty, null);
}
@SuppressWarnings("null") // setPropertyMethodVoid is not null when used
- public static boolean setProperty(Object o, String name, String value,
- boolean invokeSetProperty, StringBuilder actualMethod) {
+ public static boolean setProperty(Object o, String name, String value, boolean invokeSetProperty,
+ StringBuilder actualMethod) {
if (log.isTraceEnabled()) {
- log.trace("IntrospectionUtils: setProperty(" +
- o.getClass() + " " + name + "=" + value + ")");
+ log.trace("IntrospectionUtils: setProperty(" + o.getClass() + " " + name + "=" + value + ")");
}
if (actualMethod == null && XReflectionIntrospectionUtils.isEnabled()) {
@@ -76,8 +75,8 @@
// First, the ideal case - a setFoo( String ) method
for (Method item : methods) {
Class>[] paramT = item.getParameterTypes();
- if (setter.equals(item.getName()) && paramT.length == 1
- && "java.lang.String".equals(paramT[0].getName())) {
+ if (setter.equals(item.getName()) && paramT.length == 1 &&
+ "java.lang.String".equals(paramT[0].getName())) {
item.invoke(o, value);
if (actualMethod != null) {
actualMethod.append(item.getName()).append("(\"").append(escape(value)).append("\")");
@@ -89,8 +88,7 @@
// Try a setFoo ( int ) or ( boolean )
for (Method method : methods) {
boolean ok = true;
- if (setter.equals(method.getName())
- && method.getParameterTypes().length == 1) {
+ if (setter.equals(method.getName()) && method.getParameterTypes().length == 1) {
// match - find the type and invoke it
Class> paramType = method.getParameterTypes()[0];
@@ -106,9 +104,11 @@
}
if (actualMethod != null) {
if ("java.lang.Integer".equals(paramType.getName())) {
- actualMethod.append(method.getName()).append("(Integer.valueOf(\"").append(value).append("\"))");
+ actualMethod.append(method.getName()).append("(Integer.valueOf(\"").append(value)
+ .append("\"))");
} else {
- actualMethod.append(method.getName()).append("(Integer.parseInt(\"").append(value).append("\"))");
+ actualMethod.append(method.getName()).append("(Integer.parseInt(\"").append(value)
+ .append("\"))");
}
}
// Try a setFoo ( long )
@@ -121,9 +121,11 @@
}
if (actualMethod != null) {
if ("java.lang.Long".equals(paramType.getName())) {
- actualMethod.append(method.getName()).append("(Long.valueOf(\"").append(value).append("\"))");
+ actualMethod.append(method.getName()).append("(Long.valueOf(\"").append(value)
+ .append("\"))");
} else {
- actualMethod.append(method.getName()).append("(Long.parseLong(\"").append(value).append("\"))");
+ actualMethod.append(method.getName()).append("(Long.parseLong(\"").append(value)
+ .append("\"))");
}
}
// Try a setFoo ( boolean )
@@ -132,9 +134,11 @@
params[0] = Boolean.valueOf(value);
if (actualMethod != null) {
if ("java.lang.Boolean".equals(paramType.getName())) {
- actualMethod.append(method.getName()).append("(Boolean.valueOf(\"").append(value).append("\"))");
+ actualMethod.append(method.getName()).append("(Boolean.valueOf(\"").append(value)
+ .append("\"))");
} else {
- actualMethod.append(method.getName()).append("(Boolean.parseBoolean(\"").append(value).append("\"))");
+ actualMethod.append(method.getName()).append("(Boolean.parseBoolean(\"")
+ .append(value).append("\"))");
}
}
// Try a setFoo ( InetAddress )
@@ -144,19 +148,19 @@
params[0] = InetAddress.getByName(value);
} catch (UnknownHostException exc) {
if (log.isDebugEnabled()) {
- log.debug(sm.getString("introspectionUtils.hostResolutionFail", value));
+ log.debug(sm.getString("introspectionUtils.hostResolutionFail", value), exc);
}
ok = false;
}
if (actualMethod != null) {
- actualMethod.append(method.getName()).append("(InetAddress.getByName(\"").append(value).append("\"))");
+ actualMethod.append(method.getName()).append("(InetAddress.getByName(\"").append(value)
+ .append("\"))");
}
// Unknown type
}
default -> {
if (log.isTraceEnabled()) {
- log.trace("IntrospectionUtils: Unknown type " +
- paramType.getName());
+ log.trace("IntrospectionUtils: Unknown type " + paramType.getName());
}
}
}
@@ -179,25 +183,24 @@
}
// Ok, no setXXX found, try a setProperty("name", "value")
- if (invokeSetProperty && (setPropertyMethodBool != null ||
- setPropertyMethodVoid != null)) {
+ if (invokeSetProperty && (setPropertyMethodBool != null || setPropertyMethodVoid != null)) {
if (actualMethod != null) {
- actualMethod.append("setProperty(\"").append(name).append("\", \"").append(escape(value)).append("\")");
+ actualMethod.append("setProperty(\"").append(name).append("\", \"").append(escape(value))
+ .append("\")");
}
Object[] params = new Object[2];
params[0] = name;
params[1] = value;
if (setPropertyMethodBool != null) {
try {
- return ((Boolean) setPropertyMethodBool.invoke(o,
- params)).booleanValue();
- }catch (IllegalArgumentException biae) {
- //the boolean method had the wrong
- //parameter types. let's try the other
- if (setPropertyMethodVoid!=null) {
+ return ((Boolean) setPropertyMethodBool.invoke(o, params)).booleanValue();
+ } catch (IllegalArgumentException biae) {
+ // the boolean method had the wrong
+ // parameter types. let's try the other
+ if (setPropertyMethodVoid != null) {
setPropertyMethodVoid.invoke(o, params);
return true;
- }else {
+ } else {
throw biae;
}
}
@@ -217,8 +220,8 @@
}
/**
- * @param s
- * the input string
+ * @param s the input string
+ *
* @return escaped string, per Java rule
*/
public static String escape(String s) {
@@ -292,36 +295,29 @@
}
/**
- * Replaces ${NAME} in the value with the value of the property 'NAME'.
- * Replaces ${NAME:DEFAULT} with the value of the property 'NAME:DEFAULT',
- * if the property 'NAME:DEFAULT' is not set,
- * the expression is replaced with the value of the property 'NAME',
- * if the property 'NAME' is not set,
- * the expression is replaced with 'DEFAULT'.
- * If the property is not set and there is no default the value will be
- * returned unmodified.
+ * Replaces ${NAME} in the value with the value of the property 'NAME'. Replaces ${NAME:DEFAULT} with the value of
+ * the property 'NAME:DEFAULT', if the property 'NAME:DEFAULT' is not set, the expression is replaced with the value
+ * of the property 'NAME', if the property 'NAME' is not set, the expression is replaced with 'DEFAULT'. If the
+ * property is not set and there is no default the value will be returned unmodified.
*
- * @param value The value
- * @param staticProp Replacement properties
+ * @param value The value
+ * @param staticProp Replacement properties
* @param dynamicProp Replacement properties
- * @param classLoader Class loader associated with the code requesting the
- * property
+ * @param classLoader Class loader associated with the code requesting the property
*
* @return the replacement value
*/
- public static String replaceProperties(String value,
- Hashtable