diff --git a/java/fory-core/src/main/java/org/apache/fory/config/Config.java b/java/fory-core/src/main/java/org/apache/fory/config/Config.java index e07ada4ec1..822177c65e 100644 --- a/java/fory-core/src/main/java/org/apache/fory/config/Config.java +++ b/java/fory-core/src/main/java/org/apache/fory/config/Config.java @@ -65,6 +65,8 @@ public class Config implements Serializable { private final boolean serializeEnumByName; private final int bufferSizeLimitBytes; private final int maxDepth; + private final int maxBinarySize; + private final int maxCollectionSize; private final float mapRefLoadFactor; public Config(ForyBuilder builder) { @@ -106,6 +108,8 @@ public Config(ForyBuilder builder) { serializeEnumByName = builder.serializeEnumByName; bufferSizeLimitBytes = builder.bufferSizeLimitBytes; maxDepth = builder.maxDepth; + maxBinarySize = builder.maxBinarySize; + maxCollectionSize = builder.maxCollectionSize; mapRefLoadFactor = builder.mapRefLoadFactor; } @@ -326,6 +330,8 @@ public boolean equals(Object o) { && scalaOptimizationEnabled == config.scalaOptimizationEnabled && xlang == config.xlang && compatibleMode == config.compatibleMode + && maxBinarySize == config.maxBinarySize + && maxCollectionSize == config.maxCollectionSize && Objects.equals(defaultJDKStreamSerializerType, config.defaultJDKStreamSerializerType) && longEncoding == config.longEncoding; } @@ -353,6 +359,8 @@ public int hashCode() { compressIntArray, compressLongArray, bufferSizeLimitBytes, + maxBinarySize, + maxCollectionSize, requireClassRegistration, suppressClassRegistrationWarnings, registerGuavaTypes, @@ -381,6 +389,14 @@ public int maxDepth() { return maxDepth; } + public int maxBinarySize() { + return maxBinarySize; + } + + public int maxCollectionSize() { + return maxCollectionSize; + } + /** Returns loadFactor of MacRef's writtenObjects. */ public float mapRefLoadFactor() { return mapRefLoadFactor; diff --git a/java/fory-core/src/main/java/org/apache/fory/config/ForyBuilder.java b/java/fory-core/src/main/java/org/apache/fory/config/ForyBuilder.java index 7e4bc0fde2..ff3d923883 100644 --- a/java/fory-core/src/main/java/org/apache/fory/config/ForyBuilder.java +++ b/java/fory-core/src/main/java/org/apache/fory/config/ForyBuilder.java @@ -88,6 +88,8 @@ public final class ForyBuilder { int bufferSizeLimitBytes = 128 * 1024; MetaCompressor metaCompressor = new DeflaterMetaCompressor(); int maxDepth = 50; + int maxBinarySize = -1; + int maxCollectionSize = -1; float mapRefLoadFactor = 0.51f; public ForyBuilder() {} @@ -394,6 +396,16 @@ public ForyBuilder withMaxDepth(int maxDepth) { return this; } + public ForyBuilder withMaxBinarySize(int maxBinarySize) { + this.maxBinarySize = maxBinarySize; + return this; + } + + public ForyBuilder withMaxCollectionSize(int maxCollectionSize) { + this.maxCollectionSize = maxCollectionSize; + return this; + } + /** Set loadFactor of MapRefResolver writtenObjects. Default value is 0.51 */ public ForyBuilder withMapRefLoadFactor(float loadFactor) { Preconditions.checkArgument( diff --git a/java/fory-core/src/main/java/org/apache/fory/serializer/collection/CollectionLikeSerializer.java b/java/fory-core/src/main/java/org/apache/fory/serializer/collection/CollectionLikeSerializer.java index cee78a1638..c3ceab6642 100644 --- a/java/fory-core/src/main/java/org/apache/fory/serializer/collection/CollectionLikeSerializer.java +++ b/java/fory-core/src/main/java/org/apache/fory/serializer/collection/CollectionLikeSerializer.java @@ -437,6 +437,15 @@ public T read(MemoryBuffer buffer) { */ public Collection newCollection(MemoryBuffer buffer) { numElements = buffer.readVarUint32Small7(); + + int maxCollectionSize = fory.getConfig().maxCollectionSize(); + if (maxCollectionSize > 0 && numElements > maxCollectionSize) { + throw new IllegalArgumentException( + "Collection size " + + numElements + + " exceeds configured maxCollectionSize " + + maxCollectionSize); + } if (constructor == null) { constructor = ReflectionUtils.getCtrHandle(type, true); } diff --git a/java/fory-core/src/main/java/org/apache/fory/serializer/collection/MapSerializers.java b/java/fory-core/src/main/java/org/apache/fory/serializer/collection/MapSerializers.java index aa80d00c6d..168ce503a8 100644 --- a/java/fory-core/src/main/java/org/apache/fory/serializer/collection/MapSerializers.java +++ b/java/fory-core/src/main/java/org/apache/fory/serializer/collection/MapSerializers.java @@ -61,6 +61,15 @@ public HashMapSerializer(Fory fory) { @Override public HashMap newMap(MemoryBuffer buffer) { int numElements = buffer.readVarUint32Small7(); + int maxCollectionSize = fory.getConfig().maxCollectionSize(); + if (maxCollectionSize > 0 && numElements > maxCollectionSize) { + throw new IllegalArgumentException( + "Map size " + + numElements + + " exceeds configured maxCollectionSize " + + maxCollectionSize); + } + setNumElements(numElements); HashMap hashMap = new HashMap(numElements); fory.getRefResolver().reference(hashMap); @@ -81,6 +90,15 @@ public LinkedHashMapSerializer(Fory fory) { @Override public LinkedHashMap newMap(MemoryBuffer buffer) { int numElements = buffer.readVarUint32Small7(); + int maxCollectionSize = fory.getConfig().maxCollectionSize(); + if (maxCollectionSize > 0 && numElements > maxCollectionSize) { + throw new IllegalArgumentException( + "Map size " + + numElements + + " exceeds configured maxCollectionSize " + + maxCollectionSize); + } + setNumElements(numElements); LinkedHashMap hashMap = new LinkedHashMap(numElements); fory.getRefResolver().reference(hashMap); @@ -101,6 +119,15 @@ public LazyMapSerializer(Fory fory) { @Override public LazyMap newMap(MemoryBuffer buffer) { int numElements = buffer.readVarUint32Small7(); + int maxCollectionSize = fory.getConfig().maxCollectionSize(); + if (maxCollectionSize > 0 && numElements > maxCollectionSize) { + throw new IllegalArgumentException( + "Map size " + + numElements + + " exceeds configured maxCollectionSize " + + maxCollectionSize); + } + setNumElements(numElements); LazyMap map = new LazyMap(numElements); fory.getRefResolver().reference(map); @@ -269,6 +296,15 @@ public ConcurrentHashMapSerializer(Fory fory, Class type) { @Override public ConcurrentHashMap newMap(MemoryBuffer buffer) { int numElements = buffer.readVarUint32Small7(); + int maxCollectionSize = fory.getConfig().maxCollectionSize(); + if (maxCollectionSize > 0 && numElements > maxCollectionSize) { + throw new IllegalArgumentException( + "Map size " + + numElements + + " exceeds configured maxCollectionSize " + + maxCollectionSize); + } + setNumElements(numElements); ConcurrentHashMap map = new ConcurrentHashMap(numElements); fory.getRefResolver().reference(map); @@ -300,6 +336,15 @@ public MapSnapshot onMapWrite(MemoryBuffer buffer, ConcurrentSkipListMap value) @Override public ConcurrentSkipListMap newMap(MemoryBuffer buffer) { int numElements = buffer.readVarUint32Small7(); + int maxCollectionSize = fory.getConfig().maxCollectionSize(); + if (maxCollectionSize > 0 && numElements > maxCollectionSize) { + throw new IllegalArgumentException( + "Map size " + + numElements + + " exceeds configured maxCollectionSize " + + maxCollectionSize); + } + setNumElements(numElements); Comparator comparator = (Comparator) fory.readRef(buffer); ConcurrentSkipListMap map = new ConcurrentSkipListMap(comparator); @@ -496,6 +541,15 @@ public Object onMapCopy(Map map) { public Map newMap(MemoryBuffer buffer) { int numElements = buffer.readVarUint32Small7(); + int maxCollectionSize = fory.getConfig().maxCollectionSize(); + if (maxCollectionSize > 0 && numElements > maxCollectionSize) { + throw new IllegalArgumentException( + "Map size " + + numElements + + " exceeds configured maxCollectionSize " + + maxCollectionSize); + } + setNumElements(numElements); HashMap map = new HashMap<>(numElements); fory.getRefResolver().reference(map); diff --git a/java/fory-core/src/main/java/org/apache/fory/serializer/collection/PrimitiveListSerializers.java b/java/fory-core/src/main/java/org/apache/fory/serializer/collection/PrimitiveListSerializers.java index d86556bb1f..529d003e52 100644 --- a/java/fory-core/src/main/java/org/apache/fory/serializer/collection/PrimitiveListSerializers.java +++ b/java/fory-core/src/main/java/org/apache/fory/serializer/collection/PrimitiveListSerializers.java @@ -82,6 +82,11 @@ public void write(MemoryBuffer buffer, Int8List value) { @Override public Int8List read(MemoryBuffer buffer) { int size = buffer.readVarUint32Small7(); + int maxBinarySize = fory.getConfig().maxBinarySize(); + if (maxBinarySize > 0 && size > maxBinarySize) { + throw new IllegalArgumentException( + "Binary size " + size + " exceeds configured maxBinarySize " + maxBinarySize); + } byte[] array = new byte[size]; buffer.readBytes(array); return new Int8List(array); @@ -281,6 +286,11 @@ public void write(MemoryBuffer buffer, Uint8List value) { @Override public Uint8List read(MemoryBuffer buffer) { int size = buffer.readVarUint32Small7(); + int maxBinarySize = fory.getConfig().maxBinarySize(); + if (maxBinarySize > 0 && size > maxBinarySize) { + throw new IllegalArgumentException( + "Binary size " + size + " exceeds configured maxBinarySize " + maxBinarySize); + } byte[] array = new byte[size]; buffer.readBytes(array); return new Uint8List(array);