From 0d820eddd455c8dab6cc4a222b9c7c1290ec0dfa Mon Sep 17 00:00:00 2001 From: LexManos Date: Wed, 15 Nov 2023 09:09:18 -0800 Subject: [PATCH] Add more sanitization to the ChannelListManager because other projects like to impose arbitrary critical restrictions. Closes #9789 #9772 --- .../network/ChannelListManager.java | 31 ++++++++++++++----- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/src/main/java/net/minecraftforge/network/ChannelListManager.java b/src/main/java/net/minecraftforge/network/ChannelListManager.java index 5f84b5b409..8bfbddefd8 100644 --- a/src/main/java/net/minecraftforge/network/ChannelListManager.java +++ b/src/main/java/net/minecraftforge/network/ChannelListManager.java @@ -88,6 +88,9 @@ public class ChannelListManager { } private static void sendChannels(EventNetworkChannel channel, Connection connection, Collection channels) { + if (channels.isEmpty()) + return; + var buf = new FriendlyByteBuf(Unpooled.buffer()); for (var c : channels) { buf.writeBytes(c.toString().getBytes(StandardCharsets.UTF_8)); @@ -100,22 +103,34 @@ public class ChannelListManager { private static void updateFrom(CustomPayloadEvent.Context source, FriendlyByteBuf buffer, final ChannelRegistrationChangeEvent.Type changeType) { byte[] data = new byte[Math.max(buffer.readableBytes(), 0)]; buffer.readBytes(data); - var changed = new HashSet(); + var channels = new HashSet(); int last = 0; for (int cur = 0; cur < data.length; cur++) { if (data[cur] == '\0') { - var channel = new String(data, last, cur - last, StandardCharsets.UTF_8); - try { - changed.add(new ResourceLocation(channel)); - } catch (ResourceLocationException ex) { - // Vanilla packet deserializers now force this to be a resource location, so we should never get this, but just in case. - LOGGER.warn("Invalid channel name received: {}. Ignoring", channel); - } + channels.add(new String(data, last, cur - last, StandardCharsets.UTF_8)); last = cur + 1; } } + // Add the end of the data because the spec doesn't actually say null terminated, just null separated + if (last < data.length) + channels.add(new String(data, last, data.length - last, StandardCharsets.UTF_8)); + + var changed = new HashSet(); + for (var channel : channels) { + // It also says nothing about the format of channels of channels so ignore bad channels. + if (channel.isEmpty()) + continue; + + try { + changed.add(new ResourceLocation(channel)); + } catch (ResourceLocationException ex) { + // Vanilla packet deserializers now force this to be a resource location, so we should never get this, but just in case. + LOGGER.warn("Invalid channel name received: {}. Ignoring", channel); + } + } + ForgeEventFactory.onChannelRegistrationChange(source.getConnection(), changeType, changed); var list = NetworkContext.get(source.getConnection());