You've already forked Arcturus-Morningstar-Extended
mirror of
https://github.com/duckietm/Arcturus-Morningstar-Extended.git
synced 2026-06-20 15:36:17 +00:00
fix(guilds): validate badge packet parts
This commit is contained in:
@@ -0,0 +1,52 @@
|
|||||||
|
package com.eu.habbo.habbohotel.guilds;
|
||||||
|
|
||||||
|
import com.eu.habbo.messages.ClientMessage;
|
||||||
|
import com.eu.habbo.util.PacketGuard;
|
||||||
|
|
||||||
|
public final class GuildBadgeBuilder {
|
||||||
|
public static final int MAX_BADGE_PARTS = 5;
|
||||||
|
private static final int INTS_PER_PART = 3;
|
||||||
|
private static final int BYTES_PER_INT = 4;
|
||||||
|
private static final int MAX_PART_ID = 999;
|
||||||
|
private static final int MAX_COLOR_ID = 99;
|
||||||
|
private static final int MAX_POSITION = 8;
|
||||||
|
|
||||||
|
private GuildBadgeBuilder() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String readBadge(ClientMessage packet, int flatPartValueCount) {
|
||||||
|
if (flatPartValueCount % INTS_PER_PART != 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
int partCount = flatPartValueCount / INTS_PER_PART;
|
||||||
|
if (!PacketGuard.isCountInRange(partCount, 1, MAX_BADGE_PARTS)
|
||||||
|
|| !PacketGuard.hasFixedWidthEntries(packet, flatPartValueCount, BYTES_PER_INT)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder badge = new StringBuilder(partCount * 6);
|
||||||
|
for (int partIndex = 0; partIndex < partCount; partIndex++) {
|
||||||
|
int id = packet.readInt();
|
||||||
|
int color = packet.readInt();
|
||||||
|
int position = packet.readInt();
|
||||||
|
|
||||||
|
if (!isValidPart(id, color, position)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
badge.append(partIndex == 0 ? "b" : "s");
|
||||||
|
badge.append(id < 100 ? "0" : "").append(id < 10 ? "0" : "").append(id);
|
||||||
|
badge.append(color < 10 ? "0" : "").append(color);
|
||||||
|
badge.append(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
return badge.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isValidPart(int id, int color, int position) {
|
||||||
|
return id >= 0 && id <= MAX_PART_ID
|
||||||
|
&& color >= 0 && color <= MAX_COLOR_ID
|
||||||
|
&& position >= 0 && position <= MAX_POSITION;
|
||||||
|
}
|
||||||
|
}
|
||||||
+3
-19
@@ -2,6 +2,7 @@ package com.eu.habbo.messages.incoming.guilds;
|
|||||||
|
|
||||||
import com.eu.habbo.Emulator;
|
import com.eu.habbo.Emulator;
|
||||||
import com.eu.habbo.habbohotel.guilds.Guild;
|
import com.eu.habbo.habbohotel.guilds.Guild;
|
||||||
|
import com.eu.habbo.habbohotel.guilds.GuildBadgeBuilder;
|
||||||
import com.eu.habbo.habbohotel.permissions.Permission;
|
import com.eu.habbo.habbohotel.permissions.Permission;
|
||||||
import com.eu.habbo.habbohotel.rooms.Room;
|
import com.eu.habbo.habbohotel.rooms.Room;
|
||||||
import com.eu.habbo.messages.incoming.MessageHandler;
|
import com.eu.habbo.messages.incoming.MessageHandler;
|
||||||
@@ -27,25 +28,8 @@ public class GuildChangeBadgeEvent extends MessageHandler {
|
|||||||
|
|
||||||
int count = this.packet.readInt();
|
int count = this.packet.readInt();
|
||||||
|
|
||||||
String badge = "";
|
String badge = GuildBadgeBuilder.readBadge(this.packet, count);
|
||||||
|
if (badge == null) return;
|
||||||
byte base = 1;
|
|
||||||
|
|
||||||
while (base < count) {
|
|
||||||
int id = this.packet.readInt();
|
|
||||||
int color = this.packet.readInt();
|
|
||||||
int pos = this.packet.readInt();
|
|
||||||
|
|
||||||
if (base == 1) {
|
|
||||||
badge += "b";
|
|
||||||
} else {
|
|
||||||
badge += "s";
|
|
||||||
}
|
|
||||||
|
|
||||||
badge += (id < 100 ? "0" : "") + (id < 10 ? "0" : "") + id + (color < 10 ? "0" : "") + color + "" + pos;
|
|
||||||
|
|
||||||
base += 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (guild.getBadge().equalsIgnoreCase(badge))
|
if (guild.getBadge().equalsIgnoreCase(badge))
|
||||||
return;
|
return;
|
||||||
|
|||||||
+6
-19
@@ -2,6 +2,7 @@ package com.eu.habbo.messages.incoming.guilds;
|
|||||||
|
|
||||||
import com.eu.habbo.Emulator;
|
import com.eu.habbo.Emulator;
|
||||||
import com.eu.habbo.habbohotel.guilds.Guild;
|
import com.eu.habbo.habbohotel.guilds.Guild;
|
||||||
|
import com.eu.habbo.habbohotel.guilds.GuildBadgeBuilder;
|
||||||
import com.eu.habbo.habbohotel.modtool.ScripterManager;
|
import com.eu.habbo.habbohotel.modtool.ScripterManager;
|
||||||
import com.eu.habbo.habbohotel.permissions.Permission;
|
import com.eu.habbo.habbohotel.permissions.Permission;
|
||||||
import com.eu.habbo.habbohotel.rooms.Room;
|
import com.eu.habbo.habbohotel.rooms.Room;
|
||||||
@@ -69,24 +70,10 @@ public class RequestGuildBuyEvent extends MessageHandler {
|
|||||||
|
|
||||||
int count = this.packet.readInt();
|
int count = this.packet.readInt();
|
||||||
|
|
||||||
StringBuilder badge = new StringBuilder();
|
String badge = GuildBadgeBuilder.readBadge(this.packet, count);
|
||||||
|
if (badge == null) {
|
||||||
byte base = 1;
|
this.client.sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR));
|
||||||
|
return;
|
||||||
while (base < count) {
|
|
||||||
int id = this.packet.readInt();
|
|
||||||
int color = this.packet.readInt();
|
|
||||||
int pos = this.packet.readInt();
|
|
||||||
|
|
||||||
if (base == 1) {
|
|
||||||
badge.append("b");
|
|
||||||
} else {
|
|
||||||
badge.append("s");
|
|
||||||
}
|
|
||||||
|
|
||||||
badge.append(id < 100 ? "0" : "").append(id < 10 ? "0" : "").append(id).append(color < 10 ? "0" : "").append(color).append(pos);
|
|
||||||
|
|
||||||
base += 3;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only charge the player once every step has been validated. Previously the
|
// Only charge the player once every step has been validated. Previously the
|
||||||
@@ -103,7 +90,7 @@ public class RequestGuildBuyEvent extends MessageHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Guild guild = Emulator.getGameEnvironment().getGuildManager().createGuild(this.client.getHabbo(), roomId, r.getName(), name, description, badge.toString(), colorOne, colorTwo);
|
Guild guild = Emulator.getGameEnvironment().getGuildManager().createGuild(this.client.getHabbo(), roomId, r.getName(), name, description, badge, colorOne, colorTwo);
|
||||||
|
|
||||||
r.setGuild(guild.getId());
|
r.setGuild(guild.getId());
|
||||||
r.removeAllRights();
|
r.removeAllRights();
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package com.eu.habbo.util;
|
||||||
|
|
||||||
|
import com.eu.habbo.messages.ClientMessage;
|
||||||
|
|
||||||
|
public final class PacketGuard {
|
||||||
|
private PacketGuard() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isCountInRange(int count, int min, int max) {
|
||||||
|
return count >= min && count <= max;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean hasReadableBytes(ClientMessage packet, int requiredBytes) {
|
||||||
|
return packet != null && requiredBytes >= 0 && packet.bytesAvailable() >= requiredBytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean hasFixedWidthEntries(ClientMessage packet, int entryCount, int bytesPerEntry) {
|
||||||
|
if (packet == null || entryCount < 0 || bytesPerEntry < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
long requiredBytes = (long) entryCount * bytesPerEntry;
|
||||||
|
return requiredBytes <= Integer.MAX_VALUE && packet.bytesAvailable() >= requiredBytes;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
package com.eu.habbo.habbohotel.guilds;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
|
|
||||||
|
import com.eu.habbo.messages.ClientMessage;
|
||||||
|
import io.netty.buffer.Unpooled;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
class GuildBadgeBuilderTest {
|
||||||
|
@Test
|
||||||
|
void buildsBadgeFromFlatPartTriplets() {
|
||||||
|
ClientMessage packet = messageWithInts(
|
||||||
|
1, 2, 4,
|
||||||
|
35, 8, 0
|
||||||
|
);
|
||||||
|
|
||||||
|
assertEquals("b001024s035080", GuildBadgeBuilder.readBadge(packet, 6));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void rejectsCountThatDoesNotRepresentCompleteTriplets() {
|
||||||
|
ClientMessage packet = messageWithInts(1, 2, 4);
|
||||||
|
|
||||||
|
assertNull(GuildBadgeBuilder.readBadge(packet, 4));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void rejectsPayloadShorterThanDeclaredCount() {
|
||||||
|
ClientMessage packet = messageWithInts(1, 2);
|
||||||
|
|
||||||
|
assertNull(GuildBadgeBuilder.readBadge(packet, 3));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void rejectsTooManyBadgeParts() {
|
||||||
|
ClientMessage packet = messageWithInts(
|
||||||
|
1, 1, 4,
|
||||||
|
2, 1, 4,
|
||||||
|
3, 1, 4,
|
||||||
|
4, 1, 4,
|
||||||
|
5, 1, 4,
|
||||||
|
6, 1, 4
|
||||||
|
);
|
||||||
|
|
||||||
|
assertNull(GuildBadgeBuilder.readBadge(packet, 18));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void rejectsPartValuesOutsideBadgeCodeRanges() {
|
||||||
|
assertNull(GuildBadgeBuilder.readBadge(messageWithInts(1000, 1, 4), 3));
|
||||||
|
assertNull(GuildBadgeBuilder.readBadge(messageWithInts(1, 100, 4), 3));
|
||||||
|
assertNull(GuildBadgeBuilder.readBadge(messageWithInts(1, 1, 9), 3));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ClientMessage messageWithInts(int... values) {
|
||||||
|
var buffer = Unpooled.buffer(values.length * Integer.BYTES);
|
||||||
|
for (int value : values) {
|
||||||
|
buffer.writeInt(value);
|
||||||
|
}
|
||||||
|
return new ClientMessage(0, buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user