From 2126eaa0d9e01b1d5186f5f9f449cf6bc67ddd17 Mon Sep 17 00:00:00 2001 From: Adrian Date: Wed, 17 May 2023 11:44:50 -0500 Subject: [PATCH] fix: Fixed IndexOutOfBoundException in SpamCheck --- .../chatregulator/api/checks/SpamCheck.java | 31 +++++++++++-------- .../plugin/impl/StringChainImpl.java | 12 +++++-- .../plugin/modules/ProviderModule.java | 2 ++ .../modules/checks/SpamTest.java | 18 ++++++----- 4 files changed, 40 insertions(+), 23 deletions(-) diff --git a/api/src/main/java/io/github/_4drian3d/chatregulator/api/checks/SpamCheck.java b/api/src/main/java/io/github/_4drian3d/chatregulator/api/checks/SpamCheck.java index fa169d2..cce2f43 100644 --- a/api/src/main/java/io/github/_4drian3d/chatregulator/api/checks/SpamCheck.java +++ b/api/src/main/java/io/github/_4drian3d/chatregulator/api/checks/SpamCheck.java @@ -18,29 +18,27 @@ */ public final class SpamCheck implements Check { private final SourceType type; + private final int similarLimit; - private SpamCheck(final @NotNull SourceType type){ - this.type = Objects.requireNonNull(type); + private SpamCheck(final @NotNull SourceType type, int similarLimit) { + this.type = requireNonNull(type); + this.similarLimit = similarLimit; } @Override - public @NotNull CheckResult check(@NotNull InfractionPlayer player, @NotNull String string) { + public @NotNull CheckResult check(final @NotNull InfractionPlayer player, final @NotNull String string) { final StringChain chain = player.getChain(type); - final int originalSize = chain.size(); - int size = originalSize; - if (size % 2 != 0) { - size--; - } - if (size == 0) { + final int size = chain.size(); + if (size < similarLimit) { return CheckResult.allowed(); } - for (int i = 0; i < size; i++) { + for (int i = 0; i + 1 < size; i++) { if (!chain.index(i).equalsIgnoreCase(chain.index(i + 1))) { return CheckResult.allowed(); } } - if (chain.index(originalSize - 1).equalsIgnoreCase(string)) { + if (chain.last().equalsIgnoreCase(string)) { return CheckResult.denied(type()); } else { return CheckResult.allowed(); @@ -56,8 +54,9 @@ public static Builder builder() { return new Builder(); } - public static class Builder implements AbstractBuilder { + public static final class Builder implements AbstractBuilder { private SourceType source; + private int similarLimit; Builder() {} @@ -67,10 +66,16 @@ public Builder source(SourceType source){ return this; } + @Required + public Builder similarLimit(int limit) { + this.similarLimit = limit; + return this; + } + @Override public @NotNull SpamCheck build(){ requireNonNull(source); - return new SpamCheck(source); + return new SpamCheck(source, Math.max(2, similarLimit)); } } } diff --git a/plugin/src/main/java/io/github/_4drian3d/chatregulator/plugin/impl/StringChainImpl.java b/plugin/src/main/java/io/github/_4drian3d/chatregulator/plugin/impl/StringChainImpl.java index eb9c235..063bada 100644 --- a/plugin/src/main/java/io/github/_4drian3d/chatregulator/plugin/impl/StringChainImpl.java +++ b/plugin/src/main/java/io/github/_4drian3d/chatregulator/plugin/impl/StringChainImpl.java @@ -48,8 +48,16 @@ public Iterator iterator() { } public void executed(final String string) { - if (checksContainer != null && checksContainer.get().getSpamConfig().getSimilarStringCount() <= queue.size()) { - queue.removeFirst(); + if (checksContainer != null) { + final int similarCount = checksContainer.get().getSpamConfig().getSimilarStringCount(); + final int size = queue.size(); + if (similarCount < size) { + while (similarCount < queue.size() + 1) { + queue.removeFirst(); + } + } else if (similarCount == size) { + queue.removeFirst(); + } } queue.add(string); lastExecuted.set(Instant.now()); diff --git a/plugin/src/main/java/io/github/_4drian3d/chatregulator/plugin/modules/ProviderModule.java b/plugin/src/main/java/io/github/_4drian3d/chatregulator/plugin/modules/ProviderModule.java index ce01044..81f185c 100644 --- a/plugin/src/main/java/io/github/_4drian3d/chatregulator/plugin/modules/ProviderModule.java +++ b/plugin/src/main/java/io/github/_4drian3d/chatregulator/plugin/modules/ProviderModule.java @@ -94,6 +94,7 @@ private CheckProvider commandSpam(ConfigurationContainer conf if (infractionPlayer.isAllowed(InfractionType.SPAM) && configuration.isEnabled(InfractionType.SPAM)) { return SpamCheck.builder() .source(SourceType.COMMAND) + .similarLimit(configuration.getSpamConfig().getSimilarStringCount()) .build(); } return null; @@ -110,6 +111,7 @@ private CheckProvider chatSpam(ConfigurationContainer configu if (infractionPlayer.isAllowed(InfractionType.SPAM) && configuration.isEnabled(InfractionType.SPAM)) { return SpamCheck.builder() .source(SourceType.CHAT) + .similarLimit(configuration.getSpamConfig().getSimilarStringCount()) .build(); } return null; diff --git a/plugin/src/test/java/io/github/_4drian3d/chatregulator/modules/checks/SpamTest.java b/plugin/src/test/java/io/github/_4drian3d/chatregulator/modules/checks/SpamTest.java index 0b5b038..4631f8e 100644 --- a/plugin/src/test/java/io/github/_4drian3d/chatregulator/modules/checks/SpamTest.java +++ b/plugin/src/test/java/io/github/_4drian3d/chatregulator/modules/checks/SpamTest.java @@ -13,18 +13,20 @@ class SpamTest { @Test @DisplayName("Spam Test") - void chatTest(){ + void chatTest() { InfractionPlayerImpl player = TestsUtils.dummyPlayer(); StringChainImpl chatChain = player.getChain(SourceType.CHAT); + final String string = "holaaaaaaaa"; - chatChain.executed("holaaaaaaaa"); - chatChain.executed("holaaaaaaaa"); - chatChain.executed("holaaaaaaaa"); - chatChain.executed("holaaaaaaaa"); - chatChain.executed("holaaaaaaaa"); + chatChain.executed(string); + chatChain.executed(string); + chatChain.executed(string); + chatChain.executed(string); + chatChain.executed(string); - SpamCheck check = SpamCheck.builder().source(SourceType.CHAT).build(); + SpamCheck.Builder builder = SpamCheck.builder().source(SourceType.CHAT); - assertTrue(check.check(player, "holaaaaaaaa").isDenied()); + assertTrue(builder.similarLimit(5).build().check(player, string).isDenied()); + assertTrue(builder.similarLimit(6).build().check(player, string).isAllowed()); } }