From 21dabada3e915fab95601666fb9eecc6ffcf1181 Mon Sep 17 00:00:00 2001 From: Florian Brandt Date: Fri, 2 Oct 2026 19:17:45 +0200 Subject: [PATCH 1/2] :bug: fix(gson): Drop unparseable hex colors instead of failing components Vanilla text components may carry hex colors (#RRGGBB) since 1.16, which text3 cannot represent. The old TextColorWrapper deserialization threw JsonParseException and the whole component parse failed. This drops the unparseable color instead, keeping the text content. Named colors still parse as before. --- .../text/serializer/gson/StyleSerializer.java | 20 +++++++++---- .../serializer/gson/StyleSerializerTest.java | 30 +++++++++++++++++++ 2 files changed, 44 insertions(+), 6 deletions(-) create mode 100644 worldedit-core/src/test/java/com/sk89q/worldedit/util/formatting/text/serializer/gson/StyleSerializerTest.java diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/text/serializer/gson/StyleSerializer.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/text/serializer/gson/StyleSerializer.java index 35bd43946a..f3ba4db89c 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/text/serializer/gson/StyleSerializer.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/text/serializer/gson/StyleSerializer.java @@ -87,12 +87,20 @@ private Style deserialize(final JsonObject json, final JsonDeserializationContex final Style.Builder style = Style.builder(); if (json.has(COLOR)) { - final TextColorWrapper color = context.deserialize(json.get(COLOR), TextColorWrapper.class); - if (color.color != null) { - style.color(color.color); - } else if (color.decoration != null) { - // I know. Setting a decoration from the color is weird. This is, unfortunately, something we need to support. - style.decoration(color.decoration, true); + TextColorWrapper color = null; + try { + color = context.deserialize(json.get(COLOR), TextColorWrapper.class); + } catch (JsonParseException _) { + // Vanilla text components may carry hex colors (#RRGGBB) since 1.16, text3 cannot represent them. + // Drop the color instead of failing to parse the whole component. + } + if (color != null) { + if (color.color != null) { + style.color(color.color); + } else if (color.decoration != null) { + // I know. Setting a decoration from the color is weird. This is, unfortunately, something we need to support. + style.decoration(color.decoration, true); + } } } diff --git a/worldedit-core/src/test/java/com/sk89q/worldedit/util/formatting/text/serializer/gson/StyleSerializerTest.java b/worldedit-core/src/test/java/com/sk89q/worldedit/util/formatting/text/serializer/gson/StyleSerializerTest.java new file mode 100644 index 0000000000..a1f3ee24e2 --- /dev/null +++ b/worldedit-core/src/test/java/com/sk89q/worldedit/util/formatting/text/serializer/gson/StyleSerializerTest.java @@ -0,0 +1,30 @@ +package com.sk89q.worldedit.util.formatting.text.serializer.gson; + +import com.sk89q.worldedit.util.formatting.text.Component; +import com.sk89q.worldedit.util.formatting.text.TextComponent; +import com.sk89q.worldedit.util.formatting.text.format.TextColor; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + +class StyleSerializerTest { + + @Test + void hexColorIsDroppedInsteadOfFailing() { + // Vanilla item names may carry hex colors ("#RRGGBB") since 1.16, text3 cannot represent them. + Component hexOnly = GsonComponentSerializer.INSTANCE.deserialize( + "{\"text\":\"Gold item\",\"color\":\"#FFD700\"}" + ); + assertEquals("Gold item", ((TextComponent) hexOnly).content()); + assertNull(hexOnly.color()); + } + + @Test + void namedColorStillParsed() { + Component component = GsonComponentSerializer.INSTANCE.deserialize( + "{\"text\":\"Gold item\",\"color\":\"gold\"}" + ); + assertEquals(TextColor.GOLD, component.color()); + } +} From ce8dcaa8495b8a35310bfe62a4b371058d0660d5 Mon Sep 17 00:00:00 2001 From: Florian Brandt Date: Sat, 3 Oct 2026 01:00:08 +0200 Subject: [PATCH 2/2] :bug: fix(gson): Log dropped colors at debug level, add license header Addresses review feedback on #3029: keep the parse-failure stacktrace available at debug level, and add the GPL header to the new test class. --- .../text/serializer/gson/StyleSerializer.java | 7 ++++++- .../serializer/gson/StyleSerializerTest.java | 19 +++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/text/serializer/gson/StyleSerializer.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/text/serializer/gson/StyleSerializer.java index f3ba4db89c..fb02a81150 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/text/serializer/gson/StyleSerializer.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/text/serializer/gson/StyleSerializer.java @@ -35,12 +35,14 @@ import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.extension.platform.Capability; import com.sk89q.worldedit.internal.Constants; +import com.sk89q.worldedit.internal.util.LogManagerCompat; import com.sk89q.worldedit.util.formatting.text.Component; import com.sk89q.worldedit.util.formatting.text.event.ClickEvent; import com.sk89q.worldedit.util.formatting.text.event.HoverEvent; import com.sk89q.worldedit.util.formatting.text.format.Style; import com.sk89q.worldedit.util.formatting.text.format.TextColor; import com.sk89q.worldedit.util.formatting.text.format.TextDecoration; +import org.apache.logging.log4j.Logger; import java.lang.reflect.Type; @@ -49,6 +51,8 @@ public class StyleSerializer implements JsonDeserializer