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

markt-asf 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 db919ff991 Ensure RealmBase finds all matching extension based 
constraints
db919ff991 is described below

commit db919ff9912b4d61d1b702a1342b8bde39270031
Author: Mark Thomas <[email protected]>
AuthorDate: Wed Apr 22 12:05:25 2026 +0100

    Ensure RealmBase finds all matching extension based constraints
---
 java/org/apache/catalina/realm/RealmBase.java      | 18 +++--
 test/org/apache/catalina/realm/TestRealmBase.java  | 82 ++++++++++++++++++++++
 test/org/apache/tomcat/unittest/TesterRequest.java | 10 +++
 webapps/docs/changelog.xml                         |  4 ++
 4 files changed, 104 insertions(+), 10 deletions(-)

diff --git a/java/org/apache/catalina/realm/RealmBase.java 
b/java/org/apache/catalina/realm/RealmBase.java
index ae9108f2ef..bb3771f231 100644
--- a/java/org/apache/catalina/realm/RealmBase.java
+++ b/java/org/apache/catalina/realm/RealmBase.java
@@ -666,8 +666,6 @@ public abstract class RealmBase extends LifecycleMBeanBase 
implements Realm {
                         constraints[i].included(uri, method));
             }
 
-            boolean matched = false;
-            int pos = -1;
             for (int j = 0; j < collection.length; j++) {
                 String[] patterns = collection[j].findPatterns();
 
@@ -677,6 +675,7 @@ public abstract class RealmBase extends LifecycleMBeanBase 
implements Realm {
                     continue;
                 }
 
+                boolean matched = false;
                 for (int k = 0; k < patterns.length && !matched; k++) {
                     String pattern = patterns[k];
                     if (pattern.startsWith("*.")) {
@@ -686,19 +685,18 @@ public abstract class RealmBase extends 
LifecycleMBeanBase implements Realm {
                                 uri.length() - dot == pattern.length() - 1) {
                             if (pattern.regionMatches(1, uri, dot, 
uri.length() - dot)) {
                                 matched = true;
-                                pos = j;
                             }
                         }
                     }
                 }
-            }
-            if (matched) {
-                found = true;
-                if (collection[pos].findMethod(method)) {
-                    if (results == null) {
-                        results = new ArrayList<>();
+                if (matched) {
+                    found = true;
+                    if (collection[j].findMethod(method)) {
+                        if (results == null) {
+                            results = new ArrayList<>();
+                        }
+                        results.add(constraints[i]);
                     }
-                    results.add(constraints[i]);
                 }
             }
         }
diff --git a/test/org/apache/catalina/realm/TestRealmBase.java 
b/test/org/apache/catalina/realm/TestRealmBase.java
index d49676e42e..06d00b81ff 100644
--- a/test/org/apache/catalina/realm/TestRealmBase.java
+++ b/test/org/apache/catalina/realm/TestRealmBase.java
@@ -790,4 +790,86 @@ public class TestRealmBase {
         Assert.assertFalse(mapRealm.hasResourcePermission(
                 request, response, constraintsDelete, null));
     }
+
+
+    @Test
+    public void testUncoveredMethods() throws IOException {
+        // Create a constraint for ROLE1
+        SecurityConstraint constraint = new SecurityConstraint();
+        constraint.addAuthRole(ROLE1);
+        // Add a collection for GET
+        SecurityCollection getCollection = new SecurityCollection();
+        getCollection.addMethod(Method.GET);
+        getCollection.addPatternDecoded("*.html");
+        constraint.addCollection(getCollection);
+        // Add a collection for POST
+        SecurityCollection postCollection = new SecurityCollection();
+        postCollection.addMethod(Method.POST);
+        postCollection.addPatternDecoded("*.html");
+        constraint.addCollection(postCollection);
+
+        TesterMapRealm mapRealm = new TesterMapRealm();
+
+        // Set up the mock request and response
+        TesterRequest request = new TesterRequest();
+        Response response = new TesterResponse();
+        Context context = request.getContext();
+        context.addSecurityRole(ROLE1);
+        context.addSecurityRole(ROLE2);
+        request.getMappingData().context = context;
+
+        // Create the principals
+        List<String> userRoles1 = new ArrayList<>();
+        userRoles1.add(ROLE1);
+        GenericPrincipal gp1 = new GenericPrincipal(USER1, userRoles1);
+
+        List<String> userRoles2 = new ArrayList<>();
+        userRoles2.add(ROLE2);
+        GenericPrincipal gp2 = new GenericPrincipal(USER2, userRoles2);
+
+        List<String> userRoles99 = new ArrayList<>();
+        GenericPrincipal gp99 = new GenericPrincipal(USER99, userRoles99);
+
+        // Add the constraint to the context
+        context.addConstraint(constraint);
+
+
+        // Only user1 should be able to perform a GET
+        request.setMethod(Method.GET);
+
+        SecurityConstraint[] constraintsGet =
+                mapRealm.findSecurityConstraints(request, context);
+
+        request.setUserPrincipal(null);
+        Assert.assertFalse(mapRealm.hasResourcePermission(
+                request, response, constraintsGet, null));
+        request.setUserPrincipal(gp1);
+        Assert.assertTrue(mapRealm.hasResourcePermission(
+                request, response, constraintsGet, null));
+        request.setUserPrincipal(gp2);
+        Assert.assertFalse(mapRealm.hasResourcePermission(
+                request, response, constraintsGet, null));
+        request.setUserPrincipal(gp99);
+        Assert.assertFalse(mapRealm.hasResourcePermission(
+                request, response, constraintsGet, null));
+
+        // Only user1 should be able to perform a POST
+        request.setMethod(Method.POST);
+
+        SecurityConstraint[] constraintsPost =
+                mapRealm.findSecurityConstraints(request, context);
+
+        request.setUserPrincipal(null);
+        Assert.assertFalse(mapRealm.hasResourcePermission(
+                request, response, constraintsPost, null));
+        request.setUserPrincipal(gp1);
+        Assert.assertTrue(mapRealm.hasResourcePermission(
+                request, response, constraintsPost, null));
+        request.setUserPrincipal(gp2);
+        Assert.assertFalse(mapRealm.hasResourcePermission(
+                request, response, constraintsPost, null));
+        request.setUserPrincipal(gp99);
+        Assert.assertFalse(mapRealm.hasResourcePermission(
+                request, response, constraintsPost, null));
+    }
 }
diff --git a/test/org/apache/tomcat/unittest/TesterRequest.java 
b/test/org/apache/tomcat/unittest/TesterRequest.java
index 8de33c7e9b..7635ef6d7d 100644
--- a/test/org/apache/tomcat/unittest/TesterRequest.java
+++ b/test/org/apache/tomcat/unittest/TesterRequest.java
@@ -31,6 +31,7 @@ import javax.servlet.SessionTrackingMode;
 import org.apache.catalina.Context;
 import org.apache.catalina.connector.Request;
 import org.apache.catalina.session.StandardSession;
+import org.apache.tomcat.util.buf.MessageBytes;
 
 public class TesterRequest extends Request {
 
@@ -81,6 +82,15 @@ public class TesterRequest extends Request {
         return "/level1/level2/foo.html";
     }
 
+
+    @Override
+    public MessageBytes getRequestPathMB() {
+        MessageBytes result = MessageBytes.newInstance();
+        result.setString(getRequestURI());
+        return result;
+    }
+
+
     @Override
     public String getDecodedRequestURI() {
         // Decoding not required
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 73ccc8c9e3..ab18831560 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -172,6 +172,10 @@
       <fix>
         Correct the handling of invalid users with DIGEST authentication. 
(markt)
       </fix>
+      <fix>
+        Ensure <code>RealmBase</code> finds all matching extension based
+        security constraints. (markt)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="Coyote">


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

Reply via email to