From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Video Date: Mon, 28 Mar 2022 13:19:43 -0600 Subject: [PATCH] Better handling of invalid JSON components diff --git a/src/main/java/io/papermc/paper/util/MCUtil.java b/src/main/java/io/papermc/paper/util/MCUtil.java index 6efb8b10f17c70b05128039376d254e6beda3841..d280d5b34614442710d64443d03a5bdee86294a9 100644 --- a/src/main/java/io/papermc/paper/util/MCUtil.java +++ b/src/main/java/io/papermc/paper/util/MCUtil.java @@ -542,13 +542,7 @@ public final class MCUtil { return null; } String string = compound.getString(key); - try { - return Component.Serializer.fromJson(string); - } catch (com.google.gson.JsonParseException e) { - org.bukkit.Bukkit.getLogger().warning("Unable to parse " + key + " from " + compound +": " + e.getMessage()); - } - - return null; + return Component.Serializer.fromJsonSafe(string); } public static ChunkStatus getChunkStatus(ChunkHolder chunk) { diff --git a/src/main/java/net/minecraft/network/chat/Component.java b/src/main/java/net/minecraft/network/chat/Component.java index 37fc353c3e59dd5af2fd6c58ac084fb0e6e155d7..2873ed7c443ed8c8c57a8b1d3e444d229f10f07b 100644 --- a/src/main/java/net/minecraft/network/chat/Component.java +++ b/src/main/java/net/minecraft/network/chat/Component.java @@ -26,6 +26,7 @@ import java.util.List; import java.util.Map.Entry; import java.util.Optional; import javax.annotation.Nullable; +import net.minecraft.ChatFormatting; // Scissors import net.minecraft.Util; import net.minecraft.network.chat.contents.BlockDataSource; import net.minecraft.network.chat.contents.DataSource; @@ -522,6 +523,26 @@ public interface Component extends Message, FormattedText, Iterable { return GsonHelper.toStableString(Serializer.toJsonTree(text)); } + // Scissors start + @Nullable + public static MutableComponent fromJsonSafe(String json) { + try { + return fromJson(json); + } catch (Exception ex) { + return Component.empty().append("** Invalid JSON Component **").withStyle(ChatFormatting.RED); + } + } + + @Nullable + public static MutableComponent fromJsonSafe(JsonElement json) { + try { + return fromJson(json); + } catch (Exception ex) { + return Component.empty().append("** Invalid JSON Component **").withStyle(ChatFormatting.RED); + } + } + // Scissors end + public static JsonElement toJsonTree(Component text) { return Component.Serializer.GSON.toJsonTree(text); } diff --git a/src/main/java/net/minecraft/network/chat/HoverEvent.java b/src/main/java/net/minecraft/network/chat/HoverEvent.java index 7449a024265c42f28a6c9a1ed8d8f4b9e3096aac..487c68abc3eb5c18dc7fee762b2164001283cab7 100644 --- a/src/main/java/net/minecraft/network/chat/HoverEvent.java +++ b/src/main/java/net/minecraft/network/chat/HoverEvent.java @@ -79,7 +79,7 @@ public class HoverEvent { if (jsonElement != null) { return action.deserialize(jsonElement); } else { - Component component = Component.Serializer.fromJson(json.get("value")); + Component component = Component.Serializer.fromJsonSafe(json.get("value")); // Scissors - Use safer method for getting Components from JSON return component != null ? action.deserializeFromLegacy(component) : null; } } @@ -94,7 +94,7 @@ public class HoverEvent { } public static class Action { - public static final HoverEvent.Action SHOW_TEXT = new HoverEvent.Action<>("show_text", true, Component.Serializer::fromJson, Component.Serializer::toJsonTree, Function.identity()); + public static final HoverEvent.Action SHOW_TEXT = new HoverEvent.Action<>("show_text", true, Component.Serializer::fromJsonSafe, Component.Serializer::toJsonTree, Function.identity()); // Scissors - Use safer method for getting Components from JSON public static final HoverEvent.Action SHOW_ITEM = new HoverEvent.Action<>("show_item", true, HoverEvent.ItemStackInfo::create, HoverEvent.ItemStackInfo::serialize, HoverEvent.ItemStackInfo::create); public static final HoverEvent.Action SHOW_ENTITY = new HoverEvent.Action<>("show_entity", true, HoverEvent.EntityTooltipInfo::create, HoverEvent.EntityTooltipInfo::serialize, HoverEvent.EntityTooltipInfo::create); private static final Map> LOOKUP = Stream.of(SHOW_TEXT, SHOW_ITEM, SHOW_ENTITY).collect(ImmutableMap.toImmutableMap(HoverEvent.Action::getName, (action) -> { @@ -182,7 +182,7 @@ public class HoverEvent { return null; } // Scissors end - Component component = Component.Serializer.fromJson(jsonObject.get("name")); + Component component = Component.Serializer.fromJsonSafe(jsonObject.get("name")); // Scissors - Use safer method for getting Components from JSON return new HoverEvent.EntityTooltipInfo(entityType, uUID, component); } } @@ -191,7 +191,7 @@ public class HoverEvent { public static HoverEvent.EntityTooltipInfo create(Component text) { try { CompoundTag compoundTag = TagParser.parseTag(text.getString()); - Component component = Component.Serializer.fromJson(compoundTag.getString("name")); + Component component = Component.Serializer.fromJsonSafe(compoundTag.getString("name")); // Scissors - Use safer method for getting Components from JSON EntityType entityType = BuiltInRegistries.ENTITY_TYPE.get(new ResourceLocation(compoundTag.getString("type"))); // Scissors start UUID uUID; diff --git a/src/main/java/net/minecraft/network/chat/contents/NbtContents.java b/src/main/java/net/minecraft/network/chat/contents/NbtContents.java index 97a2657bc98d41c3c1e376b266d2c85f685acc88..9d20f3f1af8e663a8c13714c8928d4a91653daa4 100644 --- a/src/main/java/net/minecraft/network/chat/contents/NbtContents.java +++ b/src/main/java/net/minecraft/network/chat/contents/NbtContents.java @@ -8,6 +8,7 @@ import java.util.Optional; import java.util.stream.Collectors; import java.util.stream.Stream; import javax.annotation.Nullable; +import net.kyori.adventure.text.TextComponent; // Scissors import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.arguments.NbtPathArgument; import net.minecraft.nbt.Tag; @@ -107,10 +108,10 @@ public class NbtContents implements ComponentContents { Component component = DataFixUtils.orElse(ComponentUtils.updateForEntity(source, this.separator, sender, depth), ComponentUtils.DEFAULT_NO_STYLE_SEPARATOR); return stream.flatMap((text) -> { try { - MutableComponent mutableComponent = Component.Serializer.fromJson(text); + MutableComponent mutableComponent = Component.Serializer.fromJsonSafe(text); // Scissors return Stream.of(ComponentUtils.updateForEntity(source, mutableComponent, sender, depth)); } catch (Exception var5) { - LOGGER.warn("Failed to parse component: {}", text, var5); + // Scissors - don't log return Stream.of(); } }).reduce((accumulator, current) -> { diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java index 280ee1838106201f5e3ba7753caced6d030f7e55..ade4ed2f219d32050a372283eaebe75f9014ec78 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -2354,12 +2354,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { this.setRot(this.getYRot(), this.getXRot()); if (nbt.contains("CustomName", 8)) { String s = nbt.getString("CustomName"); - - try { - this.setCustomName(Component.Serializer.fromJson(s)); - } catch (Exception exception) { - Entity.LOGGER.warn("Failed to parse entity custom name {}", s, exception); - } + this.setCustomName(Component.Serializer.fromJsonSafe(s)); // Scissors - Use safer method for getting Components from JSON } this.setCustomNameVisible(nbt.getBoolean("CustomNameVisible")); diff --git a/src/main/java/net/minecraft/world/scores/ScoreboardSaveData.java b/src/main/java/net/minecraft/world/scores/ScoreboardSaveData.java index 2be7a697f08045b974579e6942b38571e744efac..84ec21c38bb44db1e9ff26c01d5c8af1a2417616 100644 --- a/src/main/java/net/minecraft/world/scores/ScoreboardSaveData.java +++ b/src/main/java/net/minecraft/world/scores/ScoreboardSaveData.java @@ -35,7 +35,7 @@ public class ScoreboardSaveData extends SavedData { CompoundTag compoundTag = nbt.getCompound(i); String string = compoundTag.getString("Name"); PlayerTeam playerTeam = this.scoreboard.addPlayerTeam(string); - Component component = Component.Serializer.fromJson(compoundTag.getString("DisplayName")); + Component component = Component.Serializer.fromJsonSafe(compoundTag.getString("DisplayName")); // Scissors - Use safer method for getting Components from JSON if (component != null) { playerTeam.setDisplayName(component); } @@ -53,14 +53,14 @@ public class ScoreboardSaveData extends SavedData { } if (compoundTag.contains("MemberNamePrefix", 8)) { - Component component2 = Component.Serializer.fromJson(compoundTag.getString("MemberNamePrefix")); + Component component2 = Component.Serializer.fromJsonSafe(compoundTag.getString("MemberNamePrefix")); // Scissors - Use safer method for getting Components from JSON if (component2 != null) { playerTeam.setPlayerPrefix(component2); } } if (compoundTag.contains("MemberNameSuffix", 8)) { - Component component3 = Component.Serializer.fromJson(compoundTag.getString("MemberNameSuffix")); + Component component3 = Component.Serializer.fromJsonSafe(compoundTag.getString("MemberNameSuffix")); // Scissors - Use safer method for getting Components from JSON if (component3 != null) { playerTeam.setPlayerSuffix(component3); } @@ -115,7 +115,7 @@ public class ScoreboardSaveData extends SavedData { CompoundTag compoundTag = nbt.getCompound(i); ObjectiveCriteria.byName(compoundTag.getString("CriteriaName")).ifPresent((criterion) -> { String string = compoundTag.getString("Name"); - Component component = Component.Serializer.fromJson(compoundTag.getString("DisplayName")); + Component component = Component.Serializer.fromJsonSafe(compoundTag.getString("DisplayName")); // Scissors - Use safer method for getting Components from JSON ObjectiveCriteria.RenderType renderType = ObjectiveCriteria.RenderType.byId(compoundTag.getString("RenderType")); this.scoreboard.addObjective(string, criterion, component, renderType); });