fix(crafting): bound secret ingredients

This commit is contained in:
simoleo89
2026-06-17 21:39:52 +02:00
parent 0109c25c80
commit 6b4da4f916
2 changed files with 50 additions and 4 deletions
@@ -20,11 +20,18 @@ import java.util.Map;
import java.util.Set;
public class CraftingCraftSecretEvent extends MessageHandler {
static final int MAX_SECRET_CRAFT_INGREDIENTS = 50;
@Override
public void handle() throws Exception {
int altarId = this.packet.readInt();
int count = this.packet.readInt();
if (count <= 0 || count > MAX_SECRET_CRAFT_INGREDIENTS) {
this.client.sendResponse(new CraftingResultComposer(null));
return;
}
HabboItem craftingAltar = this.client.getHabbo().getHabboInfo().getCurrentRoom().getHabboItem(altarId);
if (craftingAltar != null) {
@@ -35,15 +42,14 @@ public class CraftingCraftSecretEvent extends MessageHandler {
Map<Item, Integer> items = new THashMap<>();
for (int i = 0; i < count; i++) {
HabboItem habboItem = this.client.getHabbo().getInventory().getItemsComponent().getHabboItem(this.packet.readInt());
int itemId = this.packet.readInt();
HabboItem habboItem = this.client.getHabbo().getInventory().getItemsComponent().getHabboItem(itemId);
if (habboItem == null) {
if (habboItem == null || !habboItems.add(habboItem)) {
this.client.sendResponse(new CraftingResultComposer(null));
return;
}
habboItems.add(habboItem);
if (!items.containsKey(habboItem.getBaseItem())) {
items.put(habboItem.getBaseItem(), 0);
}
@@ -0,0 +1,40 @@
package com.eu.habbo.messages.incoming.crafting;
import org.junit.jupiter.api.Test;
import java.nio.file.Files;
import java.nio.file.Path;
import static org.junit.jupiter.api.Assertions.assertTrue;
class CraftingCraftSecretContractTest {
private static String source() throws Exception {
return Files.readString(Path.of("src/main/java/com/eu/habbo/messages/incoming/crafting/CraftingCraftSecretEvent.java"));
}
@Test
void rejectsInvalidIngredientCountsBeforeReadingItemIds() throws Exception {
String source = source();
int countRead = source.indexOf("int count = this.packet.readInt()");
int guard = source.indexOf("count <= 0 || count > MAX_SECRET_CRAFT_INGREDIENTS", countRead);
int loop = source.indexOf("for (int i = 0; i < count; i++)", guard);
assertTrue(countRead > -1, "secret crafting must read the client supplied ingredient count");
assertTrue(guard > countRead, "secret crafting must validate the ingredient count");
assertTrue(loop > guard, "ingredient count validation must happen before item id reads");
}
@Test
void rejectsDuplicateIngredientItemsBeforeRecipeLookup() throws Exception {
String source = source();
int setDeclaration = source.indexOf("Set<HabboItem> habboItems = new THashSet<>()");
int duplicateGuard = source.indexOf("habboItem == null || !habboItems.add(habboItem)", setDeclaration);
int recipeLookup = source.indexOf("CraftingRecipe recipe = altar.getRecipe(items)", duplicateGuard);
assertTrue(setDeclaration > -1, "secret crafting should track unique inventory items");
assertTrue(duplicateGuard > setDeclaration, "secret crafting must reject duplicate item ids");
assertTrue(recipeLookup > duplicateGuard, "duplicate rejection must happen before recipe lookup/reward creation");
}
}