From 6100e675af9d85358403cf84893a6bdaddd2d519 Mon Sep 17 00:00:00 2001 From: Shane Freeder Date: Wed, 21 Aug 2024 16:44:13 +0100 Subject: [PATCH] Switch to alt throw path for reading login message IDs (Fixes #1370) There is little expectation that we should get a -ve number in here, but it is sadly seen in the wild. We will use an alternative exception path rather than returing a magic number to indicate an invalid value. once primative classes arrive, this should probably be written to use those for passing up the result. --- .../proxy/protocol/ProtocolUtils.java | 23 +++++++++++++++++++ .../packet/LoginPluginMessagePacket.java | 2 +- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/ProtocolUtils.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/ProtocolUtils.java index 622186a99c..053dcd65f0 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/ProtocolUtils.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/ProtocolUtils.java @@ -156,6 +156,29 @@ public static int readVarIntSafely(ByteBuf buf) { return Integer.MIN_VALUE; } + /** + * Reads a Minecraft-style VarInt from the specified {@code buf}. The difference between this + * method and {@link #readVarInt(ByteBuf)} is that this function returns a sentinel value if the + * varint is invalid. + * + * @param buf the buffer to read from + * @return the decoded VarInt + * @throws DecoderException if the varint is invalid + */ + public static int readVarIntSafelyOrThrow(ByteBuf buf) { + int i = 0; + int maxRead = Math.min(5, buf.readableBytes()); + for (int j = 0; j < maxRead; j++) { + int k = buf.readByte(); + i |= (k & 0x7F) << j * 7; + if ((k & 0x80) != 128) { + return i; + } + } + throw MinecraftDecoder.DEBUG ? new CorruptedFrameException("Bad VarInt decoded") + : BAD_VARINT_CACHED; + } + /** * Returns the exact byte size of {@code value} if it were encoded as a VarInt. * diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/LoginPluginMessagePacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/LoginPluginMessagePacket.java index 682785eb27..213492cbfc 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/LoginPluginMessagePacket.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/LoginPluginMessagePacket.java @@ -63,7 +63,7 @@ public String toString() { @Override public void decode(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersion version) { - this.id = ProtocolUtils.readVarInt(buf); + this.id = ProtocolUtils.readVarIntSafelyOrThrow(buf); this.channel = ProtocolUtils.readString(buf); if (buf.isReadable()) { this.replace(buf.readRetainedSlice(buf.readableBytes()));