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(housekeeping): cap sanction durations safely
This commit is contained in:
+1
-5
@@ -17,9 +17,6 @@ import java.util.List;
|
||||
*/
|
||||
public class HousekeepingBanUserEvent extends MessageHandler {
|
||||
private static final String ACTION_KEY = "user.ban";
|
||||
private static final int SECONDS_IN_HOUR = 3600;
|
||||
// 100-year ceiling, matches ModToolSanctionBanEvent's permanent ban.
|
||||
private static final int MAX_DURATION_SECONDS = 100 * 365 * 24 * 3600;
|
||||
|
||||
@Override
|
||||
public int getRatelimit() {
|
||||
@@ -46,8 +43,7 @@ public class HousekeepingBanUserEvent extends MessageHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
long durationLong = (long) hours * SECONDS_IN_HOUR;
|
||||
int duration = durationLong > MAX_DURATION_SECONDS ? MAX_DURATION_SECONDS : (int) durationLong;
|
||||
int duration = HousekeepingSanctionDuration.secondsFromHours(hours);
|
||||
|
||||
List<ModToolBan> bans = Emulator.getGameEnvironment().getModToolManager()
|
||||
.ban(userId, this.client.getHabbo(), reason != null ? reason : "", duration, ModToolBanType.ACCOUNT, 0);
|
||||
|
||||
+1
-2
@@ -15,7 +15,6 @@ import com.eu.habbo.messages.outgoing.housekeeping.HousekeepingActionResultCompo
|
||||
*/
|
||||
public class HousekeepingMuteUserEvent extends MessageHandler {
|
||||
private static final String ACTION_KEY = "user.mute";
|
||||
private static final int SECONDS_IN_MINUTE = 60;
|
||||
|
||||
@Override
|
||||
public int getRatelimit() {
|
||||
@@ -49,7 +48,7 @@ public class HousekeepingMuteUserEvent extends MessageHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
target.mute(minutes * SECONDS_IN_MINUTE, false);
|
||||
target.mute(HousekeepingSanctionDuration.secondsFromMinutes(minutes), false);
|
||||
|
||||
if (reason != null && !reason.isEmpty()) {
|
||||
target.alert(reason);
|
||||
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
package com.eu.habbo.messages.incoming.housekeeping;
|
||||
|
||||
final class HousekeepingSanctionDuration {
|
||||
static final int SECONDS_IN_MINUTE = 60;
|
||||
static final int SECONDS_IN_HOUR = 3600;
|
||||
static final int MAX_SECONDS = Integer.MAX_VALUE;
|
||||
|
||||
private HousekeepingSanctionDuration() {
|
||||
}
|
||||
|
||||
static int secondsFromHours(int hours) {
|
||||
if (hours <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
long seconds = (long) hours * SECONDS_IN_HOUR;
|
||||
return seconds > MAX_SECONDS ? MAX_SECONDS : (int) seconds;
|
||||
}
|
||||
|
||||
static int secondsFromMinutes(int minutes) {
|
||||
if (minutes <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
long seconds = (long) minutes * SECONDS_IN_MINUTE;
|
||||
return seconds > MAX_SECONDS ? MAX_SECONDS : (int) seconds;
|
||||
}
|
||||
|
||||
static int unixUntil(int now, int durationSeconds) {
|
||||
if (durationSeconds <= 0) {
|
||||
return now;
|
||||
}
|
||||
|
||||
long until = (long) now + durationSeconds;
|
||||
return until > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) until;
|
||||
}
|
||||
}
|
||||
+2
-5
@@ -20,8 +20,6 @@ import java.sql.SQLException;
|
||||
*/
|
||||
public class HousekeepingTradeLockUserEvent extends MessageHandler {
|
||||
private static final String ACTION_KEY = "user.trade_lock";
|
||||
private static final int SECONDS_IN_HOUR = 3600;
|
||||
private static final int MAX_DURATION_SECONDS = 100 * 365 * 24 * 3600;
|
||||
|
||||
@Override
|
||||
public int getRatelimit() {
|
||||
@@ -48,9 +46,8 @@ public class HousekeepingTradeLockUserEvent extends MessageHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
long durationLong = (long) hours * SECONDS_IN_HOUR;
|
||||
int duration = durationLong > MAX_DURATION_SECONDS ? MAX_DURATION_SECONDS : (int) durationLong;
|
||||
int lockedUntil = Emulator.getIntUnixTimestamp() + duration;
|
||||
int duration = HousekeepingSanctionDuration.secondsFromHours(hours);
|
||||
int lockedUntil = HousekeepingSanctionDuration.unixUntil(Emulator.getIntUnixTimestamp(), duration);
|
||||
|
||||
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection();
|
||||
PreparedStatement statement = connection.prepareStatement("UPDATE users_settings SET trade_locked_until = ? WHERE user_id = ? LIMIT 1")) {
|
||||
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
package com.eu.habbo.messages.incoming.housekeeping;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
class HousekeepingSanctionDurationContractTest {
|
||||
private static final Path BAN_SOURCE = Path.of(
|
||||
"src/main/java/com/eu/habbo/messages/incoming/housekeeping/HousekeepingBanUserEvent.java");
|
||||
private static final Path MUTE_SOURCE = Path.of(
|
||||
"src/main/java/com/eu/habbo/messages/incoming/housekeeping/HousekeepingMuteUserEvent.java");
|
||||
private static final Path TRADE_LOCK_SOURCE = Path.of(
|
||||
"src/main/java/com/eu/habbo/messages/incoming/housekeeping/HousekeepingTradeLockUserEvent.java");
|
||||
|
||||
@Test
|
||||
void sanctionsUseSharedOverflowSafeDurationHelpers() throws IOException {
|
||||
String ban = Files.readString(BAN_SOURCE);
|
||||
String mute = Files.readString(MUTE_SOURCE);
|
||||
String tradeLock = Files.readString(TRADE_LOCK_SOURCE);
|
||||
|
||||
assertTrue(ban.contains("HousekeepingSanctionDuration.secondsFromHours(hours)"));
|
||||
assertTrue(mute.contains("HousekeepingSanctionDuration.secondsFromMinutes(minutes)"));
|
||||
assertTrue(tradeLock.contains("HousekeepingSanctionDuration.secondsFromHours(hours)"));
|
||||
assertTrue(tradeLock.contains("HousekeepingSanctionDuration.unixUntil("));
|
||||
}
|
||||
|
||||
@Test
|
||||
void sanctionsDoNotUseOverflowProneIntDurationConstants() throws IOException {
|
||||
String ban = Files.readString(BAN_SOURCE);
|
||||
String tradeLock = Files.readString(TRADE_LOCK_SOURCE);
|
||||
|
||||
assertFalse(ban.contains("100 * 365 * 24 * 3600"));
|
||||
assertFalse(tradeLock.contains("100 * 365 * 24 * 3600"));
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package com.eu.habbo.messages.incoming.housekeeping;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
class HousekeepingSanctionDurationTest {
|
||||
@Test
|
||||
void convertsHoursAndMinutesWithoutIntegerOverflow() {
|
||||
assertEquals(3600, HousekeepingSanctionDuration.secondsFromHours(1));
|
||||
assertEquals(60, HousekeepingSanctionDuration.secondsFromMinutes(1));
|
||||
assertEquals(Integer.MAX_VALUE, HousekeepingSanctionDuration.secondsFromHours(Integer.MAX_VALUE));
|
||||
assertEquals(Integer.MAX_VALUE, HousekeepingSanctionDuration.secondsFromMinutes(Integer.MAX_VALUE));
|
||||
}
|
||||
|
||||
@Test
|
||||
void capsUnixTimestampInsteadOfWrapping() {
|
||||
assertEquals(1_000_060, HousekeepingSanctionDuration.unixUntil(1_000_000, 60));
|
||||
assertEquals(Integer.MAX_VALUE, HousekeepingSanctionDuration.unixUntil(Integer.MAX_VALUE - 10, 60));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user