mirror of
https://github.com/Pumpkin-MC/Pumpkin.git
synced 2026-08-31 20:32:34 +00:00
fix(inventory): guard Swap slot click against negative slot index (#2313)
The `Swap` branch of `internal_on_slot_click` indexed
`self.get_behaviour().slots[slot_index as usize]` without first checking
`slot_index >= 0`, unlike every sibling branch (Pickup, QuickMove, Throw,
Clone, QuickCraft) which all guard with `if slot_index < 0 { return; }`.
`slot_index` originates from the client `SClickSlot` packet (`i16` slot
field, widened to `i32`). The upstream validation in `Player::on_slot_click`
relies on `ScreenHandler::is_slot_valid`, whose check
`slot == -1 || slot == -999 || slot < slots.len() as i32` returns `true`
for ANY negative slot (a negative value is always `< slots.len()`), so
negative indices are not filtered out before reaching the handler. A
crafted Swap packet with a negative slot (e.g. -5) and a hotbar button in
`0..9` (or 40) therefore evaluated `slots[(-5) as usize]`, an enormous
index, causing an out-of-bounds Vec panic and crashing the server.
Add the same `if slot_index < 0 { return; }` guard at the top of the Swap
branch, matching the sibling branches exactly. Minimal, low-risk: legitimate
Swap clicks always carry a non-negative container slot, so behaviour is
unchanged for valid input.
This commit is contained in:
@@ -1223,6 +1223,9 @@ pub trait ScreenHandler: Send + Sync {
|
||||
} else if action_type == SlotActionType::Swap && (0..9).contains(&button)
|
||||
|| button == 40
|
||||
{
|
||||
if slot_index < 0 {
|
||||
return;
|
||||
}
|
||||
let mut button_stack = player
|
||||
.get_inventory()
|
||||
.get_stack(button as usize)
|
||||
|
||||
Reference in New Issue
Block a user