You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@seata.apache.org by wa...@apache.org on 2026/09/28 02:12:16 UTC

(incubator-seata) branch 2.x updated: refactor: align class name matching (#8232)

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

WangzJi pushed a commit to branch 2.x
in repository https://gitbox.apache.org/repos/asf/incubator-seata.git


The following commit(s) were added to refs/heads/2.x by this push:
     new ed41078f65 refactor: align class name matching (#8232)
ed41078f65 is described below

commit ed41078f65bcfe0dce644345f3b69ff8ce3e4784
Author: jimin <sl...@163.com>
AuthorDate: Mon Sep 28 10:12:12 2026 +0800

    refactor: align class name matching (#8232)
---
 .../raft/serializer/CustomDeserializer.java        | 27 ++++-------
 .../raft/serializer/JacksonSerializerTest.java     | 52 ++++++++++++++++++++++
 2 files changed, 60 insertions(+), 19 deletions(-)

diff --git a/server/src/main/java/org/apache/seata/server/cluster/raft/serializer/CustomDeserializer.java b/server/src/main/java/org/apache/seata/server/cluster/raft/serializer/CustomDeserializer.java
index f27730e365..1c9788cd39 100644
--- a/server/src/main/java/org/apache/seata/server/cluster/raft/serializer/CustomDeserializer.java
+++ b/server/src/main/java/org/apache/seata/server/cluster/raft/serializer/CustomDeserializer.java
@@ -23,8 +23,6 @@ import org.apache.seata.common.exception.ErrorCode;
 import org.apache.seata.common.exception.SeataRuntimeException;
 
 import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
 
 public class CustomDeserializer extends JsonDeserializer<Class<?>> {
 
@@ -32,28 +30,19 @@ public class CustomDeserializer extends JsonDeserializer<Class<?>> {
 
     String currentPackage = "org.apache.seata.server";
 
-    private static final List<String> PERMIT_PACKAGES = new ArrayList<>();
-
-    static {
-        PERMIT_PACKAGES.add("org.apache.seata");
-        // The storage structure of vgroup is a map.
-        PERMIT_PACKAGES.add("java.util.HashMap");
-    }
-
     @Override
     public Class<?> deserialize(JsonParser jsonParser, DeserializationContext deserializationContext)
             throws IOException {
         String className = jsonParser.getValueAsString();
-        if (className.startsWith(oldPackage)) {
-            className = className.replaceFirst(oldPackage, currentPackage);
+        if (className.startsWith(oldPackage + ".")) {
+            className = currentPackage + className.substring(oldPackage.length());
         }
-        for (String permitPackage : PERMIT_PACKAGES) {
-            if (className.startsWith(permitPackage)) {
-                try {
-                    return Class.forName(className);
-                } catch (ClassNotFoundException e) {
-                    throw new RuntimeException(e.getMessage(), e);
-                }
+        // The storage structure of vgroup is a HashMap.
+        if (className.startsWith("org.apache.seata.") || "java.util.HashMap".equals(className)) {
+            try {
+                return Class.forName(className);
+            } catch (ClassNotFoundException e) {
+                throw new RuntimeException(e.getMessage(), e);
             }
         }
         throw new SeataRuntimeException(
diff --git a/server/src/test/java/org/apache/seata/server/cluster/raft/serializer/JacksonSerializerTest.java b/server/src/test/java/org/apache/seata/server/cluster/raft/serializer/JacksonSerializerTest.java
index 067537c451..37674b3f11 100644
--- a/server/src/test/java/org/apache/seata/server/cluster/raft/serializer/JacksonSerializerTest.java
+++ b/server/src/test/java/org/apache/seata/server/cluster/raft/serializer/JacksonSerializerTest.java
@@ -16,11 +16,18 @@
  */
 package org.apache.seata.server.cluster.raft.serializer;
 
+import org.apache.seata.common.exception.SeataRuntimeException;
 import org.apache.seata.server.cluster.raft.sync.msg.RaftBaseMsg;
 import org.apache.seata.server.cluster.raft.sync.msg.RaftSyncMsgType;
 import org.apache.seata.server.cluster.raft.sync.msg.dto.BranchTransactionDTO;
 import org.apache.seata.server.cluster.raft.sync.msg.dto.GlobalTransactionDTO;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.Map;
 
 import static org.junit.jupiter.api.Assertions.*;
 
@@ -77,4 +84,49 @@ public class JacksonSerializerTest {
             serializer.serialize(null);
         });
     }
+
+    @Test
+    public void testDeserializeLegacyClassName() {
+        RaftBaseMsg original = new RaftBaseMsg();
+        original.setMsgType(RaftSyncMsgType.ADD_GLOBAL_SESSION);
+        original.setGroup("legacy-group");
+        String json = new String(serializer.serialize(original), StandardCharsets.UTF_8)
+                .replace(RaftBaseMsg.class.getName(), "io.seata.server.cluster.raft.sync.msg.RaftBaseMsg");
+
+        RaftBaseMsg deserialized = serializer.deserialize(json.getBytes(StandardCharsets.UTF_8));
+        assertEquals(original.getMsgType(), deserialized.getMsgType());
+        assertEquals(original.getGroup(), deserialized.getGroup());
+    }
+
+    @Test
+    public void testSerializeAndDeserializeHashMap() {
+        Map<String, String> original = new HashMap<>();
+        original.put("vgroup", "default");
+        Map<String, String> deserialized = serializer.deserialize(serializer.serialize(original));
+        assertEquals(original, deserialized);
+    }
+
+    @ParameterizedTest
+    @ValueSource(
+            strings = {
+                "org.apache.seataOther.Marker",
+                "org.apache.seata",
+                "io.seata.serverOther.Marker",
+                "io.seata.server",
+                "java.util.HashMapOther",
+                "java.util.HashMap$Node",
+                "java.util.HashMap.Other",
+                "java.lang.String"
+            })
+    public void testRejectClassNamesOutsideAllowedScope(String className) {
+        byte[] bytes = ("{\"obj\":\"e30=\",\"clz\":\"" + className + "\"}").getBytes(StandardCharsets.UTF_8);
+        RuntimeException exception = assertThrows(RuntimeException.class, () -> serializer.deserialize(bytes));
+        Throwable cause = exception;
+        while (cause.getCause() != null) {
+            cause = cause.getCause();
+        }
+        // A missing class must be rejected by name, before attempting to load it.
+        assertInstanceOf(SeataRuntimeException.class, cause);
+        assertTrue(cause.getMessage().contains("is not permitted"));
+    }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@seata.apache.org
For additional commands, e-mail: notifications-help@seata.apache.org