diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/generic/permission/PermissionSet.java b/common/src/main/java/me/lucko/luckperms/common/commands/generic/permission/PermissionSet.java index fb8d391df..2fcc3b0f4 100644 --- a/common/src/main/java/me/lucko/luckperms/common/commands/generic/permission/PermissionSet.java +++ b/common/src/main/java/me/lucko/luckperms/common/commands/generic/permission/PermissionSet.java @@ -67,6 +67,10 @@ public class PermissionSet extends GenericChildCommand { boolean value = args.getBooleanOrInsert(1, true); MutableContextSet context = args.getContextOrDefault(2, plugin); + if (node.isEmpty()) { + Message.PERMISSION_INVALID_ENTRY_EMPTY.send(sender); + } + if (ArgumentPermissions.checkContext(plugin, sender, permission, context) || ArgumentPermissions.checkGroup(plugin, sender, target, context) || ArgumentPermissions.checkArguments(plugin, sender, permission, node)) { diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/generic/permission/PermissionSetTemp.java b/common/src/main/java/me/lucko/luckperms/common/commands/generic/permission/PermissionSetTemp.java index f4dc614a2..ec8369937 100644 --- a/common/src/main/java/me/lucko/luckperms/common/commands/generic/permission/PermissionSetTemp.java +++ b/common/src/main/java/me/lucko/luckperms/common/commands/generic/permission/PermissionSetTemp.java @@ -72,6 +72,10 @@ public class PermissionSetTemp extends GenericChildCommand { TemporaryNodeMergeStrategy modifier = args.getTemporaryModifierAndRemove(3).orElseGet(() -> plugin.getConfiguration().get(ConfigKeys.TEMPORARY_ADD_BEHAVIOUR)); MutableContextSet context = args.getContextOrDefault(3, plugin); + if (node.isEmpty()) { + Message.PERMISSION_INVALID_ENTRY_EMPTY.send(sender); + } + if (ArgumentPermissions.checkContext(plugin, sender, permission, context) || ArgumentPermissions.checkGroup(plugin, sender, target, context) || ArgumentPermissions.checkArguments(plugin, sender, permission, node)) { diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/generic/permission/PermissionUnset.java b/common/src/main/java/me/lucko/luckperms/common/commands/generic/permission/PermissionUnset.java index 1726c8f7c..320c9acf8 100644 --- a/common/src/main/java/me/lucko/luckperms/common/commands/generic/permission/PermissionUnset.java +++ b/common/src/main/java/me/lucko/luckperms/common/commands/generic/permission/PermissionUnset.java @@ -66,6 +66,10 @@ public class PermissionUnset extends GenericChildCommand { String node = args.get(0); MutableContextSet context = args.getContextOrDefault(1, plugin); + if (node.isEmpty()) { + Message.PERMISSION_INVALID_ENTRY_EMPTY.send(sender); + } + if (ArgumentPermissions.checkContext(plugin, sender, permission, context) || ArgumentPermissions.checkGroup(plugin, sender, target, context) || ArgumentPermissions.checkArguments(plugin, sender, permission, node)) { diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/generic/permission/PermissionUnsetTemp.java b/common/src/main/java/me/lucko/luckperms/common/commands/generic/permission/PermissionUnsetTemp.java index 09a04498f..1ea3d6ad8 100644 --- a/common/src/main/java/me/lucko/luckperms/common/commands/generic/permission/PermissionUnsetTemp.java +++ b/common/src/main/java/me/lucko/luckperms/common/commands/generic/permission/PermissionUnsetTemp.java @@ -69,6 +69,10 @@ public class PermissionUnsetTemp extends GenericChildCommand { int fromIndex = duration == null ? 1 : 2; MutableContextSet context = args.getContextOrDefault(fromIndex, plugin); + if (node.isEmpty()) { + Message.PERMISSION_INVALID_ENTRY_EMPTY.send(sender); + } + if (ArgumentPermissions.checkContext(plugin, sender, permission, context) || ArgumentPermissions.checkGroup(plugin, sender, target, context) || ArgumentPermissions.checkArguments(plugin, sender, permission, node)) { diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/log/LogNotify.java b/common/src/main/java/me/lucko/luckperms/common/commands/log/LogNotify.java index 1b720591b..f21e442a4 100644 --- a/common/src/main/java/me/lucko/luckperms/common/commands/log/LogNotify.java +++ b/common/src/main/java/me/lucko/luckperms/common/commands/log/LogNotify.java @@ -34,7 +34,7 @@ import me.lucko.luckperms.common.command.utils.ArgumentList; import me.lucko.luckperms.common.context.contextset.ImmutableContextSetImpl; import me.lucko.luckperms.common.locale.Message; import me.lucko.luckperms.common.model.User; -import me.lucko.luckperms.common.node.factory.NodeBuilders; +import me.lucko.luckperms.common.node.types.Permission; import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.sender.Sender; import me.lucko.luckperms.common.util.Predicates; @@ -75,7 +75,7 @@ public class LogNotify extends ChildCommand { if (state) { // add the perm - user.setNode(DataType.NORMAL, NodeBuilders.determineMostApplicable(IGNORE_NODE).build(), true); + user.setNode(DataType.NORMAL, Permission.builder().permission(IGNORE_NODE).build(), true); } else { // remove the perm user.removeIf(DataType.NORMAL, ImmutableContextSetImpl.EMPTY, n -> n.getKey().equalsIgnoreCase(IGNORE_NODE), false); diff --git a/common/src/main/java/me/lucko/luckperms/common/locale/Message.java b/common/src/main/java/me/lucko/luckperms/common/locale/Message.java index dfdd88585..f6c51ae5c 100644 --- a/common/src/main/java/me/lucko/luckperms/common/locale/Message.java +++ b/common/src/main/java/me/lucko/luckperms/common/locale/Message.java @@ -1959,6 +1959,13 @@ public interface Message { .append(FULL_STOP) ); + Args0 PERMISSION_INVALID_ENTRY_EMPTY = () -> prefixed(translatable() + // "&cThe empty string is not a valid permission." + .key("luckperms.command.misc.permission-invalid-empty") + .color(RED) + .append(FULL_STOP) + ); + Args3 SET_INHERIT_SUCCESS = (holder, parent, context) -> prefixed(translatable() // "&b{}&a now inherits permissions from &b{}&a in context {}&a." .key("luckperms.command.generic.parent.add") diff --git a/common/src/main/java/me/lucko/luckperms/common/node/AbstractNodeBuilder.java b/common/src/main/java/me/lucko/luckperms/common/node/AbstractNodeBuilder.java index 552c92533..00fde5c4d 100644 --- a/common/src/main/java/me/lucko/luckperms/common/node/AbstractNodeBuilder.java +++ b/common/src/main/java/me/lucko/luckperms/common/node/AbstractNodeBuilder.java @@ -138,4 +138,10 @@ public abstract class AbstractNodeBuilder, B extends return (B) this; } + protected static void ensureDefined(Object value, String description) { + if (value == null) { + throw new IllegalStateException(description + " has not been defined"); + } + } + } diff --git a/common/src/main/java/me/lucko/luckperms/common/node/factory/NodeBuilders.java b/common/src/main/java/me/lucko/luckperms/common/node/factory/NodeBuilders.java index 1245aa5c7..6147058f6 100644 --- a/common/src/main/java/me/lucko/luckperms/common/node/factory/NodeBuilders.java +++ b/common/src/main/java/me/lucko/luckperms/common/node/factory/NodeBuilders.java @@ -46,6 +46,8 @@ import net.luckperms.api.node.types.WeightNode; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; +import java.util.Objects; + public final class NodeBuilders { private NodeBuilders() {} @@ -60,6 +62,7 @@ public final class NodeBuilders { private static final Parser[] PARSERS = new Parser[]{INHERITANCE, PREFIX, SUFFIX, META, WEIGHT, DISPLAY_NAME, REGEX_PERMISSION}; public static @NonNull NodeBuilder determineMostApplicable(String key) { + Objects.requireNonNull(key, "key"); for (Parser parser : PARSERS) { NodeBuilder builder = parser.parse(key); if (builder != null) { diff --git a/common/src/main/java/me/lucko/luckperms/common/node/types/DisplayName.java b/common/src/main/java/me/lucko/luckperms/common/node/types/DisplayName.java index 4ba128e0b..221bd0efd 100644 --- a/common/src/main/java/me/lucko/luckperms/common/node/types/DisplayName.java +++ b/common/src/main/java/me/lucko/luckperms/common/node/types/DisplayName.java @@ -94,13 +94,13 @@ public class DisplayName extends AbstractNode implements Me @Override public @NonNull Builder key(@NonNull String key) { - this.metaKey = Objects.requireNonNull(key, "key"); + Objects.requireNonNull(key, "key"); + if (key.isEmpty()) { + throw new IllegalArgumentException("key is empty"); + } + this.metaKey = key; return this; } @@ -127,8 +131,8 @@ public class Meta extends AbstractNode implements Me @Override public @NonNull Meta build() { - Objects.requireNonNull(this.metaKey, "metaKey"); - Objects.requireNonNull(this.metaValue, "metaValue"); + ensureDefined(this.metaKey, "meta key"); + ensureDefined(this.metaValue, "meta value"); return new Meta(this.metaKey, this.metaValue, this.value, this.expireAt, this.context.build(), this.metadata); } } diff --git a/common/src/main/java/me/lucko/luckperms/common/node/types/Permission.java b/common/src/main/java/me/lucko/luckperms/common/node/types/Permission.java index 9ecf94623..8c62b021b 100644 --- a/common/src/main/java/me/lucko/luckperms/common/node/types/Permission.java +++ b/common/src/main/java/me/lucko/luckperms/common/node/types/Permission.java @@ -87,13 +87,17 @@ public class Permission extends AbstractNode testBuilder = NodeBuilders.determineMostApplicable(this.permission); if (!(testBuilder instanceof Builder)) { diff --git a/common/src/main/java/me/lucko/luckperms/common/node/types/Prefix.java b/common/src/main/java/me/lucko/luckperms/common/node/types/Prefix.java index 11c07eca1..1408466ff 100644 --- a/common/src/main/java/me/lucko/luckperms/common/node/types/Prefix.java +++ b/common/src/main/java/me/lucko/luckperms/common/node/types/Prefix.java @@ -125,7 +125,7 @@ public class Prefix extends AbstractNode impleme @Override public @NonNull Builder prefix(@NonNull String prefix) { - this.prefix = prefix; + this.prefix = Objects.requireNonNull(prefix, "prefix"); return this; } @@ -137,8 +137,8 @@ public class Prefix extends AbstractNode impleme @Override public @NonNull Prefix build() { - Objects.requireNonNull(this.prefix, "prefix"); - Objects.requireNonNull(this.priority, "priority"); + ensureDefined(this.prefix, "prefix"); + ensureDefined(this.priority, "priority"); return new Prefix(this.prefix, this.priority, this.value, this.expireAt, this.context.build(), this.metadata); } } diff --git a/common/src/main/java/me/lucko/luckperms/common/node/types/RegexPermission.java b/common/src/main/java/me/lucko/luckperms/common/node/types/RegexPermission.java index 6dab08667..e8c7df816 100644 --- a/common/src/main/java/me/lucko/luckperms/common/node/types/RegexPermission.java +++ b/common/src/main/java/me/lucko/luckperms/common/node/types/RegexPermission.java @@ -106,19 +106,22 @@ public class RegexPermission extends AbstractNode impleme @Override public @NonNull Builder suffix(@NonNull String suffix) { - this.suffix = suffix; + this.suffix = Objects.requireNonNull(suffix, "suffix"); return this; } @@ -138,8 +138,8 @@ public class Suffix extends AbstractNode impleme @Override public @NonNull Suffix build() { - Objects.requireNonNull(this.suffix, "suffix"); - Objects.requireNonNull(this.priority, "priority"); + ensureDefined(this.suffix, "suffix"); + ensureDefined(this.priority, "priority"); return new Suffix(this.suffix, this.priority, this.value, this.expireAt, this.context.build(), this.metadata); } } diff --git a/common/src/main/java/me/lucko/luckperms/common/node/types/Weight.java b/common/src/main/java/me/lucko/luckperms/common/node/types/Weight.java index d5fbcc127..13773d56c 100644 --- a/common/src/main/java/me/lucko/luckperms/common/node/types/Weight.java +++ b/common/src/main/java/me/lucko/luckperms/common/node/types/Weight.java @@ -36,7 +36,6 @@ import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import java.util.Map; -import java.util.Objects; public class Weight extends AbstractNode implements WeightNode { public static final String NODE_KEY = "weight"; @@ -105,7 +104,7 @@ public class Weight extends AbstractNode impleme @Override public @NonNull Weight build() { - Objects.requireNonNull(this.weight, "weight"); + ensureDefined(this.weight, "weight"); return new Weight(this.weight, this.value, this.expireAt, this.context.build(), this.metadata); } } diff --git a/common/src/main/java/me/lucko/luckperms/common/node/utils/NodeJsonSerializer.java b/common/src/main/java/me/lucko/luckperms/common/node/utils/NodeJsonSerializer.java index 2904e5274..cd98e6b2e 100644 --- a/common/src/main/java/me/lucko/luckperms/common/node/utils/NodeJsonSerializer.java +++ b/common/src/main/java/me/lucko/luckperms/common/node/utils/NodeJsonSerializer.java @@ -75,9 +75,15 @@ public class NodeJsonSerializer { JsonObject attributes = ent.getAsJsonObject(); String key = attributes.get("key").getAsString(); - boolean value = attributes.get("value").getAsBoolean(); - NodeBuilder builder = NodeBuilders.determineMostApplicable(key).value(value); + if (key.isEmpty()) { + continue; // skip + } + + NodeBuilder builder = NodeBuilders.determineMostApplicable(key); + + boolean value = attributes.get("value").getAsBoolean(); + builder.value(value); if (attributes.has("expiry")) { builder.expiry(attributes.get("expiry").getAsLong()); diff --git a/common/src/main/java/me/lucko/luckperms/common/storage/implementation/file/AbstractConfigurateStorage.java b/common/src/main/java/me/lucko/luckperms/common/storage/implementation/file/AbstractConfigurateStorage.java index a80515bb5..7cfe2934f 100644 --- a/common/src/main/java/me/lucko/luckperms/common/storage/implementation/file/AbstractConfigurateStorage.java +++ b/common/src/main/java/me/lucko/luckperms/common/storage/implementation/file/AbstractConfigurateStorage.java @@ -432,7 +432,7 @@ public abstract class AbstractConfigurateStorage implements StorageImplementatio String permission = entry.getKey().toString(); ConfigurationNode attributes = entry.getValue(); - if (!permission.equals(keyFieldName)) { + if (!permission.equals(keyFieldName) && !permission.isEmpty()) { return new NodeEntry(permission, attributes); } } @@ -440,7 +440,7 @@ public abstract class AbstractConfigurateStorage implements StorageImplementatio // assume 'configNode' is the actual entry. String permission = children.get(keyFieldName).getString(null); - if (permission == null) { + if (permission == null || permission.isEmpty()) { return null; } @@ -452,7 +452,7 @@ public abstract class AbstractConfigurateStorage implements StorageImplementatio for (ConfigurationNode appended : data.getNode("permissions").getChildrenList()) { String plainValue = appended.getValue(Types::strictAsString); - if (plainValue != null) { + if (plainValue != null && !plainValue.isEmpty()) { nodes.add(NodeBuilders.determineMostApplicable(plainValue).build()); continue; } diff --git a/common/src/main/java/me/lucko/luckperms/common/storage/implementation/mongodb/MongoStorage.java b/common/src/main/java/me/lucko/luckperms/common/storage/implementation/mongodb/MongoStorage.java index 71fe6a4a4..05ac6a757 100644 --- a/common/src/main/java/me/lucko/luckperms/common/storage/implementation/mongodb/MongoStorage.java +++ b/common/src/main/java/me/lucko/luckperms/common/storage/implementation/mongodb/MongoStorage.java @@ -605,7 +605,10 @@ public class MongoStorage implements StorageImplementation { //noinspection unchecked List permsList = (List) document.get("permissions"); for (Document d : permsList) { - nodes.add(nodeFromDoc(d)); + Node node = nodeFromDoc(d); + if (node != null) { + nodes.add(node); + } } } return nodes; @@ -644,6 +647,10 @@ public class MongoStorage implements StorageImplementation { private static Node nodeFromDoc(Document document) { String key = document.containsKey("permission") ? document.getString("permission") : document.getString("key"); + if (key == null || key.isEmpty()) { + return null; + } + NodeBuilder builder = NodeBuilders.determineMostApplicable(key) .value(document.getBoolean("value", true)); diff --git a/common/src/main/java/me/lucko/luckperms/common/storage/implementation/sql/SqlStorage.java b/common/src/main/java/me/lucko/luckperms/common/storage/implementation/sql/SqlStorage.java index 3916dc539..e453160bc 100644 --- a/common/src/main/java/me/lucko/luckperms/common/storage/implementation/sql/SqlStorage.java +++ b/common/src/main/java/me/lucko/luckperms/common/storage/implementation/sql/SqlStorage.java @@ -410,6 +410,9 @@ public class SqlStorage implements StorageImplementation { while (rs.next()) { UUID holder = UUID.fromString(rs.getString("uuid")); Node node = readNode(rs); + if (node == null) { + continue; + } N match = constraint.filterConstraintMatch(node); if (match != null) { @@ -511,6 +514,9 @@ public class SqlStorage implements StorageImplementation { while (rs.next()) { String holder = rs.getString("name"); Node node = readNode(rs); + if (node == null) { + continue; + } N match = constraint.filterConstraintMatch(node); if (match != null) { @@ -721,6 +727,11 @@ public class SqlStorage implements StorageImplementation { private static Node readNode(ResultSet rs) throws SQLException { long id = rs.getLong("id"); String permission = rs.getString("permission"); + + if (permission == null || permission.isEmpty()) { + return null; + } + boolean value = rs.getBoolean("value"); String server = rs.getString("server"); String world = rs.getString("world"); @@ -829,7 +840,10 @@ public class SqlStorage implements StorageImplementation { ps.setString(1, user.toString()); try (ResultSet rs = ps.executeQuery()) { while (rs.next()) { - nodes.add(readNode(rs)); + Node node = readNode(rs); + if (node != null) { + nodes.add(readNode(rs)); + } } } } @@ -906,7 +920,10 @@ public class SqlStorage implements StorageImplementation { ps.setString(1, group); try (ResultSet rs = ps.executeQuery()) { while (rs.next()) { - nodes.add(readNode(rs)); + Node node = readNode(rs); + if (node != null) { + nodes.add(node); + } } } } @@ -920,7 +937,10 @@ public class SqlStorage implements StorageImplementation { String holder = rs.getString("name"); Collection list = nodes.get(holder); if (list != null) { - list.add(readNode(rs)); + Node node = readNode(rs); + if (node != null) { + list.add(readNode(rs)); + } } } } diff --git a/common/src/main/resources/luckperms_en.properties b/common/src/main/resources/luckperms_en.properties index 9f3cae5fb..0d5202ad5 100644 --- a/common/src/main/resources/luckperms_en.properties +++ b/common/src/main/resources/luckperms_en.properties @@ -54,6 +54,7 @@ luckperms.command.misc.webapp-unable-to-communicate=Unable to communicate with t luckperms.command.misc.check-console-for-errors=Check the console for errors luckperms.command.misc.file-must-be-in-data=File {0} must be a direct child of the data directory luckperms.command.misc.wait-to-finish=Please wait for it to finish and try again +luckperms.command.misc.permission-invalid-empty=The empty string is not a valid permission luckperms.command.misc.invalid-priority=Invalid priority {0} luckperms.command.misc.expected-number=Expected a number luckperms.command.misc.date-parse-error=Could not parse date {0}