undefect. CWE-407 — 63 sites patched across 27 ecosystems

Authors: russell@unturf.com · brackishbert@gmail.com · foxhop.net · TimeHexOn.com

Patches, unit tests, benchmarks, whitepaper, and outreach briefs.
Public domain — no copyright claimed. Use freely.
This commit is contained in:
russell@unturf.com 2026-03-26 17:11:57 -04:00
commit 0a580b313d
70422 changed files with 17213626 additions and 0 deletions

View file

@ -0,0 +1,264 @@
/*
* Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
* @bug 4812591 4705328 5019111 8218228
* @summary Test append and insert methods with CharSequence params
* @key randomness
*/
import java.util.Random;
public class AppendCharSequence {
private static Random generator = new Random();
public static void main(String[] args) throws Exception {
bash();
checkNulls();
checkOffsets();
checkConstructor();
}
// Sanity test of contents
private static void bash() throws Exception {
for (int i=0; i<1000; i++) {
StringBuffer sb1 = generateTestBuffer(0, 100);
StringBuffer sb2 = generateTestBuffer(0, 100);
StringBuffer sb3 = generateTestBuffer(0, 100);
StringBuffer sb4 = generateTestBuffer(0, 100);
StringBuffer sb5 = new StringBuffer();
String s1 = sb1.toString();
String s2 = sb2.toString();
String s3 = sb3.toString();
String s4 = sb4.toString();
String s5 = null;
// append(CharSequence cs)
sb5.append((CharSequence)sb1);
s5 = sb1.toString();
if (!sb5.toString().equals(s5))
throw new RuntimeException("StringBuffer.append failure 1");
// append (CharSequence cs, int start, int end)
int index = generator.nextInt(100);
int len = generator.nextInt(100);
while (index > sb2.length() - len) {
index = generator.nextInt(100);
len = generator.nextInt(100);
}
sb5.append((CharSequence)sb2, index, index + len);
s5 = s5 + sb2.toString().substring(index, index + len);
if (!sb5.toString().equals(s5))
throw new RuntimeException("StringBuffer.append failure 2");
// insert(int dstOffset, CharSequence cs)
index = generator.nextInt(100);
while (index > s5.length()) {
index = generator.nextInt(100);
}
sb5.insert(index, (CharSequence)sb3);
s5 = new StringBuffer(s5).insert(index, sb3).toString();
if (!sb5.toString().equals(s5))
throw new RuntimeException("StringBuffer.insert failure 1");
// insert(int dstOffset, CharSequence s, int start, int end)
int index1 = generator.nextInt(100);
while (index1 > s5.length()) {
index1 = generator.nextInt(100);
}
int index2 = generator.nextInt(100);
len = generator.nextInt(100);
while (index2 > sb4.length() - len) {
index2 = generator.nextInt(100);
len = generator.nextInt(100);
}
sb5.insert(index1, (CharSequence)sb4, index2, index2 + len);
s5 = new StringBuffer(s5).insert(index1, s4.toCharArray(),
index2, len).toString();
if (!sb5.toString().equals(s5))
throw new RuntimeException("StringBuffer.insert failure 2");
}
}
private static int getRandomIndex(int constraint1, int constraint2) {
int range = constraint2 - constraint1;
int x = generator.nextInt(range);
return constraint1 + x;
}
private static StringBuffer generateTestBuffer(int min, int max) {
StringBuffer aNewStringBuffer = new StringBuffer();
int aNewLength = getRandomIndex(min, max);
for(int y=0; y<aNewLength; y++) {
int achar = generator.nextInt(30)+30;
char test = (char)(achar);
aNewStringBuffer.append(test);
}
return aNewStringBuffer;
}
// Check handling of null as "null"
private static void checkNulls() throws Exception {
StringBuffer sb1 = new StringBuffer();
CharSequence cs = null;
sb1.append("test");
sb1.append(cs);
if (!sb1.toString().equals("testnull"))
throw new RuntimeException("StringBuffer.append failure 3");
sb1 = new StringBuffer();
sb1.append("test", 0, 2);
sb1.append(cs, 0, 2);
if (!sb1.toString().equals("tenu"))
throw new RuntimeException("StringBuffer.append failure 4");
sb1 = new StringBuffer("test");
sb1.insert(2, cs);
if (!sb1.toString().equals("tenullst"))
throw new RuntimeException("StringBuffer.insert failure 3");
sb1 = new StringBuffer("test");
sb1.insert(2, cs, 0, 2);
if (!sb1.toString().equals("tenust"))
throw new RuntimeException("StringBuffer.insert failure 4");
}
// Test the bounds checking
private static void checkOffsets() throws Exception {
// append (CharSeqeunce cs, int start, int end)
for (int i=0; i<100; i++) {
StringBuffer sb = generateTestBuffer(0, 80);
CharSequence cs = (CharSequence)generateTestBuffer(0, 80);
int index = 0;
int len = 0;
while (index <= cs.length() - len) {
index = generator.nextInt(100) - 50;
len = generator.nextInt(100) - 50;
if (index < 0)
break;
if (len < 0)
break;
}
try {
sb.append(cs, index, index + len);
throw new RuntimeException("Append bounds checking failure");
} catch (IndexOutOfBoundsException e) {
// Correct result
}
}
// insert(int dstOffset, CharSequence cs)
for (int i=0; i<100; i++) {
StringBuffer sb = new StringBuffer("test1");
CharSequence cs = (CharSequence)new StringBuffer("test2");
int index = 0;
while (index <= sb.length()) {
index = generator.nextInt(100) - 50;
if (index < 0)
break;
}
try {
sb.insert(index, cs);
throw new RuntimeException("Insert bounds checking failure");
} catch (IndexOutOfBoundsException e) {
// Correct result
}
}
// insert(int dstOffset, CharSequence s, int start, int end)
for (int i=0; i<100; i++) {
StringBuffer sb = new StringBuffer("test1");
CharSequence cs = (CharSequence)new StringBuffer("test2");
int index1 = 0;
while (index1 <= sb.length()) {
index1 = generator.nextInt(100) - 50;
if (index1 < 0)
break;
}
int index2 = 0;
int len = 0;
while (index2 < sb.length() - len) {
index2 = generator.nextInt(100) - 50;
len = generator.nextInt(100) - 50;
if (index2 < 0)
break;
if (len < 0)
break;
}
try {
sb.insert(index1, cs, index2, index2 + len);
throw new RuntimeException("Insert bounds checking failure");
} catch (IndexOutOfBoundsException e) {
// Correct result
}
}
}
// Test the CharSequence constructor
private static void checkConstructor() throws Exception {
for (int i=0; i<100; i++) {
StringBuffer sb = generateTestBuffer(0, 100);
CharSequence cs = (CharSequence)sb;
StringBuffer sb2 = new StringBuffer(cs);
if (!sb.toString().equals(sb2.toString())) {
throw new RuntimeException("CharSequence constructor failure");
}
}
checkNegativeLenCharSeq(-1);
checkNegativeLenCharSeq(-16);
checkNegativeLenCharSeq(-17);
checkNegativeLenCharSeq(Integer.MIN_VALUE);
}
// Test constructing from CharSequence of negative length
private static void checkNegativeLenCharSeq(int len) {
try {
CharSequence seq = new MyNegativeLenCharSeq(len);
StringBuffer sb = new StringBuffer(seq);
} catch (NegativeArraySizeException expected) {
} catch (Throwable exc) {
throw new RuntimeException("Unexpected: " + exc, exc);
}
}
private static class MyNegativeLenCharSeq implements CharSequence {
int length;
MyNegativeLenCharSeq(int length) {
this.length = length;
}
public char charAt(int i) {
throw new UnsupportedOperationException();
}
public int length() { return length; }
public CharSequence subSequence(int st, int e) {
throw new UnsupportedOperationException();
}
public String toString() { return ""; }
}
}

View file

@ -0,0 +1,72 @@
/*
* Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
* @bug 4144267
* @summary Test StringBuffer.append(StringBuffer);
* @key randomness
*/
import java.util.Random;
public class AppendSB {
private static Random generator = new Random();
public static void main(String[] args) throws Exception {
for (int i=0; i<1000; i++) {
StringBuffer sb1 = generateTestBuffer(10, 100);
StringBuffer sb2 = generateTestBuffer(10, 100);
StringBuffer sb3 = generateTestBuffer(10, 100);
String s1 = sb1.toString();
String s2 = sb2.toString();
String s3 = sb3.toString();
String concatResult = new String(s1+s2+s3);
StringBuffer test = new StringBuffer();
test.append(sb1);
test.append(sb2);
test.append(sb3);
if (!test.toString().equals(concatResult))
throw new RuntimeException("StringBuffer.append failure");
}
}
private static int getRandomIndex(int constraint1, int constraint2) {
int range = constraint2 - constraint1;
int x = generator.nextInt(range);
return constraint1 + x;
}
private static StringBuffer generateTestBuffer(int min, int max) {
StringBuffer aNewStringBuffer = new StringBuffer(120);
int aNewLength = getRandomIndex(min, max);
for(int y=0; y<aNewLength; y++) {
int achar = generator.nextInt(30)+30;
char test = (char)(achar);
aNewStringBuffer.append(test);
}
return aNewStringBuffer;
}
}

View file

@ -0,0 +1,71 @@
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
* @bug 6206780
* @summary Test StringBuffer.append(StringBuilder);
* @key randomness
*/
import java.util.Random;
public class AppendStringBuilder {
private static Random generator = new Random();
public static void main(String[] args) throws Exception {
for (int i=0; i<1000; i++) {
StringBuilder sb1 = generateTestBuilder(10, 100);
StringBuilder sb2 = generateTestBuilder(10, 100);
StringBuilder sb3 = generateTestBuilder(10, 100);
String s1 = sb1.toString();
String s2 = sb2.toString();
String s3 = sb3.toString();
String concatResult = new String(s1+s2+s3);
StringBuffer test = new StringBuffer();
test.append(sb1);
test.append(sb2);
test.append(sb3);
if (!test.toString().equals(concatResult))
throw new RuntimeException("StringBuffer.append failure");
}
}
private static int getRandomIndex(int constraint1, int constraint2) {
int range = constraint2 - constraint1;
int x = generator.nextInt(range);
return constraint1 + x;
}
private static StringBuilder generateTestBuilder(int min, int max) {
StringBuilder aNewStringBuilder = new StringBuilder(120);
int aNewLength = getRandomIndex(min, max);
for(int y=0; y<aNewLength; y++) {
int achar = generator.nextInt(30)+30;
char test = (char)(achar);
aNewStringBuilder.append(test);
}
return aNewStringBuilder;
}
}

View file

@ -0,0 +1,240 @@
/*
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @bug 6206780
* @summary Test forwarding of methods to super in StringBuffer
* @author Jim Gish <jim.gish@oracle.com>
*/
import java.util.ArrayList;
import java.util.List;
public class BufferForwarding {
private static final String A_STRING_BUFFER_VAL = "aStringBuffer";
private static final String A_STRING_BUILDER_VAL = "aStringBuilder";
private static final String A_STRING_VAL = "aString";
private static final String NON_EMPTY_VAL = "NonEmpty";
public BufferForwarding() {
System.out.println( "Starting BufferForwarding");
}
public static void main(String... args) {
new BufferForwarding().executeTestMethods();
}
public void executeTestMethods() {
appendCharSequence();
indexOfString();
indexOfStringIntNull();
indexOfStringNull();
indexOfStringint();
insertintCharSequence();
insertintObject();
insertintboolean();
insertintchar();
insertintdouble();
insertintfloat();
insertintint();
insertintlong();
lastIndexOfString();
lastIndexOfStringint();
}
public void appendCharSequence() {
// three different flavors of CharSequence
CharSequence aString = A_STRING_VAL;
CharSequence aStringBuilder = new StringBuilder(A_STRING_BUILDER_VAL);
CharSequence aStringBuffer = new StringBuffer(A_STRING_BUFFER_VAL);
assertEquals( /*actual*/ new StringBuilder().append(aString).toString(), /*expected*/ A_STRING_VAL );
assertEquals( new StringBuilder().append(aStringBuilder).toString(), A_STRING_BUILDER_VAL );
assertEquals( new StringBuilder().append(aStringBuffer).toString(), A_STRING_BUFFER_VAL );
assertEquals( /*actual*/ new StringBuilder(NON_EMPTY_VAL).append(aString).toString(), NON_EMPTY_VAL+A_STRING_VAL );
assertEquals( new StringBuilder(NON_EMPTY_VAL).append(aStringBuilder).toString(), NON_EMPTY_VAL+A_STRING_BUILDER_VAL );
assertEquals( new StringBuilder(NON_EMPTY_VAL).append(aStringBuffer).toString(), NON_EMPTY_VAL+A_STRING_BUFFER_VAL );
}
void indexOfString() {
StringBuffer sb = new StringBuffer("xyz");
assertEquals( sb.indexOf("y"), 1 );
assertEquals( sb.indexOf("not found"), -1 );
}
public void indexOfStringint() {
StringBuffer sb = new StringBuffer("xyyz");
assertEquals( sb.indexOf("y",0), 1 );
assertEquals( sb.indexOf("y",1), 1 );
assertEquals( sb.indexOf("y",2), 2 );
assertEquals( sb.indexOf("not found"), -1 );
}
public void indexOfStringIntNull() {
StringBuffer sb = new StringBuffer();
// should be NPE if null passed
try {
sb.indexOf(null,1);
throw new RuntimeException("Test failed: should have thrown NPE");
} catch (NullPointerException npe) {
// expected: passed
} catch (Throwable t) {
throw new RuntimeException("Test failed: should have thrown NPE. Instead threw "
+ t);
}
}
public void indexOfStringNull() {
StringBuffer sb = new StringBuffer();
// should be NPE if null passed
try {
sb.indexOf(null);
throw new RuntimeException("Test failed: should have thrown NPE");
} catch (NullPointerException npe) {
// expected: passed
} catch (Throwable t) {
throw new RuntimeException("Test failed: should have thrown NPE. Instead threw "
+ t);
}
}
public void insertintboolean() {
boolean b = true;
StringBuffer sb = new StringBuffer("012345");
assertEquals( sb.insert( 2, b).toString(), "01true2345");
}
public void insertintchar() {
char c = 'C';
StringBuffer sb = new StringBuffer("012345");
assertEquals( sb.insert( 2, c ).toString(), "01C2345");
}
public void insertintCharSequence() {
final String initString = "012345";
// three different flavors of CharSequence
CharSequence aString = A_STRING_VAL;
CharSequence aStringBuilder = new StringBuilder(A_STRING_BUILDER_VAL);
CharSequence aStringBuffer = new StringBuffer(A_STRING_BUFFER_VAL);
assertEquals( new StringBuffer(initString).insert(2, aString).toString(), "01"+A_STRING_VAL+"2345" );
assertEquals( new StringBuffer(initString).insert(2, aStringBuilder).toString(), "01"+A_STRING_BUILDER_VAL+"2345" );
assertEquals( new StringBuffer(initString).insert(2, aStringBuffer).toString(), "01"+A_STRING_BUFFER_VAL+"2345" );
try {
new StringBuffer(initString).insert(7, aString);
throw new RuntimeException("Test failed: should have thrown IndexOutOfBoundsException");
} catch (IndexOutOfBoundsException soob) {
// expected: passed
} catch (Throwable t) {
throw new RuntimeException("Test failed: should have thrown IndexOutOfBoundsException, but instead threw " + t.getMessage());
}
}
public void insertintdouble() {
double d = 99d;
StringBuffer sb = new StringBuffer("012345");
assertEquals( sb.insert( 2, d ).toString(), "0199.02345"); }
public void insertintfloat() {
float f = 99.0f;
StringBuffer sb = new StringBuffer("012345");
assertEquals( sb.insert( 2, f ).toString(), "0199.02345"); }
public void insertintint() {
int i = 99;
StringBuffer sb = new StringBuffer("012345");
assertEquals( sb.insert( 2, i ).toString(), "01992345");
}
public void insertintlong() {
long l = 99;
StringBuffer sb = new StringBuffer("012345");
assertEquals( sb.insert( 2, l ).toString(), "01992345"); }
public void insertintObject() {
StringBuffer sb = new StringBuffer("012345");
List<String> ls = new ArrayList<String>();
ls.add("A"); ls.add("B");
String lsString = ls.toString();
assertEquals( sb.insert(2, ls).toString(), "01"+lsString+"2345");
try {
sb.insert(sb.length()+1, ls);
throw new RuntimeException("Test failed: should have thrown StringIndexOutOfBoundsException");
} catch (StringIndexOutOfBoundsException soob) {
// expected: passed
} catch (Throwable t) {
throw new RuntimeException("Test failed: should have thrown StringIndexOutOfBoundsException, but instead threw:"
+ t);
}
}
public void lastIndexOfString() {
String xyz = "xyz";
String xyz3 = "xyzxyzxyz";
StringBuffer sb = new StringBuffer(xyz3);
int pos = sb.lastIndexOf("xyz");
assertEquals( pos, 2*xyz.length() );
}
public void lastIndexOfStringint() {
StringBuffer sb = new StringBuffer("xyzxyzxyz");
int pos = sb.lastIndexOf("xyz",5);
assertEquals( pos, 3 );
pos = sb.lastIndexOf("xyz", 6);
assertEquals( pos, 6 );
}
public void assertEquals( String actual, String expected) {
if (!actual.equals( expected )) {
throw new RuntimeException( "Test failed: actual = '" + actual +
"', expected = '" + expected + "'");
}
}
public void assertEquals( int actual, int expected) {
if (actual != expected) {
throw new RuntimeException( "Test failed: actual = '" + actual +
"', expected = '" + expected + "'");
}
}
}

View file

@ -0,0 +1,86 @@
/*
* Copyright 2010 Google Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 6952330
* @summary Test StringBuffer/StringBuilder capacity handling.
* @key randomness
*/
import java.util.Random;
public class Capacity {
void test(String[] args) throws Throwable {
Random rnd = new Random();
int[] sizes = { 0, 1, rnd.nextInt(10), rnd.nextInt(1000) };
for (int size : sizes) {
equal(16, new StringBuffer().capacity());
equal(16, new StringBuilder().capacity());
StringBuffer buff = new StringBuffer(size);
StringBuilder bild = new StringBuilder(size);
equal(size, buff.capacity());
equal(size, bild.capacity());
buff.ensureCapacity(size);
bild.ensureCapacity(size);
equal(size, buff.capacity());
equal(size, bild.capacity());
buff.ensureCapacity(size+1);
bild.ensureCapacity(size+1);
equal(size*2+2, buff.capacity());
equal(size*2+2, bild.capacity());
size = buff.capacity();
buff.ensureCapacity(size*2+1);
bild.ensureCapacity(size*2+1);
equal(size*2+2, buff.capacity());
equal(size*2+2, bild.capacity());
size = buff.capacity();
int newSize = size * 2 + 3;
buff.ensureCapacity(newSize);
bild.ensureCapacity(newSize);
equal(newSize, buff.capacity());
equal(newSize, bild.capacity());
buff.ensureCapacity(0);
bild.ensureCapacity(0);
equal(newSize, buff.capacity());
equal(newSize, bild.capacity());
}
}
//--------------------- Infrastructure ---------------------------
volatile int passed = 0, failed = 0;
void pass() {passed++;}
void fail() {failed++; Thread.dumpStack();}
void fail(String msg) {System.err.println(msg); fail();}
void unexpected(Throwable t) {failed++; t.printStackTrace();}
void check(boolean cond) {if (cond) pass(); else fail();}
void equal(Object x, Object y) {
if (x == null ? y == null : x.equals(y)) pass();
else fail(x + " not equal to " + y);}
public static void main(String[] args) throws Throwable {
new Capacity().instanceMain(args);}
public void instanceMain(String[] args) throws Throwable {
try {test(args);} catch (Throwable t) {unexpected(t);}
System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
if (failed > 0) throw new AssertionError("Some tests failed");}
}

View file

@ -0,0 +1,494 @@
/*
* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.util.Arrays;
import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
/*
* @test
* @bug 8077559 8221430
* @summary Tests Compact String. This test is testing StringBuffer
* behavior related to Compact String.
* @run testng/othervm -XX:+CompactStrings CompactStringBuffer
* @run testng/othervm -XX:-CompactStrings CompactStringBuffer
*/
public class CompactStringBuffer {
/*
* Tests for "A"
*/
@Test
public void testCompactStringBufferForLatinA() {
final String ORIGIN = "A";
/*
* Because right now ASCII is the default encoding parameter for source
* code in JDK build environment, so we escape them. same as below.
*/
check(new StringBuffer(ORIGIN).append(new char[] { '\uFF21' }),
"A\uFF21");
check(new StringBuffer(ORIGIN).append(new StringBuffer("\uFF21")),
"A\uFF21");
check(new StringBuffer(ORIGIN).append("\uFF21"), "A\uFF21");
check(new StringBuffer(ORIGIN).append(new StringBuffer("\uFF21")),
"A\uFF21");
check(new StringBuffer(ORIGIN).delete(0, 1), "");
check(new StringBuffer(ORIGIN).delete(0, 0), "A");
check(new StringBuffer(ORIGIN).deleteCharAt(0), "");
assertEquals(new StringBuffer(ORIGIN).indexOf("A", 0), 0);
assertEquals(new StringBuffer(ORIGIN).indexOf("\uFF21", 0), -1);
assertEquals(new StringBuffer(ORIGIN).indexOf("", 0), 0);
assertEquals(new StringBuffer(ORIGIN).insert(1, "\uD801\uDC00")
.indexOf("A", 0), 0);
assertEquals(new StringBuffer(ORIGIN).insert(0, "\uD801\uDC00")
.indexOf("A", 0), 2);
check(new StringBuffer(ORIGIN).insert(0, new char[] {}), "A");
check(new StringBuffer(ORIGIN).insert(1, new char[] { '\uFF21' }),
"A\uFF21");
check(new StringBuffer(ORIGIN).insert(0, new char[] { '\uFF21' }),
"\uFF21A");
check(new StringBuffer(ORIGIN).insert(0, new StringBuffer("\uFF21")),
"\uFF21A");
check(new StringBuffer(ORIGIN).insert(1, new StringBuffer("\uFF21")),
"A\uFF21");
check(new StringBuffer(ORIGIN).insert(0, ""), "A");
check(new StringBuffer(ORIGIN).insert(0, "\uFF21"), "\uFF21A");
check(new StringBuffer(ORIGIN).insert(1, "\uFF21"), "A\uFF21");
assertEquals(new StringBuffer(ORIGIN).lastIndexOf("A"), 0);
assertEquals(new StringBuffer(ORIGIN).lastIndexOf("\uFF21"), -1);
assertEquals(new StringBuffer(ORIGIN).lastIndexOf(""), 1);
check(new StringBuffer(ORIGIN).replace(0, 0, "\uFF21"), "\uFF21A");
check(new StringBuffer(ORIGIN).replace(0, 1, "\uFF21"), "\uFF21");
checkSetCharAt(new StringBuffer(ORIGIN), 0, '\uFF21', "\uFF21");
checkSetLength(new StringBuffer(ORIGIN), 0, "");
checkSetLength(new StringBuffer(ORIGIN), 1, "A");
check(new StringBuffer(ORIGIN).substring(0), "A");
check(new StringBuffer(ORIGIN).substring(1), "");
}
/*
* Tests for "\uFF21"
*/
@Test
public void testCompactStringBufferForNonLatinA() {
final String ORIGIN = "\uFF21";
check(new StringBuffer(ORIGIN).append(new char[] { 'A' }), "\uFF21A");
check(new StringBuffer(ORIGIN).append(new StringBuffer("A")), "\uFF21A");
check(new StringBuffer(ORIGIN).append("A"), "\uFF21A");
check(new StringBuffer(ORIGIN).append(new StringBuffer("A")), "\uFF21A");
check(new StringBuffer(ORIGIN).delete(0, 1), "");
check(new StringBuffer(ORIGIN).delete(0, 0), "\uFF21");
check(new StringBuffer(ORIGIN).deleteCharAt(0), "");
assertEquals(new StringBuffer(ORIGIN).indexOf("A", 0), -1);
assertEquals(new StringBuffer(ORIGIN).indexOf("\uFF21", 0), 0);
assertEquals(new StringBuffer(ORIGIN).indexOf("", 0), 0);
check(new StringBuffer(ORIGIN).insert(0, new char[] {}), "\uFF21");
check(new StringBuffer(ORIGIN).insert(1, new char[] { 'A' }), "\uFF21A");
check(new StringBuffer(ORIGIN).insert(0, new char[] { 'A' }), "A\uFF21");
check(new StringBuffer(ORIGIN).insert(0, new StringBuffer("A")),
"A\uFF21");
check(new StringBuffer(ORIGIN).insert(1, new StringBuffer("A")),
"\uFF21A");
check(new StringBuffer(ORIGIN).insert(0, ""), "\uFF21");
check(new StringBuffer(ORIGIN).insert(0, "A"), "A\uFF21");
check(new StringBuffer(ORIGIN).insert(1, "A"), "\uFF21A");
assertEquals(new StringBuffer(ORIGIN).lastIndexOf("A"), -1);
assertEquals(new StringBuffer(ORIGIN).lastIndexOf("\uFF21"), 0);
assertEquals(new StringBuffer(ORIGIN).lastIndexOf(""), 1);
check(new StringBuffer(ORIGIN).replace(0, 0, "A"), "A\uFF21");
check(new StringBuffer(ORIGIN).replace(0, 1, "A"), "A");
checkSetCharAt(new StringBuffer(ORIGIN), 0, 'A', "A");
checkSetLength(new StringBuffer(ORIGIN), 0, "");
checkSetLength(new StringBuffer(ORIGIN), 1, "\uFF21");
check(new StringBuffer(ORIGIN).substring(0), "\uFF21");
check(new StringBuffer(ORIGIN).substring(1), "");
}
/*
* Tests for "\uFF21A"
*/
@Test
public void testCompactStringBufferForMixedA1() {
final String ORIGIN = "\uFF21A";
check(new StringBuffer(ORIGIN).delete(0, 1), "A");
check(new StringBuffer(ORIGIN).delete(1, 2), "\uFF21");
check(new StringBuffer(ORIGIN).deleteCharAt(1), "\uFF21");
check(new StringBuffer(ORIGIN).deleteCharAt(0), "A");
assertEquals(new StringBuffer(ORIGIN).indexOf("A", 0), 1);
assertEquals(new StringBuffer(ORIGIN).indexOf("\uFF21", 0), 0);
assertEquals(new StringBuffer(ORIGIN).indexOf("", 0), 0);
check(new StringBuffer(ORIGIN).insert(1, new char[] { 'A' }), "\uFF21AA");
check(new StringBuffer(ORIGIN).insert(0, new char[] { '\uFF21' }),
"\uFF21\uFF21A");
assertEquals(new StringBuffer(ORIGIN).lastIndexOf("A"), 1);
assertEquals(new StringBuffer(ORIGIN).lastIndexOf("\uFF21"), 0);
assertEquals(new StringBuffer(ORIGIN).lastIndexOf(""), 2);
check(new StringBuffer(ORIGIN).replace(0, 0, "A"), "A\uFF21A");
check(new StringBuffer(ORIGIN).replace(0, 1, "A"), "AA");
checkSetCharAt(new StringBuffer(ORIGIN), 0, 'A', "AA");
checkSetLength(new StringBuffer(ORIGIN), 0, "");
checkSetLength(new StringBuffer(ORIGIN), 1, "\uFF21");
check(new StringBuffer(ORIGIN).substring(0), "\uFF21A");
check(new StringBuffer(ORIGIN).substring(1), "A");
}
/*
* Tests for "A\uFF21"
*/
@Test
public void testCompactStringBufferForMixedA2() {
final String ORIGIN = "A\uFF21";
check(new StringBuffer(ORIGIN).replace(1, 2, "A"), "AA");
checkSetLength(new StringBuffer(ORIGIN), 1, "A");
check(new StringBuffer(ORIGIN).substring(0), "A\uFF21");
check(new StringBuffer(ORIGIN).substring(1), "\uFF21");
check(new StringBuffer(ORIGIN).substring(0, 1), "A");
}
/*
* Tests for "\uFF21A\uFF21A\uFF21A\uFF21A\uFF21A"
*/
@Test
public void testCompactStringBufferForDuplicatedMixedA1() {
final String ORIGIN = "\uFF21A\uFF21A\uFF21A\uFF21A\uFF21A";
checkSetLength(new StringBuffer(ORIGIN), 1, "\uFF21");
assertEquals(new StringBuffer(ORIGIN).indexOf("A", 5), 5);
assertEquals(new StringBuffer(ORIGIN).indexOf("\uFF21", 5), 6);
assertEquals(new StringBuffer(ORIGIN).lastIndexOf("A"), 9);
assertEquals(new StringBuffer(ORIGIN).lastIndexOf("\uFF21"), 8);
assertEquals(new StringBuffer(ORIGIN).lastIndexOf(""), 10);
check(new StringBuffer(ORIGIN).substring(9), "A");
check(new StringBuffer(ORIGIN).substring(8), "\uFF21A");
}
/*
* Tests for "A\uFF21A\uFF21A\uFF21A\uFF21A\uFF21"
*/
@Test
public void testCompactStringBufferForDuplicatedMixedA2() {
final String ORIGIN = "A\uFF21A\uFF21A\uFF21A\uFF21A\uFF21";
checkSetLength(new StringBuffer(ORIGIN), 1, "A");
assertEquals(new StringBuffer(ORIGIN).indexOf("A", 5), 6);
assertEquals(new StringBuffer(ORIGIN).indexOf("\uFF21", 5), 5);
assertEquals(new StringBuffer(ORIGIN).lastIndexOf("A"), 8);
assertEquals(new StringBuffer(ORIGIN).lastIndexOf("\uFF21"), 9);
check(new StringBuffer(ORIGIN).substring(9), "\uFF21");
check(new StringBuffer(ORIGIN).substring(8), "A\uFF21");
}
/*
* Tests for "\uD801\uDC00\uD801\uDC01"
*/
@Test
public void testCompactStringForSupplementaryCodePoint() {
final String ORIGIN = "\uD801\uDC00\uD801\uDC01";
check(new StringBuffer(ORIGIN).append("A"), "\uD801\uDC00\uD801\uDC01A");
check(new StringBuffer(ORIGIN).append("\uFF21"),
"\uD801\uDC00\uD801\uDC01\uFF21");
check(new StringBuffer(ORIGIN).appendCodePoint('A'),
"\uD801\uDC00\uD801\uDC01A");
check(new StringBuffer(ORIGIN).appendCodePoint('\uFF21'),
"\uD801\uDC00\uD801\uDC01\uFF21");
assertEquals(new StringBuffer(ORIGIN).charAt(0), '\uD801');
assertEquals(new StringBuffer(ORIGIN).codePointAt(0),
Character.codePointAt(ORIGIN, 0));
assertEquals(new StringBuffer(ORIGIN).codePointAt(1),
Character.codePointAt(ORIGIN, 1));
assertEquals(new StringBuffer(ORIGIN).codePointBefore(2),
Character.codePointAt(ORIGIN, 0));
assertEquals(new StringBuffer(ORIGIN).codePointCount(1, 3), 2);
check(new StringBuffer(ORIGIN).delete(0, 2), "\uD801\uDC01");
check(new StringBuffer(ORIGIN).delete(0, 3), "\uDC01");
check(new StringBuffer(ORIGIN).deleteCharAt(1), "\uD801\uD801\uDC01");
checkGetChars(new StringBuffer(ORIGIN), 0, 3, new char[] { '\uD801',
'\uDC00', '\uD801' });
assertEquals(new StringBuffer(ORIGIN).indexOf("\uD801\uDC01"), 2);
assertEquals(new StringBuffer(ORIGIN).indexOf("\uDC01"), 3);
assertEquals(new StringBuffer(ORIGIN).indexOf("\uFF21"), -1);
assertEquals(new StringBuffer(ORIGIN).indexOf("A"), -1);
check(new StringBuffer(ORIGIN).insert(0, "\uFF21"),
"\uFF21\uD801\uDC00\uD801\uDC01");
check(new StringBuffer(ORIGIN).insert(1, "\uFF21"),
"\uD801\uFF21\uDC00\uD801\uDC01");
check(new StringBuffer(ORIGIN).insert(1, "A"),
"\uD801A\uDC00\uD801\uDC01");
assertEquals(new StringBuffer(ORIGIN).lastIndexOf("\uDC00\uD801"), 1);
assertEquals(new StringBuffer(ORIGIN).lastIndexOf("\uD801"), 2);
assertEquals(new StringBuffer(ORIGIN).lastIndexOf("\uFF21"), -1);
assertEquals(new StringBuffer(ORIGIN).lastIndexOf("A"), -1);
assertEquals(new StringBuffer(ORIGIN).length(), 4);
assertEquals(new StringBuffer(ORIGIN).offsetByCodePoints(1, 1), 2);
assertEquals(new StringBuffer(ORIGIN).offsetByCodePoints(0, 1), 2);
check(new StringBuffer(ORIGIN).replace(0, 2, "A"), "A\uD801\uDC01");
check(new StringBuffer(ORIGIN).replace(0, 3, "A"), "A\uDC01");
check(new StringBuffer(ORIGIN).replace(0, 2, "\uFF21"),
"\uFF21\uD801\uDC01");
check(new StringBuffer(ORIGIN).replace(0, 3, "\uFF21"), "\uFF21\uDC01");
check(new StringBuffer(ORIGIN).reverse(), "\uD801\uDC01\uD801\uDC00");
checkSetCharAt(new StringBuffer(ORIGIN), 1, '\uDC01',
"\uD801\uDC01\uD801\uDC01");
checkSetCharAt(new StringBuffer(ORIGIN), 1, 'A', "\uD801A\uD801\uDC01");
checkSetLength(new StringBuffer(ORIGIN), 2, "\uD801\uDC00");
checkSetLength(new StringBuffer(ORIGIN), 3, "\uD801\uDC00\uD801");
check(new StringBuffer(ORIGIN).substring(1, 3), "\uDC00\uD801");
}
/*
* Tests for "A\uD801\uDC00\uFF21"
*/
@Test
public void testCompactStringForSupplementaryCodePointMixed1() {
final String ORIGIN = "A\uD801\uDC00\uFF21";
assertEquals(new StringBuffer(ORIGIN).codePointBefore(3),
Character.codePointAt(ORIGIN, 1));
assertEquals(new StringBuffer(ORIGIN).codePointBefore(2), '\uD801');
assertEquals(new StringBuffer(ORIGIN).codePointBefore(1), 'A');
assertEquals(new StringBuffer(ORIGIN).codePointCount(0, 3), 2);
assertEquals(new StringBuffer(ORIGIN).codePointCount(0, 4), 3);
check(new StringBuffer(ORIGIN).delete(0, 1), "\uD801\uDC00\uFF21");
check(new StringBuffer(ORIGIN).delete(0, 1).delete(2, 3), "\uD801\uDC00");
check(new StringBuffer(ORIGIN).deleteCharAt(3).deleteCharAt(0),
"\uD801\uDC00");
assertEquals(new StringBuffer(ORIGIN).indexOf("\uFF21"), 3);
assertEquals(new StringBuffer(ORIGIN).indexOf("A"), 0);
assertEquals(new StringBuffer(ORIGIN).lastIndexOf("\uFF21"), 3);
assertEquals(new StringBuffer(ORIGIN).lastIndexOf("A"), 0);
assertEquals(new StringBuffer(ORIGIN).offsetByCodePoints(0, 1), 1);
assertEquals(new StringBuffer(ORIGIN).offsetByCodePoints(1, 1), 3);
check(new StringBuffer(ORIGIN).replace(1, 3, "A"), "AA\uFF21");
check(new StringBuffer(ORIGIN).replace(1, 4, "A"), "AA");
check(new StringBuffer(ORIGIN).replace(1, 4, ""), "A");
check(new StringBuffer(ORIGIN).reverse(), "\uFF21\uD801\uDC00A");
checkSetLength(new StringBuffer(ORIGIN), 1, "A");
check(new StringBuffer(ORIGIN).substring(0, 1), "A");
}
/*
* Tests for "\uD801\uDC00\uFF21A"
*/
@Test
public void testCompactStringForSupplementaryCodePointMixed2() {
final String ORIGIN = "\uD801\uDC00\uFF21A";
assertEquals(new StringBuffer(ORIGIN).codePointBefore(3),
Character.codePointAt(ORIGIN, 2));
assertEquals(new StringBuffer(ORIGIN).codePointBefore(2),
Character.codePointAt(ORIGIN, 0));
assertEquals(new StringBuffer(ORIGIN).codePointBefore(1), '\uD801');
assertEquals(new StringBuffer(ORIGIN).codePointCount(0, 3), 2);
assertEquals(new StringBuffer(ORIGIN).codePointCount(0, 4), 3);
check(new StringBuffer(ORIGIN).delete(0, 2), "\uFF21A");
check(new StringBuffer(ORIGIN).delete(0, 3), "A");
check(new StringBuffer(ORIGIN).deleteCharAt(0).deleteCharAt(0)
.deleteCharAt(0), "A");
assertEquals(new StringBuffer(ORIGIN).indexOf("A"), 3);
assertEquals(new StringBuffer(ORIGIN).delete(0, 3).indexOf("A"), 0);
assertEquals(new StringBuffer(ORIGIN).replace(0, 3, "B").indexOf("A"),
1);
assertEquals(new StringBuffer(ORIGIN).substring(3, 4).indexOf("A"), 0);
assertEquals(new StringBuffer(ORIGIN).offsetByCodePoints(1, 1), 2);
assertEquals(new StringBuffer(ORIGIN).offsetByCodePoints(0, 1), 2);
assertEquals(new StringBuffer(ORIGIN).offsetByCodePoints(2, 1), 3);
check(new StringBuffer(ORIGIN).replace(0, 3, "B"), "BA");
check(new StringBuffer(ORIGIN).reverse(), "A\uFF21\uD801\uDC00");
}
/*
* Tests for "\uD801A\uDC00\uFF21"
*/
@Test
public void testCompactStringForSupplementaryCodePointMixed3() {
final String ORIGIN = "\uD801A\uDC00\uFF21";
assertEquals(new StringBuffer(ORIGIN).codePointAt(1), 'A');
assertEquals(new StringBuffer(ORIGIN).codePointAt(3), '\uFF21');
assertEquals(new StringBuffer(ORIGIN).codePointBefore(1), '\uD801');
assertEquals(new StringBuffer(ORIGIN).codePointBefore(2), 'A');
assertEquals(new StringBuffer(ORIGIN).codePointBefore(3), '\uDC00');
assertEquals(new StringBuffer(ORIGIN).codePointCount(0, 3), 3);
assertEquals(new StringBuffer(ORIGIN).codePointCount(1, 3), 2);
assertEquals(new StringBuffer(ORIGIN).delete(0, 1).delete(1, 3)
.indexOf("A"), 0);
assertEquals(
new StringBuffer(ORIGIN).replace(0, 1, "B").replace(2, 4, "C")
.indexOf("A"), 1);
assertEquals(new StringBuffer(ORIGIN).substring(1, 4).substring(0, 1)
.indexOf("A"), 0);
assertEquals(new StringBuffer(ORIGIN).offsetByCodePoints(0, 1), 1);
assertEquals(new StringBuffer(ORIGIN).offsetByCodePoints(1, 1), 2);
assertEquals(new StringBuffer(ORIGIN).offsetByCodePoints(2, 1), 3);
check(new StringBuffer(ORIGIN).reverse(), "\uFF21\uDC00A\uD801");
}
/*
* Tests for "A\uDC01\uFF21\uD801"
*/
@Test
public void testCompactStringForSupplementaryCodePointMixed4() {
final String ORIGIN = "A\uDC01\uFF21\uD801";
assertEquals(new StringBuffer(ORIGIN).codePointAt(1), '\uDC01');
assertEquals(new StringBuffer(ORIGIN).codePointAt(3), '\uD801');
assertEquals(new StringBuffer(ORIGIN).codePointBefore(1), 'A');
assertEquals(new StringBuffer(ORIGIN).codePointBefore(2), '\uDC01');
assertEquals(new StringBuffer(ORIGIN).codePointBefore(3), '\uFF21');
assertEquals(new StringBuffer(ORIGIN).codePointCount(0, 3), 3);
assertEquals(new StringBuffer(ORIGIN).codePointCount(1, 3), 2);
assertEquals(new StringBuffer(ORIGIN).delete(1, 4).indexOf("A"), 0);
assertEquals(new StringBuffer(ORIGIN).replace(1, 4, "B").indexOf("A"),
0);
assertEquals(new StringBuffer(ORIGIN).substring(0, 1).indexOf("A"), 0);
assertEquals(new StringBuffer(ORIGIN).offsetByCodePoints(0, 1), 1);
assertEquals(new StringBuffer(ORIGIN).offsetByCodePoints(1, 1), 2);
assertEquals(new StringBuffer(ORIGIN).offsetByCodePoints(2, 1), 3);
check(new StringBuffer(ORIGIN).reverse(), "\uD801\uFF21\uDC01A");
}
@Test
public void testCompactStringMisc() {
String ascii = "abcdefgh";
String asciiMixed = "abc" + "\u4e00\u4e01\u4e02" + "fgh";
String bmp = "\u4e00\u4e01\u4e02\u4e03\u4e04\u4e05\u4e06\u4e07\u4e08";
String bmpMixed = "\u4e00\u4e01\u4e02" + "ABC" + "\u4e06\u4e07\u4e08";
check(new StringBuffer().append(ascii).delete(0, 20).toString(),
"");
check(new StringBuffer().append(ascii).delete(3, 20).toString(),
"abc");
check(new StringBuffer().append(ascii).delete(3, 6).toString(),
"abcgh");
check(new StringBuffer().append(ascii).deleteCharAt(0).toString(),
"bcdefgh");
check(new StringBuffer().append(ascii).deleteCharAt(3).toString(),
"abcefgh");
check(new StringBuffer().append(asciiMixed).delete(3, 6).toString(),
"abcfgh");
check(new StringBuffer().append(asciiMixed).deleteCharAt(3).toString(),
"abc\u4e01\u4e02fgh");
check(new StringBuffer().append(asciiMixed).deleteCharAt(3)
.deleteCharAt(3)
.deleteCharAt(3).toString(),
"abcfgh");
check(new StringBuffer().append(bmp).delete(0, 20).toString(),
"");
check(new StringBuffer().append(bmp).delete(3, 20).toString(),
"\u4e00\u4e01\u4e02");
check(new StringBuffer().append(bmp).delete(3, 6).toString(),
"\u4e00\u4e01\u4e02\u4e06\u4e07\u4e08");
check(new StringBuffer().append(bmp).deleteCharAt(0).toString(),
"\u4e01\u4e02\u4e03\u4e04\u4e05\u4e06\u4e07\u4e08");
check(new StringBuffer().append(bmp).deleteCharAt(3).toString(),
"\u4e00\u4e01\u4e02\u4e04\u4e05\u4e06\u4e07\u4e08");
check(new StringBuffer().append(bmpMixed).delete(3, 6).toString(),
"\u4e00\u4e01\u4e02\u4e06\u4e07\u4e08");
////////////////////////////////////////////////////////////////////
check(new StringBuffer().append(ascii).replace(3, 6, "AB").toString(),
"abcABgh");
check(new StringBuffer().append(asciiMixed).replace(3, 6, "AB").toString(),
"abcABfgh");
check(new StringBuffer().append(bmp).replace(3, 6, "AB").toString(),
"\u4e00\u4e01\u4e02AB\u4e06\u4e07\u4e08");
check(new StringBuffer().append(bmpMixed).replace(3, 6, "").toString(),
"\u4e00\u4e01\u4e02\u4e06\u4e07\u4e08");
check(new StringBuffer().append(ascii).replace(3, 6, "\u4e01\u4e02").toString(),
"abc\u4e01\u4e02gh");
////////////////////////////////////////////////////////////////////
check(new StringBuffer().append(ascii).insert(3, "").toString(),
"abcdefgh");
check(new StringBuffer().append(ascii).insert(3, "AB").toString(),
"abcABdefgh");
check(new StringBuffer().append(ascii).insert(3, "\u4e01\u4e02").toString(),
"abc\u4e01\u4e02defgh");
check(new StringBuffer().append(asciiMixed).insert(0, 'A').toString(),
"Aabc\u4e00\u4e01\u4e02fgh");
check(new StringBuffer().append(asciiMixed).insert(3, "A").toString(),
"abcA\u4e00\u4e01\u4e02fgh");
check(new StringBuffer().append(ascii).insert(3, 1234567).toString(),
"abc1234567defgh");
check(new StringBuffer().append(bmp).insert(3, 1234567).toString(),
"\u4e00\u4e01\u4e021234567\u4e03\u4e04\u4e05\u4e06\u4e07\u4e08");
////////////////////////////////////////////////////////////////////
check(new StringBuffer().append(ascii).append(1.23456).toString(),
"abcdefgh1.23456");
check(new StringBuffer().append(bmp).append(1.23456).toString(),
"\u4e00\u4e01\u4e02\u4e03\u4e04\u4e05\u4e06\u4e07\u4e081.23456");
////////////////////////////////////////////////////////////////////
check(new StringBuffer((CharSequence)new StringBuffer(ascii)).toString(),
ascii);
check(new StringBuffer((CharSequence)new StringBuffer(asciiMixed)).toString(),
asciiMixed);
}
private void checkGetChars(StringBuffer sb, int srcBegin, int srcEnd,
char expected[]) {
char[] dst = new char[srcEnd - srcBegin];
sb.getChars(srcBegin, srcEnd, dst, 0);
assertTrue(Arrays.equals(dst, expected));
}
private void checkSetCharAt(StringBuffer sb, int index, char ch,
String expected) {
sb.setCharAt(index, ch);
check(sb, expected);
}
private void checkSetLength(StringBuffer sb, int newLength, String expected) {
sb.setLength(newLength);
check(sb, expected);
}
private void check(StringBuffer sb, String expected) {
check(sb.toString(), expected);
}
private void check(String str, String expected) {
assertTrue(str.equals(expected), String.format(
"Get (%s) but expect (%s), ", escapeNonASCIIs(str),
escapeNonASCIIs(expected)));
}
/*
* Escape non-ASCII characters since not all systems support them.
*/
private String escapeNonASCIIs(String str) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if (c > 0x7F) {
sb.append("\\u").append(Integer.toHexString((int) c));
} else {
sb.append(c);
}
}
return sb.toString();
}
}

View file

@ -0,0 +1,152 @@
/*
* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.io.*;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import static jdk.test.lib.util.SerializationUtils.*;
import static org.testng.Assert.*;
/*
* @test
* @bug 8077559
* @library /test/lib
* @build jdk.test.lib.util.SerializationUtils
* @summary Tests Compact String. This one is testing StringBuffer serialization
* among -XX:+CompactStrings/-XX:-CompactStrings/LegacyStringBuffer
* @run testng/othervm -XX:+CompactStrings CompactStringBufferSerialization
* @run testng/othervm -XX:-CompactStrings CompactStringBufferSerialization
*/
public class CompactStringBufferSerialization {
@DataProvider
public Object[][] provider() {
return new Object[][] {
// every byte array is serialized from corresponding StringBuilder object
// by previous JDK(build 1.8.0_45-b14).
new Object[] {
new StringBuffer(""),
new byte[] { -84, -19, 0, 5, 115, 114, 0, 22, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 83, 116, 114, 105, 110, 103, 66, 117, 102,
102, 101, 114, 47, 7, 7, -39, -22, -56, -22, -45, 3, 0, 3, 73, 0, 5, 99, 111, 117, 110, 116, 90, 0, 6, 115, 104, 97, 114, 101,
100, 91, 0, 5, 118, 97, 108, 117, 101, 116, 0, 2, 91, 67, 120, 112, 0, 0, 0, 0, 0, 117, 114, 0, 2, 91, 67, -80, 38, 102, -80,
-30, 93, -124, -84, 2, 0, 0, 120, 112, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 120 } },
new Object[] {
new StringBuffer("A"),
new byte[] { -84, -19, 0, 5, 115, 114, 0, 22, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 83, 116, 114, 105, 110, 103, 66, 117, 102,
102, 101, 114, 47, 7, 7, -39, -22, -56, -22, -45, 3, 0, 3, 73, 0, 5, 99, 111, 117, 110, 116, 90, 0, 6, 115, 104, 97, 114, 101,
100, 91, 0, 5, 118, 97, 108, 117, 101, 116, 0, 2, 91, 67, 120, 112, 0, 0, 0, 1, 0, 117, 114, 0, 2, 91, 67, -80, 38, 102, -80,
-30, 93, -124, -84, 2, 0, 0, 120, 112, 0, 0, 0, 17, 0, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 120 } },
new Object[] {
new StringBuffer("AB"),
new byte[] { -84, -19, 0, 5, 115, 114, 0, 22, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 83, 116, 114, 105, 110, 103, 66, 117, 102,
102, 101, 114, 47, 7, 7, -39, -22, -56, -22, -45, 3, 0, 3, 73, 0, 5, 99, 111, 117, 110, 116, 90, 0, 6, 115, 104, 97, 114, 101,
100, 91, 0, 5, 118, 97, 108, 117, 101, 116, 0, 2, 91, 67, 120, 112, 0, 0, 0, 2, 0, 117, 114, 0, 2, 91, 67, -80, 38, 102, -80,
-30, 93, -124, -84, 2, 0, 0, 120, 112, 0, 0, 0, 18, 0, 65, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120 } },
new Object[] {
new StringBuffer("abcdefghijk"),
new byte[] { -84, -19, 0, 5, 115, 114, 0, 22, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 83, 116, 114, 105, 110, 103, 66, 117, 102,
102, 101, 114, 47, 7, 7, -39, -22, -56, -22, -45, 3, 0, 3, 73, 0, 5, 99, 111, 117, 110, 116, 90, 0, 6, 115, 104, 97, 114, 101,
100, 91, 0, 5, 118, 97, 108, 117, 101, 116, 0, 2, 91, 67, 120, 112, 0, 0, 0, 11, 0, 117, 114, 0, 2, 91, 67, -80, 38, 102, -80,
-30, 93, -124, -84, 2, 0, 0, 120, 112, 0, 0, 0, 27, 0, 97, 0, 98, 0, 99, 0, 100, 0, 101, 0, 102, 0, 103, 0, 104, 0, 105, 0,
106, 0, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120 } },
new Object[] {
new StringBuffer("\uff21"),
new byte[] { -84, -19, 0, 5, 115, 114, 0, 22, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 83, 116, 114, 105, 110, 103, 66, 117, 102,
102, 101, 114, 47, 7, 7, -39, -22, -56, -22, -45, 3, 0, 3, 73, 0, 5, 99, 111, 117, 110, 116, 90, 0, 6, 115, 104, 97, 114, 101,
100, 91, 0, 5, 118, 97, 108, 117, 101, 116, 0, 2, 91, 67, 120, 112, 0, 0, 0, 1, 0, 117, 114, 0, 2, 91, 67, -80, 38, 102, -80,
-30, 93, -124, -84, 2, 0, 0, 120, 112, 0, 0, 0, 17, -1, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120 } },
new Object[] {
new StringBuffer("\uff21\uff22"),
new byte[] { -84, -19, 0, 5, 115, 114, 0, 22, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 83, 116, 114, 105, 110, 103, 66, 117, 102,
102, 101, 114, 47, 7, 7, -39, -22, -56, -22, -45, 3, 0, 3, 73, 0, 5, 99, 111, 117, 110, 116, 90, 0, 6, 115, 104, 97, 114, 101,
100, 91, 0, 5, 118, 97, 108, 117, 101, 116, 0, 2, 91, 67, 120, 112, 0, 0, 0, 2, 0, 117, 114, 0, 2, 91, 67, -80, 38, 102, -80,
-30, 93, -124, -84, 2, 0, 0, 120, 112, 0, 0, 0, 18, -1, 33, -1, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120 } },
new Object[] {
new StringBuffer("\uff21A\uff21A\uff21A\uff21A\uff21A"),
new byte[] { -84, -19, 0, 5, 115, 114, 0, 22, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 83, 116, 114, 105, 110, 103, 66, 117, 102,
102, 101, 114, 47, 7, 7, -39, -22, -56, -22, -45, 3, 0, 3, 73, 0, 5, 99, 111, 117, 110, 116, 90, 0, 6, 115, 104, 97, 114, 101,
100, 91, 0, 5, 118, 97, 108, 117, 101, 116, 0, 2, 91, 67, 120, 112, 0, 0, 0, 10, 0, 117, 114, 0, 2, 91, 67, -80, 38, 102, -80,
-30, 93, -124, -84, 2, 0, 0, 120, 112, 0, 0, 0, 26, -1, 33, 0, 65, -1, 33, 0, 65, -1, 33, 0, 65, -1, 33, 0, 65, -1, 33, 0, 65,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120 } },
new Object[] {
new StringBuffer("A\uff21B\uff22C\uff23D\uff24E\uff25F\uff26G\uff27H\uff28"),
new byte[] { -84, -19, 0, 5, 115, 114, 0, 22, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 83, 116, 114, 105, 110, 103, 66, 117, 102,
102, 101, 114, 47, 7, 7, -39, -22, -56, -22, -45, 3, 0, 3, 73, 0, 5, 99, 111, 117, 110, 116, 90, 0, 6, 115, 104, 97, 114, 101,
100, 91, 0, 5, 118, 97, 108, 117, 101, 116, 0, 2, 91, 67, 120, 112, 0, 0, 0, 16, 0, 117, 114, 0, 2, 91, 67, -80, 38, 102, -80,
-30, 93, -124, -84, 2, 0, 0, 120, 112, 0, 0, 0, 32, 0, 65, -1, 33, 0, 66, -1, 34, 0, 67, -1, 35, 0, 68, -1, 36, 0, 69, -1, 37,
0, 70, -1, 38, 0, 71, -1, 39, 0, 72, -1, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 120 } },
new Object[] {
new StringBuffer("\uff21A\uff22B\uff23C\uff24D\uff25E\uff26F\uff27G\uff28H"),
new byte[] { -84, -19, 0, 5, 115, 114, 0, 22, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 83, 116, 114, 105, 110, 103, 66, 117, 102,
102, 101, 114, 47, 7, 7, -39, -22, -56, -22, -45, 3, 0, 3, 73, 0, 5, 99, 111, 117, 110, 116, 90, 0, 6, 115, 104, 97, 114, 101,
100, 91, 0, 5, 118, 97, 108, 117, 101, 116, 0, 2, 91, 67, 120, 112, 0, 0, 0, 16, 0, 117, 114, 0, 2, 91, 67, -80, 38, 102, -80,
-30, 93, -124, -84, 2, 0, 0, 120, 112, 0, 0, 0, 32, -1, 33, 0, 65, -1, 34, 0, 66, -1, 35, 0, 67, -1, 36, 0, 68, -1, 37, 0, 69,
-1, 38, 0, 70, -1, 39, 0, 71, -1, 40, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 120 } },
new Object[] {
new StringBuffer("\ud801\udc00\ud801\udc01\uff21A"),
new byte[] { -84, -19, 0, 5, 115, 114, 0, 22, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 83, 116, 114, 105, 110, 103, 66, 117, 102,
102, 101, 114, 47, 7, 7, -39, -22, -56, -22, -45, 3, 0, 3, 73, 0, 5, 99, 111, 117, 110, 116, 90, 0, 6, 115, 104, 97, 114, 101,
100, 91, 0, 5, 118, 97, 108, 117, 101, 116, 0, 2, 91, 67, 120, 112, 0, 0, 0, 6, 0, 117, 114, 0, 2, 91, 67, -80, 38, 102, -80,
-30, 93, -124, -84, 2, 0, 0, 120, 112, 0, 0, 0, 22, -40, 1, -36, 0, -40, 1, -36, 1, -1, 33, 0, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120 } },
new Object[] {
new StringBuffer("\uff21\uff22\uff21\uff22\uff21\uff22\uff21\uff22\uff21\uff22"),
new byte[] { -84, -19, 0, 5, 115, 114, 0, 22, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 83, 116, 114, 105, 110, 103, 66, 117, 102,
102, 101, 114, 47, 7, 7, -39, -22, -56, -22, -45, 3, 0, 3, 73, 0, 5, 99, 111, 117, 110, 116, 90, 0, 6, 115, 104, 97, 114, 101,
100, 91, 0, 5, 118, 97, 108, 117, 101, 116, 0, 2, 91, 67, 120, 112, 0, 0, 0, 10, 0, 117, 114, 0, 2, 91, 67, -80, 38, 102, -80,
-30, 93, -124, -84, 2, 0, 0, 120, 112, 0, 0, 0, 26, -1, 33, -1, 34, -1, 33, -1, 34, -1, 33, -1, 34, -1, 33, -1, 34, -1, 33, -1,
34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120 } } };
}
/*
* Verify serialization works between Compact StringBuffer/Legacy StringBuffer
*/
@Test(dataProvider = "provider")
public void test(StringBuffer sbContent, byte[] baInJDK8) throws Exception {
// Serialize a StringBuffer object into byte array.
byte[] ba = serialize(sbContent);
assertEquals(ba, baInJDK8);
// Deserialize a StringBuffer object from byte array which is generated by previous JDK(build 1.8.0_45-b14).
Object obj = deserialize(ba);
assertEquals(obj.getClass(), StringBuffer.class);
assertTrue(equals((StringBuffer)obj, sbContent));
}
boolean equals(StringBuffer sb, StringBuffer expected) {
if(sb.length() == expected.length()
&& sb.capacity() == expected.capacity()
&& sb.toString().equals(expected.toString())) {
return true;
}
return false;
}
}

View file

@ -0,0 +1,136 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;
import org.testng.Assert;
import org.testng.annotations.Test;
/**
* @test
* @bug 8137326
* @summary Test to verify the Comparable implementation for the StringBuffer class.
* @run testng Comparison
*/
public class Comparison {
static char SEP = ':';
static String[][] books = {
{"Biography", "Steve Jobs"},
{"Biography", "Elon Musk: Tesla, SpaceX, and the Quest for a Fantastic Future"},
{"Law", "Law 101: Everything You Need to Know About American Law, Fourth Edition"},
{"Law", "The Tools of Argument: How the Best Lawyers Think, Argue, and Win"},
{"History", "The History Book (Big Ideas Simply Explained)"},
{"History", "A People's History of the United States"},
};
/**
* Verifies the Comparable implementation by comparing with two TreeSet that
* contain either StringBuffer or String.
*/
@Test
public void compareWithString() {
Set<StringBuffer> sbSet = constructSBSet();
Set<String> sSet = constructStringSet();
Iterator<StringBuffer> iSB = sbSet.iterator();
Iterator<String> iS = sSet.iterator();
while (iSB.hasNext()) {
String temp1 = iSB.next().toString();
System.out.println(temp1);
String temp2 = iS.next();
System.out.println(temp2);
Assert.assertTrue(temp1.equals(temp2), "Comparing item by item");
}
}
/**
* Compares between StringBuffers
*/
@Test
public void testCompare() {
StringBuffer sb1 = generateTestBuffer(65, 70, 97, 102);
StringBuffer sb2 = generateTestBuffer(65, 70, 97, 102);
StringBuffer sb3 = generateTestBuffer(65, 71, 97, 103);
System.out.println(sb1.toString());
System.out.println(sb2.toString());
System.out.println(sb3.toString());
Assert.assertTrue(sb1.compareTo(sb2) == 0, "Compare sb1 and sb2");
Assert.assertFalse(sb1.compareTo(sb3) == 0, "Compare sb1 and sb3");
}
/**
* Verifies that the comparison is from index 0 to length() - 1 of the two
* character sequences.
*/
@Test
public void testModifiedSequence() {
StringBuffer sb1 = generateTestBuffer(65, 70, 97, 102);
StringBuffer sb2 = generateTestBuffer(65, 70, 98, 103);
// contain different character sequences
Assert.assertFalse(sb1.compareTo(sb2) == 0, "Compare the sequences before truncation");
// the first 5 characters however are the same
sb1.setLength(5);
sb2.setLength(5);
System.out.println(sb1.toString());
System.out.println(sb2.toString());
Assert.assertTrue(sb1.compareTo(sb2) == 0, "Compare sb1 and sb2");
Assert.assertTrue(sb1.toString().compareTo(sb2.toString()) == 0, "Compare strings of sb1 and sb2");
}
private Set<String> constructStringSet() {
Set<String> sSet = new TreeSet<>();
for (String[] book : books) {
sSet.add(book[0] + SEP + book[1]);
}
return sSet;
}
private Set<StringBuffer> constructSBSet() {
Set<StringBuffer> sbSet = new TreeSet<>();
for (String[] book : books) {
sbSet.add(new StringBuffer(book[0]).append(SEP).append(book[1]));
}
return sbSet;
}
private static StringBuffer generateTestBuffer(int from1, int to1,
int from2, int to2) {
StringBuffer aBuffer = new StringBuffer(50);
for (int i = from1; i < to1; i++) {
aBuffer.append((char)i);
}
for (int i = from2; i < to2; i++) {
aBuffer.append((char)i);
}
return aBuffer;
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,124 @@
/*
* Copyright (c) 2002, 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @bug 4414306 6248507
* @summary Verify that exceptions are thrown as expected.
*/
public class Exceptions {
private static boolean ok = true;
private static void fail(Throwable ex, String s, Throwable got) {
ok = false;
System.err.println("expected "
+ ex.getClass().getName() + ": " + ex.getMessage()
+ " for " + s
+ " got "
+ got.getClass().getName() + ": " + got.getMessage()
+ " - FAILED");
}
private static void pass(String s) {
System.out.println(s + " -- OK");
}
private static void tryCatch(String s, Throwable ex, Runnable thunk) {
Throwable t = null;
try {
thunk.run();
} catch (Throwable x) {
if (ex.getClass().isAssignableFrom(x.getClass()))
t = x;
else
x.printStackTrace();
}
if ((t == null) && (ex != null))
fail(ex, s, t);
String msg = (ex == null ? null : ex.getMessage());
if ((msg != null) && !msg.equals(t.getMessage()))
fail(ex, s, t);
else
pass(s);
}
public static void main(String [] args) {
System.out.println("StringBuffer()");
tryCatch(" no args", null, new Runnable() {
public void run() {
new StringBuffer();
}});
System.out.println("StringBuffer(int length)");
tryCatch(" 1", null, new Runnable() {
public void run() {
new StringBuffer(1);
}});
tryCatch(" -1", new NegativeArraySizeException(), new Runnable() {
public void run() {
new StringBuffer(-1);
}});
System.out.println("StringBuffer(String str)");
tryCatch(" null", new NullPointerException(), new Runnable() {
public void run() {
new StringBuffer(null);
}});
tryCatch(" foo", null, new Runnable() {
public void run() {
new StringBuffer("foo");
}});
System.out.println("StringBuffer.replace(int start, int end, String str)");
tryCatch(" -1, 2, \" \"",
new StringIndexOutOfBoundsException("Range [-1, 2) out of bounds for length 7"),
new Runnable() {
public void run() {
StringBuffer sb = new StringBuffer("hilbert");
sb.replace(-1, 2, " ");
}});
tryCatch(" 7, 8, \" \"",
new StringIndexOutOfBoundsException("Range [7, 6) out of bounds for length 6"),
new Runnable() {
public void run() {
StringBuffer sb = new StringBuffer("banach");
sb.replace(7, 8, " ");
}});
tryCatch(" 2, 1, \" \"",
new StringIndexOutOfBoundsException("Range [2, 1) out of bounds for length 7"),
new Runnable() {
public void run() {
StringBuffer sb = new StringBuffer("riemann");
sb.replace(2, 1, " ");
}});
if (!ok) {
throw new RuntimeException("Some tests FAILED");
} else {
System.out.println("All tests PASSED");
}
}
}

View file

@ -0,0 +1,56 @@
/*
* Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @bug 4230290
* @summary Test GetChars method parameter checking
*/
public class GetCharsOverLength {
public static void main (String argv[]) {
StringBuffer sb = new StringBuffer("sample string buffer");
char dst[] = new char[30];
boolean failed = false;
int a[][] = {
{0, 0, dst.length + 1},
{0, 0, dst.length + 2},
{0, 0, dst.length + 20},
{5, 5, dst.length + 1},
{5, 5, dst.length + 2},
{5, 5, dst.length + 20}
};
for (int i = 0; i < a.length; i++) {
try {
sb.getChars(a[i][0], a[i][1], dst, a[i][2]);
throw new RuntimeException("Bounds test failed");
} catch (IndexOutOfBoundsException iobe) {
// Test passed
}
}
}
}

View file

@ -0,0 +1,43 @@
/*
* Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
@bug 4096341
@summary StringBuffer.getChars(): JLS requires exception if
srcBegin > srcEnd
@author Anand Palaniswamy
*/
public class GetCharsSrcEndLarger {
public static void main(String[] args) throws Exception {
boolean exceptionOccurred = false;
try {
new StringBuffer("abc").getChars(1, 0, new char[10], 0);
} catch (StringIndexOutOfBoundsException sioobe) {
exceptionOccurred = true;
}
if (!exceptionOccurred) {
throw new Exception("StringBuffer.getChars() must throw" +
" an exception if srcBegin > srcEnd");
}
}
}

View file

@ -0,0 +1,79 @@
/*
* Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import jdk.internal.util.ArraysSupport;
/**
* @test
* @bug 8218227
* @summary StringBuilder/StringBuffer constructor throws confusing
* NegativeArraySizeException
* @modules java.base/jdk.internal.util
* @requires (sun.arch.data.model == "64" & os.maxMemory >= 8G)
* @run main/othervm -Xms6G -Xmx6G HugeCapacity
*/
public class HugeCapacity {
private static int failures = 0;
public static void main(String[] args) {
testHugeInitialString();
testHugeInitialCharSequence();
if (failures > 0) {
throw new RuntimeException(failures + " tests failed");
}
}
private static void testHugeInitialString() {
try {
String str = "Z".repeat(ArraysSupport.SOFT_MAX_ARRAY_LENGTH);
StringBuffer sb = new StringBuffer(str);
} catch (OutOfMemoryError ignore) {
} catch (Throwable unexpected) {
unexpected.printStackTrace();
failures++;
}
}
private static void testHugeInitialCharSequence() {
try {
CharSequence seq = new MyHugeCharSeq();
StringBuffer sb = new StringBuffer(seq);
} catch (OutOfMemoryError ignore) {
} catch (Throwable unexpected) {
unexpected.printStackTrace();
failures++;
}
}
private static class MyHugeCharSeq implements CharSequence {
public char charAt(int i) {
throw new UnsupportedOperationException();
}
public int length() { return Integer.MAX_VALUE; }
public CharSequence subSequence(int st, int e) {
throw new UnsupportedOperationException();
}
public String toString() { return ""; }
}
}

View file

@ -0,0 +1,188 @@
/*
* Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
* @bug 4162796 4162796
* @summary Test indexOf and lastIndexOf
* @key randomness
*/
import java.util.Random;
public class IndexOf {
static Random generator = new Random();
private static boolean failure = false;
public static void main(String[] args) throws Exception {
simpleTest();
compareIndexOfLastIndexOf();
compareStringStringBuffer();
if (failure)
throw new RuntimeException("One or more BitSet failures.");
}
private static void report(String testName, int failCount) {
System.err.println(testName+": " +
(failCount==0 ? "Passed":"Failed("+failCount+")"));
if (failCount > 0)
failure = true;
}
private static String generateTestString(int min, int max) {
StringBuffer aNewString = new StringBuffer(120);
int aNewLength = getRandomIndex(min, max);
for(int y=0; y<aNewLength; y++) {
int achar = generator.nextInt(30)+30;
char test = (char)(achar);
aNewString.append(test);
}
return aNewString.toString();
}
private static int getRandomIndex(int constraint1, int constraint2) {
int range = constraint2 - constraint1;
int x = generator.nextInt(range);
return constraint1 + x;
}
private static void simpleTest() {
int failCount = 0;
String sourceString;
StringBuffer sourceBuffer;
String targetString;
for (int i=0; i<10000; i++) {
do {
sourceString = generateTestString(99, 100);
sourceBuffer = new StringBuffer(sourceString);
targetString = generateTestString(10, 11);
} while (sourceString.indexOf(targetString) != -1);
int index1 = generator.nextInt(90) + 5;
sourceBuffer = sourceBuffer.replace(index1, index1, targetString);
if (sourceBuffer.indexOf(targetString) != index1)
failCount++;
if (sourceBuffer.indexOf(targetString, 5) != index1)
failCount++;
if (sourceBuffer.indexOf(targetString, 99) == index1)
failCount++;
}
report("Basic Test ", failCount);
}
// Note: it is possible although highly improbable that failCount will
// be > 0 even if everthing is working ok
private static void compareIndexOfLastIndexOf() {
int failCount = 0;
String sourceString;
StringBuffer sourceBuffer;
String targetString;
for (int i=0; i<10000; i++) {
do {
sourceString = generateTestString(99, 100);
sourceBuffer = new StringBuffer(sourceString);
targetString = generateTestString(10, 11);
} while (sourceString.indexOf(targetString) != -1);
int index1 = generator.nextInt(100);
sourceBuffer = sourceBuffer.replace(index1, index1, targetString);
// extremely remote possibility of > 1 match
int matches = 0;
int index2 = -1;
while((index2 = sourceBuffer.indexOf(targetString,index2+1)) != -1)
matches++;
if (matches > 1)
continue;
if (sourceBuffer.indexOf(targetString) !=
sourceBuffer.lastIndexOf(targetString))
failCount++;
sourceString = sourceBuffer.toString();
if (sourceString.indexOf(targetString) !=
sourceString.lastIndexOf(targetString))
failCount++;
}
report("IndexOf vs LastIndexOf ", failCount);
}
private static void compareStringStringBuffer() {
int failCount = 0;
for (int x=0; x<10000; x++) {
String testString = generateTestString(1, 100);
int len = testString.length();
StringBuffer testBuffer = new StringBuffer(len);
testBuffer.append(testString);
if (!testString.equals(testBuffer.toString()))
throw new RuntimeException("Initial equality failure");
int x1 = 0;
int x2 = 1000;
while(x2 > testString.length()) {
x1 = generator.nextInt(len);
x2 = generator.nextInt(100);
x2 = x1 + x2;
}
String fragment = testString.substring(x1,x2);
int sAnswer = testString.indexOf(fragment);
int sbAnswer = testBuffer.indexOf(fragment);
if (sAnswer != sbAnswer)
failCount++;
int testIndex = getRandomIndex(-100, 100);
sAnswer = testString.indexOf(fragment, testIndex);
sbAnswer = testBuffer.indexOf(fragment, testIndex);
if (sAnswer != sbAnswer)
failCount++;
sAnswer = testString.lastIndexOf(fragment);
sbAnswer = testBuffer.lastIndexOf(fragment);
if (sAnswer != sbAnswer)
failCount++;
testIndex = getRandomIndex(-100, 100);
sAnswer = testString.lastIndexOf(fragment, testIndex);
sbAnswer = testBuffer.lastIndexOf(fragment, testIndex);
if (sAnswer != sbAnswer)
failCount++;
}
report("String vs StringBuffer ", failCount);
}
}

View file

@ -0,0 +1,54 @@
/*
* Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @bug 4231107
* @summary Test Insert method parameter checking
*/
public class InsertMaxValue {
public static void main (String argv[]) throws Exception {
StringBuffer sb = new StringBuffer("");
StringBuffer sb1 = new StringBuffer("Some test StringBuffer");
try {
sb.insert(0, new char[5], 1, Integer.MAX_VALUE);
throw new RuntimeException("Exception expected");
} catch (StringIndexOutOfBoundsException sobe) {
// Test passed
} catch (OutOfMemoryError oome) {
throw new RuntimeException("Wrong exception thrown.");
}
try {
sb1.insert(2, new char[25], 5, Integer.MAX_VALUE);
throw new RuntimeException("Exception expected");
} catch (StringIndexOutOfBoundsException sobe) {
// Test passed
} catch (ArrayIndexOutOfBoundsException aioe) {
throw new RuntimeException("Wrong exception thrown.");
}
}
}

View file

@ -0,0 +1,45 @@
/*
* Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
@bug 4085679
@summary JLS requires that if you insert a null string, the string
"null" must be inserted.
@author Anand Palaniswamy
*/
public class InsertNullString {
public static void main(String[] args) throws Exception {
StringBuffer s = new StringBuffer("FOOBAR");
try {
String nullstr = null;
s.insert(3, nullstr); /* this will throw null pointer exception
before the bug was fixed. */
if (!s.toString().equals("FOOnullBAR")) {
throw new Exception("StringBuffer.insert() did not insert!");
}
} catch (NullPointerException npe) {
throw new Exception("StringBuffer.insert() of null String reference threw a NullPointerException");
}
}
}

View file

@ -0,0 +1,36 @@
/*
* Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
@bug 4174396
@summary Use replace to append chars; No OutOfMemoryException should result
*/
public class Replace {
public static void main(String[] arg) throws Exception {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < 200; i++) {
sb.replace(i, i+1, "a");
}
}
}

View file

@ -0,0 +1,162 @@
/*
* Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4120694
* @summary Test new methods in StringBuffer
* @key randomness
*/
import java.lang.*;
import java.util.*;
public class SBBasher {
public static void main(String[] args) throws Exception {
SBBasher basher = new SBBasher();
for (int iterations=0; iterations<100; iterations++) {
String testString = basher.generateTestString();
boolean result = basher.Test1(testString);
if (result == false)
throw new RuntimeException("Substring or replace failure.");
}
for (int iterations=0; iterations<100; iterations++) {
String testString = basher.generateTestString();
boolean result = basher.Test2(testString);
if (result == false)
throw new RuntimeException("Insert or delete failure.");
}
for (int iterations=0; iterations<100; iterations++) {
String testString = basher.generateTestString();
boolean result = basher.Test3(testString);
if (result == false)
throw new RuntimeException("Insert, delete or replace failure.");
}
}
private int getRandomIndex(int constraint1, int constraint2) {
int range = constraint2 - constraint1;
int x = generator.nextInt();
return constraint1 + Math.abs(x % range);
}
static Random generator = new Random();
private String generateTestString() {
StringBuffer aNewString = new StringBuffer(120);
int aNewLength = getRandomIndex(1,100);
for(int y=0; y<aNewLength; y++) {
int achar = generator.nextInt();
char test = (char)(achar);
aNewString.append(test);
}
return aNewString.toString();
}
/**
* first test, get substring of a random string
* and replace same spot with same substring
* then check for equality with original
* this tests both substrings and the replace method
*/
private boolean Test1(String before) {
StringBuffer bashed = new StringBuffer(before);
String slice;
for (int i=0; i<100; i++) {
int startIndex = getRandomIndex(0, before.length());
int endIndex = getRandomIndex(startIndex, before.length());
if (endIndex < bashed.length()) {
slice = bashed.substring(startIndex, endIndex);
}
else {
slice = bashed.substring(startIndex);
}
bashed.replace(startIndex, endIndex, slice);
}
String after = bashed.toString();
if (!before.equals(after))
return false;
else
return true;
}
/**
* second test, delete random section of string
* then insert same section back again
* then check for equality with original
* this tests both substrings, both deletes and insert method
*/
private boolean Test2(String before) {
StringBuffer bashed = new StringBuffer(before);
String slice;
for (int i=0; i<100; i++) {
int startIndex = getRandomIndex(0, before.length());
int endIndex = getRandomIndex(startIndex, before.length());
if (endIndex < bashed.length())
slice = bashed.substring(startIndex, endIndex);
else
slice = bashed.substring(startIndex);
if (slice.length() == 1)
bashed.deleteCharAt(startIndex);
else
bashed.delete(startIndex, endIndex);
bashed.insert(startIndex, slice.toCharArray(), 0, slice.length());
}
String after = bashed.toString();
if (!before.equals(after))
return false;
else
return true;
}
/**
* Third test, clone string and make sure that the
* replace operation is equivalent to a delete followed
* by an insert with the equivalent arguments
* this tests replace, delete and insert
*/
private boolean Test3(String before) {
StringBuffer bashed1 = new StringBuffer(before);
StringBuffer bashed2 = new StringBuffer(before);
int startIndex = getRandomIndex(0, bashed1.length());
int endIndex = getRandomIndex(startIndex, bashed2.length());
String insertString = generateTestString();
bashed1.delete(startIndex, endIndex);
bashed1.insert(startIndex, insertString);
bashed2.replace(startIndex, endIndex, insertString);
String result1 = bashed1.toString();
String result2 = bashed2.toString();
if (!result1.equals(result2))
return false;
else
return true;
}
}

View file

@ -0,0 +1,47 @@
/*
* Copyright (c) 1997, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
@bug 4089062
@summary A String created from a StringBuffer can be overwritten
if setLength() to a value less than the buffer length is called
on the StringBuffer and then the StringBuffer is appended to.
@author Robert Field
*/
public class SetLength {
public static void main(String[] argv) throws Exception {
StringBuffer active = new StringBuffer();
active.append("first one");
String a = active.toString();
active.setLength(0);
active.append("second");
String b = active.toString();
active.setLength(0);
System.out.println("first: " + a);
System.out.println("second: " + b);
if (!a.equals("first one")) {
throw new Exception("StringBuffer.setLength() overwrote string");
}
}
}

View file

@ -0,0 +1,36 @@
/*
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
* @bug 4853816
* @summary Test StringBuffer.substring(int)
*/
public class Substring {
public static void main(String[] args) {
StringBuffer buffer = new StringBuffer();
buffer.append("Guten Morgen!");
if (buffer.substring(0).length() != 13)
throw new RuntimeException();
}
}

View file

@ -0,0 +1,417 @@
/*
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
*
* @test
* @bug 4533872 4915683 4985217 5017280 6937112
* @summary Unit tests for supplementary character support (JSR-204)
*/
import java.util.HexFormat;
public class Supplementary {
public static void main(String[] args) {
test1(); // Test for codePointAt(int index)
test2(); // Test for codePointBefore(int index)
test3(); // Test for reverse()
test4(); // Test for appendCodePoint(int codePoint)
test5(); // Test for codePointCount(int beginIndex, int endIndex)
test6(); // Test for offsetByCodePoints(int index, int offset)
}
/* Text strings which are used as input data.
* The comment above each text string means the index of each 16-bit char
* for convenience.
*/
static final String[] input = {
/* 111 1 111111 22222
0123 4 5678 9 012 3 456789 01234 */
"abc\uD800\uDC00def\uD800\uD800ab\uD800\uDC00cdefa\uDC00bcdef",
/* 1 1111 1111 1 222
0 12345 6789 0 1234 5678 9 012 */
"\uD800defg\uD800hij\uD800\uDC00klm\uDC00nop\uDC00\uD800rt\uDC00",
/* 11 1 1111 1 112 222
0 12345 6 78901 2 3456 7 890 123 */
"\uDC00abcd\uDBFF\uDFFFefgh\uD800\uDC009ik\uDC00\uDC00lm\uDC00no\uD800",
/* 111 111111 1 22 2
0 1 2345 678 9 012 345678 9 01 2 */
"\uD800\uDC00!#$\uD800%&\uD800\uDC00;+\uDC00<>;=^\uDC00\\@\uD800\uDC00",
// includes an undefined supplementary character in Unicode 4.0.0
/* 1 11 1 1111 1
0 1 2345 6 789 0 12 3 4567 8 */
"\uDB40\uDE00abc\uDE01\uDB40de\uDB40\uDE02f\uDB40\uDE03ghi\uDB40\uDE02",
};
/* Expected results for:
* test1(): for codePointAt()
*
* Each character in each array is the golden data for each text string
* in the above input data. For example, the first data in each array is
* for the first input string.
*/
static final int[][] golden1 = {
{'a', 0xD800, 0xDC00, 0x10000, 0xE0200}, // codePointAt(0)
{0xD800, 0x10000, 'g', 0xDC00, 0xE0202}, // codePointAt(9)
{'f', 0xDC00, 0xD800, 0xDC00, 0xDE02}, // codePointAt(length-1)
};
/*
* Test for codePointAt(int index) method
*/
static void test1() {
for (int i = 0; i < input.length; i++) {
StringBuffer sb = new StringBuffer(input[i]);
/*
* Normal case
*/
testCodePoint(At, sb, 0, golden1[0][i]);
testCodePoint(At, sb, 9, golden1[1][i]);
testCodePoint(At, sb, sb.length()-1, golden1[2][i]);
/*
* Abnormal case - verify that an exception is thrown.
*/
testCodePoint(At, sb, -1);
testCodePoint(At, sb, sb.length());
}
}
/* Expected results for:
* test2(): for codePointBefore()
*
* Each character in each array is the golden data for each text string
* in the above input data. For example, the first data in each array is
* for the first input string.
*/
static final int[][] golden2 = {
{'a', 0xD800, 0xDC00, 0xD800, 0xDB40}, // codePointBefore(1)
{0xD800, 'l', 0x10000, 0xDC00, 0xDB40}, // codePointBefore(13)
{'f', 0xDC00, 0xD800, 0x10000, 0xE0202}, // codePointBefore(length)
};
/*
* Test for codePointBefore(int index) method
*/
static void test2() {
for (int i = 0; i < input.length; i++) {
StringBuffer sb = new StringBuffer(input[i]);
/*
* Normal case
*/
testCodePoint(Before, sb, 1, golden2[0][i]);
testCodePoint(Before, sb, 13, golden2[1][i]);
testCodePoint(Before, sb, sb.length(), golden2[2][i]);
/*
* Abnormal case - verify that an exception is thrown.
*/
testCodePoint(Before, sb, 0);
testCodePoint(Before, sb, sb.length()+1);
}
}
/* Expected results for:
* test3(): for reverse()
*
* Unlike golden1 and golden2, each array is the golden data for each text
* string in the above input data. For example, the first array is for
* the first input string.
*/
static final String[] golden3 = {
"fedcb\uDC00afedc\uD800\uDC00ba\uD800\uD800fed\uD800\uDC00cba",
"\uDC00tr\uD800\uDC00pon\uDC00mlk\uD800\uDC00jih\uD800gfed\uD800",
"\uD800on\uDC00ml\uDC00\uDC00ki9\uD800\uDC00hgfe\uDBFF\uDFFFdcba\uDC00",
"\uD800\uDC00@\\\uDC00^=;><\uDC00+;\uD800\uDC00&%\uD800$#!\uD800\uDC00",
// includes an undefined supplementary character in Unicode 4.0.0
"\uDB40\uDE02ihg\uDB40\uDE03f\uDB40\uDE02ed\uDB40\uDE01cba\uDB40\uDE00",
};
// Additional input data & expected result for test3()
static final String[][] testdata1 = {
{"a\uD800\uDC00", "\uD800\uDC00a"},
{"a\uDC00\uD800", "\uD800\uDC00a"},
{"\uD800\uDC00a", "a\uD800\uDC00"},
{"\uDC00\uD800a", "a\uD800\uDC00"},
{"\uDC00\uD800\uD801", "\uD801\uD800\uDC00"},
{"\uDC00\uD800\uDC01", "\uD800\uDC01\uDC00"},
{"\uD801\uD800\uDC00", "\uD800\uDC00\uD801"},
{"\uD800\uDC01\uDC00", "\uDC00\uD800\uDC01"},
{"\uD800\uDC00\uDC01\uD801", "\uD801\uDC01\uD800\uDC00"},
};
/*
* Test for reverse() method
*/
static void test3() {
for (int i = 0; i < input.length; i++) {
StringBuffer sb = new StringBuffer(input[i]).reverse();
check(!golden3[i].equals(new String(sb)),
"reverse() for <" + toHexString(input[i]) + ">",
sb, golden3[i]);
}
for (int i = 0; i < testdata1.length; i++) {
StringBuffer sb = new StringBuffer(testdata1[i][0]).reverse();
check(!testdata1[i][1].equals(new String(sb)),
"reverse() for <" + toHexString(testdata1[i][0]) + ">",
sb, testdata1[i][1]);
}
}
/**
* Test for appendCodePoint() method
*/
static void test4() {
for (int i = 0; i < input.length; i++) {
String s = input[i];
StringBuffer sb = new StringBuffer();
int c;
for (int j = 0; j < s.length(); j += Character.charCount(c)) {
c = s.codePointAt(j);
StringBuffer rsb = sb.appendCodePoint(c);
check(sb != rsb, "appendCodePoint returned a wrong object");
int sbc = sb.codePointAt(j);
check(sbc != c, "appendCodePoint(j) != c", sbc, c);
}
check(!s.equals(sb.toString()),
"appendCodePoint() produced a wrong result with input["+i+"]");
}
// test exception
testAppendCodePoint(-1, IllegalArgumentException.class);
testAppendCodePoint(Character.MAX_CODE_POINT+1, IllegalArgumentException.class);
}
/**
* Test codePointCount(int, int)
*
* This test case assumes that
* Character.codePointCount(CharSequence, int, int) works
* correctly.
*/
static void test5() {
for (int i = 0; i < input.length; i++) {
String s = input[i];
StringBuffer sb = new StringBuffer(s);
int length = sb.length();
for (int j = 0; j <= length; j++) {
int result = sb.codePointCount(j, length);
int expected = Character.codePointCount(sb, j, length);
check(result != expected, "codePointCount(input["+i+"], "+j+", "+length+")",
result, expected);
}
for (int j = length; j >= 0; j--) {
int result = sb.codePointCount(0, j);
int expected = Character.codePointCount(sb, 0, j);
check(result != expected, "codePointCount(input["+i+"], 0, "+j+")",
result, expected);
}
// test exceptions
testCodePointCount(null, 0, 0, NullPointerException.class);
testCodePointCount(sb, -1, length, IndexOutOfBoundsException.class);
testCodePointCount(sb, 0, length+1, IndexOutOfBoundsException.class);
testCodePointCount(sb, length, length-1, IndexOutOfBoundsException.class);
}
}
/**
* Test offsetByCodePoints(int, int)
*
* This test case assumes that
* Character.codePointCount(CharSequence, int, int) works
* correctly.
*/
static void test6() {
for (int i = 0; i < input.length; i++) {
String s = input[i];
StringBuffer sb = new StringBuffer(s);
int length = s.length();
for (int j = 0; j <= length; j++) {
int nCodePoints = Character.codePointCount(sb, j, length);
int result = sb.offsetByCodePoints(j, nCodePoints);
check(result != length,
"offsetByCodePoints(input["+i+"], "+j+", "+nCodePoints+")",
result, length);
result = sb.offsetByCodePoints(length, -nCodePoints);
int expected = j;
if (j > 0 && j < length) {
int cp = sb.codePointBefore(j+1);
if (Character.isSupplementaryCodePoint(cp)) {
expected--;
}
}
check(result != expected,
"offsetByCodePoints(input["+i+"], "+j+", "+(-nCodePoints)+")",
result, expected);
}
for (int j = length; j >= 0; j--) {
int nCodePoints = Character.codePointCount(sb, 0, j);
int result = sb.offsetByCodePoints(0, nCodePoints);
int expected = j;
if (j > 0 && j < length) {
int cp = sb.codePointAt(j-1);
if (Character.isSupplementaryCodePoint(cp)) {
expected++;
}
}
check(result != expected,
"offsetByCodePoints(input["+i+"], 0, "+nCodePoints+")",
result, expected);
result = sb.offsetByCodePoints(j, -nCodePoints);
check(result != 0,
"offsetBycodePoints(input["+i+"], "+j+", "+(-nCodePoints)+")",
result, 0);
}
// test exceptions
testOffsetByCodePoints(null, 0, 0, NullPointerException.class);
testOffsetByCodePoints(sb, -1, length, IndexOutOfBoundsException.class);
testOffsetByCodePoints(sb, 0, length+1, IndexOutOfBoundsException.class);
testOffsetByCodePoints(sb, 1, -2, IndexOutOfBoundsException.class);
testOffsetByCodePoints(sb, length, length-1, IndexOutOfBoundsException.class);
testOffsetByCodePoints(sb, length, -(length+1), IndexOutOfBoundsException.class);
}
}
static final boolean At = true, Before = false;
static void testCodePoint(boolean isAt, StringBuffer sb, int index, int expected) {
int c = isAt ? sb.codePointAt(index) : sb.codePointBefore(index);
check(c != expected,
"codePoint" + (isAt ? "At" : "Before") + "(" + index + ") for <"
+ sb + ">", c, expected);
}
static void testCodePoint(boolean isAt, StringBuffer sb, int index) {
boolean exceptionOccurred = false;
try {
int c = isAt ? sb.codePointAt(index) : sb.codePointBefore(index);
}
catch (StringIndexOutOfBoundsException e) {
exceptionOccurred = true;
}
check(!exceptionOccurred,
"codePoint" + (isAt ? "At" : "Before") + "(" + index + ") for <"
+ sb + "> should throw StringIndexOutOfBoundsPointerException.");
}
static void testAppendCodePoint(int codePoint, Class expectedException) {
try {
new StringBuffer().appendCodePoint(codePoint);
} catch (Exception e) {
if (expectedException.isInstance(e)) {
return;
}
throw new RuntimeException("Error: Unexpected exception", e);
}
check(true, "appendCodePoint(" + toHexString(codePoint) + ") didn't throw "
+ expectedException.getName());
}
static void testCodePointCount(StringBuffer sb, int beginIndex, int endIndex,
Class expectedException) {
try {
int n = sb.codePointCount(beginIndex, endIndex);
} catch (Exception e) {
if (expectedException.isInstance(e)) {
return;
}
throw new RuntimeException("Error: Unexpected exception", e);
}
check(true, "codePointCount() didn't throw " + expectedException.getName());
}
static void testOffsetByCodePoints(StringBuffer sb, int index, int offset,
Class expectedException) {
try {
int n = sb.offsetByCodePoints(index, offset);
} catch (Exception e) {
if (expectedException.isInstance(e)) {
return;
}
throw new RuntimeException("Error: Unexpected exception", e);
}
check(true, "offsetByCodePoints() didn't throw " + expectedException.getName());
}
static void check(boolean err, String msg) {
if (err) {
throw new RuntimeException("Error: " + msg);
}
}
static void check(boolean err, String s, int got, int expected) {
if (err) {
throw new RuntimeException("Error: " + s
+ " returned an unexpected value. got "
+ toHexString(got)
+ ", expected "
+ toHexString(expected));
}
}
static void check(boolean err, String s, StringBuffer got, String expected) {
if (err) {
throw new RuntimeException("Error: " + s
+ " returned an unexpected value. got <"
+ toHexString(new String(got))
+ ">, expected <"
+ toHexString(expected)
+ ">");
}
}
private static String toHexString(int c) {
return "0x" + Integer.toHexString(c);
}
private static String toHexString(String s) {
HexFormat format = HexFormat.of();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
sb.append(" 0x");
sb.append(format.toHexDigits(c));
}
sb.append(' ');
return sb.toString();
}
}

View file

@ -0,0 +1,319 @@
/*
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
* @bug 6206780
* @summary Test that all public unsynchronized methods of StringBuffer are either directly or indirectly synchronized
*/
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* TestSynchronization tests whether synchronized methods calls on an object
* result in synchronized calls. Note that this may not test all cases desired.
* It only tests whether some synchronization has occurred on the object during
* the call chain, and can't tell whether the object was locked across all
* operations that have been performed on the object.
*/
public class TestSynchronization {
/**
* Define parameters used in methods of StringBuffer - admittedly a bit of
* hack but 'purpose-built' for StringBuffer. Something more general could
* probably be developed if the test needs to be more widely adopted.
* <p/>
* boolean char char[] int double float long Object CharSequence String
* StringBuffer StringBuilder
* <p/>
*/
private static final boolean BOOLEAN_VAL = true;
private static final char CHAR_VAL = 'x';
private static final char[] CHAR_ARRAY_VAL = {'c', 'h', 'a', 'r', 'a', 'r',
'r', 'a', 'y'};
private static final int INT_VAL = 1;
private static final double DOUBLE_VAL = 1.0d;
private static final float FLOAT_VAL = 1.0f;
private static final long LONG_VAL = 1L;
private static final Object OBJECT_VAL = new Object();
private static final String STRING_VAL = "String value";
private static final StringBuilder STRING_BUILDER_VAL =
new StringBuilder("StringBuilder value");
private static final StringBuffer STRING_BUFFER_VAL =
new StringBuffer("StringBuffer value");
private static final CharSequence[] CHAR_SEQUENCE_VAL = {STRING_VAL,
STRING_BUILDER_VAL, STRING_BUFFER_VAL};
public static void main(String... args) throws Exception {
// First, test the tester
testClass(MyTestClass.class, /*
* self-test
*/ true);
// Finally, test StringBuffer
testClass(StringBuffer.class, /*
* self-test
*/ false);
}
/**
* Test all the public, unsynchronized methods of the given class. If
* isSelfTest is true, this is a self-test to ensure that the test program
* itself is working correctly. Should help ensure correctness of this
* program if it changes.
* <p/>
* @param aClass - the class to test
* @param isSelfTest - true if this is the special self-test class
* @throws SecurityException
*/
private static void testClass(Class<?> aClass, boolean isSelfTest) throws
Exception {
// Get all unsynchronized public methods via reflection. We don't need
// to test synchronized methods. By definition. they are already doing
// the right thing.
List<Method> methods = Arrays.asList(aClass.getDeclaredMethods());
for (Method m : methods) {
// skip synthetic methods, like default interface methods and lambdas
if (m.isSynthetic()) {
continue;
}
int modifiers = m.getModifiers();
if (Modifier.isPublic(modifiers)
&& !Modifier.isSynchronized(modifiers)) {
try {
testMethod(aClass, m);
} catch (TestFailedException e) {
if (isSelfTest) {
String methodName = e.getMethod().getName();
switch (methodName) {
case "should_pass":
throw new RuntimeException(
"Test failed: self-test failed. The 'should_pass' method did not pass the synchronization test. Check the test code.");
case "should_fail":
break;
default:
throw new RuntimeException(
"Test failed: something is amiss with the test. A TestFailedException was generated on a call to "
+ methodName + " which we didn't expect to test in the first place.");
}
} else {
throw new RuntimeException("Test failed: the method "
+ e.getMethod().toString()
+ " should be synchronized, but isn't.");
}
}
}
}
}
private static void invokeMethod(Class<?> aClass, final Method m,
final Object[] args) throws TestFailedException, Exception {
//System.out.println( "Invoking " + m.toString() + " with parameters " + Arrays.toString(args));
final Constructor<?> objConstructor;
Object obj = null;
objConstructor = aClass.getConstructor(String.class);
obj = objConstructor.newInstance("LeftPalindrome-emordnilaP-thgiR");
// test method m for synchronization
if (!isSynchronized(m, obj, args)) {
throw new TestFailedException(m);
}
}
private static void testMethod(Class<?> aClass, Method m) throws
Exception {
/*
* Construct call with arguments of the correct type. Note that the
* values are somewhat irrelevant. If the call actually succeeds, it
* means we aren't synchronized and the test has failed.
*/
Class<?>[] pTypes = m.getParameterTypes();
List<Integer> charSequenceArgs = new ArrayList<>();
Object[] args = new Object[pTypes.length];
for (int i = 0; i < pTypes.length; i++) {
// determine the type and create the corresponding actual argument
Class<?> pType = pTypes[i];
if (pType.equals(boolean.class)) {
args[i] = BOOLEAN_VAL;
} else if (pType.equals(char.class)) {
args[i] = CHAR_VAL;
} else if (pType.equals(int.class)) {
args[i] = INT_VAL;
} else if (pType.equals(double.class)) {
args[i] = DOUBLE_VAL;
} else if (pType.equals(float.class)) {
args[i] = FLOAT_VAL;
} else if (pType.equals(long.class)) {
args[i] = LONG_VAL;
} else if (pType.equals(Object.class)) {
args[i] = OBJECT_VAL;
} else if (pType.equals(StringBuilder.class)) {
args[i] = STRING_BUILDER_VAL;
} else if (pType.equals(StringBuffer.class)) {
args[i] = STRING_BUFFER_VAL;
} else if (pType.equals(String.class)) {
args[i] = STRING_VAL;
} else if (pType.isArray() && pType.getComponentType().equals(char.class)) {
args[i] = CHAR_ARRAY_VAL;
} else if (pType.equals(CharSequence.class)) {
charSequenceArgs.add(new Integer(i));
} else {
throw new RuntimeException("Test Failed: not accounting for method call with parameter type of " + pType.getName() + " You must update the test.");
}
}
/*
* If there are no CharSequence args, we can simply invoke our method
* and test it
*/
if (charSequenceArgs.isEmpty()) {
invokeMethod(aClass, m, args);
} else {
/*
* Iterate through the different CharSequence types and invoke the
* method for each type.
*/
if (charSequenceArgs.size() > 1) {
throw new RuntimeException("Test Failed: the test cannot handle a method with multiple CharSequence arguments. You must update the test to handle the method "
+ m.toString());
}
for (int j = 0; j < CHAR_SEQUENCE_VAL.length; j++) {
args[charSequenceArgs.get(0)] = CHAR_SEQUENCE_VAL[j];
invokeMethod(aClass, m, args);
}
}
}
@SuppressWarnings("serial")
private static class TestFailedException extends Exception {
final Method m;
public Method getMethod() {
return m;
}
public TestFailedException(Method m) {
this.m = m;
}
}
static class InvokeTask implements Runnable {
private final Method m;
private final Object target;
private final Object[] args;
InvokeTask(Method m, Object target, Object... args) {
this.m = m;
this.target = target;
this.args = args;
}
@Override
public void run() {
try {
m.invoke(target, args);
} catch (IllegalAccessException | IllegalArgumentException |
InvocationTargetException e) {
e.printStackTrace();
}
}
}
/**
* isSynchronized tests whether the given method is synchronized or not by
* invoking it in a thread and testing the thread state after starting the
* thread
* <p/>
* @param m the method to test
* @param target the object the method is executed on
* @param args the arguments passed to the method
* @return true iff the method is synchronized
*/
private static boolean isSynchronized(Method m, Object target,
Object... args) {
Thread t = new Thread(new InvokeTask(m, target, args));
Boolean isSynchronized = null;
synchronized (target) {
t.start();
while (isSynchronized == null) {
switch (t.getState()) {
case NEW:
case RUNNABLE:
case WAITING:
case TIMED_WAITING:
Thread.yield();
break;
case BLOCKED:
isSynchronized = true;
break;
case TERMINATED:
isSynchronized = false;
break;
}
}
}
try {
t.join();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
return isSynchronized;
}
/*
* This class is used to test the synchronization tester above. It has a
* method, should_pass, that is unsynchronized but calls a synchronized
* method. It has another method, should_fail, which isn't synchronized and
* doesn't call a synchronized method. The former should pass and the latter
* should fail.
*/
private static class MyTestClass {
@SuppressWarnings("unused")
public MyTestClass(String s) {
}
@SuppressWarnings("unused")
public void should_pass() {
// call sync method
sync_shouldnt_be_tested();
}
@SuppressWarnings("unused")
public void should_fail() {
}
public synchronized void sync_shouldnt_be_tested() {
}
}
}

View file

@ -0,0 +1,311 @@
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
* @bug 8013395 8014814
* @summary Test StringBuffer.toString caching
*/
public class ToStringCache {
// we can't test that we actually use a cached value (the benchmarks
// verify that) but we have to test that the cache is cleared when
// expected
public static void main(String[] args) throws Exception {
String original = "The original String";
StringBuffer sb = new StringBuffer(original);
String a = sb.toString();
checkEqual(a, original);
String b = sb.toString();
checkEqual(a, b);
// mutating methods
sb.setLength(12);
b = sb.toString();
checkUnequal(a, b);
a = b;
sb.setCharAt(0, 'X');
b = sb.toString();
checkUnequal(a, b);
a = b;
sb.append(new Character('X'));
b = sb.toString();
checkUnequal(a, b);
a = b;
sb.append("More text");
b = sb.toString();
checkUnequal(a, b);
a = b;
sb.append(sb);
b = sb.toString();
checkUnequal(a, b);
a = b;
sb.append(new StringBuilder("Build"));
b = sb.toString();
checkUnequal(a, b);
a = b;
sb.append(new StringBuilder("Build2"), 0, 1);
b = sb.toString();
checkUnequal(a, b);
a = b;
sb.append(new char[] { 'a', 'b' });
b = sb.toString();
checkUnequal(a, b);
a = b;
sb.append(true);
b = sb.toString();
checkUnequal(a, b);
a = b;
sb.append('c');
b = sb.toString();
checkUnequal(a, b);
a = b;
sb.append(23);
b = sb.toString();
checkUnequal(a, b);
a = b;
sb.appendCodePoint(Character.codePointAt(new char[] { 'X'}, 0));
b = sb.toString();
checkUnequal(a, b);
a = b;
sb.append(1L);
b = sb.toString();
checkUnequal(a, b);
a = b;
sb.append(1.0f);
b = sb.toString();
checkUnequal(a, b);
a = b;
sb.append(1.0d);
b = sb.toString();
checkUnequal(a, b);
a = b;
sb.delete(0, 5);
b = sb.toString();
checkUnequal(a, b);
a = b;
sb.deleteCharAt(0);
b = sb.toString();
checkUnequal(a, b);
a = b;
sb.replace(0,2, "123");
b = sb.toString();
checkUnequal(a, b);
a = b;
sb.insert(0, new char[] { 'a', 'b', 'c'}, 0, 3);
b = sb.toString();
checkUnequal(a, b);
a = b;
sb.insert(0, new Object());
b = sb.toString();
checkUnequal(a, b);
a = b;
sb.insert(0, "abc");
b = sb.toString();
checkUnequal(a, b);
a = b;
sb.insert(0, new char[] { 'a', 'b', 'c' });
b = sb.toString();
checkUnequal(a, b);
a = b;
sb.insert(0, new StringBuilder("Build"));
b = sb.toString();
checkUnequal(a, b);
a = b;
sb.insert(0, new StringBuilder("Build"), 0, 1);
b = sb.toString();
checkUnequal(a, b);
a = b;
sb.insert(0, false);
b = sb.toString();
checkUnequal(a, b);
a = b;
sb.insert(0, 'X');
b = sb.toString();
checkUnequal(a, b);
a = b;
sb.insert(0, 1);
b = sb.toString();
checkUnequal(a, b);
a = b;
sb.insert(0, 1L);
b = sb.toString();
checkUnequal(a, b);
a = b;
sb.insert(0, 1.0f);
b = sb.toString();
checkUnequal(a, b);
a = b;
sb.insert(0, 1.0d);
b = sb.toString();
checkUnequal(a, b);
a = b;
sb.reverse();
b = sb.toString();
checkUnequal(a, b);
// Extra checks that append(null) works correctly
sb.append((String)null);
b = sb.toString();
checkUnequal(a, b);
a = b;
sb.append((StringBuffer)null);
b = sb.toString();
checkUnequal(a, b);
a = b;
sb.append((StringBuilder)null);
b = sb.toString();
checkUnequal(a, b);
a = b;
sb.append((CharSequence)null);
b = sb.toString();
checkUnequal(a, b);
a = b;
// non-mutating methods
// Reset to known value
sb = new StringBuffer(original);
a = sb.toString();
b = sb.toString();
checkEqual(a, b);
int l = sb.length();
b = sb.toString();
checkEqual(a, b);
int cap = sb.capacity();
b = sb.toString();
checkEqual(a, b);
sb.ensureCapacity(100);
b = sb.toString();
checkEqual(a, b);
sb.trimToSize();
b = sb.toString();
checkEqual(a, b);
char c = sb.charAt(1);
b = sb.toString();
checkEqual(a, b);
int cp = sb.codePointAt(1);
b = sb.toString();
checkEqual(a, b);
cp = sb.codePointBefore(2);
b = sb.toString();
checkEqual(a, b);
int count = sb.codePointCount(0,1);
b = sb.toString();
checkEqual(a, b);
count = sb.offsetByCodePoints(0, 1);
b = sb.toString();
checkEqual(a, b);
sb.getChars(0, 1, new char[2], 0);
b = sb.toString();
checkEqual(a, b);
String sub = sb.substring(0);
b = sb.toString();
checkEqual(a, b);
CharSequence cs = sb.subSequence(0,1);
b = sb.toString();
checkEqual(a, b);
sub = sb.substring(0, 3);
b = sb.toString();
checkEqual(a, b);
int index = sb.indexOf("rig");
b = sb.toString();
checkEqual(a, b);
index = sb.indexOf("rig", 2);
b = sb.toString();
checkEqual(a, b);
index = sb.lastIndexOf("rig");
b = sb.toString();
checkEqual(a, b);
index = sb.lastIndexOf("rig", 3);
b = sb.toString();
checkEqual(a, b);
}
private static void checkEqual(String s1, String s2) {
if (!s1.equals(s2))
throw new RuntimeException("Unmatched strings: s1 = "
+ s1 + " s2 = " + s2);
}
private static void checkUnequal(String s1, String s2) {
if (s1.equals(s2))
throw new RuntimeException("Unexpected matched strings: " + s1);
}
}

View file

@ -0,0 +1,119 @@
/*
* Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
* @bug 4546734 5007612
* @summary Test StringBuffer.trimToSize
* @key randomness
*/
import java.util.Random;
public class Trim {
private static Random generator = new Random();
public static void main(String[] args) throws Exception {
bash();
//capacityCheck();
}
// Make sure trimToSize is safe to use; it should never cause an
// exception or mutation
private static void bash() throws Exception {
for (int i=0; i<1000; i++) {
StringBuffer sb1 = generateTestBuffer(0, 100);
StringBuffer sb2 = new StringBuffer(sb1);
sb1.trimToSize();
if (!sb1.toString().equals(sb2.toString()))
throw new RuntimeException(
"trim mutated stringbuffer contents");
// Append a random sb
StringBuffer sb3 = generateTestBuffer(0, 100);
sb1.append(sb3);
sb2.append(sb3);
if (generator.nextInt(2) == 0)
sb1.trimToSize();
else
sb2.trimToSize();
if (!sb1.toString().equals(sb2.toString()))
throw new RuntimeException(
"trim mutated stringbuffer contents");
// Append sb with lots of extra space
sb3 = new StringBuffer(100);
sb3.append("a");
sb1.append(sb3);
sb2.append(sb3);
if (generator.nextInt(2) == 0)
sb1.trimToSize();
else
sb2.trimToSize();
if (!sb1.toString().equals(sb2.toString()))
throw new RuntimeException(
"trim mutated stringbuffer contents");
}
}
// This test gives some assurance that trimToSize is working but
// it should not be part of an automated run, and a failure here
// is not against spec; this method is provided simply to be run
// by hand and assure the engineer that it is working. The test
// may stop working at some time in the future depending on
// how String and StringBuffer are implemented because it depends
// upon the capacity method.
private static void capacityCheck() {
for (int i=0; i<100; i++) {
int sizeNeeded = generator.nextInt(1000)+1;
int sizeExtra = generator.nextInt(100) + 1;
StringBuffer sb = new StringBuffer(sizeNeeded + sizeExtra);
StringBuffer sb2 = generateTestBuffer(sizeNeeded, sizeNeeded);
if (sb2.length() != sizeNeeded)
throw new RuntimeException("sb generated incorrectly");
sb.append(sb2);
int oldCapacity = sb.capacity();
sb.trimToSize();
int newCapacity = sb.capacity();
if (oldCapacity == newCapacity)
throw new RuntimeException("trim failed");
}
}
private static int getRandomIndex(int constraint1, int constraint2) {
int range = constraint2 - constraint1;
if (range <= 0)
return constraint1;
int x = generator.nextInt(range);
return constraint1 + x;
}
private static StringBuffer generateTestBuffer(int min, int max) {
StringBuffer aNewStringBuffer = new StringBuffer();
int aNewLength = getRandomIndex(min, max);
for(int y=0; y<aNewLength; y++) {
int achar = generator.nextInt(30)+30;
char test = (char)(achar);
aNewStringBuffer.append(test);
}
return aNewStringBuffer;
}
}