From cb51262fb39d515d6951add825f6c5387989c463 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 13 Oct 2026 16:49:42 +0000 Subject: [PATCH 1/4] Fix CraftContainer silent fall-through for CRAFTING/CREATIVE Invalid InventoryType.CRAFTING and CREATIVE now throw IllegalArgumentException in setupSlots and getNotchInventoryType, matching CraftHumanEntity.openInventory. WORKBENCH and other legitimate custom-container types are unchanged. Co-authored-by: xii69 --- .../craftbukkit/inventory/CraftContainer.java | 9 +++- .../CraftContainerInventoryTypeTest.java | 53 +++++++++++++++++++ 2 files changed, 60 insertions(+), 2 deletions(-) create mode 100644 WindSpigot-Server/src/test/java/com/windpvp/windspigot/inventory/CraftContainerInventoryTypeTest.java diff --git a/WindSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java b/WindSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java index 2dc5f9de0..922e9cae3 100644 --- a/WindSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java +++ b/WindSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java @@ -95,6 +95,10 @@ public boolean c(EntityHuman entityhuman) { public static String getNotchInventoryType(InventoryType type) { switch (type) { + case CREATIVE: + case CRAFTING: + // Player crafting / creative UIs are client-owned; mirror CraftHumanEntity.openInventory. + throw new IllegalArgumentException("Can't open a " + type + " inventory!"); case WORKBENCH: return "minecraft:crafting_table"; case FURNACE: @@ -119,7 +123,9 @@ public static String getNotchInventoryType(InventoryType type) { private void setupSlots(IInventory top, IInventory bottom) { switch (cachedType) { case CREATIVE: - break; // TODO: This should be an error? + case CRAFTING: + // Silent no-op / workbench fall-through hid programming errors and slot desync. + throw new IllegalArgumentException("Can't open a " + cachedType + " inventory!"); case PLAYER: case CHEST: setupChest(top, bottom); @@ -130,7 +136,6 @@ private void setupSlots(IInventory top, IInventory bottom) { case FURNACE: setupFurnace(top, bottom); break; - case CRAFTING: // TODO: This should be an error? case WORKBENCH: setupWorkbench(top, bottom); break; diff --git a/WindSpigot-Server/src/test/java/com/windpvp/windspigot/inventory/CraftContainerInventoryTypeTest.java b/WindSpigot-Server/src/test/java/com/windpvp/windspigot/inventory/CraftContainerInventoryTypeTest.java new file mode 100644 index 000000000..5a9082a3b --- /dev/null +++ b/WindSpigot-Server/src/test/java/com/windpvp/windspigot/inventory/CraftContainerInventoryTypeTest.java @@ -0,0 +1,53 @@ +package com.windpvp.windspigot.inventory; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import org.bukkit.craftbukkit.inventory.CraftContainer; +import org.bukkit.event.inventory.InventoryType; +import org.junit.Test; + +/** + * Invalid InventoryTypes (player CRAFTING / CREATIVE) must fail loudly in + * CraftContainer instead of silent fall-through / wrong notch window type. + */ +public class CraftContainerInventoryTypeTest { + + @Test + public void creativeTypeThrowsFromGetNotchInventoryType() { + assertThrowsCantOpen(InventoryType.CREATIVE); + } + + @Test + public void craftingTypeThrowsFromGetNotchInventoryType() { + assertThrowsCantOpen(InventoryType.CRAFTING); + } + + @Test + public void workbenchRemainsValidCraftingTableWindow() { + assertEquals("minecraft:crafting_table", CraftContainer.getNotchInventoryType(InventoryType.WORKBENCH)); + } + + @Test + public void legitimateTypesStillMap() { + assertEquals("minecraft:furnace", CraftContainer.getNotchInventoryType(InventoryType.FURNACE)); + assertEquals("minecraft:chest", CraftContainer.getNotchInventoryType(InventoryType.CHEST)); + assertEquals("minecraft:chest", CraftContainer.getNotchInventoryType(InventoryType.PLAYER)); + assertEquals("minecraft:chest", CraftContainer.getNotchInventoryType(InventoryType.ENDER_CHEST)); + assertEquals("minecraft:hopper", CraftContainer.getNotchInventoryType(InventoryType.HOPPER)); + assertEquals("minecraft:anvil", CraftContainer.getNotchInventoryType(InventoryType.ANVIL)); + assertEquals("minecraft:beacon", CraftContainer.getNotchInventoryType(InventoryType.BEACON)); + assertEquals("minecraft:dispenser", CraftContainer.getNotchInventoryType(InventoryType.DISPENSER)); + assertEquals("minecraft:enchanting_table", CraftContainer.getNotchInventoryType(InventoryType.ENCHANTING)); + assertEquals("minecraft:brewing_stand", CraftContainer.getNotchInventoryType(InventoryType.BREWING)); + } + + private static void assertThrowsCantOpen(InventoryType type) { + try { + CraftContainer.getNotchInventoryType(type); + fail("expected IllegalArgumentException for " + type); + } catch (IllegalArgumentException expected) { + assertEquals("Can't open a " + type + " inventory!", expected.getMessage()); + } + } +} From d1cf28f5b4b634a553f259e827cc1fe67161d95d Mon Sep 17 00:00:00 2001 From: Elias Date: Wed, 14 Oct 2026 20:15:33 +0200 Subject: [PATCH 2/4] Update CraftContainer.java --- .../java/org/bukkit/craftbukkit/inventory/CraftContainer.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/WindSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java b/WindSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java index 922e9cae3..41b30cc6d 100644 --- a/WindSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java +++ b/WindSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java @@ -97,7 +97,6 @@ public static String getNotchInventoryType(InventoryType type) { switch (type) { case CREATIVE: case CRAFTING: - // Player crafting / creative UIs are client-owned; mirror CraftHumanEntity.openInventory. throw new IllegalArgumentException("Can't open a " + type + " inventory!"); case WORKBENCH: return "minecraft:crafting_table"; @@ -124,7 +123,6 @@ private void setupSlots(IInventory top, IInventory bottom) { switch (cachedType) { case CREATIVE: case CRAFTING: - // Silent no-op / workbench fall-through hid programming errors and slot desync. throw new IllegalArgumentException("Can't open a " + cachedType + " inventory!"); case PLAYER: case CHEST: From 371409c5d71fc7009ff8b90a5c1703b15b71e45d Mon Sep 17 00:00:00 2001 From: Elias Date: Wed, 14 Oct 2026 20:15:47 +0200 Subject: [PATCH 3/4] Delete WindSpigot-Server/src/test/java/com/windpvp/windspigot/inventory/CraftContainerInventoryTypeTest.java --- .../CraftContainerInventoryTypeTest.java | 53 ------------------- 1 file changed, 53 deletions(-) delete mode 100644 WindSpigot-Server/src/test/java/com/windpvp/windspigot/inventory/CraftContainerInventoryTypeTest.java diff --git a/WindSpigot-Server/src/test/java/com/windpvp/windspigot/inventory/CraftContainerInventoryTypeTest.java b/WindSpigot-Server/src/test/java/com/windpvp/windspigot/inventory/CraftContainerInventoryTypeTest.java deleted file mode 100644 index 5a9082a3b..000000000 --- a/WindSpigot-Server/src/test/java/com/windpvp/windspigot/inventory/CraftContainerInventoryTypeTest.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.windpvp.windspigot.inventory; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; - -import org.bukkit.craftbukkit.inventory.CraftContainer; -import org.bukkit.event.inventory.InventoryType; -import org.junit.Test; - -/** - * Invalid InventoryTypes (player CRAFTING / CREATIVE) must fail loudly in - * CraftContainer instead of silent fall-through / wrong notch window type. - */ -public class CraftContainerInventoryTypeTest { - - @Test - public void creativeTypeThrowsFromGetNotchInventoryType() { - assertThrowsCantOpen(InventoryType.CREATIVE); - } - - @Test - public void craftingTypeThrowsFromGetNotchInventoryType() { - assertThrowsCantOpen(InventoryType.CRAFTING); - } - - @Test - public void workbenchRemainsValidCraftingTableWindow() { - assertEquals("minecraft:crafting_table", CraftContainer.getNotchInventoryType(InventoryType.WORKBENCH)); - } - - @Test - public void legitimateTypesStillMap() { - assertEquals("minecraft:furnace", CraftContainer.getNotchInventoryType(InventoryType.FURNACE)); - assertEquals("minecraft:chest", CraftContainer.getNotchInventoryType(InventoryType.CHEST)); - assertEquals("minecraft:chest", CraftContainer.getNotchInventoryType(InventoryType.PLAYER)); - assertEquals("minecraft:chest", CraftContainer.getNotchInventoryType(InventoryType.ENDER_CHEST)); - assertEquals("minecraft:hopper", CraftContainer.getNotchInventoryType(InventoryType.HOPPER)); - assertEquals("minecraft:anvil", CraftContainer.getNotchInventoryType(InventoryType.ANVIL)); - assertEquals("minecraft:beacon", CraftContainer.getNotchInventoryType(InventoryType.BEACON)); - assertEquals("minecraft:dispenser", CraftContainer.getNotchInventoryType(InventoryType.DISPENSER)); - assertEquals("minecraft:enchanting_table", CraftContainer.getNotchInventoryType(InventoryType.ENCHANTING)); - assertEquals("minecraft:brewing_stand", CraftContainer.getNotchInventoryType(InventoryType.BREWING)); - } - - private static void assertThrowsCantOpen(InventoryType type) { - try { - CraftContainer.getNotchInventoryType(type); - fail("expected IllegalArgumentException for " + type); - } catch (IllegalArgumentException expected) { - assertEquals("Can't open a " + type + " inventory!", expected.getMessage()); - } - } -} From 02cb9a67f5cdc388e6904fa2f7273aa800ce745c Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 14 Oct 2026 21:11:44 +0000 Subject: [PATCH 4/4] Fix CraftContainer silent fall-through for CRAFTING/CREATIVE Co-authored-by: xii69 --- .../org/bukkit/craftbukkit/inventory/CraftContainer.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/WindSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java b/WindSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java index 2dc5f9de0..41b30cc6d 100644 --- a/WindSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java +++ b/WindSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java @@ -95,6 +95,9 @@ public boolean c(EntityHuman entityhuman) { public static String getNotchInventoryType(InventoryType type) { switch (type) { + case CREATIVE: + case CRAFTING: + throw new IllegalArgumentException("Can't open a " + type + " inventory!"); case WORKBENCH: return "minecraft:crafting_table"; case FURNACE: @@ -119,7 +122,8 @@ public static String getNotchInventoryType(InventoryType type) { private void setupSlots(IInventory top, IInventory bottom) { switch (cachedType) { case CREATIVE: - break; // TODO: This should be an error? + case CRAFTING: + throw new IllegalArgumentException("Can't open a " + cachedType + " inventory!"); case PLAYER: case CHEST: setupChest(top, bottom); @@ -130,7 +134,6 @@ private void setupSlots(IInventory top, IInventory bottom) { case FURNACE: setupFurnace(top, bottom); break; - case CRAFTING: // TODO: This should be an error? case WORKBENCH: setupWorkbench(top, bottom); break;