#3794: Ensure listType is set to compound tag when wrapping tags

This commit is contained in:
Julian Vennen 2025-03-01 14:48:59 +11:00 committed by md_5
parent 598d73e6f0
commit 362bd0f4c4
No known key found for this signature in database
GPG Key ID: E8E901AC7C617C11
2 changed files with 214 additions and 3 deletions

View File

@ -82,13 +82,27 @@ public final class TagUtil
{
List<JsonElement> jsonArray = ( (JsonArray) json ).asList();
if ( jsonArray.isEmpty() )
Integer listType = null;
for ( JsonElement jsonEl : jsonArray )
{
int type = fromJson( jsonEl ).tagType();
if ( listType == null )
{
listType = type;
} else if ( listType != type )
{
listType = Tag.TAG_COMPOUND;
break;
}
}
if ( listType == null )
{
return new ListTag( Tag.TAG_END, Collections.emptyList() );
}
SpecificTag listTag;
int listType = fromJson( jsonArray.get( 0 ) ).tagType();
switch ( listType )
{
case Tag.TAG_BYTE:
@ -124,7 +138,7 @@ public final class TagUtil
for ( JsonElement jsonEl : jsonArray )
{
SpecificTag subTag = fromJson( jsonEl );
if ( !( subTag instanceof CompoundTag ) )
if ( listType == Tag.TAG_COMPOUND && !( subTag instanceof CompoundTag ) )
{
CompoundTag wrapper = new CompoundTag();
wrapper.add( "", subTag );

View File

@ -2,9 +2,20 @@ package net.md_5.bungee.protocol;
import static org.junit.jupiter.api.Assertions.*;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import org.junit.jupiter.api.Test;
import se.llbit.nbt.ByteArrayTag;
import se.llbit.nbt.CompoundTag;
import se.llbit.nbt.IntArrayTag;
import se.llbit.nbt.IntTag;
import se.llbit.nbt.ListTag;
import se.llbit.nbt.LongArrayTag;
import se.llbit.nbt.SpecificTag;
import se.llbit.nbt.StringTag;
import se.llbit.nbt.Tag;
public class TagUtilTest
{
@ -26,4 +37,190 @@ public class TagUtilTest
{
testDissembleReassemble( "{\"text\":\"\",\"extra\":[\"hello\",{\"text\":\"there\",\"color\":\"#ff0000\"},{\"text\":\"friend\",\"font\":\"minecraft:default\"}]}" );
}
public void testCreateMixedList(JsonArray array)
{
SpecificTag tag = TagUtil.fromJson( array );
assertInstanceOf( ListTag.class, tag );
ListTag list = (ListTag) tag;
assertEquals( SpecificTag.TAG_COMPOUND, list.getType() );
assertEquals( array.size(), list.size() );
for ( int i = 0; i < list.size(); i++ )
{
assertTrue( i < array.size() );
Tag element = list.get( i );
assertInstanceOf( CompoundTag.class, element );
CompoundTag compound = (CompoundTag) element;
JsonElement expected = array.get( i );
if ( expected instanceof JsonObject )
{
assertEquals( TagUtil.fromJson( expected ), compound );
} else
{
assertEquals( 1, compound.size() );
Tag value = compound.get( "" );
if ( expected instanceof JsonPrimitive )
{
JsonPrimitive primitive = (JsonPrimitive) expected;
if ( primitive.isNumber() )
{
Number number = primitive.getAsNumber();
if ( number instanceof Integer )
{
assertInstanceOf( IntTag.class, value );
IntTag integer = (IntTag) value;
assertEquals( array.get( i ).getAsInt(), integer.getData() );
}
} else if ( primitive.isString() )
{
assertInstanceOf( StringTag.class, value );
StringTag string = (StringTag) value;
assertEquals( array.get( i ).getAsString(), string.getData() );
}
}
}
}
}
@Test
public void testMixedListWithInt()
{
JsonArray array = new JsonArray();
array.add( 1 );
array.add( "a" );
testCreateMixedList( array );
}
@Test
public void testMixedListWithString()
{
JsonArray array = new JsonArray();
array.add( "a" );
array.add( 1L );
testCreateMixedList( array );
}
@Test
public void testMixedListWithObject()
{
JsonObject compound = new JsonObject();
compound.addProperty( "a", "b" );
JsonArray array = new JsonArray();
array.add( compound );
array.add( 1L );
testCreateMixedList( array );
}
@Test
public void testCreateEmptyList()
{
JsonArray array = new JsonArray();
SpecificTag tag = TagUtil.fromJson( array );
assertInstanceOf( ListTag.class, tag );
ListTag list = (ListTag) tag;
assertEquals( 0, list.size() );
assertEquals( Tag.TAG_END, list.getType() );
}
@Test
public void testCreateByteArray()
{
JsonArray array = new JsonArray();
array.add( ( (byte) 1 ) );
array.add( ( (byte) 2 ) );
SpecificTag tag = TagUtil.fromJson( array );
assertInstanceOf( ByteArrayTag.class, tag );
ByteArrayTag byteArray = (ByteArrayTag) tag;
assertEquals( 2, byteArray.getData().length );
for ( int i = 0; i < byteArray.getData().length; i++ )
{
assertTrue( i < array.size() );
byte item = byteArray.getData()[i];
assertEquals( array.get( i ).getAsByte(), item );
}
}
@Test
public void testCreateIntArray()
{
JsonArray array = new JsonArray();
array.add( 1 );
array.add( 2 );
SpecificTag tag = TagUtil.fromJson( array );
assertInstanceOf( IntArrayTag.class, tag );
IntArrayTag intArray = (IntArrayTag) tag;
assertEquals( 2, intArray.getData().length );
for ( int i = 0; i < intArray.getData().length; i++ )
{
assertTrue( i < array.size() );
int item = intArray.getData()[i];
assertEquals( array.get( i ).getAsInt(), item );
}
}
@Test
public void testCreateLongArray()
{
JsonArray array = new JsonArray();
array.add( 1L );
array.add( 2L );
SpecificTag tag = TagUtil.fromJson( array );
assertInstanceOf( LongArrayTag.class, tag );
LongArrayTag intArray = (LongArrayTag) tag;
assertEquals( 2, intArray.getData().length );
for ( int i = 0; i < intArray.getData().length; i++ )
{
assertTrue( i < array.size() );
long item = intArray.getData()[i];
assertEquals( array.get( i ).getAsLong(), item );
}
}
@Test
public void testCreateStringList()
{
JsonArray array = new JsonArray();
array.add( "a" );
array.add( "b" );
SpecificTag tag = TagUtil.fromJson( array );
assertInstanceOf( ListTag.class, tag );
ListTag list = (ListTag) tag;
assertEquals( SpecificTag.TAG_STRING, list.getType() );
assertEquals( 2, list.size() );
for ( int i = 0; i < list.size(); i++ )
{
assertTrue( i < array.size() );
Tag item = list.get( i );
assertInstanceOf( StringTag.class, item );
StringTag string = (StringTag) item;
assertEquals( array.get( i ).getAsString(), string.getData() );
}
}
}