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

markt-asf pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/main by this push:
     new fb1a647ff8 Fix regression in handling of chain rules
fb1a647ff8 is described below

commit fb1a647ff83d080dc4af278a0ada149ece871915
Author: Mark Thomas <[email protected]>
AuthorDate: Mon Jul 20 14:50:50 2026 +0100

    Fix regression in handling of chain rules
    
    Test cases written using Claude / Opus 4.8
---
 .../catalina/valves/rewrite/RewriteValve.java      | 14 +++++------
 .../catalina/valves/rewrite/TestRewriteValve.java  | 28 ++++++++++++++++++++++
 2 files changed, 34 insertions(+), 8 deletions(-)

diff --git a/java/org/apache/catalina/valves/rewrite/RewriteValve.java 
b/java/org/apache/catalina/valves/rewrite/RewriteValve.java
index 8c839254df..a5f269f2dc 100644
--- a/java/org/apache/catalina/valves/rewrite/RewriteValve.java
+++ b/java/org/apache/catalina/valves/rewrite/RewriteValve.java
@@ -535,15 +535,13 @@ public class RewriteValve extends ValveBase {
 
                 // - chain (skip remaining chained rules if this one does not 
match)
                 if (rule.isChain() && newtest == null) {
-                    int skip = 0;
-                    for (int j = i + 1; j < rules.length; j++) {
-                        if (!rules[j].isChain()) {
-                            break;
-                        } else {
-                            skip++;
-                        }
+                    // Skip the remaining rules in the chain, including the
+                    // terminal rule that does not have the chain flag set.
+                    int j = i + 1;
+                    while (j < rules.length && rules[j].isChain()) {
+                        j++;
                     }
-                    i += skip;
+                    i = j;
                     continue;
                 }
                 // - last (stop rewriting here)
diff --git a/test/org/apache/catalina/valves/rewrite/TestRewriteValve.java 
b/test/org/apache/catalina/valves/rewrite/TestRewriteValve.java
index 9cfb79964c..ecf67047d5 100644
--- a/test/org/apache/catalina/valves/rewrite/TestRewriteValve.java
+++ b/test/org/apache/catalina/valves/rewrite/TestRewriteValve.java
@@ -88,6 +88,34 @@ public class TestRewriteValve extends TomcatBaseTest {
         doTestRewrite("RewriteRule ^/b/(.*) /b/../a/$1", "/b/%255A", 
"/b/../a/%255A");
     }
 
+    @Test
+    public void testChainMatch() throws Exception {
+        // The first rule matches so the chained (second) rule is applied to 
the result
+        doTestRewrite("RewriteRule ^/a(.*) /b$1 [C]\n" +
+                "RewriteRule ^/b(.*) /c$1", "/a/x", "/c/x");
+    }
+
+    @Test
+    public void testChainHeadNoMatch() throws Exception {
+        // The first rule does not match so the whole chain, including the
+        // terminal rule that would otherwise match, must be skipped. If the
+        // terminal rule were incorrectly applied the request would be 
rewritten
+        // to /W/x.
+        doTestRewrite("RewriteRule ^/never(.*) /c$1 [C]\n" +
+                "RewriteRule ^/c(.*) /W$1", "/c/x", "/c/x");
+    }
+
+    @Test
+    public void testChainMiddleNoMatch() throws Exception {
+        // The first rule matches but the second (chained) rule does not, so 
the
+        // rest of the chain, including the terminal rule, must be skipped and
+        // the result of the first rule is retained. If the terminal rule were
+        // incorrectly applied the request would be rewritten to /W/y.
+        doTestRewrite("RewriteRule ^/a(.*) /c$1 [C]\n" +
+                "RewriteRule ^/nomatch(.*) /x$1 [C]\n" +
+                "RewriteRule ^/c(.*) /W$1", "/a/y", "/c/y");
+    }
+
     // BZ 57863
     @Test
     public void testRewriteMap01() throws Exception {


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

Reply via email to