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

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

commit f9c86fc0a76ff5dab4be157840af0c0a6a8fa2a4
Author: opencode <[email protected]>
AuthorDate: Mon Oct 12 14:29:42 2026 +0200

    Fix TIME_MON and TIME_WDAY values in the rewrite valve
    
    ResolverImpl.resolve() returned the raw java.util.Calendar fields for
    TIME_MON (MONTH, zero-based) and TIME_WDAY (DAY_OF_WEEK, one-based with
    Sunday first) instead of the mod_rewrite values documented for the
    valve: TIME_MON must be 1-12 and TIME_WDAY must be 0-6 with Sunday
    being 0. Add the required offset in both cases, pin the numbering with
    updated tests that also cover multi-token substitution parsing, and add
    a changelog entry for this user-visible value change.
---
 .../apache/catalina/valves/rewrite/ResolverImpl.java  |  6 ++++--
 .../catalina/valves/rewrite/TestRewriteValve.java     | 19 +++++++++++++++++++
 webapps/docs/changelog.xml                            |  8 ++++++++
 3 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/java/org/apache/catalina/valves/rewrite/ResolverImpl.java 
b/java/org/apache/catalina/valves/rewrite/ResolverImpl.java
index 0e096d5fd1..60af913bd4 100644
--- a/java/org/apache/catalina/valves/rewrite/ResolverImpl.java
+++ b/java/org/apache/catalina/valves/rewrite/ResolverImpl.java
@@ -134,12 +134,14 @@ public class ResolverImpl extends Resolver {
             case "REQUEST_FILENAME" -> request.getPathTranslated();
             case "HTTPS" -> request.isSecure() ? "on" : "off";
             case "TIME_YEAR" -> 
String.valueOf(Calendar.getInstance().get(Calendar.YEAR));
-            case "TIME_MON" -> 
String.valueOf(Calendar.getInstance().get(Calendar.MONTH));
+            // Like mod_rewrite, TIME_MON is 1-12 and TIME_WDAY is 0-6 with 
Sunday first,
+            // unlike the zero-based Calendar.MONTH and one-based Sunday-first 
Calendar.DAY_OF_WEEK
+            case "TIME_MON" -> 
String.valueOf(Calendar.getInstance().get(Calendar.MONTH) + 1);
             case "TIME_DAY" -> 
String.valueOf(Calendar.getInstance().get(Calendar.DAY_OF_MONTH));
             case "TIME_HOUR" -> 
String.valueOf(Calendar.getInstance().get(Calendar.HOUR_OF_DAY));
             case "TIME_MIN" -> 
String.valueOf(Calendar.getInstance().get(Calendar.MINUTE));
             case "TIME_SEC" -> 
String.valueOf(Calendar.getInstance().get(Calendar.SECOND));
-            case "TIME_WDAY" -> 
String.valueOf(Calendar.getInstance().get(Calendar.DAY_OF_WEEK));
+            case "TIME_WDAY" -> 
String.valueOf(Calendar.getInstance().get(Calendar.DAY_OF_WEEK) - 1);
             case "TIME" -> FastHttpDateFormat.getCurrentDate();
             default -> null;
         };
diff --git a/test/org/apache/catalina/valves/rewrite/TestRewriteValve.java 
b/test/org/apache/catalina/valves/rewrite/TestRewriteValve.java
index 3f1047e17a..a61186d6b7 100644
--- a/test/org/apache/catalina/valves/rewrite/TestRewriteValve.java
+++ b/test/org/apache/catalina/valves/rewrite/TestRewriteValve.java
@@ -22,6 +22,7 @@ import java.io.PrintWriter;
 import java.net.HttpURLConnection;
 import java.nio.charset.Charset;
 import java.nio.charset.StandardCharsets;
+import java.time.LocalDate;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
@@ -340,6 +341,24 @@ public class TestRewriteValve extends TomcatBaseTest {
                 "/c/b/x.html/something");
     }
 
+    @Test
+    public void testRewriteTimeMonModRewriteNumbering() throws Exception {
+        // mod_rewrite numbering: 1-12; two tokens in one rule also cover
+        // concatenation parsing
+        String expected = String.valueOf(LocalDate.now().getMonthValue());
+        doTestRewrite("RewriteRule ^/c/x$ - 
[E=X-Test:%{TIME_MON}-%{TIME_MON}]",
+                "/c/x", "/c/x", null, expected + "-" + expected);
+    }
+
+    @Test
+    public void testRewriteTimeWdayModRewriteNumbering() throws Exception {
+        // mod_rewrite numbering: 0-6, Sunday being 0; the literal between the
+        // tokens also covers concatenation parsing
+        String expected = 
String.valueOf(LocalDate.now().getDayOfWeek().getValue() % 7);
+        doTestRewrite("RewriteRule ^/c/x$ - 
[E=X-Test:%{TIME_WDAY}TUE%{TIME_WDAY}]",
+                "/c/x", "/c/x", null, expected + "TUE" + expected);
+    }
+
     @Test
     public void testRewriteMissingCurlyBraceOnVar() throws Exception {
         try {
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index ba3508bf2b..d56b875cc3 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -1998,6 +1998,14 @@
         restarts. The limits are now stored in configuration order and the
         first matching pattern in configuration order is applied. (remm)
       </fix>
+      <fix>
+        Correct the values of the <code>TIME_MON</code> and
+        <code>TIME_WDAY</code> server variables in the rewrite valve, which
+        exposed the raw <code>java.util.Calendar</code> fields (month 0-11,
+        day of week 1-7 with Sunday first) instead of the documented
+        mod_rewrite values (month 1-12, day of week 0-6 with Sunday being 0).
+        (remm)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="Coyote">


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to