This is an automated email from the ASF dual-hosted git repository.
albumenj pushed a commit to branch 3.1
in repository https://gitbox.apache.org/repos/asf/dubbo.git
The following commit(s) were added to refs/heads/3.1 by this push:
new f0f01c36c3 Fix serializable check & Add test cases (#12054)
f0f01c36c3 is described below
commit f0f01c36c3ae2bd2c620fbace66ea8616df7588e
Author: Albumen Kevin <[email protected]>
AuthorDate: Tue Apr 11 16:58:55 2023 +0800
Fix serializable check & Add test cases (#12054)
* Add test cases
* Fix uts
* Add fj2 test
* save
* Fix check
* Disable some test cases
* Fix test
---
.../org/apache/dubbo/common/utils/ClassUtils.java | 100 ++--
dubbo-dependencies-bom/pom.xml | 2 +-
.../remoting/exchange/codec/ExchangeCodec.java | 2 +-
.../dubbo/remoting/codec/ExchangeCodecTest.java | 4 +
.../apache/dubbo/common/serialize/ObjectInput.java | 4 +-
.../dubbo/common/serialize/ObjectOutput.java | 4 +-
.../dubbo-serialization-fastjson2/pom.xml | 1 -
.../serialize/fastjson2/FastJson2ObjectInput.java | 32 +-
.../src/test/java/com/example/test/TestPojo.java} | 33 +-
.../fastjson2/FastJson2SerializationTest.java | 583 +++++++++++++++++++
.../fastjson2/TrustedNotSerializable.java} | 30 +-
.../common/serialize/fastjson2/TrustedPojo.java} | 31 +-
.../common/serialize/fastjson2/TrustedPojo2.java} | 31 +-
.../common/serialize/fastjson2/TypeMatchTest.java | 159 ++++++
.../serialize/hessian2/Hessian2FactoryManager.java | 7 +
.../hessian2/Hessian2ScopeModelInitializer.java | 2 +
.../hessian2/Hessian2SerializerFactory.java | 2 +-
.../java/com/example/test/TestPojo.java} | 33 +-
.../hessian2/Hessian2SerializationTest.java | 615 +++++++++++++++++++++
.../hessian2/TrustedNotSerializable.java} | 28 +-
.../common/serialize/hessian2/TrustedPojo.java} | 29 +-
.../common/serialize/hessian2/TrustedPojo2.java} | 29 +-
.../common/serialize/hessian2/TypeMatchTest.java | 162 ++++++
23 files changed, 1760 insertions(+), 163 deletions(-)
diff --git
a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ClassUtils.java
b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ClassUtils.java
index a403519318..d07d01f3a5 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ClassUtils.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ClassUtils.java
@@ -74,20 +74,20 @@ public class ClassUtils {
* @since 2.7.6
*/
public static final Set<Class<?>> SIMPLE_TYPES = ofSet(
- Void.class,
- Boolean.class,
- Character.class,
- Byte.class,
- Short.class,
- Integer.class,
- Long.class,
- Float.class,
- Double.class,
- String.class,
- BigDecimal.class,
- BigInteger.class,
- Date.class,
- Object.class
+ Void.class,
+ Boolean.class,
+ Character.class,
+ Byte.class,
+ Short.class,
+ Integer.class,
+ Long.class,
+ Float.class,
+ Double.class,
+ String.class,
+ BigDecimal.class,
+ BigInteger.class,
+ Date.class,
+ Object.class
);
/**
* Prefix for internal array class names: "[L"
@@ -118,8 +118,8 @@ public class ClassUtils {
Set<Class<?>> primitiveTypeNames = new HashSet<>(32);
primitiveTypeNames.addAll(PRIMITIVE_WRAPPER_TYPE_MAP.values());
primitiveTypeNames.addAll(Arrays
- .asList(boolean[].class, byte[].class, char[].class,
double[].class,
- float[].class, int[].class, long[].class,
short[].class));
+ .asList(boolean[].class, byte[].class, char[].class,
double[].class,
+ float[].class, int[].class, long[].class, short[].class));
for (Class<?> primitiveTypeName : primitiveTypeNames) {
PRIMITIVE_TYPE_NAME_MAP.put(primitiveTypeName.getName(),
primitiveTypeName);
}
@@ -137,12 +137,12 @@ public class ClassUtils {
private static final char PACKAGE_SEPARATOR_CHAR = '.';
public static Class<?> forNameWithThreadContextClassLoader(String name)
- throws ClassNotFoundException {
+ throws ClassNotFoundException {
return forName(name, Thread.currentThread().getContextClassLoader());
}
public static Class<?> forNameWithCallerClassLoader(String name, Class<?>
caller)
- throws ClassNotFoundException {
+ throws ClassNotFoundException {
return forName(name, caller.getClassLoader());
}
@@ -224,7 +224,7 @@ public class ClassUtils {
* @see Class#forName(String, boolean, ClassLoader)
*/
public static Class<?> forName(String name, ClassLoader classLoader)
- throws ClassNotFoundException, LinkageError {
+ throws ClassNotFoundException, LinkageError {
Class<?> clazz = resolvePrimitiveClassName(name);
if (clazz != null) {
@@ -244,7 +244,7 @@ public class ClassUtils {
String elementClassName = null;
if (internalArrayMarker == 0) {
elementClassName = name
- .substring(INTERNAL_ARRAY_PREFIX.length(),
name.length() - 1);
+ .substring(INTERNAL_ARRAY_PREFIX.length(), name.length() -
1);
} else if (name.startsWith("[")) {
elementClassName = name.substring(1);
}
@@ -354,7 +354,7 @@ public class ClassUtils {
*/
public static boolean isTypeMatch(Class<?> type, String value) {
if ((type == boolean.class || type == Boolean.class)
- && !("true".equals(value) || "false".equals(value))) {
+ && !("true".equals(value) || "false".equals(value))) {
return false;
}
return true;
@@ -408,18 +408,18 @@ public class ClassUtils {
if (isNotEmpty(interfaces)) {
// add current interfaces
Arrays.stream(interfaces)
- .filter(resolved::add)
- .forEach(cls -> {
- allInterfaces.add(cls);
- waitResolve.add(cls);
- });
+ .filter(resolved::add)
+ .forEach(cls -> {
+ allInterfaces.add(cls);
+ waitResolve.add(cls);
+ });
}
// add all super classes to waitResolve
getAllSuperClasses(clazz)
- .stream()
- .filter(resolved::add)
- .forEach(waitResolve::add);
+ .stream()
+ .filter(resolved::add)
+ .forEach(waitResolve::add);
clazz = waitResolve.poll();
}
@@ -535,7 +535,7 @@ public class ClassUtils {
}
Method[] methods = Arrays.stream(tClass.getMethods())
.collect(Collectors.toList())
- .toArray(new Method[] {});
+ .toArray(new Method[]{});
List<String> mns = new ArrayList<>(); // method names.
boolean hasMethod = hasMethods(methods);
if (hasMethod) {
@@ -551,6 +551,44 @@ public class ClassUtils {
return mns.toArray(new String[0]);
}
+ public static boolean isMatch(Class<?> from, Class<?> to) {
+ if (from == to) {
+ return true;
+ }
+ boolean isMatch;
+ if (from.isPrimitive()) {
+ isMatch = matchPrimitive(from, to);
+ } else if (to.isPrimitive()) {
+ isMatch = matchPrimitive(to, from);
+ } else {
+ isMatch = to.isAssignableFrom(from);
+ }
+ return isMatch;
+ }
+
+ private static boolean matchPrimitive(Class<?> from, Class<?> to) {
+ if (from == boolean.class) {
+ return to == Boolean.class;
+ } else if (from == byte.class) {
+ return to == Byte.class;
+ } else if (from == char.class) {
+ return to == Character.class;
+ } else if (from == short.class) {
+ return to == Short.class;
+ } else if (from == int.class) {
+ return to == Integer.class;
+ } else if (from == long.class) {
+ return to == Long.class;
+ } else if (from == float.class) {
+ return to == Float.class;
+ } else if (from == double.class) {
+ return to == Double.class;
+ } else if (from == void.class) {
+ return to == Void.class;
+ }
+ return false;
+ }
+
/**
* get method name array.
*
@@ -562,7 +600,7 @@ public class ClassUtils {
}
Method[] methods = Arrays.stream(tClass.getMethods())
.collect(Collectors.toList())
- .toArray(new Method[] {});
+ .toArray(new Method[]{});
List<String> dmns = new ArrayList<>(); // method names.
boolean hasMethod = hasMethods(methods);
if (hasMethod) {
diff --git a/dubbo-dependencies-bom/pom.xml b/dubbo-dependencies-bom/pom.xml
index 2ecc954a37..ed88d6d823 100644
--- a/dubbo-dependencies-bom/pom.xml
+++ b/dubbo-dependencies-bom/pom.xml
@@ -100,7 +100,7 @@
<httpclient_version>4.5.13</httpclient_version>
<httpcore_version>4.4.6</httpcore_version>
<fastjson_version>1.2.83</fastjson_version>
- <fastjson2_version>2.0.23</fastjson2_version>
+ <fastjson2_version>2.0.27</fastjson2_version>
<zookeeper_version>3.4.14</zookeeper_version>
<curator_version>4.2.0</curator_version>
<curator_test_version>2.12.0</curator_test_version>
diff --git
a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/codec/ExchangeCodec.java
b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/codec/ExchangeCodec.java
index 58a2eaeea8..18294aac62 100644
---
a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/codec/ExchangeCodec.java
+++
b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/codec/ExchangeCodec.java
@@ -414,7 +414,7 @@ public class ExchangeCodec extends TelnetCodec {
}
private void encodeEventData(ObjectOutput out, Object data) throws
IOException {
- out.writeEvent(data);
+ out.writeEvent((String) data);
}
@Deprecated
diff --git
a/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/codec/ExchangeCodecTest.java
b/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/codec/ExchangeCodecTest.java
index 0951739c82..09e1f6a341 100644
---
a/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/codec/ExchangeCodecTest.java
+++
b/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/codec/ExchangeCodecTest.java
@@ -37,6 +37,7 @@ import org.apache.dubbo.rpc.model.FrameworkModel;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
@@ -261,6 +262,7 @@ class ExchangeCodecTest extends TelnetCodecTest {
}
@Test
+ @Disabled("Event should not be object.")
void test_Decode_Return_Request_Event_Object() throws IOException {
//|10011111|20-stats=ok|id=0|length=0
byte[] header = new byte[]{MAGIC_HIGH, MAGIC_LOW, (byte)
(SERIALIZATION_BYTE | (byte) 0xe0), 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
@@ -306,6 +308,7 @@ class ExchangeCodecTest extends TelnetCodecTest {
}
@Test
+ @Disabled("Event should not be object.")
void test_Decode_Return_Request_Object() throws IOException {
//|10011111|20-stats=ok|id=0|length=0
byte[] header = new byte[]{MAGIC_HIGH, MAGIC_LOW, (byte)
(SERIALIZATION_BYTE | (byte) 0xe0), 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
@@ -393,6 +396,7 @@ class ExchangeCodecTest extends TelnetCodecTest {
}
@Test
+ @Disabled("Event should not be object.")
void test_Encode_Response() throws IOException {
DefaultFuture future =
DefaultFuture.newFuture(Mockito.mock(Channel.class), new Request(1001), 100000,
null);
diff --git
a/dubbo-serialization/dubbo-serialization-api/src/main/java/org/apache/dubbo/common/serialize/ObjectInput.java
b/dubbo-serialization/dubbo-serialization-api/src/main/java/org/apache/dubbo/common/serialize/ObjectInput.java
index 4c3ce7c736..b63438f714 100644
---
a/dubbo-serialization/dubbo-serialization-api/src/main/java/org/apache/dubbo/common/serialize/ObjectInput.java
+++
b/dubbo-serialization/dubbo-serialization-api/src/main/java/org/apache/dubbo/common/serialize/ObjectInput.java
@@ -78,8 +78,8 @@ public interface ObjectInput extends DataInput {
return (Throwable) obj;
}
- default Object readEvent() throws IOException, ClassNotFoundException {
- return readObject();
+ default String readEvent() throws IOException, ClassNotFoundException {
+ return readUTF();
}
default Map<String, Object> readAttachments() throws IOException,
ClassNotFoundException {
diff --git
a/dubbo-serialization/dubbo-serialization-api/src/main/java/org/apache/dubbo/common/serialize/ObjectOutput.java
b/dubbo-serialization/dubbo-serialization-api/src/main/java/org/apache/dubbo/common/serialize/ObjectOutput.java
index 997f781ce4..20b189fd5d 100644
---
a/dubbo-serialization/dubbo-serialization-api/src/main/java/org/apache/dubbo/common/serialize/ObjectOutput.java
+++
b/dubbo-serialization/dubbo-serialization-api/src/main/java/org/apache/dubbo/common/serialize/ObjectOutput.java
@@ -45,11 +45,11 @@ public interface ObjectOutput extends DataOutput {
* restricting the content of headers / attachments to Ascii strings and
uses ISO_8859_1 to encode them.
* https://tools.ietf.org/html/rfc7540#section-8.1.2
*/
- default void writeThrowable(Object obj) throws IOException {
+ default void writeThrowable(Throwable obj) throws IOException {
writeObject(obj);
}
- default void writeEvent(Object data) throws IOException {
+ default void writeEvent(String data) throws IOException {
writeObject(data);
}
diff --git a/dubbo-serialization/dubbo-serialization-fastjson2/pom.xml
b/dubbo-serialization/dubbo-serialization-fastjson2/pom.xml
index 683e099d83..736bd1fc2c 100644
--- a/dubbo-serialization/dubbo-serialization-fastjson2/pom.xml
+++ b/dubbo-serialization/dubbo-serialization-fastjson2/pom.xml
@@ -45,5 +45,4 @@ limitations under the License.
<artifactId>fastjson2</artifactId>
</dependency>
</dependencies>
-
</project>
diff --git
a/dubbo-serialization/dubbo-serialization-fastjson2/src/main/java/org/apache/dubbo/common/serialize/fastjson2/FastJson2ObjectInput.java
b/dubbo-serialization/dubbo-serialization-fastjson2/src/main/java/org/apache/dubbo/common/serialize/fastjson2/FastJson2ObjectInput.java
index 10a261e555..6b19a110ee 100644
---
a/dubbo-serialization/dubbo-serialization-fastjson2/src/main/java/org/apache/dubbo/common/serialize/fastjson2/FastJson2ObjectInput.java
+++
b/dubbo-serialization/dubbo-serialization-fastjson2/src/main/java/org/apache/dubbo/common/serialize/fastjson2/FastJson2ObjectInput.java
@@ -16,15 +16,16 @@
*/
package org.apache.dubbo.common.serialize.fastjson2;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.reflect.Type;
-
import org.apache.dubbo.common.serialize.ObjectInput;
+import org.apache.dubbo.common.utils.ClassUtils;
import com.alibaba.fastjson2.JSONB;
import com.alibaba.fastjson2.JSONReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Type;
+
/**
* FastJson object input implementation
*/
@@ -112,22 +113,28 @@ public class FastJson2ObjectInput implements ObjectInput {
throw new IllegalArgumentException("deserialize failed. expected
read length: " + length + " but actual read: " + read);
}
Fastjson2SecurityManager.Handler securityFilter =
fastjson2SecurityManager.getSecurityFilter();
+ T result;
if (securityFilter.isCheckSerializable()) {
- return (T) JSONB.parseObject(bytes, Object.class, securityFilter,
+ result = JSONB.parseObject(bytes, cls, securityFilter,
JSONReader.Feature.UseDefaultConstructorAsPossible,
JSONReader.Feature.ErrorOnNoneSerializable,
+ JSONReader.Feature.IgnoreAutoTypeNotMatch,
JSONReader.Feature.UseNativeObject,
JSONReader.Feature.FieldBased);
} else {
- return (T) JSONB.parseObject(bytes, Object.class, securityFilter,
+ result = JSONB.parseObject(bytes, cls, securityFilter,
JSONReader.Feature.UseDefaultConstructorAsPossible,
JSONReader.Feature.UseNativeObject,
+ JSONReader.Feature.IgnoreAutoTypeNotMatch,
JSONReader.Feature.FieldBased);
}
+ if (result != null && cls != null &&
!ClassUtils.isMatch(result.getClass(), cls)) {
+ throw new IllegalArgumentException("deserialize failed. expected
class: " + cls + " but actual class: " + result.getClass());
+ }
+ return result;
}
@Override
- @SuppressWarnings("unchecked")
public <T> T readObject(Class<T> cls, Type type) throws IOException,
ClassNotFoundException {
updateClassLoaderIfNeed();
int length = readLength();
@@ -137,18 +144,25 @@ public class FastJson2ObjectInput implements ObjectInput {
throw new IllegalArgumentException("deserialize failed. expected
read length: " + length + " but actual read: " + read);
}
Fastjson2SecurityManager.Handler securityFilter =
fastjson2SecurityManager.getSecurityFilter();
+ T result;
if (securityFilter.isCheckSerializable()) {
- return (T) JSONB.parseObject(bytes, Object.class, securityFilter,
+ result = JSONB.parseObject(bytes, cls, securityFilter,
JSONReader.Feature.UseDefaultConstructorAsPossible,
JSONReader.Feature.ErrorOnNoneSerializable,
+ JSONReader.Feature.IgnoreAutoTypeNotMatch,
JSONReader.Feature.UseNativeObject,
JSONReader.Feature.FieldBased);
} else {
- return (T) JSONB.parseObject(bytes, Object.class, securityFilter,
+ result = JSONB.parseObject(bytes, cls, securityFilter,
JSONReader.Feature.UseDefaultConstructorAsPossible,
JSONReader.Feature.UseNativeObject,
+ JSONReader.Feature.IgnoreAutoTypeNotMatch,
JSONReader.Feature.FieldBased);
}
+ if (result != null && cls != null &&
!ClassUtils.isMatch(result.getClass(), cls)) {
+ throw new IllegalArgumentException("deserialize failed. expected
class: " + cls + " but actual class: " + result.getClass());
+ }
+ return result;
}
private void updateClassLoaderIfNeed() {
diff --git
a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java
b/dubbo-serialization/dubbo-serialization-fastjson2/src/test/java/com/example/test/TestPojo.java
similarity index 53%
copy from
dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java
copy to
dubbo-serialization/dubbo-serialization-fastjson2/src/test/java/com/example/test/TestPojo.java
index 578850905c..3c2471ba54 100644
---
a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java
+++
b/dubbo-serialization/dubbo-serialization-fastjson2/src/test/java/com/example/test/TestPojo.java
@@ -14,28 +14,33 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.dubbo.common.serialize.hessian2;
+package com.example.test;
-import org.apache.dubbo.common.beans.factory.ScopeBeanFactory;
-import org.apache.dubbo.rpc.model.ApplicationModel;
-import org.apache.dubbo.rpc.model.FrameworkModel;
-import org.apache.dubbo.rpc.model.ModuleModel;
-import org.apache.dubbo.rpc.model.ScopeModelInitializer;
+import java.io.Serializable;
+import java.util.Objects;
-public class Hessian2ScopeModelInitializer implements ScopeModelInitializer {
- @Override
- public void initializeFrameworkModel(FrameworkModel frameworkModel) {
- ScopeBeanFactory beanFactory = frameworkModel.getBeanFactory();
- beanFactory.registerBean(Hessian2FactoryManager.class);
+public class TestPojo implements Serializable {
+ private final String data;
+
+ public TestPojo(String data) {
+ this.data = data;
}
@Override
- public void initializeApplicationModel(ApplicationModel applicationModel) {
-
+ public String toString() {
+ throw new IllegalAccessError();
}
@Override
- public void initializeModuleModel(ModuleModel moduleModel) {
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ TestPojo testPojo = (TestPojo) o;
+ return Objects.equals(data, testPojo.data);
+ }
+ @Override
+ public int hashCode() {
+ return Objects.hash(data);
}
}
diff --git
a/dubbo-serialization/dubbo-serialization-fastjson2/src/test/java/org/apache/dubbo/common/serialize/fastjson2/FastJson2SerializationTest.java
b/dubbo-serialization/dubbo-serialization-fastjson2/src/test/java/org/apache/dubbo/common/serialize/fastjson2/FastJson2SerializationTest.java
new file mode 100644
index 0000000000..447e3396aa
--- /dev/null
+++
b/dubbo-serialization/dubbo-serialization-fastjson2/src/test/java/org/apache/dubbo/common/serialize/fastjson2/FastJson2SerializationTest.java
@@ -0,0 +1,583 @@
+/*
+ * 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.dubbo.common.serialize.fastjson2;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.serialize.ObjectInput;
+import org.apache.dubbo.common.serialize.ObjectOutput;
+import org.apache.dubbo.common.serialize.Serialization;
+import org.apache.dubbo.common.utils.SerializeCheckStatus;
+import org.apache.dubbo.common.utils.SerializeSecurityManager;
+import org.apache.dubbo.rpc.model.FrameworkModel;
+
+import com.example.test.TestPojo;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ThreadLocalRandom;
+
+public class FastJson2SerializationTest {
+
+ @Test
+ void testReadString() throws IOException {
+ FrameworkModel frameworkModel = new FrameworkModel();
+ Serialization serialization =
frameworkModel.getExtensionLoader(Serialization.class).getExtension("fastjson2");
+ URL url = URL.valueOf("").setScopeModel(frameworkModel);
+
+ // write string, read string
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ objectOutput.writeObject("hello");
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertEquals("hello", objectInput.readUTF());
+ }
+
+ // write string, read string
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ objectOutput.writeObject(null);
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertNull(objectInput.readUTF());
+ }
+
+ // write date, read failed
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ objectOutput.writeObject(new HashMap<>());
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertThrows(RuntimeException.class,
objectInput::readUTF);
+ }
+
+ // write pojo, read failed
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ objectOutput.writeObject(new
TrustedPojo(ThreadLocalRandom.current().nextDouble()));
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertInstanceOf(String.class, objectInput.readUTF());
+ }
+
+ // write map, read failed
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ objectOutput.writeObject(new HashMap<>());
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertThrows(RuntimeException.class,
objectInput::readUTF);
+ }
+
+ // write list, read failed
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ objectOutput.writeObject(new LinkedList<>());
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertInstanceOf(String.class, objectInput.readUTF());
+ }
+
+ frameworkModel.destroy();
+ }
+
+ @Test
+ void testReadEvent() throws IOException, ClassNotFoundException {
+ FrameworkModel frameworkModel = new FrameworkModel();
+ Serialization serialization =
frameworkModel.getExtensionLoader(Serialization.class).getExtension("fastjson2");
+ URL url = URL.valueOf("").setScopeModel(frameworkModel);
+
+ // write string, read event
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ objectOutput.writeObject("hello");
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertEquals("hello", objectInput.readEvent());
+ }
+
+ // write date, read failed
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ objectOutput.writeObject(new HashMap<>());
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertThrows(RuntimeException.class,
objectInput::readEvent);
+ }
+
+ // write pojo, read failed
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ objectOutput.writeObject(new
TrustedPojo(ThreadLocalRandom.current().nextDouble()));
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertInstanceOf(String.class, objectInput.readEvent());
+ }
+
+ // write map, read failed
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ objectOutput.writeObject(new HashMap<>());
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertThrows(RuntimeException.class,
objectInput::readEvent);
+ }
+
+ // write list, read failed
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ objectOutput.writeObject(new LinkedList<>());
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertInstanceOf(String.class, objectInput.readEvent());
+ }
+
+ frameworkModel.destroy();
+ }
+
+ @Test
+ void testReadByte() throws IOException {
+ FrameworkModel frameworkModel = new FrameworkModel();
+ Serialization serialization =
frameworkModel.getExtensionLoader(Serialization.class).getExtension("fastjson2");
+ URL url = URL.valueOf("").setScopeModel(frameworkModel);
+
+ // write byte, read byte
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ objectOutput.writeObject((byte) 11);
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertEquals((byte) 11, objectInput.readByte());
+ }
+
+ // write date, read failed
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ objectOutput.writeObject(new Date());
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertThrows(RuntimeException.class,
objectInput::readByte);
+ }
+
+ // write pojo, read failed
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ objectOutput.writeObject(new
TrustedPojo(ThreadLocalRandom.current().nextDouble()));
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertThrows(RuntimeException.class,
objectInput::readByte);
+ }
+
+ // write map, read failed
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ objectOutput.writeObject(new HashMap<>());
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertThrows(RuntimeException.class,
objectInput::readByte);
+ }
+
+ // write list, read failed
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ objectOutput.writeObject(new LinkedList<>());
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertThrows(RuntimeException.class,
objectInput::readByte);
+ }
+
+ frameworkModel.destroy();
+ }
+
+ @Test
+ void testReadObject() throws IOException, ClassNotFoundException {
+ FrameworkModel frameworkModel = new FrameworkModel();
+ Serialization serialization =
frameworkModel.getExtensionLoader(Serialization.class).getExtension("fastjson2");
+ URL url = URL.valueOf("").setScopeModel(frameworkModel);
+
+ // write pojo, read pojo
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ TrustedPojo trustedPojo = new
TrustedPojo(ThreadLocalRandom.current().nextDouble());
+ objectOutput.writeObject(trustedPojo);
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertEquals(trustedPojo, objectInput.readObject());
+ }
+
+ // write list, read list
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ TrustedPojo trustedPojo = new
TrustedPojo(ThreadLocalRandom.current().nextDouble());
+ LinkedList<TrustedPojo> pojos = new LinkedList<>();
+ pojos.add(trustedPojo);
+
+ objectOutput.writeObject(pojos);
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertEquals(pojos, objectInput.readObject());
+ }
+
+ // write pojo, read pojo
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ TrustedPojo trustedPojo = new
TrustedPojo(ThreadLocalRandom.current().nextDouble());
+ objectOutput.writeObject(trustedPojo);
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertEquals(trustedPojo,
objectInput.readObject(TrustedPojo.class));
+ }
+
+ // write list, read list
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ TrustedPojo trustedPojo = new
TrustedPojo(ThreadLocalRandom.current().nextDouble());
+ LinkedList<TrustedPojo> pojos = new LinkedList<>();
+ pojos.add(trustedPojo);
+
+ objectOutput.writeObject(pojos);
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertEquals(pojos, objectInput.readObject(List.class));
+ }
+
+ // write list, read list
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ TrustedPojo trustedPojo = new
TrustedPojo(ThreadLocalRandom.current().nextDouble());
+ LinkedList<TrustedPojo> pojos = new LinkedList<>();
+ pojos.add(trustedPojo);
+
+ objectOutput.writeObject(pojos);
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertEquals(pojos,
objectInput.readObject(LinkedList.class));
+ }
+
+ frameworkModel.destroy();
+ }
+
+ @Test
+ void testReadObjectNotMatched() throws IOException, ClassNotFoundException
{
+ FrameworkModel frameworkModel = new FrameworkModel();
+ Serialization serialization =
frameworkModel.getExtensionLoader(Serialization.class).getExtension("fastjson2");
+
frameworkModel.getBeanFactory().getBean(SerializeSecurityManager.class).setCheckStatus(SerializeCheckStatus.STRICT);
+ URL url = URL.valueOf("").setScopeModel(frameworkModel);
+
+ // write pojo, read list failed
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ TrustedPojo trustedPojo = new
TrustedPojo(ThreadLocalRandom.current().nextDouble());
+ objectOutput.writeObject(trustedPojo);
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertThrows(RuntimeException.class, () ->
objectInput.readObject(List.class));
+ }
+
+ // write pojo, read list failed
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ TrustedPojo trustedPojo = new
TrustedPojo(ThreadLocalRandom.current().nextDouble());
+ objectOutput.writeObject(trustedPojo);
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertThrows(RuntimeException.class, () ->
objectInput.readObject(LinkedList.class));
+ }
+
+ // write pojo, read string failed
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ TrustedPojo trustedPojo = new
TrustedPojo(ThreadLocalRandom.current().nextDouble());
+ objectOutput.writeObject(trustedPojo);
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertInstanceOf(String.class,
objectInput.readObject(String.class));
+ }
+
+ // write pojo, read other failed
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ TrustedPojo trustedPojo = new
TrustedPojo(ThreadLocalRandom.current().nextDouble());
+ objectOutput.writeObject(trustedPojo);
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertThrows(RuntimeException.class, () ->
objectInput.readObject(TrustedNotSerializable.class));
+ }
+
+ // write pojo, read same field failed
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ TrustedPojo trustedPojo = new
TrustedPojo(ThreadLocalRandom.current().nextDouble());
+ objectOutput.writeObject(trustedPojo);
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertThrows(RuntimeException.class, () ->
objectInput.readObject(TrustedPojo2.class));
+ }
+
+ // write pojo, read map failed
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ TrustedPojo trustedPojo = new
TrustedPojo(ThreadLocalRandom.current().nextDouble());
+ objectOutput.writeObject(trustedPojo);
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertThrows(RuntimeException.class, () ->
objectInput.readObject(Map.class));
+ }
+
+ // write list, read pojo failed
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ TrustedPojo trustedPojo = new
TrustedPojo(ThreadLocalRandom.current().nextDouble());
+ LinkedList<TrustedPojo> pojos = new LinkedList<>();
+ pojos.add(trustedPojo);
+
+ objectOutput.writeObject(pojos);
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertThrows(RuntimeException.class, () ->
objectInput.readObject(TrustedPojo.class));
+ }
+
+ // write list, read map failed
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ TrustedPojo trustedPojo = new
TrustedPojo(ThreadLocalRandom.current().nextDouble());
+ LinkedList<TrustedPojo> pojos = new LinkedList<>();
+ pojos.add(trustedPojo);
+
+ objectOutput.writeObject(pojos);
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertThrows(RuntimeException.class, () ->
objectInput.readObject(Map.class));
+ }
+
+ frameworkModel.destroy();
+ }
+
+ @Test
+ void testLimit1() throws IOException, ClassNotFoundException {
+ FrameworkModel frameworkModel = new FrameworkModel();
+ Serialization serialization =
frameworkModel.getExtensionLoader(Serialization.class).getExtension("fastjson2");
+ URL url = URL.valueOf("").setScopeModel(frameworkModel);
+
+ // write trusted, read trusted
+ TrustedPojo trustedPojo = new
TrustedPojo(ThreadLocalRandom.current().nextDouble());
+
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url, outputStream);
+ objectOutput.writeObject(trustedPojo);
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url, inputStream);
+ Assertions.assertEquals(trustedPojo, objectInput.readObject());
+
+ frameworkModel.destroy();
+ }
+
+ @Test
+ void testLimit4() throws IOException, ClassNotFoundException {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ // write force untrusted, read failed
+
+ {
+ FrameworkModel frameworkModel = new FrameworkModel();
+ Serialization serialization =
frameworkModel.getExtensionLoader(Serialization.class).getExtension("fastjson2");
+ URL url = URL.valueOf("").setScopeModel(frameworkModel);
+
+ TestPojo trustedPojo = new TestPojo("12345");
+
+
frameworkModel.getBeanFactory().getBean(SerializeSecurityManager.class).addToAllowed(trustedPojo.getClass().getName());
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ objectOutput.writeObject(trustedPojo);
+ objectOutput.flushBuffer();
+
+ frameworkModel.destroy();
+ }
+
+ {
+ FrameworkModel frameworkModel = new FrameworkModel();
+ Serialization serialization =
frameworkModel.getExtensionLoader(Serialization.class).getExtension("fastjson2");
+ URL url = URL.valueOf("").setScopeModel(frameworkModel);
+
+ byte[] bytes = outputStream.toByteArray();
+
frameworkModel.getBeanFactory().getBean(SerializeSecurityManager.class).setCheckStatus(SerializeCheckStatus.STRICT);
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertThrows(RuntimeException.class,
objectInput::readObject);
+ frameworkModel.destroy();
+ }
+ }
+
+ @Test
+ void testLimit5() throws IOException, ClassNotFoundException {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ // write force un-serializable, read failed
+
+ {
+ FrameworkModel frameworkModel = new FrameworkModel();
+ Serialization serialization =
frameworkModel.getExtensionLoader(Serialization.class).getExtension("fastjson2");
+ URL url = URL.valueOf("").setScopeModel(frameworkModel);
+
+ TrustedNotSerializable trustedPojo = new
TrustedNotSerializable(ThreadLocalRandom.current().nextDouble());
+
+
frameworkModel.getBeanFactory().getBean(SerializeSecurityManager.class).setCheckSerializable(false);
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ objectOutput.writeObject(trustedPojo);
+ objectOutput.flushBuffer();
+
+ frameworkModel.destroy();
+ }
+
+ {
+ FrameworkModel frameworkModel = new FrameworkModel();
+ Serialization serialization =
frameworkModel.getExtensionLoader(Serialization.class).getExtension("fastjson2");
+ URL url = URL.valueOf("").setScopeModel(frameworkModel);
+
+ byte[] bytes = outputStream.toByteArray();
+
frameworkModel.getBeanFactory().getBean(SerializeSecurityManager.class).setCheckStatus(SerializeCheckStatus.STRICT);
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertThrows(RuntimeException.class,
objectInput::readObject);
+ frameworkModel.destroy();
+ }
+ }
+}
diff --git
a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java
b/dubbo-serialization/dubbo-serialization-fastjson2/src/test/java/org/apache/dubbo/common/serialize/fastjson2/TrustedNotSerializable.java
similarity index 52%
copy from
dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java
copy to
dubbo-serialization/dubbo-serialization-fastjson2/src/test/java/org/apache/dubbo/common/serialize/fastjson2/TrustedNotSerializable.java
index 578850905c..3172e870fe 100644
---
a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java
+++
b/dubbo-serialization/dubbo-serialization-fastjson2/src/test/java/org/apache/dubbo/common/serialize/fastjson2/TrustedNotSerializable.java
@@ -14,28 +14,28 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.dubbo.common.serialize.hessian2;
+package org.apache.dubbo.common.serialize.fastjson2;
-import org.apache.dubbo.common.beans.factory.ScopeBeanFactory;
-import org.apache.dubbo.rpc.model.ApplicationModel;
-import org.apache.dubbo.rpc.model.FrameworkModel;
-import org.apache.dubbo.rpc.model.ModuleModel;
-import org.apache.dubbo.rpc.model.ScopeModelInitializer;
+import java.util.Objects;
-public class Hessian2ScopeModelInitializer implements ScopeModelInitializer {
- @Override
- public void initializeFrameworkModel(FrameworkModel frameworkModel) {
- ScopeBeanFactory beanFactory = frameworkModel.getBeanFactory();
- beanFactory.registerBean(Hessian2FactoryManager.class);
- }
+public class TrustedNotSerializable {
- @Override
- public void initializeApplicationModel(ApplicationModel applicationModel) {
+ private final double data;
+ public TrustedNotSerializable(double data) {
+ this.data = data;
}
@Override
- public void initializeModuleModel(ModuleModel moduleModel) {
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ TrustedNotSerializable that = (TrustedNotSerializable) o;
+ return Objects.equals(data, that.data);
+ }
+ @Override
+ public int hashCode() {
+ return Objects.hash(data);
}
}
diff --git
a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java
b/dubbo-serialization/dubbo-serialization-fastjson2/src/test/java/org/apache/dubbo/common/serialize/fastjson2/TrustedPojo.java
similarity index 52%
copy from
dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java
copy to
dubbo-serialization/dubbo-serialization-fastjson2/src/test/java/org/apache/dubbo/common/serialize/fastjson2/TrustedPojo.java
index 578850905c..ae4f3db440 100644
---
a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java
+++
b/dubbo-serialization/dubbo-serialization-fastjson2/src/test/java/org/apache/dubbo/common/serialize/fastjson2/TrustedPojo.java
@@ -14,28 +14,29 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.dubbo.common.serialize.hessian2;
+package org.apache.dubbo.common.serialize.fastjson2;
-import org.apache.dubbo.common.beans.factory.ScopeBeanFactory;
-import org.apache.dubbo.rpc.model.ApplicationModel;
-import org.apache.dubbo.rpc.model.FrameworkModel;
-import org.apache.dubbo.rpc.model.ModuleModel;
-import org.apache.dubbo.rpc.model.ScopeModelInitializer;
+import java.io.Serializable;
+import java.util.Objects;
-public class Hessian2ScopeModelInitializer implements ScopeModelInitializer {
- @Override
- public void initializeFrameworkModel(FrameworkModel frameworkModel) {
- ScopeBeanFactory beanFactory = frameworkModel.getBeanFactory();
- beanFactory.registerBean(Hessian2FactoryManager.class);
- }
+public class TrustedPojo implements Serializable {
- @Override
- public void initializeApplicationModel(ApplicationModel applicationModel) {
+ private final double data;
+ public TrustedPojo(double data) {
+ this.data = data;
}
@Override
- public void initializeModuleModel(ModuleModel moduleModel) {
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ TrustedPojo that = (TrustedPojo) o;
+ return Objects.equals(data, that.data);
+ }
+ @Override
+ public int hashCode() {
+ return Objects.hash(data);
}
}
diff --git
a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java
b/dubbo-serialization/dubbo-serialization-fastjson2/src/test/java/org/apache/dubbo/common/serialize/fastjson2/TrustedPojo2.java
similarity index 52%
copy from
dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java
copy to
dubbo-serialization/dubbo-serialization-fastjson2/src/test/java/org/apache/dubbo/common/serialize/fastjson2/TrustedPojo2.java
index 578850905c..3aaa74684e 100644
---
a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java
+++
b/dubbo-serialization/dubbo-serialization-fastjson2/src/test/java/org/apache/dubbo/common/serialize/fastjson2/TrustedPojo2.java
@@ -14,28 +14,29 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.dubbo.common.serialize.hessian2;
+package org.apache.dubbo.common.serialize.fastjson2;
-import org.apache.dubbo.common.beans.factory.ScopeBeanFactory;
-import org.apache.dubbo.rpc.model.ApplicationModel;
-import org.apache.dubbo.rpc.model.FrameworkModel;
-import org.apache.dubbo.rpc.model.ModuleModel;
-import org.apache.dubbo.rpc.model.ScopeModelInitializer;
+import java.io.Serializable;
+import java.util.Objects;
-public class Hessian2ScopeModelInitializer implements ScopeModelInitializer {
- @Override
- public void initializeFrameworkModel(FrameworkModel frameworkModel) {
- ScopeBeanFactory beanFactory = frameworkModel.getBeanFactory();
- beanFactory.registerBean(Hessian2FactoryManager.class);
- }
+public class TrustedPojo2 implements Serializable {
- @Override
- public void initializeApplicationModel(ApplicationModel applicationModel) {
+ private final double data;
+ public TrustedPojo2(double data) {
+ this.data = data;
}
@Override
- public void initializeModuleModel(ModuleModel moduleModel) {
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ TrustedPojo2 that = (TrustedPojo2) o;
+ return Objects.equals(data, that.data);
+ }
+ @Override
+ public int hashCode() {
+ return Objects.hash(data);
}
}
diff --git
a/dubbo-serialization/dubbo-serialization-fastjson2/src/test/java/org/apache/dubbo/common/serialize/fastjson2/TypeMatchTest.java
b/dubbo-serialization/dubbo-serialization-fastjson2/src/test/java/org/apache/dubbo/common/serialize/fastjson2/TypeMatchTest.java
new file mode 100644
index 0000000000..974f685a2a
--- /dev/null
+++
b/dubbo-serialization/dubbo-serialization-fastjson2/src/test/java/org/apache/dubbo/common/serialize/fastjson2/TypeMatchTest.java
@@ -0,0 +1,159 @@
+/*
+ * 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.dubbo.common.serialize.fastjson2;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.serialize.DataInput;
+import org.apache.dubbo.common.serialize.DataOutput;
+import org.apache.dubbo.common.serialize.ObjectInput;
+import org.apache.dubbo.common.serialize.ObjectOutput;
+import org.apache.dubbo.common.serialize.Serialization;
+import org.apache.dubbo.rpc.model.FrameworkModel;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.extension.ExtensionContext;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.ArgumentsProvider;
+import org.junit.jupiter.params.provider.ArgumentsSource;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Stream;
+
+class TypeMatchTest {
+ static class DataProvider implements ArgumentsProvider {
+ @Override
+ public Stream<? extends Arguments> provideArguments(ExtensionContext
extensionContext) throws Exception {
+ List<Object> datas = new LinkedList<>();
+ List<Method> readMethods = new LinkedList<>();
+ List<Method> writeMethods = new LinkedList<>();
+
+ datas.add(true);
+ datas.add(false);
+ datas.add((byte) 123);
+ datas.add((byte) 234);
+ datas.add((short) 12345);
+ datas.add((short) 23456);
+ datas.add(123456);
+ datas.add(234567);
+ datas.add(1234567L);
+ datas.add(2345678L);
+ datas.add(0.123F);
+ datas.add(1.234F);
+ datas.add(0.1234D);
+ datas.add(1.2345D);
+ datas.add("hello");
+ datas.add("world");
+ datas.add("hello".getBytes());
+ datas.add("world".getBytes());
+
+ for (Method method : ObjectInput.class.getMethods()) {
+ if (method.getName().startsWith("read") &&
method.getParameterTypes().length == 0 &&
!method.getReturnType().equals(Object.class)) {
+ readMethods.add(method);
+ }
+ }
+ for (Method method : DataInput.class.getMethods()) {
+ if (method.getName().startsWith("read") &&
method.getParameterTypes().length == 0 &&
!method.getReturnType().equals(Object.class)) {
+ readMethods.add(method);
+ }
+ }
+
+ for (Method method : ObjectOutput.class.getMethods()) {
+ if (method.getName().startsWith("write") &&
method.getParameterTypes().length == 1 &&
!method.getParameterTypes()[0].equals(Object.class)) {
+ writeMethods.add(method);
+ }
+ }
+
+ for (Method method : DataOutput.class.getMethods()) {
+ if (method.getName().startsWith("write") &&
method.getParameterTypes().length == 1 &&
!method.getParameterTypes()[0].equals(Object.class)) {
+ writeMethods.add(method);
+ }
+ }
+
+ Map<Class<?>, Class<?>> primitiveWrapperTypeMap = new
HashMap<>(16);
+ primitiveWrapperTypeMap.put(Boolean.class, boolean.class);
+ primitiveWrapperTypeMap.put(Byte.class, byte.class);
+ primitiveWrapperTypeMap.put(Character.class, char.class);
+ primitiveWrapperTypeMap.put(Double.class, double.class);
+ primitiveWrapperTypeMap.put(Float.class, float.class);
+ primitiveWrapperTypeMap.put(Integer.class, int.class);
+ primitiveWrapperTypeMap.put(Long.class, long.class);
+ primitiveWrapperTypeMap.put(Short.class, short.class);
+ primitiveWrapperTypeMap.put(Void.class, void.class);
+
+ List<Arguments> argumentsList = new LinkedList<>();
+ for (Object data : datas) {
+ for (Method input : readMethods) {
+ for (Method output : writeMethods) {
+ if
(output.getParameterTypes()[0].isAssignableFrom(data.getClass())) {
+ argumentsList.add(Arguments.arguments(data, input,
output));
+ }
+ if
(primitiveWrapperTypeMap.containsKey(data.getClass()) &&
+
output.getParameterTypes()[0].isAssignableFrom(primitiveWrapperTypeMap.get(data.getClass())))
{
+ argumentsList.add(Arguments.arguments(data, input,
output));
+ }
+ }
+ }
+ }
+
+ return argumentsList.stream();
+ }
+ }
+
+ @ParameterizedTest
+ @ArgumentsSource(DataProvider.class)
+ void test(Object data, Method input, Method output) throws Exception {
+ FrameworkModel frameworkModel = new FrameworkModel();
+ Serialization serialization =
frameworkModel.getExtensionLoader(Serialization.class).getExtension("fastjson2");
+ URL url = URL.valueOf("").setScopeModel(frameworkModel);
+
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url, outputStream);
+ output.invoke(objectOutput, data);
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url, inputStream);
+ if (output.getParameterTypes()[0].equals(input.getReturnType())) {
+ Object result = input.invoke(objectInput);
+ if (data.getClass().isArray()) {
+ Assertions.assertArrayEquals((byte[]) data, (byte[]) result);
+ } else {
+ Assertions.assertEquals(data, result);
+ }
+ } else {
+ try {
+ Object result = input.invoke(objectInput);
+ if (data.getClass().isArray()) {
+ Assertions.assertNotEquals(data.getClass(),
result.getClass());
+ } else {
+ Assertions.assertNotEquals(data, result);
+ }
+ } catch (Exception e) {
+ // ignore
+ }
+ }
+ frameworkModel.destroy();
+ }
+}
diff --git
a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2FactoryManager.java
b/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2FactoryManager.java
index 512f67115f..60f9dfe2fe 100644
---
a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2FactoryManager.java
+++
b/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2FactoryManager.java
@@ -20,6 +20,8 @@ import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.dubbo.common.utils.DefaultSerializeClassChecker;
+import org.apache.dubbo.common.utils.SerializeCheckStatus;
+import org.apache.dubbo.common.utils.SerializeSecurityManager;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.rpc.model.FrameworkModel;
@@ -33,9 +35,11 @@ public class Hessian2FactoryManager {
private volatile SerializerFactory SYSTEM_SERIALIZER_FACTORY;
private final Map<ClassLoader, SerializerFactory> CL_2_SERIALIZER_FACTORY
= new ConcurrentHashMap<>();
+ private final SerializeSecurityManager serializeSecurityManager;
private final DefaultSerializeClassChecker defaultSerializeClassChecker;
public Hessian2FactoryManager(FrameworkModel frameworkModel) {
+ serializeSecurityManager =
frameworkModel.getBeanFactory().getOrRegisterBean(SerializeSecurityManager.class);
defaultSerializeClassChecker =
frameworkModel.getBeanFactory().getOrRegisterBean(DefaultSerializeClassChecker.class);
}
@@ -89,14 +93,17 @@ public class Hessian2FactoryManager {
if (StringUtils.isNotEmpty(allowPattern)) {
for (String pattern : allowPattern.split(";")) {
serializerFactory.getClassFactory().allow(pattern);
+ serializeSecurityManager.addToAlwaysAllowed(pattern);
}
}
+
serializeSecurityManager.setCheckStatus(SerializeCheckStatus.STRICT);
} else {
serializerFactory.getClassFactory().setWhitelist(false);
String denyPattern = System.getProperty(DENY);
if (StringUtils.isNotEmpty(denyPattern)) {
for (String pattern : denyPattern.split(";")) {
serializerFactory.getClassFactory().deny(pattern);
+ serializeSecurityManager.addToDisAllowed(pattern);
}
}
}
diff --git
a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java
b/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java
index 578850905c..a86b39bdb8 100644
---
a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java
+++
b/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java
@@ -27,6 +27,8 @@ public class Hessian2ScopeModelInitializer implements
ScopeModelInitializer {
public void initializeFrameworkModel(FrameworkModel frameworkModel) {
ScopeBeanFactory beanFactory = frameworkModel.getBeanFactory();
beanFactory.registerBean(Hessian2FactoryManager.class);
+
+ frameworkModel.addClassLoaderListener(new
Hessian2ClassLoaderListener());
}
@Override
diff --git
a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2SerializerFactory.java
b/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2SerializerFactory.java
index 099c5e9766..0d886b9d39 100644
---
a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2SerializerFactory.java
+++
b/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2SerializerFactory.java
@@ -52,7 +52,7 @@ public class Hessian2SerializerFactory extends
SerializerFactory {
}
if (!Serializable.class.isAssignableFrom(cl)
- && (!isAllowNonSerializable() ||
!defaultSerializeClassChecker.isCheckSerializable())) {
+ && (!isAllowNonSerializable() ||
defaultSerializeClassChecker.isCheckSerializable())) {
throw new IllegalStateException("Serialized class " + cl.getName()
+ " must implement java.io.Serializable");
}
diff --git
a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java
b/dubbo-serialization/dubbo-serialization-hessian2/src/test/java/com/example/test/TestPojo.java
similarity index 53%
copy from
dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java
copy to
dubbo-serialization/dubbo-serialization-hessian2/src/test/java/com/example/test/TestPojo.java
index 578850905c..3c2471ba54 100644
---
a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java
+++
b/dubbo-serialization/dubbo-serialization-hessian2/src/test/java/com/example/test/TestPojo.java
@@ -14,28 +14,33 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.dubbo.common.serialize.hessian2;
+package com.example.test;
-import org.apache.dubbo.common.beans.factory.ScopeBeanFactory;
-import org.apache.dubbo.rpc.model.ApplicationModel;
-import org.apache.dubbo.rpc.model.FrameworkModel;
-import org.apache.dubbo.rpc.model.ModuleModel;
-import org.apache.dubbo.rpc.model.ScopeModelInitializer;
+import java.io.Serializable;
+import java.util.Objects;
-public class Hessian2ScopeModelInitializer implements ScopeModelInitializer {
- @Override
- public void initializeFrameworkModel(FrameworkModel frameworkModel) {
- ScopeBeanFactory beanFactory = frameworkModel.getBeanFactory();
- beanFactory.registerBean(Hessian2FactoryManager.class);
+public class TestPojo implements Serializable {
+ private final String data;
+
+ public TestPojo(String data) {
+ this.data = data;
}
@Override
- public void initializeApplicationModel(ApplicationModel applicationModel) {
-
+ public String toString() {
+ throw new IllegalAccessError();
}
@Override
- public void initializeModuleModel(ModuleModel moduleModel) {
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ TestPojo testPojo = (TestPojo) o;
+ return Objects.equals(data, testPojo.data);
+ }
+ @Override
+ public int hashCode() {
+ return Objects.hash(data);
}
}
diff --git
a/dubbo-serialization/dubbo-serialization-hessian2/src/test/java/org/apache/dubbo/common/serialize/hessian2/Hessian2SerializationTest.java
b/dubbo-serialization/dubbo-serialization-hessian2/src/test/java/org/apache/dubbo/common/serialize/hessian2/Hessian2SerializationTest.java
new file mode 100644
index 0000000000..b43e0a8c80
--- /dev/null
+++
b/dubbo-serialization/dubbo-serialization-hessian2/src/test/java/org/apache/dubbo/common/serialize/hessian2/Hessian2SerializationTest.java
@@ -0,0 +1,615 @@
+/*
+ * 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.dubbo.common.serialize.hessian2;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.serialize.ObjectInput;
+import org.apache.dubbo.common.serialize.ObjectOutput;
+import org.apache.dubbo.common.serialize.Serialization;
+import org.apache.dubbo.common.utils.SerializeCheckStatus;
+import org.apache.dubbo.common.utils.SerializeSecurityManager;
+import org.apache.dubbo.rpc.model.FrameworkModel;
+
+import com.example.test.TestPojo;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ThreadLocalRandom;
+
+class Hessian2SerializationTest {
+ @Test
+ void testReadString() throws IOException {
+ FrameworkModel frameworkModel = new FrameworkModel();
+ Serialization serialization =
frameworkModel.getExtensionLoader(Serialization.class).getExtension("hessian2");
+ URL url = URL.valueOf("").setScopeModel(frameworkModel);
+
+ // write string, read string
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ objectOutput.writeObject("hello");
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertEquals("hello", objectInput.readUTF());
+ }
+
+ // write string, read string
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ objectOutput.writeObject(null);
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertNull(objectInput.readUTF());
+ }
+
+ // write date, read failed
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ objectOutput.writeObject(new Date());
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertThrows(IOException.class, objectInput::readUTF);
+ }
+
+ // write pojo, read failed
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ objectOutput.writeObject(new
TrustedPojo(ThreadLocalRandom.current().nextDouble()));
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertThrows(IOException.class, objectInput::readUTF);
+ }
+
+ // write map, read failed
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ objectOutput.writeObject(new HashMap<>());
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertThrows(IOException.class, objectInput::readUTF);
+ }
+
+ // write list, read failed
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ objectOutput.writeObject(new LinkedList<>());
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertThrows(IOException.class, objectInput::readUTF);
+ }
+
+ frameworkModel.destroy();
+ }
+
+ @Test
+ void testReadEvent() throws IOException, ClassNotFoundException {
+ FrameworkModel frameworkModel = new FrameworkModel();
+ Serialization serialization =
frameworkModel.getExtensionLoader(Serialization.class).getExtension("hessian2");
+ URL url = URL.valueOf("").setScopeModel(frameworkModel);
+
+ // write string, read event
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ objectOutput.writeObject("hello");
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertEquals("hello", objectInput.readEvent());
+ }
+
+ // write date, read failed
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ objectOutput.writeObject(new Date());
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertThrows(IOException.class, objectInput::readEvent);
+ }
+
+ // write pojo, read failed
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ objectOutput.writeObject(new
TrustedPojo(ThreadLocalRandom.current().nextDouble()));
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertThrows(IOException.class, objectInput::readEvent);
+ }
+
+ // write map, read failed
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ objectOutput.writeObject(new HashMap<>());
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertThrows(IOException.class, objectInput::readEvent);
+ }
+
+ // write list, read failed
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ objectOutput.writeObject(new LinkedList<>());
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertThrows(IOException.class, objectInput::readEvent);
+ }
+
+ frameworkModel.destroy();
+ }
+
+ @Test
+ void testReadByte() throws IOException {
+ FrameworkModel frameworkModel = new FrameworkModel();
+ Serialization serialization =
frameworkModel.getExtensionLoader(Serialization.class).getExtension("hessian2");
+ URL url = URL.valueOf("").setScopeModel(frameworkModel);
+
+ // write byte, read byte
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ objectOutput.writeObject((byte) 11);
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertEquals((byte) 11, objectInput.readByte());
+ }
+
+ // write date, read failed
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ objectOutput.writeObject(new Date());
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertThrows(IOException.class, objectInput::readByte);
+ }
+
+ // write pojo, read failed
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ objectOutput.writeObject(new
TrustedPojo(ThreadLocalRandom.current().nextDouble()));
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertThrows(IOException.class, objectInput::readByte);
+ }
+
+ // write map, read failed
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ objectOutput.writeObject(new HashMap<>());
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertThrows(IOException.class, objectInput::readByte);
+ }
+
+ // write list, read failed
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ objectOutput.writeObject(new LinkedList<>());
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertThrows(IOException.class, objectInput::readByte);
+ }
+
+ frameworkModel.destroy();
+ }
+
+ @Test
+ void testReadObject() throws IOException, ClassNotFoundException {
+ FrameworkModel frameworkModel = new FrameworkModel();
+ Serialization serialization =
frameworkModel.getExtensionLoader(Serialization.class).getExtension("hessian2");
+ URL url = URL.valueOf("").setScopeModel(frameworkModel);
+
+ // write pojo, read pojo
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ TrustedPojo trustedPojo = new
TrustedPojo(ThreadLocalRandom.current().nextDouble());
+ objectOutput.writeObject(trustedPojo);
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertEquals(trustedPojo, objectInput.readObject());
+ }
+
+ // write list, read list
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ TrustedPojo trustedPojo = new
TrustedPojo(ThreadLocalRandom.current().nextDouble());
+ LinkedList<TrustedPojo> pojos = new LinkedList<>();
+ pojos.add(trustedPojo);
+
+ objectOutput.writeObject(pojos);
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertEquals(pojos, objectInput.readObject());
+ }
+
+ // write pojo, read pojo
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ TrustedPojo trustedPojo = new
TrustedPojo(ThreadLocalRandom.current().nextDouble());
+ objectOutput.writeObject(trustedPojo);
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertEquals(trustedPojo,
objectInput.readObject(TrustedPojo.class));
+ }
+
+ // write list, read list
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ TrustedPojo trustedPojo = new
TrustedPojo(ThreadLocalRandom.current().nextDouble());
+ LinkedList<TrustedPojo> pojos = new LinkedList<>();
+ pojos.add(trustedPojo);
+
+ objectOutput.writeObject(pojos);
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertEquals(pojos, objectInput.readObject(List.class));
+ }
+
+ // write list, read list
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ TrustedPojo trustedPojo = new
TrustedPojo(ThreadLocalRandom.current().nextDouble());
+ LinkedList<TrustedPojo> pojos = new LinkedList<>();
+ pojos.add(trustedPojo);
+
+ objectOutput.writeObject(pojos);
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertEquals(pojos,
objectInput.readObject(LinkedList.class));
+ }
+
+ frameworkModel.destroy();
+ }
+
+ @Test
+ void testReadObjectNotMatched() throws IOException, ClassNotFoundException
{
+ FrameworkModel frameworkModel = new FrameworkModel();
+ Serialization serialization =
frameworkModel.getExtensionLoader(Serialization.class).getExtension("hessian2");
+ URL url = URL.valueOf("").setScopeModel(frameworkModel);
+
+ // write pojo, read list failed
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ TrustedPojo trustedPojo = new
TrustedPojo(ThreadLocalRandom.current().nextDouble());
+ objectOutput.writeObject(trustedPojo);
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertThrows(RuntimeException.class, () ->
objectInput.readObject(List.class));
+ }
+
+ // write pojo, read list failed
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ TrustedPojo trustedPojo = new
TrustedPojo(ThreadLocalRandom.current().nextDouble());
+ objectOutput.writeObject(trustedPojo);
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertThrows(RuntimeException.class, () ->
objectInput.readObject(LinkedList.class));
+ }
+
+ // write pojo, read string failed
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ TrustedPojo trustedPojo = new
TrustedPojo(ThreadLocalRandom.current().nextDouble());
+ objectOutput.writeObject(trustedPojo);
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertThrows(RuntimeException.class, () ->
objectInput.readObject(String.class));
+ }
+
+ // write pojo, read other failed
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ TrustedPojo trustedPojo = new
TrustedPojo(ThreadLocalRandom.current().nextDouble());
+ objectOutput.writeObject(trustedPojo);
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertThrows(RuntimeException.class, () ->
objectInput.readObject(TrustedNotSerializable.class));
+ }
+
+ // write pojo, read same field failed
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ TrustedPojo trustedPojo = new
TrustedPojo(ThreadLocalRandom.current().nextDouble());
+ objectOutput.writeObject(trustedPojo);
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertInstanceOf(TrustedPojo2.class,
objectInput.readObject(TrustedPojo2.class));
+ }
+
+ // write pojo, read map failed
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ TrustedPojo trustedPojo = new
TrustedPojo(ThreadLocalRandom.current().nextDouble());
+ objectOutput.writeObject(trustedPojo);
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertInstanceOf(Map.class,
objectInput.readObject(Map.class));
+ }
+
+ // write list, read pojo failed
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ TrustedPojo trustedPojo = new
TrustedPojo(ThreadLocalRandom.current().nextDouble());
+ LinkedList<TrustedPojo> pojos = new LinkedList<>();
+ pojos.add(trustedPojo);
+
+ objectOutput.writeObject(pojos);
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertThrows(RuntimeException.class, () ->
objectInput.readObject(TrustedPojo.class));
+ }
+
+ // write list, read map failed
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ TrustedPojo trustedPojo = new
TrustedPojo(ThreadLocalRandom.current().nextDouble());
+ LinkedList<TrustedPojo> pojos = new LinkedList<>();
+ pojos.add(trustedPojo);
+
+ objectOutput.writeObject(pojos);
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertThrows(RuntimeException.class, () ->
objectInput.readObject(Map.class));
+ }
+
+ frameworkModel.destroy();
+ }
+
+ @Test
+ void testLimit1() throws IOException, ClassNotFoundException {
+ FrameworkModel frameworkModel = new FrameworkModel();
+ Serialization serialization =
frameworkModel.getExtensionLoader(Serialization.class).getExtension("hessian2");
+ URL url = URL.valueOf("").setScopeModel(frameworkModel);
+
+ // write trusted, read trusted
+ TrustedPojo trustedPojo = new
TrustedPojo(ThreadLocalRandom.current().nextDouble());
+
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url, outputStream);
+ objectOutput.writeObject(trustedPojo);
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url, inputStream);
+ Assertions.assertEquals(trustedPojo, objectInput.readObject());
+
+ frameworkModel.destroy();
+ }
+
+ @Test
+ void testLimit2() throws IOException, ClassNotFoundException {
+ FrameworkModel frameworkModel = new FrameworkModel();
+ Serialization serialization =
frameworkModel.getExtensionLoader(Serialization.class).getExtension("hessian2");
+
frameworkModel.getBeanFactory().getBean(SerializeSecurityManager.class).setCheckStatus(SerializeCheckStatus.STRICT);
+ URL url = URL.valueOf("").setScopeModel(frameworkModel);
+
+ // write untrusted failed
+ TestPojo trustedPojo = new TestPojo("12345");
+
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url, outputStream);
+ Assertions.assertThrows(IllegalArgumentException.class, () ->
objectOutput.writeObject(trustedPojo));
+
+ frameworkModel.destroy();
+ }
+
+ @Test
+ void testLimit3() throws IOException, ClassNotFoundException {
+ FrameworkModel frameworkModel = new FrameworkModel();
+ Serialization serialization =
frameworkModel.getExtensionLoader(Serialization.class).getExtension("hessian2");
+ URL url = URL.valueOf("").setScopeModel(frameworkModel);
+
+ // write un-serializable failed
+ TrustedNotSerializable trustedPojo = new
TrustedNotSerializable(ThreadLocalRandom.current().nextDouble());
+
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url, outputStream);
+ Assertions.assertThrows(IllegalArgumentException.class, () ->
objectOutput.writeObject(trustedPojo));
+
+ frameworkModel.destroy();
+ }
+
+ @Test
+ void testLimit4() throws IOException, ClassNotFoundException {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ // write force untrusted, read failed
+
+ {
+ FrameworkModel frameworkModel = new FrameworkModel();
+ Serialization serialization =
frameworkModel.getExtensionLoader(Serialization.class).getExtension("hessian2");
+ URL url = URL.valueOf("").setScopeModel(frameworkModel);
+
+ TestPojo trustedPojo = new TestPojo("12345");
+
+
frameworkModel.getBeanFactory().getBean(SerializeSecurityManager.class).addToAllowed(trustedPojo.getClass().getName());
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ objectOutput.writeObject(trustedPojo);
+ objectOutput.flushBuffer();
+
+ frameworkModel.destroy();
+ }
+
+ {
+ FrameworkModel frameworkModel = new FrameworkModel();
+ Serialization serialization =
frameworkModel.getExtensionLoader(Serialization.class).getExtension("hessian2");
+ URL url = URL.valueOf("").setScopeModel(frameworkModel);
+
+ byte[] bytes = outputStream.toByteArray();
+
frameworkModel.getBeanFactory().getBean(SerializeSecurityManager.class).setCheckStatus(SerializeCheckStatus.STRICT);
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertInstanceOf(Map.class, objectInput.readObject());
+ frameworkModel.destroy();
+ }
+ }
+
+ @Test
+ void testLimit5() throws IOException, ClassNotFoundException {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ // write force un-serializable, read failed
+
+ {
+ System.setProperty("dubbo.hessian.allowNonSerializable", "true");
+ FrameworkModel frameworkModel = new FrameworkModel();
+ Serialization serialization =
frameworkModel.getExtensionLoader(Serialization.class).getExtension("hessian2");
+ URL url = URL.valueOf("").setScopeModel(frameworkModel);
+
+ TrustedNotSerializable trustedPojo = new
TrustedNotSerializable(ThreadLocalRandom.current().nextDouble());
+
+
frameworkModel.getBeanFactory().getBean(SerializeSecurityManager.class).setCheckSerializable(false);
+ ObjectOutput objectOutput = serialization.serialize(url,
outputStream);
+ objectOutput.writeObject(trustedPojo);
+ objectOutput.flushBuffer();
+
+ frameworkModel.destroy();
+ System.clearProperty("dubbo.hessian.allowNonSerializable");
+ }
+
+ {
+ FrameworkModel frameworkModel = new FrameworkModel();
+ Serialization serialization =
frameworkModel.getExtensionLoader(Serialization.class).getExtension("hessian2");
+ URL url = URL.valueOf("").setScopeModel(frameworkModel);
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url,
inputStream);
+ Assertions.assertInstanceOf(Map.class, objectInput.readObject());
+ frameworkModel.destroy();
+ }
+ }
+}
diff --git
a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java
b/dubbo-serialization/dubbo-serialization-hessian2/src/test/java/org/apache/dubbo/common/serialize/hessian2/TrustedNotSerializable.java
similarity index 55%
copy from
dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java
copy to
dubbo-serialization/dubbo-serialization-hessian2/src/test/java/org/apache/dubbo/common/serialize/hessian2/TrustedNotSerializable.java
index 578850905c..dea99604e8 100644
---
a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java
+++
b/dubbo-serialization/dubbo-serialization-hessian2/src/test/java/org/apache/dubbo/common/serialize/hessian2/TrustedNotSerializable.java
@@ -16,26 +16,26 @@
*/
package org.apache.dubbo.common.serialize.hessian2;
-import org.apache.dubbo.common.beans.factory.ScopeBeanFactory;
-import org.apache.dubbo.rpc.model.ApplicationModel;
-import org.apache.dubbo.rpc.model.FrameworkModel;
-import org.apache.dubbo.rpc.model.ModuleModel;
-import org.apache.dubbo.rpc.model.ScopeModelInitializer;
+import java.util.Objects;
-public class Hessian2ScopeModelInitializer implements ScopeModelInitializer {
- @Override
- public void initializeFrameworkModel(FrameworkModel frameworkModel) {
- ScopeBeanFactory beanFactory = frameworkModel.getBeanFactory();
- beanFactory.registerBean(Hessian2FactoryManager.class);
- }
+public class TrustedNotSerializable {
- @Override
- public void initializeApplicationModel(ApplicationModel applicationModel) {
+ private final double data;
+ public TrustedNotSerializable(double data) {
+ this.data = data;
}
@Override
- public void initializeModuleModel(ModuleModel moduleModel) {
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ TrustedNotSerializable that = (TrustedNotSerializable) o;
+ return Objects.equals(data, that.data);
+ }
+ @Override
+ public int hashCode() {
+ return Objects.hash(data);
}
}
diff --git
a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java
b/dubbo-serialization/dubbo-serialization-hessian2/src/test/java/org/apache/dubbo/common/serialize/hessian2/TrustedPojo.java
similarity index 55%
copy from
dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java
copy to
dubbo-serialization/dubbo-serialization-hessian2/src/test/java/org/apache/dubbo/common/serialize/hessian2/TrustedPojo.java
index 578850905c..14eabaa853 100644
---
a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java
+++
b/dubbo-serialization/dubbo-serialization-hessian2/src/test/java/org/apache/dubbo/common/serialize/hessian2/TrustedPojo.java
@@ -16,26 +16,27 @@
*/
package org.apache.dubbo.common.serialize.hessian2;
-import org.apache.dubbo.common.beans.factory.ScopeBeanFactory;
-import org.apache.dubbo.rpc.model.ApplicationModel;
-import org.apache.dubbo.rpc.model.FrameworkModel;
-import org.apache.dubbo.rpc.model.ModuleModel;
-import org.apache.dubbo.rpc.model.ScopeModelInitializer;
+import java.io.Serializable;
+import java.util.Objects;
-public class Hessian2ScopeModelInitializer implements ScopeModelInitializer {
- @Override
- public void initializeFrameworkModel(FrameworkModel frameworkModel) {
- ScopeBeanFactory beanFactory = frameworkModel.getBeanFactory();
- beanFactory.registerBean(Hessian2FactoryManager.class);
- }
+public class TrustedPojo implements Serializable {
- @Override
- public void initializeApplicationModel(ApplicationModel applicationModel) {
+ private final double data;
+ public TrustedPojo(double data) {
+ this.data = data;
}
@Override
- public void initializeModuleModel(ModuleModel moduleModel) {
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ TrustedPojo that = (TrustedPojo) o;
+ return Objects.equals(data, that.data);
+ }
+ @Override
+ public int hashCode() {
+ return Objects.hash(data);
}
}
diff --git
a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java
b/dubbo-serialization/dubbo-serialization-hessian2/src/test/java/org/apache/dubbo/common/serialize/hessian2/TrustedPojo2.java
similarity index 55%
copy from
dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java
copy to
dubbo-serialization/dubbo-serialization-hessian2/src/test/java/org/apache/dubbo/common/serialize/hessian2/TrustedPojo2.java
index 578850905c..db499e49f3 100644
---
a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java
+++
b/dubbo-serialization/dubbo-serialization-hessian2/src/test/java/org/apache/dubbo/common/serialize/hessian2/TrustedPojo2.java
@@ -16,26 +16,27 @@
*/
package org.apache.dubbo.common.serialize.hessian2;
-import org.apache.dubbo.common.beans.factory.ScopeBeanFactory;
-import org.apache.dubbo.rpc.model.ApplicationModel;
-import org.apache.dubbo.rpc.model.FrameworkModel;
-import org.apache.dubbo.rpc.model.ModuleModel;
-import org.apache.dubbo.rpc.model.ScopeModelInitializer;
+import java.io.Serializable;
+import java.util.Objects;
-public class Hessian2ScopeModelInitializer implements ScopeModelInitializer {
- @Override
- public void initializeFrameworkModel(FrameworkModel frameworkModel) {
- ScopeBeanFactory beanFactory = frameworkModel.getBeanFactory();
- beanFactory.registerBean(Hessian2FactoryManager.class);
- }
+public class TrustedPojo2 implements Serializable {
- @Override
- public void initializeApplicationModel(ApplicationModel applicationModel) {
+ private final double data;
+ public TrustedPojo2(double data) {
+ this.data = data;
}
@Override
- public void initializeModuleModel(ModuleModel moduleModel) {
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ TrustedPojo2 that = (TrustedPojo2) o;
+ return Objects.equals(data, that.data);
+ }
+ @Override
+ public int hashCode() {
+ return Objects.hash(data);
}
}
diff --git
a/dubbo-serialization/dubbo-serialization-hessian2/src/test/java/org/apache/dubbo/common/serialize/hessian2/TypeMatchTest.java
b/dubbo-serialization/dubbo-serialization-hessian2/src/test/java/org/apache/dubbo/common/serialize/hessian2/TypeMatchTest.java
new file mode 100644
index 0000000000..b155981be7
--- /dev/null
+++
b/dubbo-serialization/dubbo-serialization-hessian2/src/test/java/org/apache/dubbo/common/serialize/hessian2/TypeMatchTest.java
@@ -0,0 +1,162 @@
+/*
+ * 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.dubbo.common.serialize.hessian2;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.serialize.DataInput;
+import org.apache.dubbo.common.serialize.DataOutput;
+import org.apache.dubbo.common.serialize.ObjectInput;
+import org.apache.dubbo.common.serialize.ObjectOutput;
+import org.apache.dubbo.common.serialize.Serialization;
+import org.apache.dubbo.common.utils.ClassUtils;
+import org.apache.dubbo.rpc.model.FrameworkModel;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.extension.ExtensionContext;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.ArgumentsProvider;
+import org.junit.jupiter.params.provider.ArgumentsSource;
+import org.junit.jupiter.params.provider.ArgumentsSources;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Stream;
+
+class TypeMatchTest {
+ static class DataProvider implements ArgumentsProvider {
+ @Override
+ public Stream<? extends Arguments> provideArguments(ExtensionContext
extensionContext) throws Exception {
+ List<Object> datas = new LinkedList<>();
+ List<Method> readMethods = new LinkedList<>();
+ List<Method> writeMethods = new LinkedList<>();
+
+ datas.add(true);
+ datas.add(false);
+ datas.add((byte) 123);
+ datas.add((byte) 234);
+ datas.add((short) 12345);
+ datas.add((short) 23456);
+ datas.add(123456);
+ datas.add(234567);
+ datas.add(1234567L);
+ datas.add(2345678L);
+ datas.add(0.123F);
+ datas.add(1.234F);
+ datas.add(0.1234D);
+ datas.add(1.2345D);
+ datas.add("hello");
+ datas.add("world");
+ datas.add("hello".getBytes());
+ datas.add("world".getBytes());
+
+ for (Method method : ObjectInput.class.getMethods()) {
+ if (method.getName().startsWith("read") &&
method.getParameterTypes().length == 0 &&
!method.getReturnType().equals(Object.class)) {
+ readMethods.add(method);
+ }
+ }
+ for (Method method : DataInput.class.getMethods()) {
+ if (method.getName().startsWith("read") &&
method.getParameterTypes().length == 0 &&
!method.getReturnType().equals(Object.class)) {
+ readMethods.add(method);
+ }
+ }
+
+ for (Method method : ObjectOutput.class.getMethods()) {
+ if (method.getName().startsWith("write") &&
method.getParameterTypes().length == 1 &&
!method.getParameterTypes()[0].equals(Object.class)) {
+ writeMethods.add(method);
+ }
+ }
+
+ for (Method method : DataOutput.class.getMethods()) {
+ if (method.getName().startsWith("write") &&
method.getParameterTypes().length == 1 &&
!method.getParameterTypes()[0].equals(Object.class)) {
+ writeMethods.add(method);
+ }
+ }
+
+ Map<Class<?>, Class<?>> primitiveWrapperTypeMap = new
HashMap<>(16);
+ primitiveWrapperTypeMap.put(Boolean.class, boolean.class);
+ primitiveWrapperTypeMap.put(Byte.class, byte.class);
+ primitiveWrapperTypeMap.put(Character.class, char.class);
+ primitiveWrapperTypeMap.put(Double.class, double.class);
+ primitiveWrapperTypeMap.put(Float.class, float.class);
+ primitiveWrapperTypeMap.put(Integer.class, int.class);
+ primitiveWrapperTypeMap.put(Long.class, long.class);
+ primitiveWrapperTypeMap.put(Short.class, short.class);
+ primitiveWrapperTypeMap.put(Void.class, void.class);
+
+ List<Arguments> argumentsList = new LinkedList<>();
+ for (Object data : datas) {
+ for (Method input : readMethods) {
+ for (Method output : writeMethods) {
+ if
(output.getParameterTypes()[0].isAssignableFrom(data.getClass())) {
+ argumentsList.add(Arguments.arguments(data, input,
output));
+ }
+ if
(primitiveWrapperTypeMap.containsKey(data.getClass()) &&
+
output.getParameterTypes()[0].isAssignableFrom(primitiveWrapperTypeMap.get(data.getClass())))
{
+ argumentsList.add(Arguments.arguments(data, input,
output));
+ }
+ }
+ }
+ }
+
+ return argumentsList.stream();
+ }
+ }
+
+ @ParameterizedTest
+ @ArgumentsSource(DataProvider.class)
+ void test(Object data, Method input, Method output) throws Exception {
+ FrameworkModel frameworkModel = new FrameworkModel();
+ Serialization serialization =
frameworkModel.getExtensionLoader(Serialization.class).getExtension("hessian2");
+ URL url = URL.valueOf("").setScopeModel(frameworkModel);
+
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ObjectOutput objectOutput = serialization.serialize(url, outputStream);
+ output.invoke(objectOutput, data);
+ objectOutput.flushBuffer();
+
+ byte[] bytes = outputStream.toByteArray();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+ ObjectInput objectInput = serialization.deserialize(url, inputStream);
+ if (output.getParameterTypes()[0].equals(input.getReturnType())) {
+ Object result = input.invoke(objectInput);
+ if (data.getClass().isArray()) {
+ Assertions.assertArrayEquals((byte[]) data, (byte[]) result);
+ } else {
+ Assertions.assertEquals(data, result);
+ }
+ } else {
+ try {
+ Object result = input.invoke(objectInput);
+ if (data.getClass().isArray()) {
+ Assertions.assertNotEquals(data.getClass(),
result.getClass());
+ } else {
+ Assertions.assertNotEquals(data, result);
+ }
+ } catch (Exception e) {
+ // ignore
+ }
+ }
+ frameworkModel.destroy();
+ }
+}