diff --git a/protocol/src/main/java/com/zfoo/protocol/buffer/ByteBufUtils.java b/protocol/src/main/java/com/zfoo/protocol/buffer/ByteBufUtils.java index cfea9334..94624f9d 100644 --- a/protocol/src/main/java/com/zfoo/protocol/buffer/ByteBufUtils.java +++ b/protocol/src/main/java/com/zfoo/protocol/buffer/ByteBufUtils.java @@ -714,7 +714,7 @@ public abstract class ByteBufUtils { public static boolean[] readBooleanArray(ByteBuf byteBuf) { var length = readInt(byteBuf); - var bytes = new byte[CollectionUtils.comfortableLength(length)]; + var bytes = new byte[CollectionUtils.comfortableByteLength(length)]; var array = new boolean[length]; byteBuf.readBytes(bytes); for (var i = 0; i < length; i++) { @@ -736,7 +736,7 @@ public abstract class ByteBufUtils { public static Boolean[] readBooleanBoxArray(ByteBuf byteBuf) { var length = readInt(byteBuf); - var array = new Boolean[CollectionUtils.comfortableLength(length)]; + var array = new Boolean[CollectionUtils.comfortableByteLength(length)]; for (var i = 0; i < length; i++) { array[i] = readBooleanBox(byteBuf); } @@ -791,7 +791,7 @@ public abstract class ByteBufUtils { return ArrayUtils.EMPTY_BYTE_ARRAY; } - var bytes = new byte[CollectionUtils.comfortableLength(length)]; + var bytes = new byte[CollectionUtils.comfortableByteLength(length)]; byteBuf.readBytes(bytes); return bytes; } @@ -809,7 +809,7 @@ public abstract class ByteBufUtils { public static Byte[] readByteBoxArray(ByteBuf byteBuf) { var length = readInt(byteBuf); - var bytesBox = new Byte[CollectionUtils.comfortableLength(length)]; + var bytesBox = new Byte[CollectionUtils.comfortableByteLength(length)]; for (var i = 0; i < length; i++) { bytesBox[i] = readByteBox(byteBuf); } @@ -1253,7 +1253,7 @@ public abstract class ByteBufUtils { public static String[] readStringArray(ByteBuf byteBuf) { var length = readInt(byteBuf); - var strings = new String[CollectionUtils.comfortableLongLength(length)]; + var strings = new String[CollectionUtils.comfortableObjectLength(length)]; for (var i = 0; i < length; i++) { strings[i] = readString(byteBuf); } diff --git a/protocol/src/main/java/com/zfoo/protocol/buffer/CustomByteBuf.java b/protocol/src/main/java/com/zfoo/protocol/buffer/CustomByteBuf.java index 214a685f..40032bed 100644 --- a/protocol/src/main/java/com/zfoo/protocol/buffer/CustomByteBuf.java +++ b/protocol/src/main/java/com/zfoo/protocol/buffer/CustomByteBuf.java @@ -14,7 +14,6 @@ package com.zfoo.protocol.buffer; import com.zfoo.protocol.collection.ArrayListInt; import com.zfoo.protocol.collection.ArrayUtils; -import com.zfoo.protocol.collection.CollectionUtils; import io.netty.buffer.ByteBuf; import java.nio.ByteBuffer; @@ -47,7 +46,7 @@ public abstract class CustomByteBuf { public static int[] readIntArraySimple(ByteBuf byteBuf) { var length = ByteBufUtils.readInt(byteBuf); - var ints = new int[CollectionUtils.comfortableLength(length)]; + var ints = new int[length]; var readIndex = byteBuf.readerIndex(); for (var i = 0; i < length; i++) { ints[i] = byteBuf.getInt(readIndex); diff --git a/protocol/src/main/java/com/zfoo/protocol/collection/CollectionUtils.java b/protocol/src/main/java/com/zfoo/protocol/collection/CollectionUtils.java index 34221ab0..1b6ac2cd 100644 --- a/protocol/src/main/java/com/zfoo/protocol/collection/CollectionUtils.java +++ b/protocol/src/main/java/com/zfoo/protocol/collection/CollectionUtils.java @@ -14,7 +14,6 @@ package com.zfoo.protocol.collection; import com.zfoo.protocol.util.IOUtils; -import com.zfoo.protocol.util.MathSafeUtils; import com.zfoo.protocol.util.StringUtils; import java.util.*; @@ -84,7 +83,7 @@ public abstract class CollectionUtils { } public static List newList(int size) { - return size <= 0 ? new ArrayList<>() : new ArrayList<>(comfortableLength(size)); + return size <= 0 ? new ArrayList<>() : new ArrayList<>(comfortableObjectLength(size)); } public static Set newSet(int size) { @@ -99,39 +98,49 @@ public abstract class CollectionUtils { * EN: The safety limit of the array initialization length prevents deserialization exceptions from causing a sudden increase in memory * CN: 数组初始化长度的安全上限限制,防止反序列化异常导致内存突然升高 */ - public static int comfortableLength(int length) { - if (length >= MathSafeUtils.MAX_LENGTH) { - throw new ArrayStoreException(StringUtils.format("The length of the newly created array [{}] exceeds the set safety range [{}]" - , length, MathSafeUtils.MAX_LENGTH)); + public static final long MAX_BYTE_LENGTH_ARRAY = 64 * IOUtils.BYTES_PER_MB; + public static final long MAX_LENGTH_SHORT_ARRAY = IOUtils.BYTES_PER_MB / 2; + public static final long MAX_LENGTH_INT_ARRAY = IOUtils.BYTES_PER_MB / 4; + public static final long MAX_LENGTH_LONG_ARRAY = IOUtils.BYTES_PER_MB / 8; + public static final long MAX_LENGTH_OBJECT_ARRAY = IOUtils.BYTES_PER_MB / 16; + public static final long MAX_SIZE_MAP = IOUtils.BYTES_PER_MB / 32; + + public static int comfortableByteLength(int length) { + if (length >= MAX_BYTE_LENGTH_ARRAY) { + throw new ArrayStoreException(StringUtils.format("The length of the newly created array [{}] exceeds the safety range [{}]" + , length, MAX_BYTE_LENGTH_ARRAY)); } return length; } + public static int comfortableShortLength(int length) { - if (length >= MathSafeUtils.MAX_LENGTH_SHORT_ARRAY) { - throw new ArrayStoreException(StringUtils.format("The length of the newly created array [{}] exceeds the set safety range [{}]" - , length, MathSafeUtils.MAX_LENGTH_SHORT_ARRAY)); + if (length >= MAX_LENGTH_SHORT_ARRAY) { + throw new ArrayStoreException(StringUtils.format("The length of the newly created array [{}] exceeds the safety range [{}]" + , length, MAX_LENGTH_SHORT_ARRAY)); } return length; } + public static int comfortableIntLength(int length) { - if (length >= MathSafeUtils.MAX_LENGTH_INT_ARRAY) { - throw new ArrayStoreException(StringUtils.format("The length of the newly created array [{}] exceeds the set safety range [{}]" - , length, MathSafeUtils.MAX_LENGTH_INT_ARRAY)); + if (length >= MAX_LENGTH_INT_ARRAY) { + throw new ArrayStoreException(StringUtils.format("The length of the newly created array [{}] exceeds the safety range [{}]" + , length, MAX_LENGTH_INT_ARRAY)); } return length; } + public static int comfortableLongLength(int length) { - if (length >= MathSafeUtils.MAX_LENGTH_LONG_ARRAY) { - throw new ArrayStoreException(StringUtils.format("The length of the newly created array [{}] exceeds the set safety range [{}]" - , length, MathSafeUtils.MAX_LENGTH_LONG_ARRAY)); + if (length >= MAX_LENGTH_LONG_ARRAY) { + throw new ArrayStoreException(StringUtils.format("The length of the newly created array [{}] exceeds the safety range [{}]" + , length, MAX_LENGTH_LONG_ARRAY)); } return length; } public static int comfortableObjectLength(int length) { - if (length >= MathSafeUtils.MAX_LENGTH_OBJECT_ARRAY) { - throw new ArrayStoreException(StringUtils.format("The length of the newly created array [{}] exceeds the set safety range [{}]" - , length, MathSafeUtils.MAX_LENGTH_OBJECT_ARRAY)); + if (length >= MAX_LENGTH_OBJECT_ARRAY) { + throw new ArrayStoreException(StringUtils.format("The length of the newly created array [{}] exceeds the safety range [{}]" + , length, MAX_LENGTH_OBJECT_ARRAY)); } return length; } @@ -143,7 +152,11 @@ public abstract class CollectionUtils { * CN: 计算HashMap初始化合适的大小,为了安全必须给初始化的集合一个最大上限,防止反序列化一个不合法的包导致内存突然升高 */ public static int comfortableCapacity(int capacity) { - return MathSafeUtils.safeFindNextPositivePowerOfTwo(capacity); + if (capacity >= MAX_SIZE_MAP) { + throw new ArrayStoreException(StringUtils.format("The length of the newly created map [{}] exceeds the safety range [{}]" + , capacity, MAX_SIZE_MAP)); + } + return capacity; } public static int capacity(int expectedSize) { diff --git a/protocol/src/main/java/com/zfoo/protocol/serializer/enhance/EnhanceArraySerializer.java b/protocol/src/main/java/com/zfoo/protocol/serializer/enhance/EnhanceArraySerializer.java index a39211f4..0bab0d4d 100644 --- a/protocol/src/main/java/com/zfoo/protocol/serializer/enhance/EnhanceArraySerializer.java +++ b/protocol/src/main/java/com/zfoo/protocol/serializer/enhance/EnhanceArraySerializer.java @@ -69,7 +69,7 @@ public class EnhanceArraySerializer implements IEnhanceSerializer { var length = "length" + GenerateProtocolFile.index.getAndIncrement(); builder.append(StringUtils.format("int {} = {}.readInt($1);", length, EnhanceUtils.byteBufUtils)); - builder.append(StringUtils.format("{}[] {} = new {}[CollectionUtils.comfortableLength({})];", arrayName, array, arrayName, length)); + builder.append(StringUtils.format("{}[] {} = new {}[{}];", arrayName, array, arrayName, length)); var i = "i" + GenerateProtocolFile.index.getAndIncrement(); builder.append(StringUtils.format("for(int {}=0; {} < {}; {}++){", i, i, length, i)); diff --git a/protocol/src/main/java/com/zfoo/protocol/util/MathSafeUtils.java b/protocol/src/main/java/com/zfoo/protocol/util/MathSafeUtils.java deleted file mode 100644 index 50ea3d6b..00000000 --- a/protocol/src/main/java/com/zfoo/protocol/util/MathSafeUtils.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.zfoo.protocol.util; - -/** - * @author Boone Jack - */ -public abstract class MathSafeUtils { - - public static final long MAX_LENGTH = IOUtils.BYTES_PER_MB; - public static final long MAX_LENGTH_SHORT_ARRAY = MAX_LENGTH / 2; - public static final long MAX_LENGTH_INT_ARRAY = MAX_LENGTH / 4; - public static final long MAX_LENGTH_LONG_ARRAY = MAX_LENGTH / 8; - public static final long MAX_LENGTH_OBJECT_ARRAY = MAX_LENGTH / 16; - - public static int findNextPositivePowerOfTwo(int value) { - assert value > Integer.MIN_VALUE && value < IOUtils.BYTES_PER_MB; - - return 1 << 32 - Integer.numberOfLeadingZeros(value - 1); - } - - public static int safeFindNextPositivePowerOfTwo(int value) { - return value <= 0 ? 1 : (value >= IOUtils.BYTES_PER_MB ? IOUtils.BYTES_PER_MB : findNextPositivePowerOfTwo(value)); - } -}