This bug was introduced in 23w42a
Previously, the maximum string length of serialized components was 262144 characters, but starting from 23w42a, it has been changed to 32767. (Only writing. reading is still 262144)
How to Reproduce:
1. Set the ban reason for the player to be over 32704 characters.
2. Connect to the server.
Stacktrace:
[15:11:15] [Netty Server IO #2/ERROR]: Error receiving packet 0
io.netty.handler.codec.EncoderException: String too big (was 32768 characters, max 32767)
at uv.a(SourceFile:38) ~[server-1.20.4.jar:?]
at ui.a(SourceFile:637) ~[server-1.20.4.jar:?]
at ui.a(SourceFile:633) ~[server-1.20.4.jar:?]
at afr.a(SourceFile:23) ~[server-1.20.4.jar:?]
at um.a(SourceFile:47) ~[server-1.20.4.jar:?]
at um.encode(SourceFile:15) ~[server-1.20.4.jar:?]
at io.netty.handler.codec.MessageToByteEncoder.write(MessageToByteEncoder.java:107) ~[netty-codec-4.1.97.Final.jar:4.1.97.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeWrite0(AbstractChannelHandlerContext.java:881) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeWrite(AbstractChannelHandlerContext.java:863) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:968) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:856) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
at io.netty.handler.codec.MessageToMessageEncoder.write(MessageToMessageEncoder.java:113) ~[netty-codec-4.1.97.Final.jar:4.1.97.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeWrite0(AbstractChannelHandlerContext.java:881) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeWriteAndFlush(AbstractChannelHandlerContext.java:940) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:966) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
at io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:934) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
at io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:984) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
at io.netty.channel.DefaultChannelPipeline.writeAndFlush(DefaultChannelPipeline.java:1025) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
at io.netty.channel.AbstractChannel.writeAndFlush(AbstractChannel.java:306) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
at ug.c(SourceFile:321) ~[server-1.20.4.jar:?]
at ug.d(SourceFile:316) ~[server-1.20.4.jar:?]
at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:174) ~[netty-common-4.1.97.Final.jar:4.1.97.Final]
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:167) ~[netty-common-4.1.97.Final.jar:4.1.97.Final]
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:470) ~[netty-common-4.1.97.Final.jar:4.1.97.Final]
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:569) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997) ~[netty-common-4.1.97.Final.jar:4.1.97.Final]
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.97.Final.jar:4.1.97.Final]
at java.lang.Thread.run(Thread.java:840) ~[?:?]
Code analysis:
...
public class ClientboundLoginDisconnectPacket implements Packet<ClientLoginPacketListener> {
...
public ClientboundLoginDisconnectPacket(FriendlyByteBuf buf) {
this.reason = Component.Serializer.fromJsonLenient(buf.readUtf(FriendlyByteBuf.MAX_COMPONENT_STRING_LENGTH));
}
@Override
public void write(FriendlyByteBuf buf) {
//buf.writeUtf(Component.Serializer.toJson(this.reason));
// Set the maximum component length correctly.
buf.writeUtf(Component.Serializer.toJson(this.reason), FriendlyByteBuf.MAX_COMPONENT_STRING_LENGTH);
}
...
Comments 2
Ban reason is converted to JSON component format when sent to the player.
The converted ban reason always has the following format. (64 number of characters)
{"translate":"multiplayer.disconnect.banned.reason","with":[""]}
To trigger the error, it needs to exceed 32767 characters(32768+), so 32704 characters or more is correct.
Is it intended that the number of characters mentioned in the "How to Reproduce" part is different to 32767?