This is an automated email from the ASF dual-hosted git repository. rmaucher pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit 0b61c3087e31c2801423e7a4bf853fef4f0551b2 Author: opencode <[email protected]> AuthorDate: Mon Oct 12 11:00:44 2026 +0200 Fix NPE in the extended access log servlet context element The x-A(...) element of the ExtendedAccessLogValve dereferenced the context of the logged request unconditionally. A request can map to no context at all, which is the normal outcome for which CoyoteAdapter logs at the Host or Engine level, so a valve attached there and using this element threw a NullPointerException for such requests and the whole log entry was dropped. On a couple of the logging paths, such as the OPTIONS * one, the NPE was not even caught around the logAccess call and could escape the adapter. The element now logs the standard dash placeholder when the request has no mapped context, which matches how it reports a missing attribute and how the sibling elements report missing values. A regression test covers an element fed a request without a context. --- .../catalina/valves/ExtendedAccessLogValve.java | 7 +++- .../valves/TestExtendedAccessLogValveElements.java | 45 ++++++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/java/org/apache/catalina/valves/ExtendedAccessLogValve.java b/java/org/apache/catalina/valves/ExtendedAccessLogValve.java index cb3919125a..d5c28c982f 100644 --- a/java/org/apache/catalina/valves/ExtendedAccessLogValve.java +++ b/java/org/apache/catalina/valves/ExtendedAccessLogValve.java @@ -32,6 +32,7 @@ import java.util.TimeZone; import jakarta.servlet.http.Cookie; import jakarta.servlet.http.HttpSession; +import org.apache.catalina.Context; import org.apache.catalina.connector.Request; import org.apache.catalina.connector.Response; import org.apache.catalina.util.ServerInfo; @@ -262,7 +263,11 @@ public class ExtendedAccessLogValve extends AccessLogValve { @Override public void addElement(CharArrayWriter buf, Request request, Response response, long time) { - wrap(request.getContext().getServletContext().getAttribute(attribute), buf); + // The request may not have mapped to a context, for example when a + // valve attached to a Host or Engine logs requests that matched no + // context + Context context = request.getContext(); + wrap(context == null ? null : context.getServletContext().getAttribute(attribute), buf); } } diff --git a/test/org/apache/catalina/valves/TestExtendedAccessLogValveElements.java b/test/org/apache/catalina/valves/TestExtendedAccessLogValveElements.java new file mode 100644 index 0000000000..355c69fa04 --- /dev/null +++ b/test/org/apache/catalina/valves/TestExtendedAccessLogValveElements.java @@ -0,0 +1,45 @@ +/* + * 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.catalina.valves; + +import java.io.CharArrayWriter; + +import org.junit.Assert; +import org.junit.Test; + +import org.apache.catalina.connector.Request; + +public class TestExtendedAccessLogValveElements { + + /* + * A valve attached to a Host or Engine also logs requests that did not map to any context, for which + * Request.getContext() is null. The servlet context attribute element must use the standard placeholder rather + * than throwing, since an exception would cause the entire log entry to be dropped. + */ + @Test + public void testServletContextElementWithoutMappedContext() { + ExtendedAccessLogValve.ServletContextElement element = new ExtendedAccessLogValve.ServletContextElement( + "attributeName"); + Request request = new Request(null, new org.apache.coyote.Request()); + Assert.assertNull(request.getContext()); + + CharArrayWriter buf = new CharArrayWriter(); + element.addElement(buf, request, null, 0); + + Assert.assertEquals("-", buf.toString()); + } +} --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
