SpigotMC / BungeeCord

BungeeCord, the 6th in a generation of server portal suites. Efficiently proxies and maintains connections and transport between multiple Minecraft servers.
https://www.spigotmc.org/go/bungeecord
Other
1.57k stars 1.1k forks source link

Just canceling onLogin throws NullPointerException (and not fully closing connection) #3355

Closed iselink closed 2 years ago

iselink commented 2 years ago

Bungeecord version

git:BungeeCord-Bootstrap:1.19-R0.1-SNAPSHOT:587fb37:1653

Server version

n/a

Client version

1.19 (1.18.2)

Bungeecord plugins

None (only test plugin).

The bug

By cancelling login event, server throws exception and closing connection (without client not being aware) if reason is not set.
Client is stuck on Encrypting until timeout.

@EventHandler
public void onLogin(LoginEvent event) {
  event.setCancelled(true);
}

If cancel reason is set, proxy works as expected. In offline mode exception is still thrown but client is disconnected immediately.

Edit: I believe PreLogin event is affected as well; not tested against clean BugeeCord.

Log output (links)

03:10:37 [INFO] [/127.0.0.1:52770] <-> InitialHandler has pinged
03:10:39 [INFO] [/127.0.0.1:52786] <-> InitialHandler has connected
03:10:40 [WARNING] An exceptionCaught() event was fired, and it reached at the tail of the pipeline. It usually means the last handler in the pipeline did not handle the exception.
java.lang.NullPointerException: Cannot read the array length because "components" is null
at net.md_5.bungee.chat.ComponentSerializer.toString(ComponentSerializer.java:74)
at net.md_5.bungee.connection.InitialHandler.disconnect(InitialHandler.java:625)
at net.md_5.bungee.connection.InitialHandler$6.done(InitialHandler.java:554)
at net.md_5.bungee.connection.InitialHandler$6.done(InitialHandler.java:548)
at net.md_5.bungee.api.event.AsyncEvent.postCall(AsyncEvent.java:40)
at net.md_5.bungee.api.plugin.PluginManager.callEvent(PluginManager.java:413)
at net.md_5.bungee.connection.InitialHandler.finish(InitialHandler.java:599)
at net.md_5.bungee.connection.InitialHandler.access$800(InitialHandler.java:73)
at net.md_5.bungee.connection.InitialHandler$5.done(InitialHandler.java:494)
at net.md_5.bungee.connection.InitialHandler$5.done(InitialHandler.java:482)
at net.md_5.bungee.http.HttpHandler.done(HttpHandler.java:69)
at net.md_5.bungee.http.HttpHandler.channelRead0(HttpHandler.java:60)
at net.md_5.bungee.http.HttpHandler.channelRead0(HttpHandler.java:14)
at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:99)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:436)
at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:327)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:299)
at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:251)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1372)
at io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1235)
at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1284)
at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:510)
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:449)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:279)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:286)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
at io.netty.channel.epoll.AbstractEpollStreamChannel$EpollStreamUnsafe.epollInReady(AbstractEpollStreamChannel.java:800)
at io.netty.channel.epoll.EpollEventLoop.processReady(EpollEventLoop.java:487)
at io.netty.channel.epoll.EpollEventLoop.run(EpollEventLoop.java:385)
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:995)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at java.base/java.lang.Thread.run(Thread.java:833)

Checking

Janmm14 commented 2 years ago

Looks like a valid bug. Login event handler should check for null and use this as fallback.