From 6a398c9b8d9646c37f2437cf2c547acd9cdc88e1 Mon Sep 17 00:00:00 2001 From: Bernd Busse Date: Thu, 27 Jul 2023 20:59:30 +0200 Subject: [PATCH] classlib: properly duplicate inner map when cloning TreeMap --- .../org/teavm/classlib/java/util/TTreeMap.java | 16 +++++++++++++--- .../teavm/classlib/java/util/TreeMapTest.java | 4 ++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/classlib/src/main/java/org/teavm/classlib/java/util/TTreeMap.java b/classlib/src/main/java/org/teavm/classlib/java/util/TTreeMap.java index 9b2493631..e5a703459 100644 --- a/classlib/src/main/java/org/teavm/classlib/java/util/TTreeMap.java +++ b/classlib/src/main/java/org/teavm/classlib/java/util/TTreeMap.java @@ -16,6 +16,7 @@ package org.teavm.classlib.java.util; import org.teavm.classlib.java.io.TSerializable; +import org.teavm.classlib.java.lang.TCloneNotSupportedException; import org.teavm.classlib.java.lang.TCloneable; public class TTreeMap extends TAbstractMap implements TCloneable, TSerializable, TNavigableMap { @@ -558,10 +559,19 @@ public class TTreeMap extends TAbstractMap implements TCloneable, TS } @Override + @SuppressWarnings("unchecked") public Object clone() { - TTreeMap copy = (TTreeMap) super.clone(); - copy.cachedEntrySet = null; - return copy; + try { + TTreeMap map = (TTreeMap) super.clone(); + map.root = null; + map.modCount = 0; + map.cachedEntrySet = null; + map.putAll(this); + + return map; + } catch (TCloneNotSupportedException e) { + return null; + } } static class EntrySet extends TAbstractSet> implements TSequencedSet> { diff --git a/tests/src/test/java/org/teavm/classlib/java/util/TreeMapTest.java b/tests/src/test/java/org/teavm/classlib/java/util/TreeMapTest.java index 06e05e08a..f17dd85e2 100644 --- a/tests/src/test/java/org/teavm/classlib/java/util/TreeMapTest.java +++ b/tests/src/test/java/org/teavm/classlib/java/util/TreeMapTest.java @@ -215,6 +215,10 @@ public class TreeMapTest { Set key2 = map2.keySet(); assertTrue("keySet() is identical", key2 != keys); assertEquals("keySet() was not cloned", "key2", key2.iterator().next()); + @SuppressWarnings("unchecked") + Map map3 = (Map) map.clone(); + map3.put("key2", "value2"); + assertFalse("Original map modified through clone", map.containsKey("key2")); } @Test