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 454c099089 Avoid some scenarios of expiration of never expire sessions
454c099089 is described below

commit 454c0990893e189923b4361a4d51eddededde92f
Author: remm <[email protected]>
AuthorDate: Fri Aug 28 11:44:55 2026 +0200

    Avoid some scenarios of expiration of never expire sessions
    
    Tests written by OpenCode.
---
 .../apache/catalina/session/DataSourceStore.java   |  1 +
 java/org/apache/catalina/session/StoreBase.java    |  3 +-
 .../org/apache/catalina/session/TestFileStore.java | 34 ++++++++++++++++++++++
 3 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/java/org/apache/catalina/session/DataSourceStore.java 
b/java/org/apache/catalina/session/DataSourceStore.java
index 168f863d81..c3dae78c41 100644
--- a/java/org/apache/catalina/session/DataSourceStore.java
+++ b/java/org/apache/catalina/session/DataSourceStore.java
@@ -74,6 +74,7 @@ public class DataSourceStore extends JDBCStore {
     private String[] keys(boolean expiredOnly) throws IOException {
         String sqlTmp = "SELECT " + sessionIdCol + " FROM " + sessionTable + " 
WHERE " + sessionAppCol + " = ?";
         if (expiredOnly) {
+            sqlTmp += " AND " + sessionMaxInactiveCol + " >= 0";
             sqlTmp += " AND (" + sessionLastAccessedCol + " + " + 
sessionMaxInactiveCol + " * 1000 < ?)";
         }
         final String keysSql = sqlTmp;
diff --git a/java/org/apache/catalina/session/StoreBase.java 
b/java/org/apache/catalina/session/StoreBase.java
index eaa4ab56b5..ee5a7d9dc5 100644
--- a/java/org/apache/catalina/session/StoreBase.java
+++ b/java/org/apache/catalina/session/StoreBase.java
@@ -160,7 +160,8 @@ public abstract class StoreBase extends LifecycleBase 
implements Store {
                     continue;
                 }
                 int timeIdle = (int) ((timeNow - 
session.getThisAccessedTime()) / 1000L);
-                if (timeIdle < session.getMaxInactiveInterval()) {
+                int maxInactive = session.getMaxInactiveInterval();
+                if (maxInactive < 0 || timeIdle < maxInactive) {
                     continue;
                 }
                 if (manager.getContext().getLogger().isTraceEnabled()) {
diff --git a/test/org/apache/catalina/session/TestFileStore.java 
b/test/org/apache/catalina/session/TestFileStore.java
index e2109a9dda..67a878a0fb 100644
--- a/test/org/apache/catalina/session/TestFileStore.java
+++ b/test/org/apache/catalina/session/TestFileStore.java
@@ -102,6 +102,40 @@ public class TestFileStore {
         Assert.assertEquals(1, fileStore.getSize());
     }
 
+    @Test
+    public void processExpiresNeverExpiringSession() throws Exception {
+        // Use a separate store and directory so this test does not
+        // interfere with the fixtures used by the other tests.
+        FileStore expireStore = new FileStore();
+        expireStore.setManager(manager);
+        expireStore.setDirectory(new File(dir, "expire").getAbsolutePath());
+        expireStore.start();
+        try {
+            // A session that is idle longer than its max inactive interval
+            // but that must never expire.
+            StandardSession neverExpiring = (StandardSession) 
manager.createSession("never-expiring");
+            neverExpiring.setManager(manager);
+            neverExpiring.setMaxInactiveInterval(-1);
+            neverExpiring.setCreationTime(System.currentTimeMillis() - 
60_000L);
+            expireStore.save(neverExpiring);
+
+            // A session that is idle longer than its max inactive interval
+            // and that must be expired.
+            StandardSession expiring = (StandardSession) 
manager.createSession("expiring");
+            expiring.setManager(manager);
+            expiring.setMaxInactiveInterval(1);
+            expiring.setCreationTime(System.currentTimeMillis() - 60_000L);
+            expireStore.save(expiring);
+
+            expireStore.processExpires();
+
+            Assert.assertArrayEquals(new String[] { "never-expiring" }, 
expireStore.keys());
+        } finally {
+            expireStore.clear();
+            expireStore.stop();
+        }
+    }
+
     @Test
     public void pathTraversalSessionId() throws Exception {
         File storageDir = dir.getAbsoluteFile();


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

Reply via email to