From 15d8ba25abd251aef371751ab615a964c0751780 Mon Sep 17 00:00:00 2001 From: Devin Lin Date: Sun, 12 Nov 2023 18:42:16 -0800 Subject: [PATCH] Fix errors and potential infinite loops caused by invalid page numbers --- .../java/dev/espi/protectionstones/PSL.java | 1 + .../protectionstones/commands/ArgFlag.java | 25 ++++++++++++++----- .../protectionstones/commands/ArgHelp.java | 7 ++++-- .../protectionstones/commands/ArgHome.java | 3 ++- .../protectionstones/commands/ArgTax.java | 3 ++- .../espi/protectionstones/utils/MiscUtil.java | 15 ++++++++++- .../espi/protectionstones/utils/TextGUI.java | 5 ++++ 7 files changed, 48 insertions(+), 11 deletions(-) diff --git a/src/main/java/dev/espi/protectionstones/PSL.java b/src/main/java/dev/espi/protectionstones/PSL.java index b12cc347..534d11fa 100644 --- a/src/main/java/dev/espi/protectionstones/PSL.java +++ b/src/main/java/dev/espi/protectionstones/PSL.java @@ -44,6 +44,7 @@ public enum PSL { MUST_BE_PLAYER("must_be_player", ChatColor.RED + "You must be a player to execute this command."), GO_BACK_PAGE("go_back_page", "Go back a page."), GO_NEXT_PAGE("go_next_page", "Go to next page."), + PAGE_DOES_NOT_EXIST("page_does_not_exist", ChatColor.RED + "Page does not exist."), HELP("help", ChatColor.DARK_GRAY + "" + ChatColor.STRIKETHROUGH + "=====" + ChatColor.RESET + " PS Help " + ChatColor.DARK_GRAY + ChatColor.STRIKETHROUGH + "=====\n" + ChatColor.AQUA + "> " + ChatColor.GRAY + "/ps help"), HELP_NEXT("help_next", ChatColor.GRAY + "Do /ps help %page% to go to the next page!"), diff --git a/src/main/java/dev/espi/protectionstones/commands/ArgFlag.java b/src/main/java/dev/espi/protectionstones/commands/ArgFlag.java index 27529552..323433fe 100644 --- a/src/main/java/dev/espi/protectionstones/commands/ArgFlag.java +++ b/src/main/java/dev/espi/protectionstones/commands/ArgFlag.java @@ -19,6 +19,7 @@ import com.sk89q.worldguard.protection.flags.*; import com.sk89q.worldguard.protection.regions.ProtectedRegion; import dev.espi.protectionstones.*; +import dev.espi.protectionstones.utils.MiscUtil; import dev.espi.protectionstones.utils.WGUtils; import net.md_5.bungee.api.chat.*; import org.apache.commons.lang.StringUtils; @@ -66,18 +67,24 @@ private String getDots(int num) { // flag gui that has ability to use pages private boolean openFlagGUI(Player p, PSRegion r, int page) { + List allowedFlags = new ArrayList<>(r.getTypeOptions().allowedFlags.keySet()); + + // ensure the page is valid and in range + if (page < 0 || (page * GUI_SIZE) > allowedFlags.size()) { + PSL.msg(p, PSL.PAGE_DOES_NOT_EXIST.msg()); + return true; + } + // add blank space if gui not long enough - for (int i = 0; i < (GUI_SIZE * page + GUI_SIZE) - (Math.min(r.getTypeOptions().allowedFlags.size(), GUI_SIZE * page + GUI_SIZE) - GUI_SIZE * page); i++) { + for (int i = 0; i < (GUI_SIZE * page + GUI_SIZE) - (Math.min(allowedFlags.size(), GUI_SIZE * page + GUI_SIZE) - GUI_SIZE * page); i++) { PSL.msg(p, ChatColor.WHITE + ""); } PSL.msg(p, PSL.FLAG_GUI_HEADER.msg()); - List allowedFlags = new ArrayList<>(r.getTypeOptions().allowedFlags.keySet()); - // send actual flags for (int i = GUI_SIZE * page; i < Math.min(allowedFlags.size(), GUI_SIZE * page + GUI_SIZE); i++) { - if (i >= r.getTypeOptions().allowedFlags.size()) { + if (i >= allowedFlags.size()) { PSL.msg(p, ChatColor.WHITE + ""); } else { String flag = allowedFlags.get(i); @@ -244,9 +251,15 @@ public boolean executeArgument(CommandSender s, String[] args, HashMap getRegisteredFlags() { @Override public boolean executeArgument(CommandSender p, String[] args, HashMap flags) { int page = 0; - if (args.length > 1 && StringUtils.isNumeric(args[1])) { + if (args.length > 1 && MiscUtil.isValidInteger(args[1])) { page = Integer.parseInt(args[1]) - 1; } @@ -125,7 +126,9 @@ public boolean executeArgument(CommandSender p, String[] args, HashMap= 0 && page * GUI_SIZE + GUI_SIZE < entries.size()) { + PSL.msg(p, PSL.HELP_NEXT.msg().replace("%page%", page + 2 + "")); + } return true; } diff --git a/src/main/java/dev/espi/protectionstones/commands/ArgHome.java b/src/main/java/dev/espi/protectionstones/commands/ArgHome.java index 456da644..5dd37974 100644 --- a/src/main/java/dev/espi/protectionstones/commands/ArgHome.java +++ b/src/main/java/dev/espi/protectionstones/commands/ArgHome.java @@ -17,6 +17,7 @@ import dev.espi.protectionstones.*; import dev.espi.protectionstones.utils.ChatUtil; +import dev.espi.protectionstones.utils.MiscUtil; import dev.espi.protectionstones.utils.TextGUI; import net.md_5.bungee.api.chat.ClickEvent; import net.md_5.bungee.api.chat.ComponentBuilder; @@ -136,7 +137,7 @@ public boolean executeArgument(CommandSender s, String[] args, HashMap flags, PSPlayer p) { if (args.length == 2) { // /ps tax info Bukkit.getScheduler().runTaskAsynchronously(ProtectionStones.getInstance(), () -> { - int pageNum = (flags.get("-p") == null || !StringUtils.isNumeric(flags.get("-p")) ? 0 : Integer.parseInt(flags.get("-p"))-1); + int pageNum = (flags.get("-p") == null || !MiscUtil.isValidInteger(flags.get("-p")) ? 0 : Integer.parseInt(flags.get("-p"))-1); List entries = new ArrayList<>(); for (PSRegion r : p.getTaxEligibleRegions()) { diff --git a/src/main/java/dev/espi/protectionstones/utils/MiscUtil.java b/src/main/java/dev/espi/protectionstones/utils/MiscUtil.java index efa39eff..8876684e 100644 --- a/src/main/java/dev/espi/protectionstones/utils/MiscUtil.java +++ b/src/main/java/dev/espi/protectionstones/utils/MiscUtil.java @@ -72,7 +72,7 @@ public static int getPermissionNumber(List permissions, String perm, int for (String permission : permissions) { if (permission.startsWith(perm)) { String value = permission.substring(perm.length()); - if (StringUtils.isNumeric(value)) { + if (MiscUtil.isValidInteger(value)) { n = Math.max(n, Integer.parseInt(value)); } } @@ -126,4 +126,17 @@ public static List getLuckPermsUserPermissions(UUID uniqueId) throws Exe return permissions; } + public static boolean isValidInteger(String str) { + if (str == null) { + return false; + } + + try { + // this apparently throws NumberFormatException if it is beyond the integer limit, so we catch that + Integer.parseInt(str); + return true; + } catch (NumberFormatException e) { + } catch (NullPointerException e) {} + return false; + } } diff --git a/src/main/java/dev/espi/protectionstones/utils/TextGUI.java b/src/main/java/dev/espi/protectionstones/utils/TextGUI.java index abcfee11..6dba7141 100644 --- a/src/main/java/dev/espi/protectionstones/utils/TextGUI.java +++ b/src/main/java/dev/espi/protectionstones/utils/TextGUI.java @@ -30,6 +30,11 @@ public class TextGUI { // page starts at zero, but displays start at one // pageCommand will be replacing %page% public static void displayGUI(CommandSender s, String header, String pageCommand, int currentPage, int guiSize, List lines, boolean sendBlankLines) { + int currentLine = currentPage * guiSize; + if (currentPage < 0 || currentLine > lines.size()) { + return; + } + PSL.msg(s, header); for (int i = currentPage*guiSize; i < Math.min((currentPage+1) * guiSize, lines.size()); i++) {