Detect component loops

This commit is contained in:
Thinkofdeath 2014-02-21 10:13:03 +00:00
parent e87d25c321
commit 941450b4e4
3 changed files with 37 additions and 1 deletions

View File

@ -1,5 +1,6 @@
package net.md_5.bungee.chat; package net.md_5.bungee.chat;
import com.google.common.base.Preconditions;
import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.google.gson.JsonSerializationContext; import com.google.gson.JsonSerializationContext;
@ -72,6 +73,8 @@ public class BaseComponentSerializer
protected void serialize(JsonObject object, BaseComponent component, JsonSerializationContext context) protected void serialize(JsonObject object, BaseComponent component, JsonSerializationContext context)
{ {
Preconditions.checkArgument( !ComponentSerializer.serializedComponents.get().contains( component ), "Component loop" );
ComponentSerializer.serializedComponents.get().add( component );
if ( component.getColorRaw() != null ) if ( component.getColorRaw() != null )
{ {
object.addProperty( "color", component.getColorRaw().getName() ); object.addProperty( "color", component.getColorRaw().getName() );

View File

@ -14,6 +14,7 @@ import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.chat.TranslatableComponent; import net.md_5.bungee.api.chat.TranslatableComponent;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.HashSet;
public class ComponentSerializer implements JsonSerializer<BaseComponent>, JsonDeserializer<BaseComponent> public class ComponentSerializer implements JsonSerializer<BaseComponent>, JsonDeserializer<BaseComponent>
{ {
@ -24,6 +25,15 @@ public class ComponentSerializer implements JsonSerializer<BaseComponent>, JsonD
registerTypeAdapter( TranslatableComponent.class, new TranslatableComponentSerializer() ). registerTypeAdapter( TranslatableComponent.class, new TranslatableComponentSerializer() ).
create(); create();
public final static ThreadLocal<HashSet<BaseComponent>> serializedComponents = new ThreadLocal<HashSet<BaseComponent>>()
{
@Override
protected HashSet<BaseComponent> initialValue()
{
return new HashSet<>();
}
};
public static BaseComponent[] parse(String json) public static BaseComponent[] parse(String json)
{ {
if ( json.startsWith( "[" ) ) if ( json.startsWith( "[" ) )
@ -64,6 +74,11 @@ public class ComponentSerializer implements JsonSerializer<BaseComponent>, JsonD
@Override @Override
public JsonElement serialize(BaseComponent src, Type typeOfSrc, JsonSerializationContext context) public JsonElement serialize(BaseComponent src, Type typeOfSrc, JsonSerializationContext context)
{ {
return context.serialize( src, src.getClass() ); try {
return context.serialize( src, src.getClass() );
} finally
{
serializedComponents.get().clear();
}
} }
} }

View File

@ -80,4 +80,22 @@ public class ComponentsTest
+ "World" + ChatColor.YELLOW + ChatColor.BOLD + "!", BaseComponent.toLegacyText( components ) ); + "World" + ChatColor.YELLOW + ChatColor.BOLD + "!", BaseComponent.toLegacyText( components ) );
} }
@Test(expected = IllegalArgumentException.class)
public void testLoopSimple() {
TextComponent component = new TextComponent( "Testing" );
component.addExtra( component );
ComponentSerializer.toString( component );
}
@Test(expected = IllegalArgumentException.class)
public void testLoopComplex() {
TextComponent a = new TextComponent( "A" );
TextComponent b = new TextComponent( "B" );
TextComponent c = new TextComponent( "C" );
a.addExtra( b );
b.addExtra( c );
c.addExtra( a );
ComponentSerializer.toString( a );
}
} }