Specifically clone Spigot's chat components to fix stack overflow

Addresses #601
This commit is contained in:
Dan Mulloy 2019-05-06 20:32:20 -04:00
parent 9f5d95f617
commit d297e373b4
3 changed files with 22 additions and 10 deletions

View File

@ -31,6 +31,8 @@ import com.comphenix.protocol.wrappers.*;
import com.comphenix.protocol.wrappers.nbt.NbtFactory;
import com.google.common.collect.Maps;
import net.md_5.bungee.api.chat.BaseComponent;
/**
* Represents an object that can clone a specific list of Bukkit- and Minecraft-related objects.
*
@ -78,6 +80,8 @@ public class BukkitCloner implements Cloner {
fromManual(MinecraftReflection::getNonNullListClass, source -> nonNullListCloner().clone(source));
fromWrapper(MinecraftReflection::getNBTBaseClass, NbtFactory::fromNMS);
fromWrapper(MinecraftReflection::getIChatBaseComponentClass, WrappedChatComponent::fromHandle);
fromManual(ComponentConverter::getBaseComponentArrayClass, source ->
ComponentConverter.clone((BaseComponent[]) source));
}
private Function<Object, Object> findCloner(Class<?> type) {

View File

@ -47,4 +47,12 @@ public final class ComponentConverter {
public static WrappedChatComponent fromBaseComponent(BaseComponent... components) {
return WrappedChatComponent.fromJson(ComponentSerializer.toString(components));
}
public static Class<?> getBaseComponentArrayClass() {
return BaseComponent[].class;
}
public static BaseComponent[] clone(BaseComponent... components) {
return ComponentSerializer.parse(ComponentSerializer.toString(components));
}
}

View File

@ -16,6 +16,10 @@
*/
package com.comphenix.protocol.events;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.util.*;
import com.comphenix.protocol.BukkitInitialization;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.injector.PacketConstructor;
@ -51,10 +55,6 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.util.*;
import static com.comphenix.protocol.utility.TestUtils.*;
import static org.junit.Assert.*;
@ -66,17 +66,18 @@ public class PacketContainerTest {
// Helper converters
private EquivalentConverter<WrappedDataWatcher> watchConvert = BukkitConverters.getDataWatcherConverter();
private EquivalentConverter<ItemStack> itemConvert = BukkitConverters.getItemStackConverter();
private static BaseComponent[] TEST_COMPONENT;
@BeforeClass
public static void initializeBukkit() {
BukkitInitialization.initializeItemMeta();
BukkitInitialization.initializePackage();
TEST_COMPONENT = ComponentConverter.fromBaseComponent(
TEST_COMPONENT =
new ComponentBuilder("Hit or miss?")
.event(new ClickEvent(ClickEvent.Action.OPEN_URL, "http://reddit.com"))
.event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new BaseComponent[] { new TextComponent("The \"front page\" of the internet") }))
.append("I guess they never miss, huh?").create());
.append("I guess they never miss, huh?").create();
}
private <T> void testPrimitive(StructureModifier<T> modifier, int index, T initialValue, T testValue) {
@ -511,8 +512,6 @@ public class PacketContainerTest {
PacketType.Play.Server.TAGS
);
private static WrappedChatComponent TEST_COMPONENT;
@Test
public void testDeepClone() {
// Try constructing all the packets
@ -536,10 +535,11 @@ public class PacketContainerTest {
"String"),
new WrappedWatchableObject(new WrappedDataWatcherObject(0, Registry.get(Float.class)), 1.0F),
new WrappedWatchableObject(new WrappedDataWatcherObject(0, Registry.getChatComponentSerializer(true)),
com.google.common.base.Optional.of(TEST_COMPONENT.getHandle()))
com.google.common.base.Optional.of(ComponentConverter.fromBaseComponent(TEST_COMPONENT).getHandle()))
));
} else if (type == PacketType.Play.Server.CHAT) {
constructed.getChatComponents().write(0, TEST_COMPONENT);
constructed.getChatComponents().write(0, ComponentConverter.fromBaseComponent(TEST_COMPONENT));
//constructed.getModifier().write(1, TEST_COMPONENT);
}
// Clone the packet