fix(rooms): harden room item packet guards

This commit is contained in:
simoleo89
2026-06-15 22:07:24 +02:00
parent c48e01cb8e
commit bea385afe2
4 changed files with 100 additions and 4 deletions
@@ -0,0 +1,37 @@
package com.eu.habbo.messages.incoming.rooms.items;
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 RoomPickupChooserContractTest {
private static String source() throws Exception {
return Files.readString(Path.of("src/main/java/com/eu/habbo/messages/incoming/rooms/items/RoomPickupChooserEvent.java"));
}
@Test
void rejectsInvalidBatchSizesBeforeReadingItemIds() throws Exception {
String source = source();
int countRead = source.indexOf("int count = this.packet.readInt()");
int guard = source.indexOf("count <= 0 || count > MAX_PICKUP_CHOOSER_ITEMS", countRead);
int loop = source.indexOf("for (int i = 0; i < count; i++)", countRead);
assertTrue(countRead > -1, "Pickup chooser must read the client-provided count");
assertTrue(guard > countRead, "Pickup chooser must reject invalid batch sizes");
assertTrue(guard < loop, "Batch size validation must happen before consuming item ids");
}
@Test
void chooserSkipsPostItsLikeSinglePickup() throws Exception {
String source = source();
assertTrue(source.contains("import com.eu.habbo.habbohotel.items.interactions.InteractionPostIt;"));
assertTrue(source.contains("item instanceof InteractionPostIt"));
assertTrue(source.contains("continue;"));
}
}
@@ -0,0 +1,44 @@
package com.eu.habbo.messages.incoming.rooms.items;
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 SavePostItStickyPoleContractTest {
private static String source() throws Exception {
return Files.readString(Path.of("src/main/java/com/eu/habbo/messages/incoming/rooms/items/SavePostItStickyPoleEvent.java"));
}
@Test
void stickyPoleTextIsFilteredAndBoundedBeforeMutation() throws Exception {
String source = source();
int textRead = source.indexOf("WordFilter().filter");
int charLimit = source.indexOf("text.length() > Emulator.getConfig().getInt(\"postit.charlimit\")", textRead);
int update = source.indexOf("sticky.setExtradata", textRead);
assertTrue(textRead > -1, "Sticky pole text should pass through the word filter");
assertTrue(charLimit > textRead, "Sticky pole text must enforce the configured post-it char limit");
assertTrue(charLimit < update, "Sticky pole text must be bounded before item mutation");
}
@Test
void stickyPoleOnlyMutatesPostItItemsInARoom() throws Exception {
String source = source();
assertTrue(source.contains("if (room == null)"));
assertTrue(source.contains("sticky instanceof InteractionPostIt"));
}
@Test
void stickyPoleNormalizesCustomOrYellowColors() throws Exception {
String source = source();
assertTrue(source.contains("PostItColor.isCustomColor(color) || color.equalsIgnoreCase(PostItColor.YELLOW.hexColor)"));
assertTrue(source.contains("PostItColor.randomColorNotYellow().hexColor"));
}
}