From dc6a912632e3da74a71574ea18f7c4f913a42cf6 Mon Sep 17 00:00:00 2001 From: simoleo89 Date: Wed, 17 Jun 2026 19:13:00 +0200 Subject: [PATCH] fix(wired): bound user condition payloads --- .../conditions/WiredConditionActorDir.java | 14 +++++-- .../WiredConditionTriggererMatch.java | 29 ++++++++++---- .../WiredConditionUserPayloadGuardTest.java | 38 +++++++++++++++++++ 3 files changed, 69 insertions(+), 12 deletions(-) create mode 100644 Emulator/src/test/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionUserPayloadGuardTest.java diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionActorDir.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionActorDir.java index a9670b2e..16eb8f83 100644 --- a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionActorDir.java +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionActorDir.java @@ -111,7 +111,13 @@ public class WiredConditionActorDir extends InteractionWiredCondition { } if (wiredData.startsWith("{")) { - JsonData data = WiredManager.getGson().fromJson(wiredData, JsonData.class); + JsonData data; + try { + data = WiredManager.getGson().fromJson(wiredData, JsonData.class); + } catch (RuntimeException exception) { + this.onPickUp(); + return; + } if (data == null) { return; @@ -157,15 +163,15 @@ public class WiredConditionActorDir extends InteractionWiredCondition { return (this.directionMask & (1 << direction)) != 0; } - private int normalizeDirectionMask(int value) { + int normalizeDirectionMask(int value) { return value & ALL_DIRECTIONS_MASK; } - private int normalizeUserSource(int value) { + int normalizeUserSource(int value) { return WiredSourceUtil.isDefaultUserSource(value) ? value : WiredSourceUtil.SOURCE_TRIGGER; } - private int normalizeQuantifier(int value) { + int normalizeQuantifier(int value) { return (value == QUANTIFIER_ANY) ? QUANTIFIER_ANY : QUANTIFIER_ALL; } diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionTriggererMatch.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionTriggererMatch.java index e7f01dcb..8609dda3 100644 --- a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionTriggererMatch.java +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionTriggererMatch.java @@ -33,6 +33,7 @@ public class WiredConditionTriggererMatch extends InteractionWiredCondition { protected static final int QUANTIFIER_ALL = 0; protected static final int QUANTIFIER_ANY = 1; protected static final int SOURCE_SPECIFIED_USERNAME = 101; + protected static final int MAX_USERNAME_LENGTH = 64; public static final WiredConditionType type = WiredConditionType.TRIGGERER_MATCH; @@ -84,7 +85,14 @@ public class WiredConditionTriggererMatch extends InteractionWiredCondition { return; } - JsonData data = WiredManager.getGson().fromJson(wiredData, JsonData.class); + JsonData data; + try { + data = WiredManager.getGson().fromJson(wiredData, JsonData.class); + } catch (RuntimeException exception) { + this.resetSettings(); + return; + } + if (data == null) { return; } @@ -284,7 +292,7 @@ public class WiredConditionTriggererMatch extends InteractionWiredCondition { return ""; } - private int normalizeEntityType(int value) { + int normalizeEntityType(int value) { switch (value) { case ENTITY_HABBO: case ENTITY_PET: @@ -295,19 +303,19 @@ public class WiredConditionTriggererMatch extends InteractionWiredCondition { } } - private int normalizeAvatarMode(int value) { + int normalizeAvatarMode(int value) { return (value == AVATAR_MODE_CERTAIN) ? AVATAR_MODE_CERTAIN : AVATAR_MODE_ANY; } - private int normalizeQuantifier(int value) { + int normalizeQuantifier(int value) { return (value == QUANTIFIER_ANY) ? QUANTIFIER_ANY : QUANTIFIER_ALL; } - private int normalizePrimaryUserSource(int value) { + int normalizePrimaryUserSource(int value) { return WiredSourceUtil.isDefaultUserSource(value) ? value : WiredSourceUtil.SOURCE_TRIGGER; } - private int normalizeCompareUserSource(int value) { + int normalizeCompareUserSource(int value) { switch (value) { case WiredSourceUtil.SOURCE_CLICKED_USER: case SOURCE_SPECIFIED_USERNAME: @@ -317,8 +325,13 @@ public class WiredConditionTriggererMatch extends InteractionWiredCondition { } } - private String normalizeUsername(String value) { - return (value == null) ? "" : value.trim(); + String normalizeUsername(String value) { + if (value == null) { + return ""; + } + + String normalized = value.trim(); + return normalized.length() <= MAX_USERNAME_LENGTH ? normalized : normalized.substring(0, MAX_USERNAME_LENGTH); } protected static class MatchResult { diff --git a/Emulator/src/test/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionUserPayloadGuardTest.java b/Emulator/src/test/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionUserPayloadGuardTest.java new file mode 100644 index 00000000..e2f8e856 --- /dev/null +++ b/Emulator/src/test/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionUserPayloadGuardTest.java @@ -0,0 +1,38 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.conditions; + +import com.eu.habbo.habbohotel.wired.core.WiredSourceUtil; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class WiredConditionUserPayloadGuardTest { + @Test + void actorDirectionBoundsMaskSourceAndQuantifier() { + WiredConditionActorDir condition = new WiredConditionActorDir(1, 1, null, "", 0, 0); + + assertEquals(255, condition.normalizeDirectionMask(-1)); + assertEquals(0, condition.normalizeDirectionMask(256)); + assertEquals(WiredSourceUtil.SOURCE_CLICKED_USER, condition.normalizeUserSource(WiredSourceUtil.SOURCE_CLICKED_USER)); + assertEquals(WiredSourceUtil.SOURCE_TRIGGER, condition.normalizeUserSource(123_456)); + assertEquals(1, condition.normalizeQuantifier(1)); + assertEquals(0, condition.normalizeQuantifier(2)); + } + + @Test + void triggererMatchBoundsEntitySourcesQuantifierAndUsername() { + WiredConditionTriggererMatch condition = new WiredConditionTriggererMatch(1, 1, null, "", 0, 0); + + assertEquals(WiredConditionTriggererMatch.ENTITY_HABBO, condition.normalizeEntityType(999)); + assertEquals(WiredConditionTriggererMatch.ENTITY_PET, condition.normalizeEntityType(WiredConditionTriggererMatch.ENTITY_PET)); + assertEquals(WiredConditionTriggererMatch.AVATAR_MODE_CERTAIN, condition.normalizeAvatarMode(1)); + assertEquals(WiredConditionTriggererMatch.AVATAR_MODE_ANY, condition.normalizeAvatarMode(2)); + assertEquals(WiredSourceUtil.SOURCE_SIGNAL, condition.normalizePrimaryUserSource(WiredSourceUtil.SOURCE_SIGNAL)); + assertEquals(WiredSourceUtil.SOURCE_TRIGGER, condition.normalizePrimaryUserSource(900)); + assertEquals(WiredConditionTriggererMatch.SOURCE_SPECIFIED_USERNAME, condition.normalizeCompareUserSource(WiredConditionTriggererMatch.SOURCE_SPECIFIED_USERNAME)); + assertEquals(WiredSourceUtil.SOURCE_TRIGGER, condition.normalizeCompareUserSource(-1)); + assertEquals(1, condition.normalizeQuantifier(1)); + assertEquals(0, condition.normalizeQuantifier(5)); + assertEquals("tester", condition.normalizeUsername(" tester ")); + assertEquals(WiredConditionTriggererMatch.MAX_USERNAME_LENGTH, condition.normalizeUsername("x".repeat(200)).length()); + } +}