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

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


The following commit(s) were added to refs/heads/9.0.x by this push:
     new fe06ae8a71 Align the rewrite conditions ornext processing with 
mod_rewrite
fe06ae8a71 is described below

commit fe06ae8a71997061596f54189dae1b1b5da75430
Author: remm <[email protected]>
AuthorDate: Thu Jun 4 21:17:10 2026 +0200

    Align the rewrite conditions ornext processing with mod_rewrite
    
    This now follows a sequential condition evaluation.
    Test case co-authored with OpenCode.
---
 .../catalina/valves/rewrite/RewriteRule.java       |  8 ++++--
 .../catalina/valves/rewrite/RewriteValve.java      |  5 ----
 .../catalina/valves/rewrite/TestRewriteValve.java  | 30 ++++++++++++++++++++++
 webapps/docs/changelog.xml                         |  5 ++++
 4 files changed, 41 insertions(+), 7 deletions(-)

diff --git a/java/org/apache/catalina/valves/rewrite/RewriteRule.java 
b/java/org/apache/catalina/valves/rewrite/RewriteRule.java
index d323895c68..49c0353636 100644
--- a/java/org/apache/catalina/valves/rewrite/RewriteRule.java
+++ b/java/org/apache/catalina/valves/rewrite/RewriteRule.java
@@ -159,8 +159,12 @@ public class RewriteRule {
                     if (lastMatcher2 != null) {
                         lastMatcher = lastMatcher2;
                     }
-                    while (pos < conditions.length && 
conditions[pos].isOrnext()) {
-                        pos++;
+                    if (conditions[pos].isOrnext()) {
+                        // Skip until the next condition not covered by the OR
+                        // The rule immediately after the OR is covered
+                        do {
+                            pos++;
+                        } while (pos < conditions.length && 
conditions[pos].isOrnext());
                     }
                 } else if (!conditions[pos].isOrnext()) {
                     done = true;
diff --git a/java/org/apache/catalina/valves/rewrite/RewriteValve.java 
b/java/org/apache/catalina/valves/rewrite/RewriteValve.java
index 3a284b5995..d1d3a2fc4e 100644
--- a/java/org/apache/catalina/valves/rewrite/RewriteValve.java
+++ b/java/org/apache/catalina/valves/rewrite/RewriteValve.java
@@ -280,11 +280,6 @@ public class RewriteValve extends ValveBase {
                         containerLog.trace("Add rule with pattern " + 
rule.getPatternString() + " and substitution " +
                                 rule.getSubstitutionString());
                     }
-                    for (int i = (conditions.size() - 1); i > 0; i--) {
-                        if (conditions.get(i - 1).isOrnext()) {
-                            conditions.get(i).setOrnext(true);
-                        }
-                    }
                     for (RewriteCond condition : conditions) {
                         if (containerLog.isTraceEnabled()) {
                             containerLog.trace("Add condition " + 
condition.getCondPattern() + " test " +
diff --git a/test/org/apache/catalina/valves/rewrite/TestRewriteValve.java 
b/test/org/apache/catalina/valves/rewrite/TestRewriteValve.java
index e2f9c904c4..aecc854259 100644
--- a/test/org/apache/catalina/valves/rewrite/TestRewriteValve.java
+++ b/test/org/apache/catalina/valves/rewrite/TestRewriteValve.java
@@ -1114,4 +1114,34 @@ public class TestRewriteValve extends TomcatBaseTest {
                 URLDecoder.decode(expectedSegment, "UTF-8")));
         Assert.assertTrue(body, body.contains("REQUEST-QUERY-STRING: " + 
expectedQueryString));
     }
+
+    @Test
+    public void testOrCondDoesNotSkipNonOrCond() throws Exception {
+        Tomcat tomcat = getTomcatInstance();
+
+        Context ctx = getProgrammaticRootContext();
+
+        RewriteValve rewriteValve = new RewriteValve();
+        ctx.getPipeline().addValve(rewriteValve);
+
+        rewriteValve.setConfiguration(
+                "RewriteCond %{HTTP_HOST} localhost [OR]\n" +
+                        "RewriteCond %{HTTP_HOST} 127.0.0.1\n" +
+                        "RewriteCond %{REQUEST_URI} ^/admin\n" +
+                "RewriteRule ^(.*) /blocked$1 [R]");
+
+        Tomcat.addServlet(ctx, "snoop", new SnoopServlet());
+        ctx.addServletMappingDecoded("/other", "snoop");
+
+        tomcat.start();
+
+        ByteChunk res = new ByteChunk();
+        int rc = getUrl("http://localhost:"; + getPort() + "/other", res, 
false);
+
+        Assert.assertEquals(HttpServletResponse.SC_OK, rc);
+
+        res.setCharset(StandardCharsets.UTF_8);
+        String body = res.toString();
+        Assert.assertTrue(body, body.contains("REQUEST-URI: /other"));
+    }
 }
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 4603593a61..b5c6df2031 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -239,6 +239,11 @@
         Fix various instances of double decoding of URL patterns configured
         either programmatically or in web.xml. (remm/markt)
       </fix>
+      <fix>
+        Align the rewrite conditions <code>ornext</code> flag processing with
+        mod_rewrite, which follows a purely sequential evaluation strategy.
+        (remm)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="Coyote">


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

Reply via email to