From 9b8d6e1dc74833cd4b5e51fc9df335828b1bb978 Mon Sep 17 00:00:00 2001 From: Luck Date: Sat, 4 Feb 2017 12:18:45 +0000 Subject: [PATCH] Modify node escaping to use "\" characters, and remove all limits on node/server/world strings - closes #166 --- .../me/lucko/luckperms/api/MetaUtils.java | 21 ++++- .../luckperms/common/api/ApiProvider.java | 4 +- .../lucko/luckperms/common/api/ApiUtils.java | 16 ---- .../common/api/delegate/GroupDelegate.java | 21 ++--- .../delegate/PermissionHolderDelegate.java | 42 ++++----- .../common/api/delegate/UserDelegate.java | 21 ++--- .../common/commands/track/TrackAppend.java | 2 +- .../common/commands/track/TrackInsert.java | 2 +- .../common/commands/track/TrackRemove.java | 2 +- .../common/commands/utils/ArgumentUtils.java | 11 +-- .../luckperms/common/constants/Patterns.java | 8 ++ .../luckperms/common/core/NodeBuilder.java | 18 ++-- .../luckperms/common/core/NodeFactory.java | 93 ++++++++++++++++--- .../common/core/model/ImmutableNode.java | 40 ++++---- .../common/utils/ArgumentChecker.java | 8 -- .../sponge/migration/MigrationUtils.java | 10 +- 16 files changed, 179 insertions(+), 140 deletions(-) diff --git a/api/src/main/java/me/lucko/luckperms/api/MetaUtils.java b/api/src/main/java/me/lucko/luckperms/api/MetaUtils.java index 503fb968..cc99667f 100644 --- a/api/src/main/java/me/lucko/luckperms/api/MetaUtils.java +++ b/api/src/main/java/me/lucko/luckperms/api/MetaUtils.java @@ -37,6 +37,20 @@ import java.util.Set; */ public class MetaUtils { + private static String escapeDelimiters(String s, String... delims) { + for (String delim : delims) { + s = s.replace(delim, "\\" + delim); + } + return s; + } + + private static String unescapeDelimiters(String s, String... delims) { + for (String delim : delims) { + s = s.replace("\\" + delim, delim); + } + return s; + } + /** * Escapes special characters used within LuckPerms, so the string can be saved without issues * @@ -49,11 +63,7 @@ public class MetaUtils { throw new NullPointerException(); } - s = s.replace(".", "{SEP}"); - s = s.replace("/", "{FSEP}"); - s = s.replace("$", "{DSEP}"); - - return s; + return escapeDelimiters(s, ".", "/", "-", "$"); } /** @@ -71,6 +81,7 @@ public class MetaUtils { s = s.replace("{SEP}", "."); s = s.replace("{FSEP}", "/"); s = s.replace("{DSEP}", "$"); + s = unescapeDelimiters(s, ".", "/", "-", "$"); return s; } diff --git a/common/src/main/java/me/lucko/luckperms/common/api/ApiProvider.java b/common/src/main/java/me/lucko/luckperms/common/api/ApiProvider.java index 82e9a00e..5ac0bed8 100644 --- a/common/src/main/java/me/lucko/luckperms/common/api/ApiProvider.java +++ b/common/src/main/java/me/lucko/luckperms/common/api/ApiProvider.java @@ -63,8 +63,6 @@ import java.util.Set; import java.util.UUID; import java.util.stream.Collectors; -import static me.lucko.luckperms.common.api.ApiUtils.checkNode; - /** * Implements the LuckPerms API using the plugin instance */ @@ -235,7 +233,7 @@ public class ApiProvider implements LuckPermsApi { @Override public Node.Builder buildNode(@NonNull String permission) throws IllegalArgumentException { - return new NodeBuilder(checkNode(permission)); + return new NodeBuilder(permission); } @SuppressWarnings("unchecked") diff --git a/common/src/main/java/me/lucko/luckperms/common/api/ApiUtils.java b/common/src/main/java/me/lucko/luckperms/common/api/ApiUtils.java index 39d962bd..0ce3fdc2 100644 --- a/common/src/main/java/me/lucko/luckperms/common/api/ApiUtils.java +++ b/common/src/main/java/me/lucko/luckperms/common/api/ApiUtils.java @@ -65,22 +65,6 @@ public class ApiUtils { return s.toLowerCase(); } - public static String checkServer(String s) { - Preconditions.checkArgument( - !ArgumentChecker.checkServer(s), - "Invalid server entry '" + s + "'. Server names can only contain alphanumeric characters." - ); - return s; - } - - public static String checkNode(String s) { - Preconditions.checkArgument( - !ArgumentChecker.checkNode(s), - "Invalid node entry '" + s + "'. Nodes cannot contain '/' or '$' characters." - ); - return s; - } - public static long checkTime(long l) { Preconditions.checkArgument(!ArgumentChecker.checkTime(l), "Unix time '" + l + "' is invalid, as it has already passed."); return l; diff --git a/common/src/main/java/me/lucko/luckperms/common/api/delegate/GroupDelegate.java b/common/src/main/java/me/lucko/luckperms/common/api/delegate/GroupDelegate.java index e4f943bb..35428968 100644 --- a/common/src/main/java/me/lucko/luckperms/common/api/delegate/GroupDelegate.java +++ b/common/src/main/java/me/lucko/luckperms/common/api/delegate/GroupDelegate.java @@ -35,7 +35,6 @@ import java.util.List; import java.util.OptionalInt; import static me.lucko.luckperms.common.api.ApiUtils.checkGroup; -import static me.lucko.luckperms.common.api.ApiUtils.checkServer; import static me.lucko.luckperms.common.api.ApiUtils.checkTime; /** @@ -83,13 +82,13 @@ public class GroupDelegate extends PermissionHolderDelegate implements Group { @Override public void setInheritGroup(@NonNull Group group, @NonNull String server) throws ObjectAlreadyHasException { checkGroup(group); - master.setInheritGroup(((GroupDelegate) group).getMaster(), checkServer(server)); + master.setInheritGroup(((GroupDelegate) group).getMaster(), server); } @Override public void setInheritGroup(@NonNull Group group, @NonNull String server, @NonNull String world) throws ObjectAlreadyHasException { checkGroup(group); - master.setInheritGroup(((GroupDelegate) group).getMaster(), checkServer(server), world); + master.setInheritGroup(((GroupDelegate) group).getMaster(), server, world); } @Override @@ -101,13 +100,13 @@ public class GroupDelegate extends PermissionHolderDelegate implements Group { @Override public void setInheritGroup(@NonNull Group group, @NonNull String server, @NonNull long expireAt) throws ObjectAlreadyHasException { checkGroup(group); - master.setInheritGroup(((GroupDelegate) group).getMaster(), checkServer(server), checkTime(expireAt)); + master.setInheritGroup(((GroupDelegate) group).getMaster(), server, checkTime(expireAt)); } @Override public void setInheritGroup(@NonNull Group group, @NonNull String server, @NonNull String world, @NonNull long expireAt) throws ObjectAlreadyHasException { checkGroup(group); - master.setInheritGroup(((GroupDelegate) group).getMaster(), checkServer(server), world, checkTime(expireAt)); + master.setInheritGroup(((GroupDelegate) group).getMaster(), server, world, checkTime(expireAt)); } @Override @@ -125,25 +124,25 @@ public class GroupDelegate extends PermissionHolderDelegate implements Group { @Override public void unsetInheritGroup(@NonNull Group group, @NonNull String server) throws ObjectLacksException { checkGroup(group); - master.unsetInheritGroup(((GroupDelegate) group).getMaster(), checkServer(server)); + master.unsetInheritGroup(((GroupDelegate) group).getMaster(), server); } @Override public void unsetInheritGroup(@NonNull Group group, @NonNull String server, @NonNull String world) throws ObjectLacksException { checkGroup(group); - master.unsetInheritGroup(((GroupDelegate) group).getMaster(), checkServer(server), world); + master.unsetInheritGroup(((GroupDelegate) group).getMaster(), server, world); } @Override public void unsetInheritGroup(@NonNull Group group, @NonNull String server, @NonNull boolean temporary) throws ObjectLacksException { checkGroup(group); - master.unsetInheritGroup(((GroupDelegate) group).getMaster(), checkServer(server), temporary); + master.unsetInheritGroup(((GroupDelegate) group).getMaster(), server, temporary); } @Override public void unsetInheritGroup(@NonNull Group group, @NonNull String server, @NonNull String world, @NonNull boolean temporary) throws ObjectLacksException { checkGroup(group); - master.unsetInheritGroup(((GroupDelegate) group).getMaster(), checkServer(server), world, temporary); + master.unsetInheritGroup(((GroupDelegate) group).getMaster(), server, world, temporary); } @Override @@ -158,7 +157,7 @@ public class GroupDelegate extends PermissionHolderDelegate implements Group { @Override public List getLocalGroups(@NonNull String server, @NonNull String world) { - return master.getLocalGroups(checkServer(server), world); + return master.getLocalGroups(server, world); } @Override @@ -168,6 +167,6 @@ public class GroupDelegate extends PermissionHolderDelegate implements Group { @Override public List getLocalGroups(@NonNull String server) { - return master.getLocalGroups(checkServer(server)); + return master.getLocalGroups(server); } } diff --git a/common/src/main/java/me/lucko/luckperms/common/api/delegate/PermissionHolderDelegate.java b/common/src/main/java/me/lucko/luckperms/common/api/delegate/PermissionHolderDelegate.java index 16de2565..9df69c71 100644 --- a/common/src/main/java/me/lucko/luckperms/common/api/delegate/PermissionHolderDelegate.java +++ b/common/src/main/java/me/lucko/luckperms/common/api/delegate/PermissionHolderDelegate.java @@ -48,8 +48,6 @@ import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; -import static me.lucko.luckperms.common.api.ApiUtils.checkNode; -import static me.lucko.luckperms.common.api.ApiUtils.checkServer; import static me.lucko.luckperms.common.api.ApiUtils.checkTime; import static me.lucko.luckperms.common.core.model.PermissionHolder.exportToLegacy; @@ -123,12 +121,12 @@ public class PermissionHolderDelegate implements PermissionHolder { @Override public boolean hasPermission(@NonNull String node, @NonNull boolean b, @NonNull String server) { - return master.hasPermission(node, b, checkServer(server)); + return master.hasPermission(node, b, server); } @Override public boolean hasPermission(@NonNull String node, @NonNull boolean b, @NonNull String server, @NonNull String world) { - return master.hasPermission(node, b, checkServer(server), world); + return master.hasPermission(node, b, server, world); } @Override @@ -138,12 +136,12 @@ public class PermissionHolderDelegate implements PermissionHolder { @Override public boolean hasPermission(@NonNull String node, @NonNull boolean b, @NonNull String server, @NonNull boolean temporary) { - return master.hasPermission(node, b, checkServer(server), temporary); + return master.hasPermission(node, b, server, temporary); } @Override public boolean hasPermission(@NonNull String node, @NonNull boolean b, @NonNull String server, @NonNull String world, @NonNull boolean temporary) { - return master.hasPermission(node, b, checkServer(server), world, temporary); + return master.hasPermission(node, b, server, world, temporary); } @Override @@ -158,12 +156,12 @@ public class PermissionHolderDelegate implements PermissionHolder { @Override public boolean inheritsPermission(@NonNull String node, @NonNull boolean b, @NonNull String server) { - return master.inheritsPermission(node, b, checkServer(server)); + return master.inheritsPermission(node, b, server); } @Override public boolean inheritsPermission(@NonNull String node, @NonNull boolean b, @NonNull String server, @NonNull String world) { - return master.inheritsPermission(node, b, checkServer(server), world); + return master.inheritsPermission(node, b, server, world); } @Override @@ -173,12 +171,12 @@ public class PermissionHolderDelegate implements PermissionHolder { @Override public boolean inheritsPermission(@NonNull String node, @NonNull boolean b, @NonNull String server, @NonNull boolean temporary) { - return master.inheritsPermission(node, b, checkServer(server), temporary); + return master.inheritsPermission(node, b, server, temporary); } @Override public boolean inheritsPermission(@NonNull String node, @NonNull boolean b, @NonNull String server, @NonNull String world, @NonNull boolean temporary) { - return master.inheritsPermission(node, b, checkServer(server), world, temporary); + return master.inheritsPermission(node, b, server, world, temporary); } @Override @@ -193,32 +191,32 @@ public class PermissionHolderDelegate implements PermissionHolder { @Override public void setPermission(@NonNull String node, @NonNull boolean value) throws ObjectAlreadyHasException { - master.setPermission(checkNode(node), value); + master.setPermission(node, value); } @Override public void setPermission(@NonNull String node, @NonNull boolean value, @NonNull String server) throws ObjectAlreadyHasException { - master.setPermission(checkNode(node), value, checkServer(server)); + master.setPermission(node, value, server); } @Override public void setPermission(@NonNull String node, @NonNull boolean value, @NonNull String server, @NonNull String world) throws ObjectAlreadyHasException { - master.setPermission(checkNode(node), value, checkServer(server), world); + master.setPermission(node, value, server, world); } @Override public void setPermission(@NonNull String node, @NonNull boolean value, @NonNull long expireAt) throws ObjectAlreadyHasException { - master.setPermission(checkNode(node), value, checkTime(expireAt)); + master.setPermission(node, value, checkTime(expireAt)); } @Override public void setPermission(@NonNull String node, @NonNull boolean value, @NonNull String server, @NonNull long expireAt) throws ObjectAlreadyHasException { - master.setPermission(checkNode(node), value, checkServer(server), checkTime(expireAt)); + master.setPermission(node, value, server, checkTime(expireAt)); } @Override public void setPermission(@NonNull String node, @NonNull boolean value, @NonNull String server, @NonNull String world, @NonNull long expireAt) throws ObjectAlreadyHasException { - master.setPermission(checkNode(node), value, checkServer(server), world, checkTime(expireAt)); + master.setPermission(node, value, server, world, checkTime(expireAt)); } @Override @@ -233,32 +231,32 @@ public class PermissionHolderDelegate implements PermissionHolder { @Override public void unsetPermission(@NonNull String node, @NonNull boolean temporary) throws ObjectLacksException { - master.unsetPermission(checkNode(node), temporary); + master.unsetPermission(node, temporary); } @Override public void unsetPermission(@NonNull String node) throws ObjectLacksException { - master.unsetPermission(checkNode(node)); + master.unsetPermission(node); } @Override public void unsetPermission(@NonNull String node, @NonNull String server) throws ObjectLacksException { - master.unsetPermission(checkNode(node), checkServer(server)); + master.unsetPermission(node, server); } @Override public void unsetPermission(@NonNull String node, @NonNull String server, @NonNull String world) throws ObjectLacksException { - master.unsetPermission(checkNode(node), checkServer(server), world); + master.unsetPermission(node, server, world); } @Override public void unsetPermission(@NonNull String node, @NonNull String server, @NonNull boolean temporary) throws ObjectLacksException { - master.unsetPermission(checkNode(node), checkServer(server), temporary); + master.unsetPermission(node, server, temporary); } @Override public void unsetPermission(@NonNull String node, @NonNull String server, @NonNull String world, @NonNull boolean temporary) throws ObjectLacksException { - master.unsetPermission(checkNode(node), checkServer(server), world, temporary); + master.unsetPermission(node, server, world, temporary); } @Override diff --git a/common/src/main/java/me/lucko/luckperms/common/api/delegate/UserDelegate.java b/common/src/main/java/me/lucko/luckperms/common/api/delegate/UserDelegate.java index 8884e8bc..098747f7 100644 --- a/common/src/main/java/me/lucko/luckperms/common/api/delegate/UserDelegate.java +++ b/common/src/main/java/me/lucko/luckperms/common/api/delegate/UserDelegate.java @@ -37,7 +37,6 @@ import java.util.Optional; import java.util.UUID; import static me.lucko.luckperms.common.api.ApiUtils.checkGroup; -import static me.lucko.luckperms.common.api.ApiUtils.checkServer; import static me.lucko.luckperms.common.api.ApiUtils.checkTime; /** @@ -124,13 +123,13 @@ public class UserDelegate extends PermissionHolderDelegate implements User { @Override public void addGroup(@NonNull Group group, @NonNull String server) throws ObjectAlreadyHasException { checkGroup(group); - master.setInheritGroup(((GroupDelegate) group).getMaster(), checkServer(server)); + master.setInheritGroup(((GroupDelegate) group).getMaster(), server); } @Override public void addGroup(@NonNull Group group, @NonNull String server, @NonNull String world) throws ObjectAlreadyHasException { checkGroup(group); - master.setInheritGroup(((GroupDelegate) group).getMaster(), checkServer(server), world); + master.setInheritGroup(((GroupDelegate) group).getMaster(), server, world); } @Override @@ -142,13 +141,13 @@ public class UserDelegate extends PermissionHolderDelegate implements User { @Override public void addGroup(@NonNull Group group, @NonNull String server, @NonNull long expireAt) throws ObjectAlreadyHasException { checkGroup(group); - master.setInheritGroup(((GroupDelegate) group).getMaster(), checkServer(server), checkTime(expireAt)); + master.setInheritGroup(((GroupDelegate) group).getMaster(), server, checkTime(expireAt)); } @Override public void addGroup(@NonNull Group group, @NonNull String server, @NonNull String world, @NonNull long expireAt) throws ObjectAlreadyHasException { checkGroup(group); - master.setInheritGroup(((GroupDelegate) group).getMaster(), checkServer(server), world, checkTime(expireAt)); + master.setInheritGroup(((GroupDelegate) group).getMaster(), server, world, checkTime(expireAt)); } @Override @@ -166,25 +165,25 @@ public class UserDelegate extends PermissionHolderDelegate implements User { @Override public void removeGroup(@NonNull Group group, @NonNull String server) throws ObjectLacksException { checkGroup(group); - master.unsetInheritGroup(((GroupDelegate) group).getMaster(), checkServer(server)); + master.unsetInheritGroup(((GroupDelegate) group).getMaster(), server); } @Override public void removeGroup(@NonNull Group group, @NonNull String server, @NonNull String world) throws ObjectLacksException { checkGroup(group); - master.unsetInheritGroup(((GroupDelegate) group).getMaster(), checkServer(server), world); + master.unsetInheritGroup(((GroupDelegate) group).getMaster(), server, world); } @Override public void removeGroup(@NonNull Group group, @NonNull String server, @NonNull boolean temporary) throws ObjectLacksException { checkGroup(group); - master.unsetInheritGroup(((GroupDelegate) group).getMaster(), checkServer(server), temporary); + master.unsetInheritGroup(((GroupDelegate) group).getMaster(), server, temporary); } @Override public void removeGroup(@NonNull Group group, @NonNull String server, @NonNull String world, @NonNull boolean temporary) throws ObjectLacksException { checkGroup(group); - master.unsetInheritGroup(((GroupDelegate) group).getMaster(), checkServer(server), world, temporary); + master.unsetInheritGroup(((GroupDelegate) group).getMaster(), server, world, temporary); } @Override @@ -199,12 +198,12 @@ public class UserDelegate extends PermissionHolderDelegate implements User { @Override public List getLocalGroups(@NonNull String server, @NonNull String world) { - return master.getLocalGroups(checkServer(server), world); + return master.getLocalGroups(server, world); } @Override public List getLocalGroups(@NonNull String server) { - return master.getLocalGroups(checkServer(server)); + return master.getLocalGroups(server); } } diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/track/TrackAppend.java b/common/src/main/java/me/lucko/luckperms/common/commands/track/TrackAppend.java index c6b277a0..693dd0a8 100644 --- a/common/src/main/java/me/lucko/luckperms/common/commands/track/TrackAppend.java +++ b/common/src/main/java/me/lucko/luckperms/common/commands/track/TrackAppend.java @@ -51,7 +51,7 @@ public class TrackAppend extends SubCommand { public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Track track, List args, String label) throws CommandException { String groupName = args.get(0).toLowerCase(); - if (ArgumentChecker.checkNode(groupName)) { + if (ArgumentChecker.checkName(groupName)) { sendDetailedUsage(sender, label); return CommandResult.INVALID_ARGS; } diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/track/TrackInsert.java b/common/src/main/java/me/lucko/luckperms/common/commands/track/TrackInsert.java index 7bbd1ec1..41bd182c 100644 --- a/common/src/main/java/me/lucko/luckperms/common/commands/track/TrackInsert.java +++ b/common/src/main/java/me/lucko/luckperms/common/commands/track/TrackInsert.java @@ -54,7 +54,7 @@ public class TrackInsert extends SubCommand { public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Track track, List args, String label) throws CommandException { String groupName = args.get(0).toLowerCase(); - if (ArgumentChecker.checkNode(groupName)) { + if (ArgumentChecker.checkName(groupName)) { sendDetailedUsage(sender, label); return CommandResult.INVALID_ARGS; } diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/track/TrackRemove.java b/common/src/main/java/me/lucko/luckperms/common/commands/track/TrackRemove.java index 9d17458a..9af0e148 100644 --- a/common/src/main/java/me/lucko/luckperms/common/commands/track/TrackRemove.java +++ b/common/src/main/java/me/lucko/luckperms/common/commands/track/TrackRemove.java @@ -50,7 +50,7 @@ public class TrackRemove extends SubCommand { public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Track track, List args, String label) throws CommandException { String groupName = args.get(0).toLowerCase(); - if (ArgumentChecker.checkNode(groupName)) { + if (ArgumentChecker.checkName(groupName)) { sendDetailedUsage(sender, label); return CommandResult.INVALID_ARGS; } diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/utils/ArgumentUtils.java b/common/src/main/java/me/lucko/luckperms/common/commands/utils/ArgumentUtils.java index 54b7b4a4..6b74c553 100644 --- a/common/src/main/java/me/lucko/luckperms/common/commands/utils/ArgumentUtils.java +++ b/common/src/main/java/me/lucko/luckperms/common/commands/utils/ArgumentUtils.java @@ -66,14 +66,11 @@ public class ArgumentUtils { public static String handleNode(int index, List args) throws ArgumentException { String node = args.get(index).replace("{SPACE}", " "); - if (ArgumentChecker.checkNode(node)) { - throw new DetailedUsageException(); - } - if (node.toLowerCase().startsWith("group.")) { throw new UseInheritException(); } + return node; } @@ -107,11 +104,7 @@ public class ArgumentUtils { public static String handleServer(int index, List args) throws ArgumentException { if (args.size() > index) { - final String server = args.get(index).toLowerCase(); - if (ArgumentChecker.checkServer(server)) { - throw new InvalidServerException(); - } - return server; + return args.get(index).toLowerCase(); } return null; } diff --git a/common/src/main/java/me/lucko/luckperms/common/constants/Patterns.java b/common/src/main/java/me/lucko/luckperms/common/constants/Patterns.java index eca16070..3d17fb9a 100644 --- a/common/src/main/java/me/lucko/luckperms/common/constants/Patterns.java +++ b/common/src/main/java/me/lucko/luckperms/common/constants/Patterns.java @@ -66,4 +66,12 @@ public class Patterns { } } + public static String buildDelimitedMatcher(String delim, String esc) { + return "(? contextParts = Splitter.on(')').limit(2).splitToList(permission.substring(1)); + List contextParts = Splitter.on(Patterns.compileDelimitedMatcher(")", "\\")).limit(2).splitToList(permission.substring(1)); // 0 = context, 1 = node this.permission = contextParts.get(1); try { - extraContexts.addAll(Splitter.on(',').withKeyValueSeparator('=').split(contextParts.get(0))); + Map map = Splitter.on(Patterns.compileDelimitedMatcher(",", "\\")).withKeyValueSeparator(Splitter.on(Patterns.compileDelimitedMatcher("=", "\\"))).split(contextParts.get(0)); + for (Map.Entry e : map.entrySet()) { + this.withExtraContext(NodeFactory.unescapeDelimiters(e.getKey(), "=", "(", ")", ","), NodeFactory.unescapeDelimiters(e.getValue(), "=", "(", ")", ",")); + } + } catch (IllegalArgumentException e) { e.printStackTrace(); } @@ -113,15 +116,6 @@ public class NodeBuilder implements Node.Builder { @Override public Node.Builder setServer(String server) { - if (server != null && ArgumentChecker.checkServer(server)) { - throw new IllegalArgumentException("Server name invalid."); - } - - this.server = server; - return this; - } - - public Node.Builder setServerRaw(String server) { this.server = server; return this; } diff --git a/common/src/main/java/me/lucko/luckperms/common/core/NodeFactory.java b/common/src/main/java/me/lucko/luckperms/common/core/NodeFactory.java index 528a0c37..a1abf780 100644 --- a/common/src/main/java/me/lucko/luckperms/common/core/NodeFactory.java +++ b/common/src/main/java/me/lucko/luckperms/common/core/NodeFactory.java @@ -32,6 +32,7 @@ import com.google.common.util.concurrent.UncheckedExecutionException; import me.lucko.luckperms.api.MetaUtils; import me.lucko.luckperms.api.Node; +import me.lucko.luckperms.common.constants.Patterns; import java.util.List; import java.util.concurrent.ExecutionException; @@ -70,36 +71,42 @@ public class NodeFactory { } public static Node.Builder builderFromSerialisedNode(String s, Boolean b) { - if (s.contains("/")) { - List parts = Splitter.on('/').limit(2).splitToList(s); + // if contains / + if (Patterns.compileDelimitedMatcher("/", "\\").matcher(s).find()) { + List parts = Splitter.on(Patterns.compileDelimitedMatcher("/", "\\")).limit(2).splitToList(s); // 0=server(+world) 1=node // WORLD SPECIFIC - if (parts.get(0).contains("-")) { - List serverParts = Splitter.on('-').limit(2).splitToList(parts.get(0)); + // if parts[0] contains - + if (Patterns.compileDelimitedMatcher("-", "\\").matcher(parts.get(0)).find()) { + List serverParts = Splitter.on(Patterns.compileDelimitedMatcher("-", "\\")).limit(2).splitToList(parts.get(0)); // 0=server 1=world - if (parts.get(1).contains("$")) { + // if parts[1] contains $ + if (Patterns.compileDelimitedMatcher("$", "\\").matcher(parts.get(1)).find()) { List tempParts = Splitter.on('$').limit(2).splitToList(parts.get(1)); - return new NodeBuilder(tempParts.get(0), true).setServerRaw(serverParts.get(0)).setWorld(serverParts.get(1)) + return new NodeBuilder(tempParts.get(0), true).setServer(serverParts.get(0)).setWorld(serverParts.get(1)) .setExpiry(Long.parseLong(tempParts.get(1))).setValue(b); } else { - return new NodeBuilder(parts.get(1), true).setServerRaw(serverParts.get(0)).setWorld(serverParts.get(1)).setValue(b); + return new NodeBuilder(parts.get(1), true).setServer(serverParts.get(0)).setWorld(serverParts.get(1)).setValue(b); } - } else { // SERVER BUT NOT WORLD SPECIFIC - if (parts.get(1).contains("$")) { - List tempParts = Splitter.on('$').limit(2).splitToList(parts.get(1)); - return new NodeBuilder(tempParts.get(0), true).setServerRaw(parts.get(0)).setExpiry(Long.parseLong(tempParts.get(1))).setValue(b); + + // if parts[1] contains $ + if (Patterns.compileDelimitedMatcher("$", "\\").matcher(parts.get(1)).find()) { + List tempParts = Splitter.on(Patterns.compileDelimitedMatcher("$", "\\")).limit(2).splitToList(parts.get(1)); + return new NodeBuilder(tempParts.get(0), true).setServer(parts.get(0)).setExpiry(Long.parseLong(tempParts.get(1))).setValue(b); } else { - return new NodeBuilder(parts.get(1), true).setServerRaw(parts.get(0)).setValue(b); + return new NodeBuilder(parts.get(1), true).setServer(parts.get(0)).setValue(b); } } } else { // NOT SERVER SPECIFIC - if (s.contains("$")) { - List tempParts = Splitter.on('$').limit(2).splitToList(s); + + // if s contains $ + if (Patterns.compileDelimitedMatcher("$", "\\").matcher(s).find()) { + List tempParts = Splitter.on(Patterns.compileDelimitedMatcher("$", "\\")).limit(2).splitToList(s); return new NodeBuilder(tempParts.get(0), true).setExpiry(Long.parseLong(tempParts.get(1))).setValue(b); } else { return new NodeBuilder(s, true).setValue(b); @@ -173,4 +180,62 @@ public class NodeFactory { return sb.toString(); } + + public static String escapeDelimiters(String s, String... delims) { + if (s == null) { + return null; + } + + for (String delim : delims) { + s = s.replace(delim, "\\" + delim); + } + return s; + } + + public static String unescapeDelimiters(String s, String... delims) { + if (s == null) { + return null; + } + + for (String delim : delims) { + s = s.replace("\\" + delim, delim); + } + return s; + } + + public static boolean isMetaNode(String s) { + if (!s.startsWith("meta.")) { + return false; + } + String parts = s.substring("meta.".length()); + return Patterns.compileDelimitedMatcher(".", "\\").matcher(parts).find(); + } + + private static boolean isChatMetaNode(String type, String s) { + if (!s.startsWith(type + ".")) { + return false; + } + String parts = s.substring((type + ".").length()); + + if (!Patterns.compileDelimitedMatcher(".", "\\").matcher(parts).find()) { + return false; + } + + List metaParts = Splitter.on(Patterns.compileDelimitedMatcher(".", "\\")).limit(2).splitToList(parts); + String priority = metaParts.get(0); + try { + Integer.parseInt(priority); + return true; + } catch (NumberFormatException e) { + return false; + } + } + + public static boolean isPrefixNode(String s) { + return isChatMetaNode("prefix", s); + } + + public static boolean isSuffixNode(String s) { + return isChatMetaNode("suffix", s); + } } diff --git a/common/src/main/java/me/lucko/luckperms/common/core/model/ImmutableNode.java b/common/src/main/java/me/lucko/luckperms/common/core/model/ImmutableNode.java index 8388eeef..a0a6811a 100644 --- a/common/src/main/java/me/lucko/luckperms/common/core/model/ImmutableNode.java +++ b/common/src/main/java/me/lucko/luckperms/common/core/model/ImmutableNode.java @@ -37,6 +37,7 @@ import me.lucko.luckperms.api.Tristate; import me.lucko.luckperms.api.context.ContextSet; import me.lucko.luckperms.api.context.ImmutableContextSet; import me.lucko.luckperms.common.constants.Patterns; +import me.lucko.luckperms.common.core.NodeFactory; import me.lucko.luckperms.common.utils.ShorthandParser; import java.util.Collections; @@ -56,9 +57,6 @@ import java.util.stream.Collectors; @ToString(of = {"permission", "value", "override", "server", "world", "expireAt", "contexts"}) @EqualsAndHashCode(of = {"permission", "value", "override", "server", "world", "expireAt", "contexts"}) public class ImmutableNode implements Node { - private static final Pattern PREFIX_PATTERN = Pattern.compile("(?i)prefix\\.-?\\d+\\..*"); - private static final Pattern SUFFIX_PATTERN = Pattern.compile("(?i)suffix\\.-?\\d+\\..*"); - private static final Pattern META_PATTERN = Pattern.compile("meta\\..*\\..*"); private static boolean shouldApply(String str, boolean applyRegex, String thisStr) { if (str.equalsIgnoreCase(thisStr)) { @@ -197,39 +195,39 @@ public class ImmutableNode implements Node { server = "global"; } - this.permission = permission; + this.permission = NodeFactory.unescapeDelimiters(permission, "/", "-", "$", "(", ")", "=", ","); this.value = value; this.override = override; this.expireAt = expireAt; - this.server = server; - this.world = world; + this.server = NodeFactory.unescapeDelimiters(server, "/", "-"); + this.world = NodeFactory.unescapeDelimiters(world, "/", "-"); this.contexts = contexts == null ? ContextSet.empty() : contexts.makeImmutable(); // Setup state - isGroup = permission.toLowerCase().startsWith("group."); + isGroup = this.permission.toLowerCase().startsWith("group."); if (isGroup) { - groupName = permission.substring("group.".length()); + groupName = this.permission.substring("group.".length()); } - isWildcard = permission.endsWith(".*"); - wildcardLevel = (int) permission.chars().filter(num -> num == Character.getNumericValue('.')).count(); + isWildcard = this.permission.endsWith(".*"); + wildcardLevel = (int) this.permission.chars().filter(num -> num == Character.getNumericValue('.')).count(); - isMeta = META_PATTERN.matcher(permission).matches(); + isMeta = NodeFactory.isMetaNode(this.permission); if (isMeta) { - List metaPart = Splitter.on('.').limit(2).splitToList(getPermission().substring("meta.".length())); + List metaPart = Splitter.on(Patterns.compileDelimitedMatcher(".", "\\")).limit(2).splitToList(getPermission().substring("meta.".length())); meta = Maps.immutableEntry(MetaUtils.unescapeCharacters(metaPart.get(0)), MetaUtils.unescapeCharacters(metaPart.get(1))); } - isPrefix = PREFIX_PATTERN.matcher(permission).matches(); + isPrefix = NodeFactory.isPrefixNode(this.permission); if (isPrefix) { - List prefixPart = Splitter.on('.').limit(2).splitToList(getPermission().substring("prefix.".length())); + List prefixPart = Splitter.on(Patterns.compileDelimitedMatcher(".", "\\")).limit(2).splitToList(getPermission().substring("prefix.".length())); Integer i = Integer.parseInt(prefixPart.get(0)); prefix = Maps.immutableEntry(i, MetaUtils.unescapeCharacters(prefixPart.get(1))); } - isSuffix = SUFFIX_PATTERN.matcher(permission).matches(); + isSuffix = NodeFactory.isSuffixNode(this.permission); if (isSuffix) { - List suffixPart = Splitter.on('.').limit(2).splitToList(getPermission().substring("suffix.".length())); + List suffixPart = Splitter.on(Patterns.compileDelimitedMatcher(".", "\\")).limit(2).splitToList(getPermission().substring("suffix.".length())); Integer i = Integer.parseInt(suffixPart.get(0)); suffix = Maps.immutableEntry(i, MetaUtils.unescapeCharacters(suffixPart.get(1))); } @@ -453,29 +451,29 @@ public class ImmutableNode implements Node { StringBuilder builder = new StringBuilder(); if (server != null) { - builder.append(server); + builder.append(NodeFactory.escapeDelimiters(server, "/", "-")); if (world != null) { - builder.append("-").append(world); + builder.append("-").append(NodeFactory.escapeDelimiters(world, "/", "-")); } builder.append("/"); } else { if (world != null) { - builder.append("global-").append(world).append("/"); + builder.append("global-").append(NodeFactory.escapeDelimiters(world, "/", "-")).append("/"); } } if (!contexts.isEmpty()) { builder.append("("); for (Map.Entry entry : contexts.toSet()) { - builder.append(entry.getKey()).append("=").append(entry.getValue()).append(","); + builder.append(NodeFactory.escapeDelimiters(entry.getKey(), "=", "(", ")", ",")).append("=").append(NodeFactory.escapeDelimiters(entry.getValue(), "=", "(", ")", ",")).append(","); } builder.deleteCharAt(builder.length() - 1); builder.append(")"); } - builder.append(permission); + builder.append(NodeFactory.escapeDelimiters(permission, "/", "-", "$", "(", ")", "=", ",")); if (expireAt != 0L) { builder.append("$").append(expireAt); diff --git a/common/src/main/java/me/lucko/luckperms/common/utils/ArgumentChecker.java b/common/src/main/java/me/lucko/luckperms/common/utils/ArgumentChecker.java index 7df05334..fd16ba2a 100644 --- a/common/src/main/java/me/lucko/luckperms/common/utils/ArgumentChecker.java +++ b/common/src/main/java/me/lucko/luckperms/common/utils/ArgumentChecker.java @@ -44,14 +44,6 @@ public class ArgumentChecker { return (s.length() > 36 || Patterns.NON_ALPHA_NUMERIC_SPACE.matcher(s).find()); } - public static boolean checkServer(String s) { - return !s.toLowerCase().startsWith("r=") && Patterns.NON_ALPHA_NUMERIC_SPACE.matcher(s).find(); - } - - public static boolean checkNode(String s) { - return (s.contains("/") || s.contains("$")); - } - public static boolean checkTime(long l) { return DateUtil.shouldExpire(l); } diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/migration/MigrationUtils.java b/sponge/src/main/java/me/lucko/luckperms/sponge/migration/MigrationUtils.java index c154a904..538f95a1 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/migration/MigrationUtils.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/migration/MigrationUtils.java @@ -58,7 +58,7 @@ public class MigrationUtils { for (Map.Entry perm : e.getValue().entrySet()) { try { - holder.setPermission(new NodeBuilder(perm.getKey()).setServerRaw(server).setWorld(world).withExtraContext(contexts).setValue(perm.getValue()).build()); + holder.setPermission(new NodeBuilder(perm.getKey()).setServer(server).setWorld(world).withExtraContext(contexts).setValue(perm.getValue()).build()); } catch (ObjectAlreadyHasException ignored) {} } } @@ -77,15 +77,15 @@ public class MigrationUtils { for (Map.Entry opt : e.getValue().entrySet()) { if (opt.getKey().equalsIgnoreCase("prefix")) { try { - holder.setPermission(NodeFactory.makePrefixNode(priority, opt.getValue()).setServerRaw(server).setWorld(world).withExtraContext(contexts).setValue(true).build()); + holder.setPermission(NodeFactory.makePrefixNode(priority, opt.getValue()).setServer(server).setWorld(world).withExtraContext(contexts).setValue(true).build()); } catch (ObjectAlreadyHasException ignored) {} } else if (opt.getKey().equalsIgnoreCase("suffix")) { try { - holder.setPermission(NodeFactory.makeSuffixNode(priority, opt.getValue()).setServerRaw(server).setWorld(world).withExtraContext(contexts).setValue(true).build()); + holder.setPermission(NodeFactory.makeSuffixNode(priority, opt.getValue()).setServer(server).setWorld(world).withExtraContext(contexts).setValue(true).build()); } catch (ObjectAlreadyHasException ignored) {} } else { try { - holder.setPermission(NodeFactory.makeMetaNode(opt.getKey(), opt.getValue()).setServerRaw(server).setWorld(world).withExtraContext(contexts).setValue(true).build()); + holder.setPermission(NodeFactory.makeMetaNode(opt.getKey(), opt.getValue()).setServer(server).setWorld(world).withExtraContext(contexts).setValue(true).build()); } catch (ObjectAlreadyHasException ignored) {} } } @@ -111,7 +111,7 @@ public class MigrationUtils { } try { - holder.setPermission(new NodeBuilder("group." + convertName(s.getIdentifier())).setServerRaw(server).setWorld(world).withExtraContext(contexts).setValue(true).build()); + holder.setPermission(new NodeBuilder("group." + convertName(s.getIdentifier())).setServer(server).setWorld(world).withExtraContext(contexts).setValue(true).build()); } catch (ObjectAlreadyHasException ignored) {} } }