This is an automated email from the ASF dual-hosted git repository.

rmaucher pushed a commit to branch 10.1.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git

commit e06af7c472a43491098500ab9e4fb220354466ea
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 966ca23835..df538ff508 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;
@@ -250,7 +251,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]

Reply via email to