Skip to content

fix async packet type logic, buffer slicing, and null/out-of-bounds guards - #3655

Open
Spagles wants to merge 4 commits into
dmulloy2:masterfrom
Spagles:master
Open

fix async packet type logic, buffer slicing, and null/out-of-bounds guards#3655
Spagles wants to merge 4 commits into
dmulloy2:masterfrom
Spagles:master

Conversation

@Spagles

@Spagles Spagles commented Aug 3, 2026

Copy link
Copy Markdown
  • fixed inverted return values for getSendingTypes() and getReceivingTypes() in AsyncFilterManager
  • fixed StreamSerializer.getBytesAndRelease() returning un-trimmed backing arrays with trailing capacity bytes
  • added missing array boundary checks to IntegerMap.remove() to prevent ArrayIndexOutOfBoundsException
  • added a null check for players in PlayerSendingHandler.getSendingQueue() to prevent NullPointerException on login/status packets

@dmulloy2 dmulloy2 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review findings are attached inline.

return bytes;
}
byte[] bytes = new byte[buf.readableBytes()];
buf.readBytes(bytes);

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

readBytes advances the caller's readerIndex, while the previous heap-buffer path left it unchanged. Since this is a public method, that is an observable compatibility change for callers that retain/reuse the buffer. Could we use ByteBufUtil.getBytes(buf) instead? It returns the exact readable bytes, handles direct buffers and array offsets, and preserves the indices. Please also add a regression assertion for both exact output length and unchanged readerIndex.

public PacketSendingQueue getSendingQueue(PacketEvent packet, boolean createNew) {
QueueContainer queues = playerSendingQueues.get(packet.getPlayer());
Player player = packet.getPlayer();
if (player == null)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not cover the reported login/status failure: those events normally have a non-null TemporaryPlayer. The remaining reachable NPE is when ConcurrentPlayerMap.cachePlayerKey derives a null address and inserts it into the Guava cache. Please guard the derived key there. Keeping the local player variable is still useful because it removes the weak-reference TOCTOU between the lookup and putIfAbsent.

@Override
public Set<PacketType> getSendingTypes() {
return clientProcessingQueue.keySet();
return serverProcessingQueue.keySet();

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This mapping correction is right, but no existing test distinguishes the old inverted behavior. Please add a regression test with a sending-only whitelist and assert that its type appears in getSendingTypes() and not getReceivingTypes().

* @return The old associated value, or NULL.
*/
public T remove(int key) {
if (key < 0 || key >= array.length) return null;

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add regression coverage for negative and oversized keys, asserting remove() returns null and leaves size() unchanged. There currently are no IntegerMap.remove() bounds tests, so this can regress without detection.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants