mirror of
https://github.com/PaperMC/Velocity.git
synced 2026-04-21 20:08:17 +02:00
Add remaining pre-sizing checks
This commit is contained in:
@@ -415,7 +415,10 @@ public enum ProtocolUtils {
|
|||||||
*/
|
*/
|
||||||
public static int[] readIntegerArray(ByteBuf buf) {
|
public static int[] readIntegerArray(ByteBuf buf) {
|
||||||
int len = readVarInt(buf);
|
int len = readVarInt(buf);
|
||||||
checkArgument(len >= 0, "Got a negative-length integer array (%s)", len);
|
checkFrame(len >= 0, "Got a negative-length integer array (%s)", len);
|
||||||
|
checkFrame(buf.isReadable(len),
|
||||||
|
"Trying to read an array that is too long (wanted %s, only have %s)", len,
|
||||||
|
buf.readableBytes());
|
||||||
int[] array = new int[len];
|
int[] array = new int[len];
|
||||||
for (int i = 0; i < len; i++) {
|
for (int i = 0; i < len; i++) {
|
||||||
array[i] = readVarInt(buf);
|
array[i] = readVarInt(buf);
|
||||||
@@ -535,6 +538,10 @@ public enum ProtocolUtils {
|
|||||||
*/
|
*/
|
||||||
public static String[] readStringArray(ByteBuf buf) {
|
public static String[] readStringArray(ByteBuf buf) {
|
||||||
int length = readVarInt(buf);
|
int length = readVarInt(buf);
|
||||||
|
checkFrame(length >= 0, "Got a negative-length array (%s)", length);
|
||||||
|
checkFrame(buf.isReadable(length),
|
||||||
|
"Trying to read an array that is too long (wanted %s, only have %s)", length,
|
||||||
|
buf.readableBytes());
|
||||||
String[] ret = new String[length];
|
String[] ret = new String[length];
|
||||||
for (int i = 0; i < length; i++) {
|
for (int i = 0; i < length; i++) {
|
||||||
ret[i] = readString(buf);
|
ret[i] = readString(buf);
|
||||||
@@ -646,6 +653,9 @@ public enum ProtocolUtils {
|
|||||||
|
|
||||||
checkArgument(len <= FORGE_MAX_ARRAY_LENGTH,
|
checkArgument(len <= FORGE_MAX_ARRAY_LENGTH,
|
||||||
"Cannot receive array longer than %s (got %s bytes)", FORGE_MAX_ARRAY_LENGTH, len);
|
"Cannot receive array longer than %s (got %s bytes)", FORGE_MAX_ARRAY_LENGTH, len);
|
||||||
|
checkFrame(buf.isReadable(len),
|
||||||
|
"Trying to read an array that is too long (wanted %s, only have %s)", len,
|
||||||
|
buf.readableBytes());
|
||||||
|
|
||||||
byte[] ret = new byte[len];
|
byte[] ret = new byte[len];
|
||||||
buf.readBytes(ret);
|
buf.readBytes(ret);
|
||||||
@@ -844,6 +854,17 @@ public enum ProtocolUtils {
|
|||||||
writeVarInt(buf, source.ordinal());
|
writeVarInt(buf, source.ordinal());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a pre-sized list with a max initial size of {@code Short.MAX_VALUE}
|
||||||
|
*
|
||||||
|
* @param initialCapacity expected initial capacity
|
||||||
|
* @param <T> entry type
|
||||||
|
* @return pre-sized list
|
||||||
|
*/
|
||||||
|
public static <T> List<T> newList(int initialCapacity) {
|
||||||
|
return new ArrayList<>(Math.min(initialCapacity, Short.MAX_VALUE));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents the direction in which a packet flows.
|
* Represents the direction in which a packet flows.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -44,9 +44,9 @@ import io.netty.buffer.ByteBuf;
|
|||||||
import it.unimi.dsi.fastutil.objects.Object2IntLinkedOpenCustomHashMap;
|
import it.unimi.dsi.fastutil.objects.Object2IntLinkedOpenCustomHashMap;
|
||||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||||
import java.util.ArrayDeque;
|
import java.util.ArrayDeque;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Deque;
|
import java.util.Deque;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
@@ -85,14 +85,14 @@ public class AvailableCommandsPacket implements MinecraftPacket {
|
|||||||
@Override
|
@Override
|
||||||
public void decode(ByteBuf buf, Direction direction, ProtocolVersion protocolVersion) {
|
public void decode(ByteBuf buf, Direction direction, ProtocolVersion protocolVersion) {
|
||||||
int commands = ProtocolUtils.readVarInt(buf);
|
int commands = ProtocolUtils.readVarInt(buf);
|
||||||
WireNode[] wireNodes = new WireNode[commands];
|
List<WireNode> wireNodes = ProtocolUtils.newList(commands);
|
||||||
for (int i = 0; i < commands; i++) {
|
for (int i = 0; i < commands; i++) {
|
||||||
wireNodes[i] = deserializeNode(buf, i, protocolVersion);
|
wireNodes.add(deserializeNode(buf, i, protocolVersion));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Iterate over the deserialized nodes and attempt to form a graph. We also resolve any cycles
|
// Iterate over the deserialized nodes and attempt to form a graph. We also resolve any cycles
|
||||||
// that exist.
|
// that exist.
|
||||||
Queue<WireNode> nodeQueue = new ArrayDeque<>(Arrays.asList(wireNodes));
|
Queue<WireNode> nodeQueue = new ArrayDeque<>(wireNodes);
|
||||||
while (!nodeQueue.isEmpty()) {
|
while (!nodeQueue.isEmpty()) {
|
||||||
boolean cycling = false;
|
boolean cycling = false;
|
||||||
|
|
||||||
@@ -111,7 +111,7 @@ public class AvailableCommandsPacket implements MinecraftPacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int rootIdx = ProtocolUtils.readVarInt(buf);
|
int rootIdx = ProtocolUtils.readVarInt(buf);
|
||||||
rootNode = (RootCommandNode<CommandSource>) wireNodes[rootIdx].built;
|
rootNode = (RootCommandNode<CommandSource>) wireNodes.get(rootIdx).built;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -245,17 +245,17 @@ public class AvailableCommandsPacket implements MinecraftPacket {
|
|||||||
this.validated = false;
|
this.validated = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void validate(WireNode[] wireNodes) {
|
void validate(List<WireNode> wireNodes) {
|
||||||
// Ensure all children exist. Note that we delay checking if the node has been built yet;
|
// Ensure all children exist. Note that we delay checking if the node has been built yet;
|
||||||
// that needs to come after this node is built.
|
// that needs to come after this node is built.
|
||||||
for (int child : children) {
|
for (int child : children) {
|
||||||
if (child < 0 || child >= wireNodes.length) {
|
if (child < 0 || child >= wireNodes.size()) {
|
||||||
throw new IllegalStateException("Node points to non-existent index " + child);
|
throw new IllegalStateException("Node points to non-existent index " + child);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (redirectTo != -1) {
|
if (redirectTo != -1) {
|
||||||
if (redirectTo < 0 || redirectTo >= wireNodes.length) {
|
if (redirectTo < 0 || redirectTo >= wireNodes.size()) {
|
||||||
throw new IllegalStateException("Redirect node points to non-existent index "
|
throw new IllegalStateException("Redirect node points to non-existent index "
|
||||||
+ redirectTo);
|
+ redirectTo);
|
||||||
}
|
}
|
||||||
@@ -264,7 +264,7 @@ public class AvailableCommandsPacket implements MinecraftPacket {
|
|||||||
this.validated = true;
|
this.validated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean toNode(WireNode[] wireNodes) {
|
boolean toNode(List<WireNode> wireNodes) {
|
||||||
if (!this.validated) {
|
if (!this.validated) {
|
||||||
this.validate(wireNodes);
|
this.validate(wireNodes);
|
||||||
}
|
}
|
||||||
@@ -280,7 +280,7 @@ public class AvailableCommandsPacket implements MinecraftPacket {
|
|||||||
|
|
||||||
// Add any redirects
|
// Add any redirects
|
||||||
if (redirectTo != -1) {
|
if (redirectTo != -1) {
|
||||||
WireNode redirect = wireNodes[redirectTo];
|
WireNode redirect = wireNodes.get(redirectTo);
|
||||||
if (redirect.built != null) {
|
if (redirect.built != null) {
|
||||||
args.redirect(redirect.built);
|
args.redirect(redirect.built);
|
||||||
} else {
|
} else {
|
||||||
@@ -304,7 +304,7 @@ public class AvailableCommandsPacket implements MinecraftPacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (int child : children) {
|
for (int child : children) {
|
||||||
if (wireNodes[child].built == null) {
|
if (wireNodes.get(child).built == null) {
|
||||||
// The child is not yet deserialized. The node can't be built now.
|
// The child is not yet deserialized. The node can't be built now.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -312,7 +312,7 @@ public class AvailableCommandsPacket implements MinecraftPacket {
|
|||||||
|
|
||||||
// Associate children with nodes
|
// Associate children with nodes
|
||||||
for (int child : children) {
|
for (int child : children) {
|
||||||
CommandNode<CommandSource> childNode = wireNodes[child].built;
|
CommandNode<CommandSource> childNode = wireNodes.get(child).built;
|
||||||
if (!(childNode instanceof RootCommandNode)) {
|
if (!(childNode instanceof RootCommandNode)) {
|
||||||
built.addChild(childNode);
|
built.addChild(childNode);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,13 +18,11 @@
|
|||||||
package com.velocitypowered.proxy.protocol.packet.config;
|
package com.velocitypowered.proxy.protocol.packet.config;
|
||||||
|
|
||||||
import com.velocitypowered.api.network.ProtocolVersion;
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
import com.velocitypowered.api.util.ServerLink;
|
|
||||||
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
||||||
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
||||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||||
import com.velocitypowered.proxy.protocol.packet.chat.ComponentHolder;
|
import com.velocitypowered.proxy.protocol.packet.chat.ComponentHolder;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class ClientboundServerLinksPacket implements MinecraftPacket {
|
public class ClientboundServerLinksPacket implements MinecraftPacket {
|
||||||
@@ -42,7 +40,7 @@ public class ClientboundServerLinksPacket implements MinecraftPacket {
|
|||||||
public void decode(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersion version) {
|
public void decode(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersion version) {
|
||||||
int linksCount = ProtocolUtils.readVarInt(buf);
|
int linksCount = ProtocolUtils.readVarInt(buf);
|
||||||
|
|
||||||
this.serverLinks = new ArrayList<>(linksCount);
|
this.serverLinks = ProtocolUtils.newList(linksCount);
|
||||||
for (int i = 0; i < linksCount; i++) {
|
for (int i = 0; i < linksCount; i++) {
|
||||||
serverLinks.add(ServerLink.read(buf, version));
|
serverLinks.add(ServerLink.read(buf, version));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
|||||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||||
import com.velocitypowered.proxy.util.except.QuietDecoderException;
|
import com.velocitypowered.proxy.util.except.QuietDecoderException;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class KnownPacksPacket implements MinecraftPacket {
|
public class KnownPacksPacket implements MinecraftPacket {
|
||||||
|
|
||||||
@@ -30,7 +31,7 @@ public class KnownPacksPacket implements MinecraftPacket {
|
|||||||
private static final QuietDecoderException TOO_MANY_PACKS =
|
private static final QuietDecoderException TOO_MANY_PACKS =
|
||||||
new QuietDecoderException("too many known packs");
|
new QuietDecoderException("too many known packs");
|
||||||
|
|
||||||
private KnownPack[] packs;
|
private List<KnownPack> packs;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
public void decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||||
@@ -40,10 +41,10 @@ public class KnownPacksPacket implements MinecraftPacket {
|
|||||||
throw TOO_MANY_PACKS;
|
throw TOO_MANY_PACKS;
|
||||||
}
|
}
|
||||||
|
|
||||||
final KnownPack[] packs = new KnownPack[packCount];
|
final List<KnownPack> packs = ProtocolUtils.newList(packCount);
|
||||||
|
|
||||||
for (int i = 0; i < packCount; i++) {
|
for (int i = 0; i < packCount; i++) {
|
||||||
packs[i] = KnownPack.read(buf);
|
packs.add(KnownPack.read(buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
this.packs = packs;
|
this.packs = packs;
|
||||||
@@ -52,7 +53,7 @@ public class KnownPacksPacket implements MinecraftPacket {
|
|||||||
@Override
|
@Override
|
||||||
public void encode(ByteBuf buf, ProtocolUtils.Direction direction,
|
public void encode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||||
ProtocolVersion protocolVersion) {
|
ProtocolVersion protocolVersion) {
|
||||||
ProtocolUtils.writeVarInt(buf, packs.length);
|
ProtocolUtils.writeVarInt(buf, packs.size());
|
||||||
|
|
||||||
for (KnownPack pack : packs) {
|
for (KnownPack pack : packs) {
|
||||||
pack.write(buf);
|
pack.write(buf);
|
||||||
|
|||||||
Reference in New Issue
Block a user