Merge pull request #230 from simoleo89/fix/catalog-inputs

fix(catalog): bound marketplace inputs
This commit is contained in:
DuckieTM
2026-06-17 10:01:29 +02:00
committed by GitHub
9 changed files with 161 additions and 8 deletions
@@ -0,0 +1,50 @@
package com.eu.habbo.messages.incoming.catalog.marketplace;
import org.junit.jupiter.api.Test;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertTrue;
class MarketplaceInputContractTest {
@Test
void marketplaceIdHandlersRejectNonPositiveIds() throws Exception {
Path base = Path.of("src/main/java/com/eu/habbo/messages/incoming/catalog/marketplace");
for (String handler : List.of(
"BuyItemEvent.java",
"RequestItemInfoEvent.java",
"SellItemEvent.java",
"TakeBackItemEvent.java"
)) {
String source = Files.readString(base.resolve(handler));
assertTrue(source.contains("MarketplaceInputGuard.isPositiveId"),
handler + " must reject zero or negative ids before marketplace or inventory lookup");
}
}
@Test
void offerSearchNormalizesCacheKeyInputs() throws Exception {
String source = Files.readString(Path.of("src/main/java/com/eu/habbo/messages/incoming/catalog/marketplace/RequestOffersEvent.java"));
assertTrue(source.contains("MarketplaceInputGuard.normalizeMinPrice"),
"marketplace offer search must normalize minimum price");
assertTrue(source.contains("MarketplaceInputGuard.normalizeMaxPrice"),
"marketplace offer search must normalize maximum price");
assertTrue(source.contains("MarketplaceInputGuard.normalizeSearch"),
"marketplace offer search must trim and bound search text");
assertTrue(source.contains("MarketplaceInputGuard.normalizeSort"),
"marketplace offer search must normalize sort before using it as a cache key");
}
@Test
void takeBackDoesNotFirePluginEventForMissingOffer() throws Exception {
String source = Files.readString(Path.of("src/main/java/com/eu/habbo/habbohotel/catalog/marketplace/MarketPlace.java"));
assertTrue(source.contains("if (offer == null)"),
"takeBackItem must ignore missing offers before constructing plugin events");
}
}
@@ -0,0 +1,42 @@
package com.eu.habbo.messages.incoming.catalog.marketplace;
import com.eu.habbo.habbohotel.catalog.marketplace.MarketPlace;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
class MarketplaceInputGuardTest {
@Test
void idsMustBePositive() {
assertFalse(MarketplaceInputGuard.isPositiveId(0));
assertFalse(MarketplaceInputGuard.isPositiveId(-1));
assertTrue(MarketplaceInputGuard.isPositiveId(1));
}
@Test
void searchIsTrimmedAndBounded() {
assertEquals("", MarketplaceInputGuard.normalizeSearch(null));
assertEquals("rare", MarketplaceInputGuard.normalizeSearch(" rare "));
assertEquals(MarketplaceInputGuard.MAX_SEARCH_LENGTH, MarketplaceInputGuard.normalizeSearch("a".repeat(80)).length());
}
@Test
void sortFallsBackToDefaultOutsideKnownRange() {
assertEquals(MarketplaceInputGuard.DEFAULT_SORT, MarketplaceInputGuard.normalizeSort(0));
assertEquals(3, MarketplaceInputGuard.normalizeSort(3));
assertEquals(MarketplaceInputGuard.DEFAULT_SORT, MarketplaceInputGuard.normalizeSort(7));
}
@Test
void priceRangesPreserveCacheSentinelAndStayBounded() {
assertEquals(-1, MarketplaceInputGuard.normalizeMinPrice(-1));
assertEquals(0, MarketplaceInputGuard.normalizeMinPrice(-100));
assertEquals(MarketPlace.MAXIMUM_LISTING_PRICE, MarketplaceInputGuard.normalizeMinPrice(Integer.MAX_VALUE));
assertEquals(-1, MarketplaceInputGuard.normalizeMaxPrice(-1, -1));
assertEquals(500, MarketplaceInputGuard.normalizeMaxPrice(100, 500));
assertEquals(MarketPlace.MAXIMUM_LISTING_PRICE, MarketplaceInputGuard.normalizeMaxPrice(Integer.MAX_VALUE, 0));
}
}