From d8f9d81b302fc71827a99288361ab5d8ab5a2135 Mon Sep 17 00:00:00 2001 From: Outfluencer Date: Tue, 27 May 2025 19:37:54 +1000 Subject: [PATCH] #3835: Check for dialog loops --- .../md_5/bungee/dialog/DialogSerializer.java | 40 ++++++++++++++----- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/serializer/src/main/java/net/md_5/bungee/dialog/DialogSerializer.java b/serializer/src/main/java/net/md_5/bungee/dialog/DialogSerializer.java index ec4e910f..d33adb71 100644 --- a/serializer/src/main/java/net/md_5/bungee/dialog/DialogSerializer.java +++ b/serializer/src/main/java/net/md_5/bungee/dialog/DialogSerializer.java @@ -13,6 +13,9 @@ import com.google.gson.JsonParser; import com.google.gson.JsonSerializationContext; import com.google.gson.JsonSerializer; import java.lang.reflect.Type; +import java.util.Collections; +import java.util.IdentityHashMap; +import java.util.Set; import lombok.RequiredArgsConstructor; import net.md_5.bungee.api.dialog.ConfirmationDialog; import net.md_5.bungee.api.dialog.Dialog; @@ -28,7 +31,7 @@ import net.md_5.bungee.chat.VersionedComponentSerializer; @RequiredArgsConstructor public class DialogSerializer implements JsonDeserializer, JsonSerializer { - + private static final ThreadLocal> serializedDialogs = new ThreadLocal>(); private static final BiMap> TYPES; private final VersionedComponentSerializer serializer; @@ -102,16 +105,35 @@ public class DialogSerializer implements JsonDeserializer, JsonSerialize return JsonNull.INSTANCE; } - Class realType = src.getClass(); - String type = TYPES.inverse().get( realType ); - Preconditions.checkArgument( type != null, "Unknown type %s", typeOfSrc ); + boolean first = serializedDialogs.get() == null; + if ( first ) + { + serializedDialogs.set( Collections.newSetFromMap( new IdentityHashMap() ) ); + } - JsonObject object = (JsonObject) context.serialize( src, realType ); - object.addProperty( "type", type ); + try + { + Preconditions.checkArgument( !serializedDialogs.get().contains( src ), "Dialog loop" ); + serializedDialogs.get().add( src ); - JsonObject base = (JsonObject) context.serialize( src.getBase() ); - object.asMap().putAll( base.asMap() ); + Class realType = src.getClass(); + String type = TYPES.inverse().get( realType ); + Preconditions.checkArgument( type != null, "Unknown type %s", typeOfSrc ); - return object; + JsonObject object = (JsonObject) context.serialize( src, realType ); + object.addProperty( "type", type ); + + JsonObject base = (JsonObject) context.serialize( src.getBase() ); + object.asMap().putAll( base.asMap() ); + + return object; + } finally + { + serializedDialogs.get().remove( src ); + if ( first ) + { + serializedDialogs.set( null ); + } + } } }