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

joerghoh pushed a commit to branch SLING-13360
in repository 
https://gitbox.apache.org/repos/asf/sling-org-apache-sling-engine.git

commit 77d4499f718c3c2d39cd3ad7da2bf859a3bcdc70
Author: Joerg Hoh <[email protected]>
AuthorDate: Tue Sep 22 13:38:08 2026 +0200

    SLING-13360 all log directives should handle CR/LF escaping
---
 .../sling/engine/impl/log/CustomLogFormat.java     | 11 +++---
 .../sling/engine/impl/log/CustomLogFormatTest.java | 40 ++++++++++++++++++++++
 2 files changed, 47 insertions(+), 4 deletions(-)

diff --git 
a/src/main/java/org/apache/sling/engine/impl/log/CustomLogFormat.java 
b/src/main/java/org/apache/sling/engine/impl/log/CustomLogFormat.java
index 8d353b5..e67b119 100644
--- a/src/main/java/org/apache/sling/engine/impl/log/CustomLogFormat.java
+++ b/src/main/java/org/apache/sling/engine/impl/log/CustomLogFormat.java
@@ -547,7 +547,7 @@ class CustomLogFormat {
         }
 
         protected String getValue(RequestLoggerRequest request) {
-            return Thread.currentThread().getName();
+            return escape(Thread.currentThread().getName());
         }
 
         protected String getValue(RequestLoggerResponse response) {
@@ -561,7 +561,7 @@ class CustomLogFormat {
         }
 
         protected String getValue(RequestLoggerRequest request) {
-            return request.getParameter(this.getParParam());
+            return escape(request.getParameter(this.getParParam()));
         }
 
         protected String getValue(RequestLoggerResponse response) {
@@ -705,7 +705,7 @@ class CustomLogFormat {
         }
 
         protected String getValue(RequestLoggerRequest request) {
-            return request.getRemoteHost();
+            return escape(request.getRemoteHost());
         }
 
         protected String getValue(RequestLoggerResponse response) {
@@ -763,7 +763,10 @@ class CustomLogFormat {
         protected String getValue(RequestLoggerRequest request) {
             final Object resourcePath = 
request.getAttribute(RequestData.REQUEST_RESOURCE_PATH_ATTR);
             if (resourcePath instanceof String) {
-                return (String) resourcePath;
+                // the resolved resource path is derived from the decoded 
request
+                // path and may contain control characters (e.g. for 
non-existing
+                // resources), so it must be escaped like other request data
+                return escape((String) resourcePath);
             }
             return null;
         }
diff --git 
a/src/test/java/org/apache/sling/engine/impl/log/CustomLogFormatTest.java 
b/src/test/java/org/apache/sling/engine/impl/log/CustomLogFormatTest.java
index 1553e88..9738cae 100644
--- a/src/test/java/org/apache/sling/engine/impl/log/CustomLogFormatTest.java
+++ b/src/test/java/org/apache/sling/engine/impl/log/CustomLogFormatTest.java
@@ -19,6 +19,8 @@
 package org.apache.sling.engine.impl.log;
 
 import junit.framework.TestCase;
+import org.apache.sling.engine.impl.request.RequestData;
+import org.mockito.Mockito;
 
 /**
  * The <code>CustomLogFormatTest</code> class tests the
@@ -69,4 +71,42 @@ public class CustomLogFormatTest extends TestCase {
                 "This is a special character \\u1234",
                 CustomLogFormat.HeaderParameter.escape("This is a special 
character \u1234"));
     }
+
+    public void testRequestParameterValueEscaped() {
+        final RequestLoggerRequest request = 
Mockito.mock(RequestLoggerRequest.class);
+        Mockito.when(request.getParameter("ref"))
+                .thenReturn("x\r\n192.168.1.1 - admin \"POST /system/console 
HTTP/1.1\" 200");
+
+        final CustomLogFormat.ParamParameter param = new 
CustomLogFormat.ParamParameter("ref");
+        final String value = param.getValue(request);
+
+        // no raw CR/LF may end up in the log line
+        assertFalse(value.contains("\r"));
+        assertFalse(value.contains("\n"));
+        assertEquals("x\\r\\n192.168.1.1 - admin \\\"POST /system/console 
HTTP/1.1\\\" 200", value);
+    }
+
+    public void testContentPathEscaped() {
+        final RequestLoggerRequest request = 
Mockito.mock(RequestLoggerRequest.class);
+        
Mockito.when(request.getAttribute(RequestData.REQUEST_RESOURCE_PATH_ATTR))
+                .thenReturn("/content/foo\r\nFORGED LINE");
+
+        final CustomLogFormat.ContentPathParameter param = new 
CustomLogFormat.ContentPathParameter();
+        final String value = param.getValue(request);
+
+        assertFalse(value.contains("\r"));
+        assertFalse(value.contains("\n"));
+        assertEquals("/content/foo\\r\\nFORGED LINE", value);
+    }
+
+    public void testRemoteHostEscaped() {
+        final RequestLoggerRequest request = 
Mockito.mock(RequestLoggerRequest.class);
+        
Mockito.when(request.getRemoteHost()).thenReturn("evil\nhost.example.com");
+
+        final CustomLogFormat.RemoteHostParameter param = new 
CustomLogFormat.RemoteHostParameter();
+        final String value = param.getValue(request);
+
+        assertFalse(value.contains("\n"));
+        assertEquals("evil\\nhost.example.com", value);
+    }
 }

Reply via email to