You've already forked Arcturus-Morningstar-Extended
mirror of
https://github.com/duckietm/Arcturus-Morningstar-Extended.git
synced 2026-06-19 15:06:19 +00:00
fix(wired): bound save payloads
This commit is contained in:
+6
-26
@@ -2,6 +2,7 @@ package com.eu.habbo.habbohotel.items.interactions;
|
||||
|
||||
import com.eu.habbo.Emulator;
|
||||
import com.eu.habbo.habbohotel.items.Item;
|
||||
import com.eu.habbo.habbohotel.items.interactions.wired.WiredInputGuard;
|
||||
import com.eu.habbo.habbohotel.items.interactions.wired.WiredSettings;
|
||||
import com.eu.habbo.habbohotel.rooms.Room;
|
||||
import com.eu.habbo.habbohotel.rooms.RoomUnit;
|
||||
@@ -230,39 +231,18 @@ public abstract class InteractionWired extends InteractionDefault {
|
||||
|
||||
public static WiredSettings readSettings(ClientMessage packet, boolean isEffect)
|
||||
{
|
||||
int intParamCount = packet.readInt();
|
||||
if (intParamCount < 0 || intParamCount > 100) {
|
||||
throw new IllegalArgumentException("Invalid intParamCount: " + intParamCount);
|
||||
}
|
||||
int[] intParams = new int[intParamCount];
|
||||
|
||||
for(int i = 0; i < intParamCount; i++)
|
||||
{
|
||||
intParams[i] = packet.readInt();
|
||||
}
|
||||
|
||||
String stringParam = packet.readString();
|
||||
|
||||
int itemCount = packet.readInt();
|
||||
int selectionLimit = Emulator.getConfig() != null ? Emulator.getConfig().getInt("hotel.wired.furni.selection.count", 5) : 5;
|
||||
if (itemCount < 0 || itemCount > selectionLimit * 20) {
|
||||
throw new IllegalArgumentException("Invalid itemCount: " + itemCount + " exceeds maximum allowed limit");
|
||||
}
|
||||
int[] itemIds = new int[itemCount];
|
||||
|
||||
for(int i = 0; i < itemCount; i++)
|
||||
{
|
||||
itemIds[i] = packet.readInt();
|
||||
}
|
||||
int[] intParams = WiredInputGuard.readIntParams(packet);
|
||||
String stringParam = WiredInputGuard.readStringParam(packet);
|
||||
int[] itemIds = WiredInputGuard.readFurniIds(packet);
|
||||
|
||||
WiredSettings settings = new WiredSettings(intParams, stringParam, itemIds, -1);
|
||||
|
||||
if(isEffect)
|
||||
{
|
||||
settings.setDelay(packet.readInt());
|
||||
settings.setDelay(WiredInputGuard.normalizeDelay(packet.readInt()));
|
||||
}
|
||||
|
||||
settings.setStuffTypeSelectionCode(packet.readInt());
|
||||
settings.setStuffTypeSelectionCode(WiredInputGuard.normalizeStuffSelectionCode(packet.readInt()));
|
||||
return settings;
|
||||
}
|
||||
}
|
||||
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
package com.eu.habbo.habbohotel.items.interactions.wired;
|
||||
|
||||
import com.eu.habbo.Emulator;
|
||||
import com.eu.habbo.messages.ClientMessage;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public final class WiredInputGuard {
|
||||
public static final int MAX_INT_PARAMS = 100;
|
||||
public static final int MAX_STRING_PARAM_LENGTH = 1024;
|
||||
public static final int MAX_ABSOLUTE_FURNI_IDS = 100;
|
||||
public static final int DEFAULT_MAX_DELAY = 20;
|
||||
public static final int MAX_ABSOLUTE_DELAY = 3600;
|
||||
public static final int MIN_STUFF_SELECTION_CODE = -1;
|
||||
public static final int MAX_STUFF_SELECTION_CODE = 2;
|
||||
|
||||
private WiredInputGuard() {
|
||||
}
|
||||
|
||||
public static int[] readIntParams(ClientMessage packet) {
|
||||
int count = packet.readInt();
|
||||
if (count < 0 || count > MAX_INT_PARAMS) {
|
||||
throw new IllegalArgumentException("Invalid wired int param count");
|
||||
}
|
||||
|
||||
int[] values = new int[count];
|
||||
for (int i = 0; i < count; i++) {
|
||||
values[i] = packet.readInt();
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
public static String readStringParam(ClientMessage packet) {
|
||||
String value = packet.readString();
|
||||
if (value == null || value.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return value.length() > MAX_STRING_PARAM_LENGTH
|
||||
? value.substring(0, MAX_STRING_PARAM_LENGTH)
|
||||
: value;
|
||||
}
|
||||
|
||||
public static int[] readFurniIds(ClientMessage packet) {
|
||||
int count = packet.readInt();
|
||||
int maxCount = maxFurniSelectionCount();
|
||||
if (count < 0 || count > maxCount) {
|
||||
throw new IllegalArgumentException("Invalid wired furni selection count");
|
||||
}
|
||||
|
||||
int[] values = new int[count];
|
||||
int accepted = 0;
|
||||
for (int i = 0; i < count; i++) {
|
||||
int itemId = packet.readInt();
|
||||
if (itemId > 0) {
|
||||
values[accepted++] = itemId;
|
||||
}
|
||||
}
|
||||
|
||||
return accepted == values.length ? values : Arrays.copyOf(values, accepted);
|
||||
}
|
||||
|
||||
public static int normalizeDelay(int delay) {
|
||||
return Math.max(0, Math.min(delay, maxDelay()));
|
||||
}
|
||||
|
||||
public static int normalizeStuffSelectionCode(int code) {
|
||||
if (code < MIN_STUFF_SELECTION_CODE || code > MAX_STUFF_SELECTION_CODE) {
|
||||
return MIN_STUFF_SELECTION_CODE;
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
public static int maxFurniSelectionCount() {
|
||||
int selectionLimit = Emulator.getConfig() != null
|
||||
? Emulator.getConfig().getInt("hotel.wired.furni.selection.count", 5)
|
||||
: 5;
|
||||
selectionLimit = Math.max(1, selectionLimit);
|
||||
return Math.min(MAX_ABSOLUTE_FURNI_IDS, selectionLimit * 20);
|
||||
}
|
||||
|
||||
public static int maxDelay() {
|
||||
int configured = Emulator.getConfig() != null
|
||||
? Emulator.getConfig().getInt("hotel.wired.max_delay", DEFAULT_MAX_DELAY)
|
||||
: DEFAULT_MAX_DELAY;
|
||||
configured = Math.max(0, configured);
|
||||
return Math.min(MAX_ABSOLUTE_DELAY, configured);
|
||||
}
|
||||
}
|
||||
+7
-1
@@ -31,7 +31,13 @@ public class WiredConditionSaveDataEvent extends MessageHandler {
|
||||
|
||||
if(saveMethod.isPresent()) {
|
||||
if (saveMethod.get().getParameterTypes()[0] == WiredSettings.class) {
|
||||
WiredSettings settings = InteractionWired.readSettings(this.packet, false);
|
||||
WiredSettings settings;
|
||||
try {
|
||||
settings = InteractionWired.readSettings(this.packet, false);
|
||||
} catch (IllegalArgumentException e) {
|
||||
this.client.sendResponse(new UpdateFailedComposer("Invalid wired condition settings"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (condition.saveData(settings)) {
|
||||
this.client.sendResponse(new WiredSavedComposer());
|
||||
|
||||
+7
-1
@@ -28,7 +28,13 @@ public class WiredEffectSaveDataEvent extends MessageHandler {
|
||||
if (effect == null && extra == null)
|
||||
throw new WiredSaveException(String.format("Wired effect/extra with item id %s not found in room", itemId));
|
||||
|
||||
WiredSettings settings = InteractionWired.readSettings(this.packet, true);
|
||||
WiredSettings settings;
|
||||
try {
|
||||
settings = InteractionWired.readSettings(this.packet, true);
|
||||
} catch (IllegalArgumentException e) {
|
||||
this.client.sendResponse(new UpdateFailedComposer("Invalid wired effect settings"));
|
||||
return;
|
||||
}
|
||||
boolean saved;
|
||||
|
||||
if (effect != null) {
|
||||
|
||||
+7
-1
@@ -22,7 +22,13 @@ public class WiredTriggerSaveDataEvent extends MessageHandler {
|
||||
InteractionWiredTrigger trigger = room.getRoomSpecialTypes().getTrigger(itemId);
|
||||
|
||||
if (trigger != null) {
|
||||
WiredSettings settings = InteractionWired.readSettings(this.packet, false);
|
||||
WiredSettings settings;
|
||||
try {
|
||||
settings = InteractionWired.readSettings(this.packet, false);
|
||||
} catch (IllegalArgumentException e) {
|
||||
this.client.sendResponse(new UpdateFailedComposer("Invalid wired trigger settings"));
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
boolean saved = trigger.saveData(settings, this.client);
|
||||
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
package com.eu.habbo.habbohotel.items.interactions.wired;
|
||||
|
||||
import com.eu.habbo.messages.ClientMessage;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
class WiredInputGuardTest {
|
||||
|
||||
@Test
|
||||
void trimsOversizedStringParams() {
|
||||
String input = "x".repeat(WiredInputGuard.MAX_STRING_PARAM_LENGTH + 1);
|
||||
ClientMessage message = new ClientMessage(1, stringBuffer(input));
|
||||
|
||||
assertEquals(WiredInputGuard.MAX_STRING_PARAM_LENGTH,
|
||||
WiredInputGuard.readStringParam(message).length());
|
||||
}
|
||||
|
||||
@Test
|
||||
void filtersNonPositiveFurniIds() {
|
||||
ByteBuf buffer = Unpooled.buffer();
|
||||
buffer.writeInt(4);
|
||||
buffer.writeInt(1);
|
||||
buffer.writeInt(0);
|
||||
buffer.writeInt(-1);
|
||||
buffer.writeInt(2);
|
||||
|
||||
assertArrayEquals(new int[]{1, 2}, WiredInputGuard.readFurniIds(new ClientMessage(1, buffer)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void clampsDelayAndSelectionCode() {
|
||||
assertEquals(0, WiredInputGuard.normalizeDelay(-10));
|
||||
assertEquals(WiredInputGuard.DEFAULT_MAX_DELAY, WiredInputGuard.normalizeDelay(WiredInputGuard.DEFAULT_MAX_DELAY + 1));
|
||||
assertEquals(-1, WiredInputGuard.normalizeStuffSelectionCode(99));
|
||||
assertEquals(2, WiredInputGuard.normalizeStuffSelectionCode(2));
|
||||
}
|
||||
|
||||
private static ByteBuf stringBuffer(String value) {
|
||||
byte[] bytes = value.getBytes(StandardCharsets.UTF_8);
|
||||
ByteBuf buffer = Unpooled.buffer();
|
||||
buffer.writeShort(bytes.length);
|
||||
buffer.writeBytes(bytes);
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user