2024-02-05 12:31:51 +01:00
|
|
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
|
|
From: Nassim Jahnke <nassim@njahnke.dev>
|
|
|
|
Date: Mon, 5 Feb 2024 11:54:04 +0100
|
|
|
|
Subject: [PATCH] Improve tag parser handling
|
|
|
|
|
|
|
|
|
|
|
|
diff --git a/src/main/java/com/mojang/brigadier/CommandDispatcher.java b/src/main/java/com/mojang/brigadier/CommandDispatcher.java
|
2024-02-18 12:53:27 +01:00
|
|
|
index 92848b64a78fce7a92e1657c2da6fc5ee53eea44..5d5562676a77259b875e15b744b53258533851a7 100644
|
2024-02-05 12:31:51 +01:00
|
|
|
--- a/src/main/java/com/mojang/brigadier/CommandDispatcher.java
|
|
|
|
+++ b/src/main/java/com/mojang/brigadier/CommandDispatcher.java
|
2024-02-18 12:53:27 +01:00
|
|
|
@@ -304,9 +304,15 @@ public class CommandDispatcher<S> {
|
|
|
|
}
|
|
|
|
final CommandContextBuilder<S> context = contextSoFar.copy();
|
|
|
|
final StringReader reader = new StringReader(originalReader);
|
|
|
|
+ boolean stop = false; // Paper - Handle non-recoverable exceptions
|
2024-02-05 12:31:51 +01:00
|
|
|
try {
|
|
|
|
try {
|
|
|
|
child.parse(reader, context);
|
2024-02-18 12:53:27 +01:00
|
|
|
+ // Paper start - Handle non-recoverable exceptions
|
|
|
|
+ } catch (final com.mojang.brigadier.exceptions.TagParseCommandSyntaxException e) {
|
|
|
|
+ stop = true;
|
2024-02-05 12:31:51 +01:00
|
|
|
+ throw e;
|
2024-02-18 12:53:27 +01:00
|
|
|
+ // Paper end - Handle non-recoverable exceptions
|
2024-02-05 12:31:51 +01:00
|
|
|
} catch (final RuntimeException ex) {
|
|
|
|
throw CommandSyntaxException.BUILT_IN_EXCEPTIONS.dispatcherParseException().createWithContext(reader, ex.getMessage());
|
|
|
|
}
|
2024-02-18 12:53:27 +01:00
|
|
|
@@ -321,6 +327,7 @@ public class CommandDispatcher<S> {
|
|
|
|
}
|
|
|
|
errors.put(child, ex);
|
|
|
|
reader.setCursor(cursor);
|
|
|
|
+ if (stop) return new ParseResults<>(contextSoFar, originalReader, errors); // Paper - Handle non-recoverable exceptions
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
diff --git a/src/main/java/com/mojang/brigadier/exceptions/TagParseCommandSyntaxException.java b/src/main/java/com/mojang/brigadier/exceptions/TagParseCommandSyntaxException.java
|
|
|
|
new file mode 100644
|
|
|
|
index 0000000000000000000000000000000000000000..bf248a215dc69bb303c836112309471aab687e23
|
|
|
|
--- /dev/null
|
|
|
|
+++ b/src/main/java/com/mojang/brigadier/exceptions/TagParseCommandSyntaxException.java
|
|
|
|
@@ -0,0 +1,13 @@
|
|
|
|
+package com.mojang.brigadier.exceptions;
|
|
|
|
+
|
|
|
|
+import com.mojang.brigadier.LiteralMessage;
|
|
|
|
+import net.minecraft.network.chat.Component;
|
|
|
|
+
|
|
|
|
+public final class TagParseCommandSyntaxException extends CommandSyntaxException {
|
|
|
|
+
|
|
|
|
+ private static final SimpleCommandExceptionType EXCEPTION_TYPE = new SimpleCommandExceptionType(new LiteralMessage("Error parsing NBT"));
|
|
|
|
+
|
|
|
|
+ public TagParseCommandSyntaxException(final String message) {
|
|
|
|
+ super(EXCEPTION_TYPE, Component.literal(message));
|
|
|
|
+ }
|
|
|
|
+}
|
2024-02-05 12:31:51 +01:00
|
|
|
diff --git a/src/main/java/net/minecraft/nbt/TagParser.java b/src/main/java/net/minecraft/nbt/TagParser.java
|
2024-02-18 12:53:27 +01:00
|
|
|
index 5bec54239a2b185284c10d58854e5a13e33daae5..94cb73e7f60171aa57bd1dbe7e91ef4db94e70b7 100644
|
2024-02-05 12:31:51 +01:00
|
|
|
--- a/src/main/java/net/minecraft/nbt/TagParser.java
|
|
|
|
+++ b/src/main/java/net/minecraft/nbt/TagParser.java
|
|
|
|
@@ -48,6 +48,7 @@ public class TagParser {
|
|
|
|
}
|
|
|
|
}, CompoundTag::toString);
|
|
|
|
private final StringReader reader;
|
|
|
|
+ private int depth; // Paper
|
|
|
|
|
|
|
|
public static CompoundTag parseTag(String string) throws CommandSyntaxException {
|
|
|
|
return (new TagParser(new StringReader(string))).readSingleStruct();
|
|
|
|
@@ -156,6 +157,7 @@ public class TagParser {
|
|
|
|
|
|
|
|
public CompoundTag readStruct() throws CommandSyntaxException {
|
|
|
|
this.expect('{');
|
|
|
|
+ this.increaseDepth(); // Paper
|
|
|
|
CompoundTag compoundTag = new CompoundTag();
|
|
|
|
this.reader.skipWhitespace();
|
|
|
|
|
|
|
|
@@ -179,6 +181,7 @@ public class TagParser {
|
|
|
|
}
|
|
|
|
|
|
|
|
this.expect('}');
|
|
|
|
+ this.depth--; // Paper
|
|
|
|
return compoundTag;
|
|
|
|
}
|
|
|
|
|
|
|
|
@@ -188,6 +191,7 @@ public class TagParser {
|
|
|
|
if (!this.reader.canRead()) {
|
|
|
|
throw ERROR_EXPECTED_VALUE.createWithContext(this.reader);
|
|
|
|
} else {
|
|
|
|
+ this.increaseDepth(); // Paper
|
|
|
|
ListTag listTag = new ListTag();
|
|
|
|
TagType<?> tagType = null;
|
|
|
|
|
|
|
|
@@ -213,6 +217,7 @@ public class TagParser {
|
|
|
|
}
|
|
|
|
|
|
|
|
this.expect(']');
|
|
|
|
+ this.depth--; // Paper
|
|
|
|
return listTag;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@@ -251,11 +256,11 @@ public class TagParser {
|
|
|
|
}
|
|
|
|
|
|
|
|
if (typeReader == ByteTag.TYPE) {
|
|
|
|
- list.add((T)((NumericTag)tag).getAsByte());
|
|
|
|
+ list.add((T)((NumericTag)tag).getAsNumber()); // Paper - decompile fix
|
|
|
|
} else if (typeReader == LongTag.TYPE) {
|
|
|
|
- list.add((T)((NumericTag)tag).getAsLong());
|
|
|
|
+ list.add((T)((NumericTag)tag).getAsNumber()); // Paper - decompile fix
|
|
|
|
} else {
|
|
|
|
- list.add((T)((NumericTag)tag).getAsInt());
|
|
|
|
+ list.add((T)((NumericTag)tag).getAsNumber()); // Paper - decompile fix
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.hasElementSeparator()) {
|
|
|
|
@@ -286,4 +291,11 @@ public class TagParser {
|
|
|
|
this.reader.skipWhitespace();
|
|
|
|
this.reader.expect(c);
|
|
|
|
}
|
|
|
|
+
|
2024-02-18 12:53:27 +01:00
|
|
|
+ private void increaseDepth() throws CommandSyntaxException {
|
2024-02-05 12:31:51 +01:00
|
|
|
+ this.depth++;
|
|
|
|
+ if (this.depth > 512) {
|
2024-02-18 12:53:27 +01:00
|
|
|
+ throw new com.mojang.brigadier.exceptions.TagParseCommandSyntaxException("NBT tag is too complex, depth > 512");
|
2024-02-05 12:31:51 +01:00
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
}
|
|
|
|
diff --git a/src/main/java/net/minecraft/network/protocol/game/ServerboundCommandSuggestionPacket.java b/src/main/java/net/minecraft/network/protocol/game/ServerboundCommandSuggestionPacket.java
|
|
|
|
index a5e438a834826161c52ca9db57d234d9ff80a591..4766994cce060564370b0d24836a7da8b5e4a8a1 100644
|
|
|
|
--- a/src/main/java/net/minecraft/network/protocol/game/ServerboundCommandSuggestionPacket.java
|
|
|
|
+++ b/src/main/java/net/minecraft/network/protocol/game/ServerboundCommandSuggestionPacket.java
|
|
|
|
@@ -14,7 +14,7 @@ public class ServerboundCommandSuggestionPacket implements Packet<ServerGamePack
|
|
|
|
|
|
|
|
public ServerboundCommandSuggestionPacket(FriendlyByteBuf buf) {
|
|
|
|
this.id = buf.readVarInt();
|
|
|
|
- this.command = buf.readUtf(32500);
|
|
|
|
+ this.command = buf.readUtf(2048); // Paper
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
2024-02-18 12:53:27 +01:00
|
|
|
index 2f9c62f2c4c4356a896f7004b77f12a595f9c6dc..ab5b259d8f72022c875cae73be25fe2da346c6b3 100644
|
2024-02-05 12:31:51 +01:00
|
|
|
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
|
|
|
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
|
|
|
@@ -777,6 +777,13 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// Paper end - Don't suggest if tab-complete is disabled
|
|
|
|
+ // Paper start
|
|
|
|
+ final int index;
|
|
|
|
+ if (packet.getCommand().length() > 64 && ((index = packet.getCommand().indexOf(' ')) == -1 || index >= 64)) {
|
|
|
|
+ this.disconnect(Component.translatable("disconnect.spam"), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ // Paper end
|
|
|
|
// Paper start - AsyncTabCompleteEvent
|
|
|
|
TAB_COMPLETE_EXECUTOR.execute(() -> this.handleCustomCommandSuggestions0(packet));
|
|
|
|
}
|
2024-02-18 12:53:27 +01:00
|
|
|
@@ -824,6 +831,13 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
|
2024-02-05 12:31:51 +01:00
|
|
|
private void sendServerSuggestions(final ServerboundCommandSuggestionPacket packet, final StringReader stringreader) {
|
|
|
|
// Paper end - AsyncTabCompleteEvent
|
2024-02-18 12:53:27 +01:00
|
|
|
ParseResults<CommandSourceStack> parseresults = this.server.getCommands().getDispatcher().parse(stringreader, this.player.createCommandSourceStack());
|
|
|
|
+ // Paper start - Handle non-recoverable exceptions
|
|
|
|
+ if (!parseresults.getExceptions().isEmpty()
|
|
|
|
+ && parseresults.getExceptions().values().stream().anyMatch(e -> e instanceof com.mojang.brigadier.exceptions.TagParseCommandSyntaxException)) {
|
2024-02-05 12:31:51 +01:00
|
|
|
+ this.disconnect(Component.translatable("disconnect.spam"), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM);
|
|
|
|
+ return;
|
|
|
|
+ }
|
2024-02-18 12:53:27 +01:00
|
|
|
+ // Paper end - Handle non-recoverable exceptions
|
2024-02-05 12:31:51 +01:00
|
|
|
|
|
|
|
this.server.getCommands().getDispatcher().getCompletionSuggestions(parseresults).thenAccept((suggestions) -> {
|
|
|
|
// Paper start - Don't tab-complete namespaced commands if send-namespaced is false
|