From 6b00b14539bbfe4b32a93de4ce66856b71ba9d8f Mon Sep 17 00:00:00 2001 From: Bjarne Koll Date: Sun, 1 Mar 2020 17:23:54 +0100 Subject: [PATCH] #639: Deep clone itemmetas persistent container on clone After this commit, spigot now creates a deep copy of the itemmeta's persistent data container when the itemmeta instance is cloned. This change fixes the bug that, after cloning itemmeta, the container instance the cloned meta would point to was equal to the original one. This resulted in two itemmeta instances sharing a single persistent container. --- .../craftbukkit/inventory/CraftMetaItem.java | 3 ++- .../inventory/PersistentDataContainerTest.java | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java index 9bfbb90579..8d0e465c26 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java @@ -279,7 +279,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { private NBTTagCompound internalTag; private final Map unhandledTags = new HashMap(); - private final CraftPersistentDataContainer persistentDataContainer = new CraftPersistentDataContainer(DATA_TYPE_REGISTRY); + private CraftPersistentDataContainer persistentDataContainer = new CraftPersistentDataContainer(DATA_TYPE_REGISTRY); private int version = CraftMagicNumbers.INSTANCE.getDataVersion(); // Internal use only @@ -1197,6 +1197,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { if (this.hasAttributeModifiers()) { clone.attributeModifiers = LinkedHashMultimap.create(this.attributeModifiers); } + clone.persistentDataContainer = new CraftPersistentDataContainer(this.persistentDataContainer.getRaw(), DATA_TYPE_REGISTRY); clone.hideFlag = this.hideFlag; clone.unbreakable = this.unbreakable; clone.damage = this.damage; diff --git a/src/test/java/org/bukkit/craftbukkit/inventory/PersistentDataContainerTest.java b/src/test/java/org/bukkit/craftbukkit/inventory/PersistentDataContainerTest.java index 22d8fbd714..6feee747e1 100644 --- a/src/test/java/org/bukkit/craftbukkit/inventory/PersistentDataContainerTest.java +++ b/src/test/java/org/bukkit/craftbukkit/inventory/PersistentDataContainerTest.java @@ -310,4 +310,20 @@ public class PersistentDataContainerTest extends AbstractTestingBase { return primitive; } } + + @Test + public void testItemMetaClone() { + ItemMeta itemMeta = createNewItemMeta(); + PersistentDataContainer container = itemMeta.getPersistentDataContainer(); + itemMeta.getPersistentDataContainer().set(VALID_KEY, PersistentDataType.STRING, "notch"); + + ItemMeta clonedMeta = itemMeta.clone(); + PersistentDataContainer clonedContainer = clonedMeta.getPersistentDataContainer(); + + assertNotSame(container, clonedContainer); + assertEquals(container, clonedContainer); + + clonedContainer.set(VALID_KEY, PersistentDataType.STRING, "dinnerbone"); + assertNotEquals(container, clonedContainer); + } }