8020977: StringJoiner merges with itself not as expected
authorhenryjen
Tue, 30 Jul 2013 15:47:35 -0700
changeset 19071 bc096b85d91d
parent 19070 24b4333be1d8
child 19072 8f176099ec00
8020977: StringJoiner merges with itself not as expected Reviewed-by: psandoz, chegar, mduigou, smarks
jdk/src/share/classes/java/util/StringJoiner.java
jdk/test/java/util/StringJoiner/MergeTest.java
--- a/jdk/src/share/classes/java/util/StringJoiner.java	Tue Jul 30 14:43:19 2013 -0700
+++ b/jdk/src/share/classes/java/util/StringJoiner.java	Tue Jul 30 15:47:35 2013 -0700
@@ -206,11 +206,12 @@
     public StringJoiner merge(StringJoiner other) {
         Objects.requireNonNull(other);
         if (other.value != null) {
+            final int length = other.value.length();
+            // lock the length so that we can seize the data to be appended
+            // before initiate copying to avoid interference, especially when
+            // merge 'this'
             StringBuilder builder = prepareBuilder();
-            StringBuilder otherBuilder = other.value;
-            if (other.prefix.length() < otherBuilder.length()) {
-                builder.append(otherBuilder, other.prefix.length(), otherBuilder.length());
-            }
+            builder.append(other.value, other.prefix.length(), length);
         }
         return this;
     }
--- a/jdk/test/java/util/StringJoiner/MergeTest.java	Tue Jul 30 14:43:19 2013 -0700
+++ b/jdk/test/java/util/StringJoiner/MergeTest.java	Tue Jul 30 15:47:35 2013 -0700
@@ -23,7 +23,7 @@
 
 /**
  * @test
- * @bug 8017231
+ * @bug 8017231 8020977
  * @summary test  StringJoiner::merge
  * @run testng MergeTest
  */
@@ -121,4 +121,13 @@
         sj.merge(other);
         assertEquals(sj.toString(), "{a,b,c,d:e:f}");
     }
-}
\ No newline at end of file
+
+    public void testMergeSelf() {
+        final StringJoiner sj = new StringJoiner(",", "[", "]").add("a").add("b");
+        assertEquals(sj.merge(sj).toString(), "[a,b,a,b]");
+        assertEquals(sj.merge(sj).toString(), "[a,b,a,b,a,b,a,b]");
+
+        final StringJoiner sj2 = new StringJoiner(",").add("c").add("d");
+        assertEquals(sj2.merge(sj2).toString(), "c,d,c,d");
+    }
+}