mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-28 15:30:19 +01:00
526795bacd
* Update patches to handle vineflower decompiler * update patches again to handle inlined simple lambdas * update vf again and re-apply/rebuild patches * update patches after removal of verify-merges flag * fix compile issue * remove maven local * fix some issues * address more issues * fix collision patch * use paperweight release * more fixes * update fineflower and fix patches again * add missing comment descriptor --------- Co-authored-by: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
202 lines
9.7 KiB
Diff
202 lines
9.7 KiB
Diff
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
|
|
index 92848b64a78fce7a92e1657c2da6fc5ee53eea44..4b4f812eb13d5f03bcf3f8724d8aa8dbbc724e8b 100644
|
|
--- a/src/main/java/com/mojang/brigadier/CommandDispatcher.java
|
|
+++ b/src/main/java/com/mojang/brigadier/CommandDispatcher.java
|
|
@@ -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
|
|
try {
|
|
try {
|
|
child.parse(reader, context);
|
|
+ // Paper start - Handle non-recoverable exceptions
|
|
+ } catch (final io.papermc.paper.brigadier.TagParseCommandSyntaxException e) {
|
|
+ stop = true;
|
|
+ throw e;
|
|
+ // Paper end - Handle non-recoverable exceptions
|
|
} catch (final RuntimeException ex) {
|
|
throw CommandSyntaxException.BUILT_IN_EXCEPTIONS.dispatcherParseException().createWithContext(reader, ex.getMessage());
|
|
}
|
|
@@ -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/io/papermc/paper/brigadier/TagParseCommandSyntaxException.java b/src/main/java/io/papermc/paper/brigadier/TagParseCommandSyntaxException.java
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..a375ad4ba9db990b24a2b9ff366fcba66b753815
|
|
--- /dev/null
|
|
+++ b/src/main/java/io/papermc/paper/brigadier/TagParseCommandSyntaxException.java
|
|
@@ -0,0 +1,15 @@
|
|
+package io.papermc.paper.brigadier;
|
|
+
|
|
+import com.mojang.brigadier.LiteralMessage;
|
|
+import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
|
+import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
|
|
+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));
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/minecraft/nbt/TagParser.java b/src/main/java/net/minecraft/nbt/TagParser.java
|
|
index ebe0efe488357ae895aaf752e9bc008b96db156f..c77860a141064aea6a0b510bb44d35fea90aee42 100644
|
|
--- 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();
|
|
@@ -158,6 +159,7 @@ public class TagParser {
|
|
|
|
public CompoundTag readStruct() throws CommandSyntaxException {
|
|
this.expect('{');
|
|
+ this.increaseDepth(); // Paper
|
|
CompoundTag compoundTag = new CompoundTag();
|
|
this.reader.skipWhitespace();
|
|
|
|
@@ -181,6 +183,7 @@ public class TagParser {
|
|
}
|
|
|
|
this.expect('}');
|
|
+ this.depth--; // Paper
|
|
return compoundTag;
|
|
}
|
|
|
|
@@ -190,6 +193,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;
|
|
|
|
@@ -215,6 +219,7 @@ public class TagParser {
|
|
}
|
|
|
|
this.expect(']');
|
|
+ this.depth--; // Paper
|
|
return listTag;
|
|
}
|
|
}
|
|
@@ -287,4 +292,11 @@ public class TagParser {
|
|
this.reader.skipWhitespace();
|
|
this.reader.expect(c);
|
|
}
|
|
+
|
|
+ private void increaseDepth() throws CommandSyntaxException {
|
|
+ this.depth++;
|
|
+ if (this.depth > 512) {
|
|
+ throw new io.papermc.paper.brigadier.TagParseCommandSyntaxException("NBT tag is too complex, depth > 512");
|
|
+ }
|
|
+ }
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/network/chat/contents/TranslatableContents.java b/src/main/java/net/minecraft/network/chat/contents/TranslatableContents.java
|
|
index 65debad7aa7ffb1b0b19f89713ff394e8c9d245e..18e53db59082bae94922edc4baa812aa6f089576 100644
|
|
--- a/src/main/java/net/minecraft/network/chat/contents/TranslatableContents.java
|
|
+++ b/src/main/java/net/minecraft/network/chat/contents/TranslatableContents.java
|
|
@@ -181,6 +181,15 @@ public class TranslatableContents implements ComponentContents {
|
|
|
|
@Override
|
|
public <T> Optional<T> visit(FormattedText.ContentConsumer<T> visitor) {
|
|
+ // Paper start - Count visited parts
|
|
+ try {
|
|
+ return this.visit(new TranslatableContentConsumer<>(visitor));
|
|
+ } catch (IllegalArgumentException ignored) {
|
|
+ return visitor.accept("...");
|
|
+ }
|
|
+ }
|
|
+ private <T> Optional<T> visit(TranslatableContentConsumer<T> visitor) {
|
|
+ // Paper end - Count visited parts
|
|
this.decompose();
|
|
|
|
for (FormattedText formattedText : this.decomposedParts) {
|
|
@@ -192,6 +201,25 @@ public class TranslatableContents implements ComponentContents {
|
|
|
|
return Optional.empty();
|
|
}
|
|
+ // Paper start - Count visited parts
|
|
+ private static final class TranslatableContentConsumer<T> implements FormattedText.ContentConsumer<T> {
|
|
+ private static final IllegalArgumentException EX = new IllegalArgumentException("Too long");
|
|
+ private final FormattedText.ContentConsumer<T> visitor;
|
|
+ private int visited;
|
|
+
|
|
+ private TranslatableContentConsumer(FormattedText.ContentConsumer<T> visitor) {
|
|
+ this.visitor = visitor;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public Optional<T> accept(final String asString) {
|
|
+ if (visited++ > 32) {
|
|
+ throw EX;
|
|
+ }
|
|
+ return this.visitor.accept(asString);
|
|
+ }
|
|
+ }
|
|
+ // Paper end - Count visited parts
|
|
|
|
@Override
|
|
public MutableComponent resolve(@Nullable CommandSourceStack source, @Nullable Entity sender, int depth) throws CommandSyntaxException {
|
|
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
|
|
index 98496bcc7ab9adde3fdc8b2cd9eaeceee99e28b4..860d33ac56680babd87358b1d7d2216dac3f7865 100644
|
|
--- 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));
|
|
}
|
|
@@ -824,6 +831,13 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
|
|
private void sendServerSuggestions(final ServerboundCommandSuggestionPacket packet, final StringReader stringreader) {
|
|
// Paper end - AsyncTabCompleteEvent
|
|
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 io.papermc.paper.brigadier.TagParseCommandSyntaxException)) {
|
|
+ this.disconnect(Component.translatable("disconnect.spam"), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM);
|
|
+ return;
|
|
+ }
|
|
+ // Paper end - Handle non-recoverable exceptions
|
|
|
|
this.server.getCommands().getDispatcher().getCompletionSuggestions(parseresults).thenAccept((suggestions) -> {
|
|
// Paper start - Don't tab-complete namespaced commands if send-namespaced is false
|