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

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


The following commit(s) were added to refs/heads/11.0.x by this push:
     new 88bd14598d Review "Deserialize the key of a backup request with the 
loaders ..."
88bd14598d is described below

commit 88bd14598dfb192e0dba3463870780e0402e9341
Author: Mark Thomas <[email protected]>
AuthorDate: Fri Oct 23 12:20:32 2026 +0100

    Review "Deserialize the key of a backup request with the loaders ..."
    
    Fix test
---
 .../tribes/tipis/TestAbstractReplicatedMap.java    | 76 +++++++++-------------
 .../tomcat/unittest/TesterSerializableKey.java     | 42 ++++++++++++
 2 files changed, 74 insertions(+), 44 deletions(-)

diff --git 
a/test/org/apache/catalina/tribes/tipis/TestAbstractReplicatedMap.java 
b/test/org/apache/catalina/tribes/tipis/TestAbstractReplicatedMap.java
index 8e85d5863f..6dd8a069c6 100644
--- a/test/org/apache/catalina/tribes/tipis/TestAbstractReplicatedMap.java
+++ b/test/org/apache/catalina/tribes/tipis/TestAbstractReplicatedMap.java
@@ -20,6 +20,8 @@ import java.io.IOException;
 import java.io.ObjectOutputStream;
 import java.io.Serial;
 import java.io.Serializable;
+import java.net.URL;
+import java.net.URLClassLoader;
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.Iterator;
@@ -40,6 +42,7 @@ import org.apache.catalina.tribes.group.GroupChannel;
 import org.apache.catalina.tribes.io.XByteBuffer;
 import org.apache.catalina.tribes.membership.MemberImpl;
 import org.apache.catalina.tribes.tipis.AbstractReplicatedMap.MapMessage;
+import org.apache.tomcat.unittest.TesterSerializableKey;
 
 public class TestAbstractReplicatedMap {
 
@@ -387,28 +390,6 @@ public class TestAbstractReplicatedMap {
         Assert.assertFalse(map.containsValue("missing"));
     }
 
-    private static final class SerialKey implements Serializable {
-
-        @Serial
-        private static final long serialVersionUID = 1L;
-
-        private final String id;
-
-        SerialKey(String id) {
-            this.id = id;
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            return o instanceof SerialKey && id.equals(((SerialKey) o).id);
-        }
-
-        @Override
-        public int hashCode() {
-            return id.hashCode();
-        }
-    }
-
     /*
      * A received backup request carries its key only in serialized form. The 
reply must deserialize that key with the
      * loaders of the map, like the other receive paths do, and must fail the 
request without throwing when the key
@@ -417,28 +398,35 @@ public class TestAbstractReplicatedMap {
      */
     @Test
     public void testBackupRequestDeserializesKeyOfReceivedMessage() throws 
Exception {
-        LazyReplicatedMap<Object,String> map = new LazyReplicatedMap<>((key, 
value) -> {
-            // Not made primary here
-        }, new TestChannel(), 1000, "TestAbstractReplicatedMap", null);
-        map.put(new SerialKey("key"), "value");
-        Member sender = new MemberImpl("localhost", 4017, -1);
-
-        // Round trip over the serialization to get a message with the key 
data but no live key
-        byte[] wire = XByteBuffer.serialize(new 
MapMessage("TestAbstractReplicatedMap".getBytes(StandardCharsets.UTF_8),
-                MapMessage.MSG_RETRIEVE_BACKUP, false, new SerialKey("key"), 
null, null, null, null));
-
-        MapMessage received = (MapMessage) XByteBuffer.deserialize(wire);
-        Serializable reply = map.replyRequest(received, sender);
-        Assert.assertTrue(reply instanceof MapMessage);
-        Assert.assertEquals("value", ((MapMessage) reply).getValue());
-
-        // Corrupt the class name inside the serialized key, so it cannot be 
deserialized
-        byte[] corrupted = wire.clone();
-        int at = indexOf(corrupted, 
"SerialKey".getBytes(StandardCharsets.US_ASCII));
-        Assert.assertTrue(at > 0);
-        corrupted[at] = 'X';
-        MapMessage broken = (MapMessage) XByteBuffer.deserialize(corrupted);
-        Assert.assertNull(map.replyRequest(broken, sender));
+        URL testClasses = 
TesterSerializableKey.class.getProtectionDomain().getCodeSource().getLocation();
+        try (URLClassLoader externalLoader =
+                new URLClassLoader(new URL[] { testClasses }, 
ClassLoader.getPlatformClassLoader())) {
+            Class<?> keyClass = 
externalLoader.loadClass(TesterSerializableKey.class.getName());
+            Serializable key = (Serializable) 
keyClass.getConstructor(String.class).newInstance("key");
+            LazyReplicatedMap<Object,String> map = new 
LazyReplicatedMap<>((mapKey, value) -> {
+                // Not made primary here
+            }, new TestChannel(), 1000, "TestAbstractReplicatedMap", new 
ClassLoader[] { externalLoader });
+            map.put(key, "value");
+            Member sender = new MemberImpl("localhost", 4017, -1);
+
+            // Round trip over the serialization to get a message with the key 
data but no live key
+            byte[] wire = XByteBuffer.serialize(new MapMessage(
+                    
"TestAbstractReplicatedMap".getBytes(StandardCharsets.UTF_8), 
MapMessage.MSG_RETRIEVE_BACKUP, false,
+                    key, null, null, null, null));
+
+            MapMessage received = (MapMessage) XByteBuffer.deserialize(wire);
+            Serializable reply = map.replyRequest(received, sender);
+            Assert.assertTrue(reply instanceof MapMessage);
+            Assert.assertEquals("value", ((MapMessage) reply).getValue());
+
+            // Corrupt the class name inside the serialized key, so it cannot 
be deserialized
+            byte[] corrupted = wire.clone();
+            int at = indexOf(corrupted, 
"TesterSerializableKey".getBytes(StandardCharsets.US_ASCII));
+            Assert.assertTrue(at > 0);
+            corrupted[at] = 'X';
+            MapMessage broken = (MapMessage) 
XByteBuffer.deserialize(corrupted);
+            Assert.assertNull(map.replyRequest(broken, sender));
+        }
     }
 
     private static int indexOf(byte[] data, byte[] pattern) {
diff --git a/test/org/apache/tomcat/unittest/TesterSerializableKey.java 
b/test/org/apache/tomcat/unittest/TesterSerializableKey.java
new file mode 100644
index 0000000000..ccc956d325
--- /dev/null
+++ b/test/org/apache/tomcat/unittest/TesterSerializableKey.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomcat.unittest;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+public class TesterSerializableKey implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    private final String id;
+
+    public TesterSerializableKey(String id) {
+        this.id = id;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        return o instanceof TesterSerializableKey && 
id.equals(((TesterSerializableKey) o).id);
+    }
+
+    @Override
+    public int hashCode() {
+        return id.hashCode();
+    }
+}


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

Reply via email to