diff --git a/text-serializer-gson/src/main/java/net/kyori/adventure/text/serializer/gson/StyleSerializer.java b/text-serializer-gson/src/main/java/net/kyori/adventure/text/serializer/gson/StyleSerializer.java index 4f74b0161..5f692cb69 100644 --- a/text-serializer-gson/src/main/java/net/kyori/adventure/text/serializer/gson/StyleSerializer.java +++ b/text-serializer-gson/src/main/java/net/kyori/adventure/text/serializer/gson/StyleSerializer.java @@ -147,7 +147,9 @@ public Style read(final JsonReader in) throws IOException { if (hoverEventObject.has(HOVER_EVENT_CONTENTS)) { final @Nullable JsonElement rawValue = hoverEventObject.get(HOVER_EVENT_CONTENTS); final Class actionType = action.type(); - if (SerializerFactory.COMPONENT_TYPE.isAssignableFrom(actionType)) { + if (isNullOrEmpty(rawValue)) { + value = null; + } else if (SerializerFactory.COMPONENT_TYPE.isAssignableFrom(actionType)) { value = this.gson.fromJson(rawValue, SerializerFactory.COMPONENT_TYPE); } else if (SerializerFactory.SHOW_ITEM_TYPE.isAssignableFrom(actionType)) { value = this.gson.fromJson(rawValue, SerializerFactory.SHOW_ITEM_TYPE); @@ -157,8 +159,13 @@ public Style read(final JsonReader in) throws IOException { value = null; } } else if (hoverEventObject.has(HOVER_EVENT_VALUE)) { - final Component rawValue = this.gson.fromJson(hoverEventObject.get(HOVER_EVENT_VALUE), SerializerFactory.COMPONENT_TYPE); - value = this.legacyHoverEventContents(action, rawValue); + final JsonElement element = hoverEventObject.get(HOVER_EVENT_VALUE); + if (isNullOrEmpty(element)) { + value = null; + } else { + final Component rawValue = this.gson.fromJson(element, SerializerFactory.COMPONENT_TYPE); + value = this.legacyHoverEventContents(action, rawValue); + } } else { value = null; } @@ -177,6 +184,10 @@ public Style read(final JsonReader in) throws IOException { return style.build(); } + private static boolean isNullOrEmpty(final @Nullable JsonElement element) { + return element == null || element.isJsonNull() || (element.isJsonArray() && element.getAsJsonArray().size() == 0) || (element.isJsonObject() && element.getAsJsonObject().size() == 0); + } + private boolean readBoolean(final JsonReader in) throws IOException { final JsonToken peek = in.peek(); if (peek == JsonToken.BOOLEAN) { diff --git a/text-serializer-gson/src/test/java/net/kyori/adventure/text/serializer/gson/GsonComponentSerializerTest.java b/text-serializer-gson/src/test/java/net/kyori/adventure/text/serializer/gson/GsonComponentSerializerTest.java index 7cad7c7c4..db6f1416c 100644 --- a/text-serializer-gson/src/test/java/net/kyori/adventure/text/serializer/gson/GsonComponentSerializerTest.java +++ b/text-serializer-gson/src/test/java/net/kyori/adventure/text/serializer/gson/GsonComponentSerializerTest.java @@ -90,6 +90,14 @@ void testDeserializeJsonNull() { assertEquals("Don't know how to turn null into a Component", ex.getMessage()); } + // https://github.com/KyoriPowered/adventure/issues/414 + @Test + void testSkipInvalidHoverEvent() { + final String input = "{\"text\": \"hello\", \"hoverEvent\":{\"action\":\"show_text\",\"value\":[]}}"; + final Component expected = Component.text("hello"); + assertEquals(expected, GsonComponentSerializer.gson().deserialize(input)); + } + private static String name(final NamedTextColor color) { return NamedTextColor.NAMES.key(color); }