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,76 @@
/*
* 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.
*/
/*
* @test
* @bug 4218776
* @summary Test loading of properties files with blank lines
*/
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
/**
* This class tests to see if a properties object correctly handles blank
* lines in a properties file
*/
public class BlankLines {
public static void main(String []args)
{
try {
// create test file
File file = new File("test.properties");
// write a single space to the test file
FileOutputStream fos = new FileOutputStream(file);
fos.write(' ');
fos.close();
// test empty properties
Properties prop1 = new Properties();
// now load the file we just created, into a
// properties object.
// the properties object should have no elements,
// but due to a bug, it has an empty key/value.
// key = "", value = ""
Properties prop2 = new Properties();
InputStream is = new FileInputStream(file);
try {
prop2.load(is);
} finally {
is.close();
}
if (!prop1.equals(prop2))
throw new RuntimeException("Incorrect properties loading.");
// cleanup
file.delete();
}
catch(IOException e) {}
}
}

View file

@ -0,0 +1,53 @@
/*
* 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 6609431
* @summary Test whether loading of a property value in a file ending with
* a backslash works fine.
*/
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Properties;
public class Bug6609431 {
private static final String expected = "backslash";
public static void main(String[] args) throws IOException {
try (FileReader fr =
new FileReader(new File(System.getProperty("test.src", "."),
"Bug6609431.properties"))) {
Properties p = new Properties();
p.load(fr);
p.getProperty("a");
String val = p.getProperty("b");
if (!val.equals(expected)) {
throw new RuntimeException("Value returned from the property" +
" list was incorrect. Returned: '" + val +
"', expected: '" + expected + "'");
}
}
}
}

View file

@ -0,0 +1,24 @@
#
# 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.
#
a=backslashbackslash
b=backslash\

View file

@ -0,0 +1,106 @@
/*
* Copyright (c) 2016, 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.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/*
* @test
* @bug 8029891
* @summary Test that the Properties class overrides all public+protected
* methods of all ancestor classes and interfaces
* @run main CheckOverrides
*/
public class CheckOverrides {
public static void main(String[] args) {
Set<MethodSignature> pMethodSignatures =
Stream.of(Properties.class.getDeclaredMethods())
.filter(CheckOverrides::isMethodOfInterest)
.map(MethodSignature::new)
.collect(Collectors.toSet());
Map<MethodSignature, Method> unoverriddenMethods = new HashMap<>();
for (Class<?> superclass = Properties.class.getSuperclass();
superclass != Object.class;
superclass = superclass.getSuperclass()) {
Stream.of(superclass.getDeclaredMethods())
.filter(CheckOverrides::isMethodOfInterest)
.forEach(m -> unoverriddenMethods.putIfAbsent(new MethodSignature(m), m));
}
unoverriddenMethods.keySet().removeAll(pMethodSignatures);
if (!unoverriddenMethods.isEmpty()) {
throw new RuntimeException(
"The following methods should be overridden by Properties class:\n" +
unoverriddenMethods.values().stream()
.map(Method::toString)
.collect(Collectors.joining("\n ", " ", "\n"))
);
}
}
static boolean isMethodOfInterest(Method method) {
int mods = method.getModifiers();
return !Modifier.isStatic(mods) &&
(Modifier.isPublic(mods) || Modifier.isProtected(mods));
}
static class MethodSignature {
final Class<?> returnType;
final String name;
final Class<?>[] parameterTypes;
MethodSignature(Method method) {
this(method.getReturnType(), method.getName(), method.getParameterTypes());
}
private MethodSignature(Class<?> returnType, String name, Class<?>[] parameterTypes) {
this.returnType = returnType;
this.name = name;
this.parameterTypes = parameterTypes;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MethodSignature that = (MethodSignature) o;
if (!returnType.equals(that.returnType)) return false;
if (!name.equals(that.name)) return false;
return Arrays.equals(parameterTypes, that.parameterTypes);
}
@Override
public int hashCode() {
int result = returnType.hashCode();
result = 31 * result + name.hashCode();
result = 31 * result + Arrays.hashCode(parameterTypes);
return result;
}
}
}

View file

@ -0,0 +1,61 @@
/*
* Copyright (c) 2016, 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.Enumeration;
import java.util.Properties;
import java.util.concurrent.CompletableFuture;
/*
* @test
* @bug 8029891
* @summary Test Properties methods that do not synchronize any more
* @run main CheckUnsynchronized
*/
public class CheckUnsynchronized {
public static void main(String[] args) {
Properties props = new Properties();
synchronized (props) {
props.setProperty("key", "value");
System.out.println("contains(value)? " +
CompletableFuture.supplyAsync(() -> props.contains("value")).join());
System.out.println("containsKey(key)? " +
CompletableFuture.supplyAsync(() -> props.containsKey("key")).join());
System.out.println("containsValue(value)? " +
CompletableFuture.supplyAsync(() -> props.containsValue("value")).join());
Enumeration<Object> elems =
CompletableFuture.supplyAsync(() -> props.elements()).join();
System.out.println("first value from elements(): " + elems.nextElement());
System.out.println("value from get(): " +
CompletableFuture.supplyAsync(() -> props.getProperty("key")).join());
System.out.println("getOrDefault(\"missing\"): " +
CompletableFuture.supplyAsync(() -> props.getOrDefault("missing", "default")).join());
System.out.println("isEmpty()? " +
CompletableFuture.supplyAsync(() -> props.isEmpty()).join());
Enumeration<Object> keys =
CompletableFuture.supplyAsync(() -> props.keys()).join();
System.out.println("first key from keys(): " + keys.nextElement());
System.out.println("size(): " +
CompletableFuture.supplyAsync(() -> props.size()).join());
}
}
}

View file

@ -0,0 +1,50 @@
/*
* 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.
*/
/*
* @test
* @bug 6270682
* @summary Test the input stream is closed after loadtoXML returns.
*/
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.Properties;
public class CloseXMLStream {
public static void main(String[] args) throws Throwable {
class ExpectedClosingException extends RuntimeException {};
Properties props = new Properties();
ByteArrayOutputStream out = new ByteArrayOutputStream();
props.storeToXML(out, null);
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()) {
public void close() {
throw new ExpectedClosingException();
}
};
try {
props.loadFromXML(in);
throw new Exception("Failed: loadFromXML does not close the is!");
} catch (ExpectedClosingException ex) { /*OK*/ }
}
}

View file

@ -0,0 +1,68 @@
/*
* Copyright (c) 2020, 2025, 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.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Properties;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
/*
* @test
* @bug 8252354
* @run junit CompatibilityTest
* @summary Verify compatibility.
*/
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class CompatibilityTest {
public Object[][] getEntries() throws IOException {
return new Object[][]{
{8, 238923},
{1.1, 1.1},
{new Object(), "Value"},
{"Key", new Object()},
};
}
/**
* Verifies that a ClassCastException is thrown as specified by the
* {@code storeToXML} method.
* @param key the key
* @param value the value
* @throws IOException
*/
@ParameterizedTest
@MethodSource("getEntries")
void testThrows(Object key, Object value) throws IOException {
Assertions.assertThrows(ClassCastException.class, () -> storeToXML(key, value));
}
void storeToXML(Object key, Object value) throws IOException {
ByteArrayOutputStream os = new ByteArrayOutputStream();
Properties pr = new Properties();
pr.put(key, value);
pr.storeToXML(os, "Test", "UTF-8");
}
}

View file

@ -0,0 +1,113 @@
/*
* 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 8005281
* @summary Test that the Properties storeToXML and loadFromXML methods are
* thread safe
* @key randomness
*/
import java.io.*;
import java.util.Properties;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
public class ConcurrentLoadAndStoreXML {
static final Random RAND = new Random();
static volatile boolean done;
/**
* Simple task that bashes on storeToXML and loadFromXML until the "done"
* flag is set.
*/
static class Basher implements Callable<Void> {
final Properties props;
Basher(Properties props) {
this.props = props;
}
public Void call() throws IOException {
while (!done) {
// store as XML format
ByteArrayOutputStream out = new ByteArrayOutputStream();
props.storeToXML(out, null, "UTF-8");
// load from XML format
Properties p = new Properties();
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
p.loadFromXML(in);
// check that the properties are as expected
if (!p.equals(props))
throw new RuntimeException("Properties not equal");
}
return null;
}
}
public static void main(String[] args) throws Exception {
final int NTASKS = 4 + RAND.nextInt(4);
// create Bashers with Properties of random keys and values
Basher[] basher = new Basher[NTASKS];
for (int i=0; i<NTASKS; i++) {
Properties props = new Properties();
for (int j=0; j<RAND.nextInt(100); j++) {
String key = "k" + RAND.nextInt(1000);
String value = "v" + RAND.nextInt(1000);
props.put(key, value);
}
basher[i] = new Basher(props);
}
ExecutorService pool = Executors.newFixedThreadPool(NTASKS);
try {
// kick off the bashers
Future<Void>[] task = new Future[NTASKS];
for (int i=0; i<NTASKS; i++) {
task[i] = pool.submit(basher[i]);
}
// give them time to interfere with each other
Thread.sleep(2000);
done = true;
// check the result
for (int i=0; i<NTASKS; i++) {
task[i].get();
}
} finally {
done = true;
pool.shutdown();
}
}
}

View file

@ -0,0 +1,81 @@
/*
* Copyright (c) 2017, 2025, 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.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Properties;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
/**
* @test
* @bug 8183743
* @summary Test to verify the new overload method with Charset functions the
* same as the existing method that takes a charset name.
* @run junit EncodingTest
*/
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class EncodingTest {
public Object[][] getParameters() throws IOException {
return new Object[][]{
{StandardCharsets.UTF_8.name(), null},
{null, StandardCharsets.UTF_8},};
}
/**
* Tests that properties saved with Properties#storeToXML with either an
* encoding name or a charset can be read with Properties#loadFromXML that
* returns the same Properties object.
*/
@ParameterizedTest
@MethodSource("getParameters")
void testLoadAndStore(String encoding, Charset charset) throws IOException {
Properties props = new Properties();
props.put("k0", "\u6C34");
props.put("k1", "foo");
props.put("k2", "bar");
props.put("k3", "\u0020\u0391\u0392\u0393\u0394\u0395\u0396\u0397");
props.put("k4", "\u7532\u9aa8\u6587");
props.put("k5", "<java.home>/conf/jaxp.properties");
props.put("k6", "\ud800\u00fa");
Properties p;
try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
if (encoding != null) {
props.storeToXML(out, null, encoding);
} else {
props.storeToXML(out, null, charset);
} p = new Properties();
try (ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray())) {
p.loadFromXML(in);
}
}
Assertions.assertEquals(p, props);
}
}

View file

@ -0,0 +1,142 @@
/*
* 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.
*/
/*
* @test
* @bug 4219644
* @summary Escaping of spaces required only for leading spaces in the value
* part of the property.
*/
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;
public class EscapeSpace {
static String props =
"key1=\\ \\ Value1, has leading and trailing spaces\\ \n" +
"key2=Value2,\\ does not have\\ leading or trailing\\ spaces\n" +
"key3=Value3,has,no,spaces\n" +
"key4=Value4, does not have leading spaces\\ \n" +
"key5=\\t\\ \\ Value5, has leading tab and no trailing spaces\n" +
"key6=\\ \\ Value6,doesnothaveembeddedspaces\\ \\ \n" +
"\\ key1\\ test\\ =key1, has leading and trailing spaces \n" +
"key2\\ test=key2, does not have leading or trailing spaces\n" +
"key3test=key3,has,no,spaces\n" +
"key4\\ test\\ =key4, does not have leading spaces \n" +
"\\t\\ key5\\ test=key5, has leading tab and no trailing spaces\n" +
"\\ \\ key6\\ \\ =\\ key6,doesnothaveembeddedspaces ";
static void load(Properties p, String file) throws Exception
{
FileInputStream fis = null;
BufferedInputStream bis = null;
try {
fis = new FileInputStream(file);
bis = new BufferedInputStream( fis );
p.load(bis);
}
catch (IOException e) {
throw new RuntimeException(e.getMessage());
} finally {
if (fis != null)
fis.close();
}
}
static void store(Properties p, String file) throws Exception
{
FileOutputStream fos = null;
BufferedOutputStream bos = null;
try {
fos = new FileOutputStream(file);
bos = new BufferedOutputStream( fos );
p.store( bos, "Omitting escape characters for non leading space \" \" in properties");
}
catch (IOException e) {
throw new RuntimeException(e.getMessage());
} finally {
if (fos != null)
fos.close();
}
}
public static void main( String args[] ) throws Exception
{
ByteArrayInputStream bais = new ByteArrayInputStream(props.getBytes());
Properties props0 = new Properties();
// Load properties with escape character '\' before space characters
try {
props0.load(bais);
} catch (IOException e) {
throw new RuntimeException(e.getMessage());
}
Properties props1 = new Properties();
/*
* Put the same properties, but without the escape char for space in
* value part.
*/
props1.put( "key1", " Value1, has leading and trailing spaces " );
props1.put( "key2",
"Value2, does not have leading or trailing spaces" );
props1.put( "key3", "Value3,has,no,spaces" );
props1.put( "key4", "Value4, does not have leading spaces " );
props1.put( "key5",
"\t Value5, has leading tab and no trailing spaces" );
props1.put( "key6", " Value6,doesnothaveembeddedspaces " );
props1.put( " key1 test ", "key1, has leading and trailing spaces " );
props1.put( "key2 test",
"key2, does not have leading or trailing spaces" );
props1.put( "key3test", "key3,has,no,spaces" );
props1.put( "key4 test ", "key4, does not have leading spaces " );
props1.put( "\t key5 test",
"key5, has leading tab and no trailing spaces" );
props1.put( " key6 ", " key6,doesnothaveembeddedspaces " );
// Check if both the properties match
if (!props0.equals(props1))
throw new RuntimeException("Test failed");
// Also store the new properties to a file
store(props1, "out1.props");
Properties props2 = new Properties();
// Reread the properties from the file
load(props2, "out1.props");
// Make sure that the properties match
if (!props1.equals(props2))
throw new RuntimeException("Test failed");
}
}

View file

@ -0,0 +1,64 @@
/*
* 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.
*/
/*
* @test
* @bug 5060820 5054615 5056707 5061476
* @modules java.desktop
* java.naming
* @compile GenerifiedUses.java
*/
import java.awt.image.CropImageFilter;
import java.awt.image.ImageFilter;
import java.awt.image.PixelGrabber;
import java.awt.image.ReplicateScaleFilter;
import java.util.Properties;
import javax.naming.InitialContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.spi.NamingManager;
public class GenerifiedUses {
static void foo() throws Exception {
Properties props = new Properties();
// 5060820
new InitialDirContext(props);
// 5054615
new InitialContext(props);
// 5056707
NamingManager.getObjectInstance(null, null, null, props);
// 5061476
new CropImageFilter(0, 0, 0, 0).setProperties(props);
new ImageFilter().setProperties(props);
new PixelGrabber(null, 0, 0, 0, 0, false).setProperties(props);
new ReplicateScaleFilter(1, 1).setProperties(props);
}
}

View file

@ -0,0 +1,44 @@
/*
* Copyright (c) 2017, 2025, 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.Properties;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
/*
* @test
* @bug 8189319
* @summary Test that Properties(int initialCapacity) throws exceptions (or
doesn't) as expected
* @run junit InitialCapacity
*/
public class InitialCapacity {
@Test
public void negativeInitCap() { Assertions.assertThrows(IllegalArgumentException.class, () -> {
Properties p = new Properties(-1);
});
}
@Test
public void positiveInitCap() { Properties p = new Properties(10); }
}

View file

@ -0,0 +1,75 @@
/*
* Copyright (c) 2015, 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.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
import java.util.Properties;
/*
* @test
* @bug 8073214 8075362
* @summary Tests to verify that load() and store() throw NPEs as advertised.
*/
public class LoadAndStoreNPE
{
public static void main(String[] args) throws Exception
{
int failures = 0;
Properties props = new Properties();
try {
props.store((OutputStream)null, "comments");
failures++;
} catch (NullPointerException e) {
// do nothing
}
try {
props.store((Writer)null, "comments");
failures++;
} catch (NullPointerException e) {
// do nothing
}
try {
props.load((InputStream)null);
failures++;
} catch (NullPointerException e) {
// do nothing
}
try {
props.load((Reader)null);
failures++;
} catch (NullPointerException e) {
// do nothing
}
if (failures != 0) {
throw new RuntimeException("LoadAndStoreNPE failed with "
+ failures + " errors!");
}
}
}

View file

@ -0,0 +1,254 @@
/*
* Copyright (c) 2012, 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.
*/
/*
* @test
* @bug 8000354 8000685 8004371 8043119 8276207
* @summary Basic test of storeToXML and loadToXML
* @run main/othervm LoadAndStoreXML
*/
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.InvalidPropertiesFormatException;
import java.util.Properties;
public class LoadAndStoreXML {
static final String bomChar = "\uFEFF";
/**
* A {@code ByteArrayInputStream} that allows testing if the
* {@code close} method has been invoked.
*/
static class TestInputStream extends ByteArrayInputStream {
private boolean closed;
TestInputStream(byte[] buf) {
super(buf);
}
boolean isOpen() {
return !closed;
}
public void close() throws IOException {
try {
super.close();
} finally {
closed = true;
}
}
}
/**
* A {@code ByteArrayOutputStream} that allows testing if the
* {@code close} method has been invoked.
*/
static class TestOutputStream extends ByteArrayOutputStream {
private boolean closed;
boolean isOpen() {
return !closed;
}
public void close() throws IOException {
try {
super.close();
} finally {
closed = true;
}
}
}
/**
* Sanity test that properties saved with Properties#storeToXML can be
* read with Properties#loadFromXML.
*/
static void testLoadAndStore(String encoding, boolean appendBOM) throws IOException {
System.out.println("testLoadAndStore, encoding=" + encoding);
Properties props = new Properties();
props.put("k0", "\u6C34");
props.put("k1", "foo");
props.put("k2", "bar");
props.put("k3", "\u0020\u0391\u0392\u0393\u0394\u0395\u0396\u0397");
props.put("k4", "\u7532\u9aa8\u6587");
props.put("k5", "<java.home>/conf/jaxp.properties");
props.put("k6", "\uD834\uDD1E");
TestOutputStream out = new TestOutputStream();
props.storeToXML(out, null, encoding);
if (!out.isOpen())
throw new RuntimeException("OutputStream closed by storeToXML");
Properties p = new Properties();
TestInputStream in;
if (appendBOM) {
byte[] byteOrderMark = bomChar.getBytes(Charset.forName(encoding));
byte[] outArray = out.toByteArray();
byte[] inputArray = new byte[byteOrderMark.length + outArray.length];
System.arraycopy(byteOrderMark, 0, inputArray, 0, byteOrderMark.length);
System.arraycopy(outArray, 0, inputArray, byteOrderMark.length, outArray.length);
in = new TestInputStream(inputArray);
} else {
in = new TestInputStream(out.toByteArray());
}
p.loadFromXML(in);
if (in.isOpen())
throw new RuntimeException("InputStream not closed by loadFromXML");
if (!p.equals(props)) {
System.err.println("stored: " + props);
System.err.println("loaded: " + p);
throw new RuntimeException("Test failed");
}
}
/**
* Test loadFromXML with a document that does not have an encoding declaration
*/
static void testLoadWithoutEncoding() throws IOException {
System.out.println("testLoadWithoutEncoding");
Properties expected = new Properties();
expected.put("foo", "bar");
String s = "<?xml version=\"1.0\"?>" +
"<!DOCTYPE properties SYSTEM \"http://java.sun.com/dtd/properties.dtd\">" +
"<properties>" +
"<entry key=\"foo\">bar</entry>" +
"</properties>";
ByteArrayInputStream in = new ByteArrayInputStream(s.getBytes("UTF-8"));
Properties props = new Properties();
props.loadFromXML(in);
if (!props.equals(expected)) {
System.err.println("loaded: " + props + ", expected: " + expected);
throw new RuntimeException("Test failed");
}
}
/**
* Test loadFromXML with unsupported encoding
*/
static void testLoadWithBadEncoding() throws IOException {
System.out.println("testLoadWithBadEncoding");
String s = "<?xml version=\"1.0\" encoding=\"BAD\"?>" +
"<!DOCTYPE properties SYSTEM \"http://java.sun.com/dtd/properties.dtd\">" +
"<properties>" +
"<entry key=\"foo\">bar</entry>" +
"</properties>";
ByteArrayInputStream in = new ByteArrayInputStream(s.getBytes("UTF-8"));
Properties props = new Properties();
try {
props.loadFromXML(in);
throw new RuntimeException("UnsupportedEncodingException expected");
} catch (UnsupportedEncodingException expected) { }
}
/**
* Test storeToXML with unsupported encoding
*/
static void testStoreWithBadEncoding() throws IOException {
System.out.println("testStoreWithBadEncoding");
Properties props = new Properties();
props.put("foo", "bar");
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
props.storeToXML(out, null, "BAD");
throw new RuntimeException("UnsupportedEncodingException expected");
} catch (UnsupportedEncodingException expected) { }
}
/**
* Test loadFromXML with malformed documents
*/
static void testLoadWithMalformedDoc(Path dir) throws IOException {
try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir, "*.xml")) {
for (Path file: stream) {
System.out.println("testLoadWithMalformedDoc, file=" + file.getFileName());
try (InputStream in = Files.newInputStream(file)) {
Properties props = new Properties();
try {
props.loadFromXML(in);
throw new RuntimeException("InvalidPropertiesFormatException not thrown");
} catch (InvalidPropertiesFormatException x) {
System.out.println(x);
}
}
}
}
}
/**
* Test loadFromXML with supplementary characters
*/
static void testLoadWithSupplementaryCharacters() throws IOException {
System.out.println("testLoadWithSupplementaryCharacters");
Properties expected = new Properties();
expected.put("\uD834\uDD1E", "\uD834\uDD1E");
String s = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<!DOCTYPE properties SYSTEM \"http://java.sun.com/dtd/properties.dtd\">" +
"<properties>" +
"<entry key=\"&#119070;\">&#x1d11e;</entry>" +
"</properties>";
ByteArrayInputStream in = new ByteArrayInputStream(s.getBytes("UTF-8"));
Properties props = new Properties();
props.loadFromXML(in);
if (!props.equals(expected)) {
System.err.println("loaded: " + props + ", expected: " + expected);
throw new RuntimeException("Test failed");
}
}
public static void main(String[] args) throws IOException {
testLoadAndStore("UTF-8", false);
testLoadAndStore("UTF-16", false);
testLoadAndStore("UTF-16BE", false);
testLoadAndStore("UTF-16LE", false);
testLoadAndStore("UTF-16BE", true);
testLoadAndStore("UTF-16LE", true);
testLoadWithoutEncoding();
testLoadWithBadEncoding();
testStoreWithBadEncoding();
testLoadWithSupplementaryCharacters();
// malformed documents
String src = System.getProperty("test.src");
String subdir = "invalidxml";
Path dir = (src == null) ? Paths.get(subdir) : Paths.get(src, subdir);
testLoadWithMalformedDoc(dir);
}
}

View file

@ -0,0 +1,104 @@
/*
* 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.
*/
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Properties;
/**
* @test
* @bug 8016344
* @summary checks that Properties.storeToXML only stores properties locally
* defined on the Properties object, excluding those that are inherited.
* @author danielfuchs
*/
public class LoadAndStoreXMLWithDefaults {
static String writeToXML(Properties props) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
props.storeToXML(baos, "Test 8016344");
return baos.toString();
}
static Properties loadFromXML(String xml, Properties defaults) throws IOException {
ByteArrayInputStream bais = new ByteArrayInputStream(xml.getBytes("UTF-8"));
Properties props = new Properties(defaults);
props.loadFromXML(bais);
return props;
}
static enum Objects { OBJ1, OBJ2, OBJ3 };
public static void main(String[] args) throws IOException {
Properties p1 = new Properties();
p1.setProperty("p1.prop", "prop1-p1");
p1.setProperty("p1.and.p2.prop", "prop2-p1");
p1.setProperty("p1.and.p2.and.p3.prop", "prop3-p1");
Properties p2 = new Properties(p1);
p2.setProperty("p2.prop", "prop4-p2");
p2.setProperty("p1.and.p2.prop", "prop5-p2");
p2.setProperty("p1.and.p2.and.p3.prop", "prop6-p2");
p2.setProperty("p2.and.p3.prop", "prop7-p2");
Properties p3 = new Properties(p2);
p3.setProperty("p3.prop", "prop8-p3");
p3.setProperty("p1.and.p2.and.p3.prop", "prop9-p3");
p3.setProperty("p2.and.p3.prop", "prop10-p3");
Properties P1 = loadFromXML(writeToXML(p1), null);
Properties P2 = loadFromXML(writeToXML(p2), P1);
Properties P3 = loadFromXML(writeToXML(p3), P2);
testResults(p1, P1, p2, P2, p3, P3);
}
public static void testResults(Properties... pps) {
for (int i=0 ; i < pps.length ; i += 2) {
if (!pps[i].equals(pps[i+1])) {
System.err.println("P" + (i/2+1)
+ " Reloaded properties differ from original");
System.err.println("\toriginal: " + pps[i]);
System.err.println("\treloaded: " + pps[i+1]);
throw new RuntimeException("P" + (i/2+1)
+ " Reloaded properties differ from original");
}
if (!pps[i].keySet().equals(pps[i+1].keySet())) {
System.err.println("P" + (i/2+1)
+ " Reloaded property names differ from original");
System.err.println("\toriginal: " + pps[i].keySet());
System.err.println("\treloaded: " + pps[i+1].keySet());
throw new RuntimeException("P" + (i/2+1)
+ " Reloaded property names differ from original");
}
if (!pps[i].stringPropertyNames().equals(pps[i+1].stringPropertyNames())) {
System.err.println("P" + (i/2+1)
+ " Reloaded string property names differ from original");
System.err.println("\toriginal: " + pps[i].stringPropertyNames());
System.err.println("\treloaded: " + pps[i+1].stringPropertyNames());
throw new RuntimeException("P" + (i/2+1)
+ " Reloaded string property names differ from original");
}
}
}
}

View file

@ -0,0 +1,62 @@
/*
* 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.
*/
/*
* @test
* @bug 4115936 4385195 4972297
* @summary checks for processing errors in properties.load
*/
import java.io.File;
import java.io.FileInputStream;
import java.util.Properties;
public class LoadParsing {
public static void main(String[] argv) throws Exception {
File f = new File(System.getProperty("test.src", "."), "input.txt");
FileInputStream myIn = new FileInputStream(f);
Properties myProps = new Properties();
int size = 0;
try {
myProps.load(myIn);
} finally {
myIn.close();
}
if (!myProps.getProperty("key1").equals("value1"))
throw new RuntimeException("Bad comment parsing");
if (!myProps.getProperty("key2").equals("abc\\defg\\"))
throw new RuntimeException("Bad slash parsing");
if (!myProps.getProperty("key3").equals("value3"))
throw new RuntimeException("Adds spaces to key");
if (!myProps.getProperty("key4").equals(":value4"))
throw new RuntimeException("Bad separator parsing");
if (myProps.getProperty("#") != null)
throw new RuntimeException(
"Does not recognize comments with leading spaces");
if ((size=myProps.size()) != 4)
throw new RuntimeException(
"Wrong number of keys in Properties; expected 4, got " +
size + ".");
}
}

View file

@ -0,0 +1,143 @@
/*
* 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.
*/
/*
* @test
* @bug 4881291 4094886
* @summary checks for processing errors in properties.load
*/
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Properties;
public class LoadParsing2 {
public static void main(String[] argv) throws Exception {
for (int i = 0; i < dfiles.length; i++) {
test(dfiles[i], keys[i], values[i], true);
test(dfiles[i], keys[i], values[i], false);
}
}
private static Properties getLoadedProperties(InputStream is,
boolean doStream)
throws Exception
{
Properties props = new Properties();
if (doStream)
props.load(is);
else
props.load(new InputStreamReader(is, "UTF-8"));
return props;
}
private static void test(String fnData,
String[] keys,
String[] values,
boolean doStream)
throws Exception
{
File f = new File(System.getProperty("test.src", "."), fnData);
FileInputStream myIn = new FileInputStream(f);
Properties myProps = getLoadedProperties(myIn, doStream);
for (int i = 0; i < keys.length; i++) {
if (!myProps.getProperty(keys[i]).equals(values[i])) {
throw new RuntimeException("Test1: Bad parsing at " + i);
}
}
}
static String[] keys1 = {
"\\",
"\\:key12",
"key16 b",
"key14_asdfa",
"\\\\",
"key8notassign",
"key17",
"key15",
"keyabcdef",
"key13dialog.3",
"key7",
"key6",
"key5",
"key3",
"key2",
"key1",
"key9 Term",
"key0"
};
static String[] keys2 = {
"key1",
"key2"
};
static String[] keys3 = {
"key1",
"key2"
};
static String[] values1 = {
"key10=bar",
"bar2",
" abcdef",
"",
"key11=bar2",
"abcdef",
"#barbaz",
" abcdef",
"",
"",
"Symbol,SYMBOL_CHARSET ",
"WingDings,SYMBOL_CHARSET \\abc",
"==Arial,ANSI_CHARSET",
"",
"= abcde",
"value1",
"ABCDE",
"abcd"
};
static String[] values2 = {
"-monotype-timesnewroman-regular-r---*-%d-*-*-p-*-iso8859-1serif.1a-monotype-timesnewroman-regular-r-normal--*-%d-*-*-p-*-iso8859-2serif.2a-b&h-LucidaBrightLat4-Normal-r-normal--*-%d-*-*-p-*-iso8859-4serif.3a-monotype-times-regular-r-normal--*-%d-*-*-p-*-iso8859-5serif.4a-monotype-timesnewromangreek-regular-r-normal--*-%d-*-*-p-*-iso8859-7serif.5a-monotype-times-regular-r-normal--*-%d-*-*-p-*-iso8859-9serif.6a-monotype-times-regular-r-normal--*-%d-*-*-p-*-iso8859-15serif.7a-hanyi-ming-medium-r-normal--*-%d-*-*-m-*-big5-1serif.8a-sun-song-medium-r-normal--*-%d-*-*-c-*-gb2312.1980-0serif.9a-ricoh-hgminchol-medium-r-normal--*-%d-*-*-m-*-jisx0201.1976-0serif.10a-ricoh-hgminchol-medium-r-normal--*-%d-*-*-m-*-jisx0208.1983-0serif.11a-ricoh-heiseimin-w3-r-normal--*-%d-*-*-m-*-jisx0212.1990-0serif.12a-hanyang-myeongjo-medium-r-normal--*-%d-*-*-m-*-ksc5601.1992-3serif.13a-urw-itczapfdingbats-medium-r-normal--*-%d-*-*-p-*-sun-fontspecificserif.14a-*-symbol-medium-r-normal--*-%d-*-*-p-*-sun-fontspecificbserif.italic.0=-monotype-timesbnewbroman-regular-i---*-%d-*-*-p-*-iso8859-1bserif.italic.1=-monotype-timesbnewbroman-regular-i-normal-italic-*-%d-*-*-p-*-iso8859-2",
"-b&h-LucidaBrightLat4-normal-i-normal-Italic-*-%d-*-*-p-*-iso8859-4"
};
static String[] values3 = {
"-monotype-times new roman-regular-r---*-%d-*-*-p-*-iso8859-1, -monotype-times new roman-regular-r-normal--*-%d-*-*-p-*-iso8859-2, -b&h-LucidaBrightLat4-Normal-r-normal--*-%d-*-*-p-*-iso8859-4, -monotype-times-regular-r-normal--*-%d-*-*-p-*-iso8859-5, -monotype-times new roman greek-regular-r-normal--*-%d-*-*-p-*-iso8859-7, -monotype-times-regular-r-normal--*-%d-*-*-p-*-iso8859-9, -monotype-times-regular-r-normal--*-%d-*-*-p-*-iso8859-15, -hanyi-ming-medium-r-normal--*-%d-*-*-m-*-big5-1, -sun-song-medium-r-normal--*-%d-*-*-c-*-gb2312.1980-0, -ricoh-hg gothic b-medium-r-normal--*-%d-*-*-m-*-jisx0201.1976-0, -ricoh-hg gothic b-medium-r-normal-*-*-%d-*-*-m-*-jisx0208.1983-0, -ricoh-heiseimin-w3-r-normal--*-%d-*-*-m-*-jisx0212.1990-0, -hanyang-myeongjo-medium-r-normal--*-%d-*-*-m-*-ksc5601.1992-3",
"-monotype-times new roman-regular-i---*-%d-*-*-p-*-iso8859-1, -monotype-times new roman-regular-i-normal-italic-*-%d-*-*-p-*-iso8859-2, -b&h-LucidaBrightLat4-normal-i-normal-Italic-*-%d-*-*-p-*-iso8859-4, -monotype-times-regular-i-normal-italic-*-%d-*-*-p-*-iso8859-5, -monotype-times new roman greek-regular-i-normal--*-%d-*-*-p-*-iso8859-7, -monotype-times-regular-i-normal-italic-*-%d-*-*-p-*-iso8859-9, -monotype-times-regular-i-normal--*-%d-*-*-p-*-iso8859-15, -hanyi-ming-medium-r-normal--*-%d-*-*-m-*-big5-1, -sun-song-medium-r-normal--*-%d-*-*-c-*-gb2312.1980-0, -ricoh-hg gothic b-medium-r-normal--*-%d-*-*-m-*-jisx0201.1976-0, -ricoh-hg gothic b-medium-r-normal-*-*-%d-*-*-m-*-jisx0208.1983-0, -ricoh-heiseimin-w3-r-normal--*-%d-*-*-m-*-jisx0212.1990-0, -hanyang-myeongjo-medium-r-normal--*-%d-*-*-m-*-ksc5601.1992-3"
};
static String[][] keys = {keys1, keys1, keys2, keys2, keys3};
static String[][] values = {values1, values1, values2, values2, values3};
static String[] dfiles = {
"testData1",
"testData1.dos",
"testData2",
"testData2.dos",
"testData3.dos"
};
}

View file

@ -0,0 +1,76 @@
/*
* 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.
*/
/*
* @test
* @bug 4192678
* @summary Test loading of values that are key value separators
*/
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;
/**
* This class tests to see if a properties object can successfully save and
* load properties with a non-escaped value that is also a key value separator
*
*/
public class LoadSeparators {
public static void main(String[] argv) throws Exception {
try {
// Destroy old test file if any
// Create a properties file
File propFile = new File("testout");
propFile.delete();
// Create a properties file
FileOutputStream myOut = new FileOutputStream(propFile);
String testProperty = "Test3==";
myOut.write(testProperty.getBytes());
myOut.close();
// Load the properties set
FileInputStream myIn = new FileInputStream("testout");
Properties myNewProps = new Properties();
try {
myNewProps.load(myIn);
} finally {
myIn.close();
}
// Read in the test property
String equalSign = myNewProps.getProperty("Test3");
// Clean up
propFile.delete();
if (!equalSign.equals("="))
throw new Exception("Cannot read key-value separators.");
} catch (IOException e) {
System.err.println(e);
}
}
}

View file

@ -0,0 +1,201 @@
/*
* Copyright (c) 2020, 2025, 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 8245694
* @summary tests the entrySet() method of Properties class
* @author Yu Li
* @run junit PropertiesEntrySetTest
*/
import java.util.Properties;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.Test;
public class PropertiesEntrySetTest {
@Test
public void testEquals() {
Properties a = new Properties();
var aEntrySet = a.entrySet();
assertFalse(aEntrySet.equals(null));
assertTrue(aEntrySet.equals(aEntrySet));
Properties b = new Properties();
var bEntrySet = b.entrySet();
assertTrue(bEntrySet.equals(aEntrySet));
assertTrue(bEntrySet.hashCode() == aEntrySet.hashCode());
a.setProperty("p1", "1");
assertFalse(bEntrySet.equals(aEntrySet));
assertFalse(bEntrySet.hashCode() == aEntrySet.hashCode());
b.setProperty("p1", "1");
assertTrue(aEntrySet.equals(bEntrySet));
assertTrue(bEntrySet.hashCode() == aEntrySet.hashCode());
Properties c = new Properties();
c.setProperty("p1", "2");
var cEntrySet = c.entrySet();
assertFalse(cEntrySet.equals(bEntrySet));
assertFalse(bEntrySet.hashCode() == cEntrySet.hashCode());
assertFalse(cEntrySet.equals(aEntrySet));
assertFalse(aEntrySet.hashCode() == cEntrySet.hashCode());
a.setProperty("p2", "2");
Properties d = new Properties();
d.setProperty("p2", "2");
d.setProperty("p1", "1");
var dEntrySet = d.entrySet();
assertTrue(dEntrySet.equals(aEntrySet));
assertTrue(aEntrySet.hashCode() == dEntrySet.hashCode());
a.remove("p1");
assertFalse(aEntrySet.equals(dEntrySet));
assertFalse(aEntrySet.hashCode() == dEntrySet.hashCode());
d.remove("p1", "1");
assertTrue(dEntrySet.equals(aEntrySet));
assertTrue(aEntrySet.hashCode() == dEntrySet.hashCode());
a.clear();
assertFalse(aEntrySet.equals(dEntrySet));
assertFalse(aEntrySet.hashCode() == dEntrySet.hashCode());
assertTrue(aEntrySet.isEmpty());
d.clear();
assertTrue(dEntrySet.equals(aEntrySet));
assertTrue(aEntrySet.hashCode() == dEntrySet.hashCode());
assertTrue(dEntrySet.isEmpty());
}
@Test
public void testToString() {
Properties a = new Properties();
var aEntrySet = a.entrySet();
assertEquals("[]", aEntrySet.toString());
a.setProperty("p1", "1");
assertEquals("[p1=1]", aEntrySet.toString());
a.setProperty("p2", "2");
assertEquals(2, aEntrySet.size());
assertTrue(aEntrySet.toString().trim().startsWith("["));
assertTrue(aEntrySet.toString().contains("p1=1"));
assertTrue(aEntrySet.toString().contains("p2=2"));
assertTrue(aEntrySet.toString().trim().endsWith("]"));
Properties b = new Properties();
b.setProperty("p2", "2");
b.setProperty("p1", "1");
var bEntrySet = b.entrySet();
assertEquals(2, bEntrySet.size());
assertTrue(bEntrySet.toString().trim().startsWith("["));
assertTrue(bEntrySet.toString().contains("p1=1"));
assertTrue(bEntrySet.toString().contains("p2=2"));
assertTrue(bEntrySet.toString().trim().endsWith("]"));
b.setProperty("p0", "0");
assertEquals(3, bEntrySet.size());
assertTrue(bEntrySet.toString().contains("p0=0"));
b.remove("p1");
assertEquals(2, bEntrySet.size());
assertFalse(bEntrySet.toString().contains("p1=1"));
assertTrue(bEntrySet.toString().trim().startsWith("["));
assertTrue(bEntrySet.toString().contains("p0=0"));
assertTrue(bEntrySet.toString().contains("p2=2"));
assertTrue(bEntrySet.toString().trim().endsWith("]"));
b.remove("p0", "0");
assertEquals(1, bEntrySet.size());
assertFalse(bEntrySet.toString().contains("p0=0"));
assertTrue(bEntrySet.toString().trim().startsWith("["));
assertTrue(bEntrySet.toString().contains("p2=2"));
assertTrue(bEntrySet.toString().trim().endsWith("]"));
b.clear();
assertTrue(bEntrySet.isEmpty());
assertTrue(bEntrySet.toString().equals("[]"));
}
@Test
public void testEntrySetWithoutException() {
Properties a = new Properties();
a.setProperty("p1", "1");
a.setProperty("p2", "2");
var aEntrySet = a.entrySet();
assertEquals(2, aEntrySet.size());
var i = aEntrySet.iterator();
var e1 = i.next();
i.remove();
assertFalse(aEntrySet.contains(e1));
assertEquals(1, aEntrySet.size());
var e2 = i.next();
aEntrySet.remove(e2);
assertFalse(aEntrySet.contains(e2));
assertTrue(aEntrySet.isEmpty());
a.setProperty("p1", "1");
a.setProperty("p3", "3");
Properties b = new Properties();
b.setProperty("p2", "2");
b.setProperty("p1", "1");
var bEntrySet = b.entrySet();
assertFalse(bEntrySet.containsAll(aEntrySet));
assertEquals(2, bEntrySet.size());
assertTrue(bEntrySet.removeAll(aEntrySet));
assertEquals(1, bEntrySet.size());
assertTrue(bEntrySet.retainAll(aEntrySet));
assertTrue(bEntrySet.isEmpty());
assertEquals(2, aEntrySet.size());
aEntrySet.clear();
assertTrue(aEntrySet.isEmpty());
}
@Test
public void testEntrySetExceptionWhenAdd() {
Properties a = new Properties();
a.setProperty("p1", "1");
var aEntrySet = a.entrySet();
Properties b = new Properties();
b.setProperty("p2", "2");
var bEntrySet = b.entrySet();
assertThrows(UnsupportedOperationException.class, () -> aEntrySet.addAll(bEntrySet));
assertThrows(UnsupportedOperationException.class, () -> aEntrySet.add(bEntrySet.iterator().next()));
}
}

View file

@ -0,0 +1,148 @@
/*
* Copyright (c) 2016, 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.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Base64;
import java.util.Properties;
/**
* @test
* @bug 8029891
* @summary tests the compatibility of Properties serial form
* @run main PropertiesSerialization read
*
* To update this test in case the serial form of Properties changes, run this
* test with the 'write' flag, and copy the resulting output back into this
* file, replacing the existing String declaration(s).
*/
public class PropertiesSerialization {
private static final Properties TEST_PROPS;
static {
TEST_PROPS = new Properties();
TEST_PROPS.setProperty("one", "two");
TEST_PROPS.setProperty("buckle", "shoe");
TEST_PROPS.setProperty("three", "four");
TEST_PROPS.setProperty("shut", "door");
}
/**
* Base64 encoded string for Properties object
* Java version: 1.8.0
**/
private static final String TEST_SER_BASE64 =
"rO0ABXNyABRqYXZhLnV0aWwuUHJvcGVydGllczkS0HpwNj6YAgABTAAIZGVmYXVs"
+ "dHN0ABZMamF2YS91dGlsL1Byb3BlcnRpZXM7eHIAE2phdmEudXRpbC5IYXNodGFi"
+ "bGUTuw8lIUrkuAMAAkYACmxvYWRGYWN0b3JJAAl0aHJlc2hvbGR4cD9AAAAAAAAI"
+ "dwgAAAALAAAABHQAA29uZXQAA3R3b3QABHNodXR0AARkb29ydAAGYnVja2xldAAE"
+ "c2hvZXQABXRocmVldAAEZm91cnhw";
public static void main(String[] args) throws IOException,
ClassNotFoundException {
if (args.length == 0) {
System.err.println("Run with 'read' or 'write'");
System.err.println(" read mode: normal test mode.");
System.err.println(" Confirms that serial stream can");
System.err.println(" be deserialized as expected.");
System.err.println(" write mode: meant for updating the test,");
System.err.println(" should the serial form change.");
System.err.println(" Test output should be pasted");
System.err.println(" back into the test source.");
return;
}
Properties deserializedObject;
if ("read".equals(args[0])) {
ByteArrayInputStream bais = new
ByteArrayInputStream(Base64.getDecoder().decode(TEST_SER_BASE64));
try (ObjectInputStream ois = new ObjectInputStream(bais)) {
deserializedObject = (Properties) ois.readObject();
}
if (!TEST_PROPS.equals(deserializedObject)) {
throw new RuntimeException("deserializedObject not equals()");
}
System.out.println("Test passed");
} else if ("write".equals(args[0])) {
System.out.println("\nTo update the test, paste the following back "
+ "into the test code:\n");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(TEST_PROPS);
oos.flush();
oos.close();
byte[] byteArray = baos.toByteArray();
// Check that the Properties deserializes correctly
ByteArrayInputStream bais = new ByteArrayInputStream(byteArray);
ObjectInputStream ois = new ObjectInputStream(bais);
Properties deser = (Properties)ois.readObject();
if (!TEST_PROPS.equals(deser)) {
throw new RuntimeException("write: Deserialized != original");
}
// Now get a Base64 string representation of the serialized bytes.
final String base64 = Base64.getEncoder().encodeToString(byteArray);
// Check that we can deserialize the Base64 string we just computed.
ByteArrayInputStream bais2 =
new ByteArrayInputStream(Base64.getDecoder().decode(base64));
ObjectInputStream ois2 = new ObjectInputStream(bais2);
Properties deser2 = (Properties)ois2.readObject();
if (!TEST_PROPS.equals(deser2)) {
throw new RuntimeException("write: Deserialized base64 != "
+ "original");
}
System.out.println(dumpBase64SerialStream(base64));
}
}
private static final String INDENT = " ";
/* Based on:
* java/util/logging/HigherResolutionTimeStamps/SerializeLogRecored.java
*/
private static String dumpBase64SerialStream(String base64) {
// Generates the Java Pseudo code that can be cut & pasted into
// this test (see Jdk8SerializedLog and Jdk9SerializedLog below)
final StringBuilder sb = new StringBuilder();
sb.append(INDENT).append(" /**").append('\n');
sb.append(INDENT).append(" * Base64 encoded string for Properties object\n");
sb.append(INDENT).append(" * Java version: ")
.append(System.getProperty("java.version")).append('\n');
sb.append(INDENT).append(" **/").append('\n');
sb.append(INDENT).append(" private static final String TEST_SER_BASE64 = ")
.append("\n").append(INDENT).append(" ");
final int last = base64.length() - 1;
for (int i=0; i<base64.length();i++) {
if (i%64 == 0) sb.append("\"");
sb.append(base64.charAt(i));
if (i%64 == 63 || i == last) {
sb.append("\"");
if (i == last) sb.append(";\n");
else sb.append("\n").append(INDENT).append(" + ");
}
}
return sb.toString();
}
}

View file

@ -0,0 +1,322 @@
/*
* Copyright (c) 2021, 2025, 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.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Writer;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.TreeSet;
import java.util.stream.Collectors;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
/*
* @test
* @summary tests the order in which the Properties.store() method writes out the properties
* @bug 8231640 8282023
* @run junit/othervm PropertiesStoreTest
*/
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class PropertiesStoreTest {
private static final String DATE_FORMAT_PATTERN = "EEE MMM dd HH:mm:ss zzz uuuu";
// use Locale.US, since when the date comment was written by Properties.store(...),
// it internally calls the Date.toString() which uses Locale.US for time zone names
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern(DATE_FORMAT_PATTERN, Locale.US);
private static final Locale PREV_LOCALE = Locale.getDefault();
private Object[][] createProps() {
final Properties simple = new Properties();
simple.setProperty("1", "one");
simple.setProperty("2", "two");
simple.setProperty("10", "ten");
simple.setProperty("02", "zero-two");
simple.setProperty("3", "three");
simple.setProperty("0", "zero");
simple.setProperty("00", "zero-zero");
simple.setProperty("0", "zero-again");
final Properties specialChars = new Properties();
// some special chars
simple.setProperty(" 1", "space-one");
simple.setProperty("\t 3 7 \n", "tab-space-three-space-seven-space-newline");
// add some simple chars
simple.setProperty("3", "three");
simple.setProperty("0", "zero");
final Properties overrideCallsSuper = new OverridesEntrySetCallsSuper();
overrideCallsSuper.putAll(simple);
final OverridesEntrySet overridesEntrySet = new OverridesEntrySet();
overridesEntrySet.putAll(simple);
final Properties doesNotOverrideEntrySet = new DoesNotOverrideEntrySet();
doesNotOverrideEntrySet.putAll(simple);
return new Object[][]{
{simple, naturalOrder(simple)},
{specialChars, naturalOrder(specialChars)},
{overrideCallsSuper, naturalOrder(overrideCallsSuper)},
{overridesEntrySet, overridesEntrySet.expectedKeyOrder()},
{doesNotOverrideEntrySet, naturalOrder(doesNotOverrideEntrySet)}
};
}
/**
* Returns a {@link Locale} to use for testing
*/
private Object[][] provideLocales() {
// pick a non-english locale for testing
Set<Locale> locales = Arrays.stream(Locale.getAvailableLocales())
.filter(l -> !l.getLanguage().isEmpty() && !l.getLanguage().equals("en"))
.limit(1)
.collect(Collectors.toCollection(HashSet::new));
locales.add(Locale.getDefault()); // always test the default locale
locales.add(Locale.US); // guaranteed to be present
locales.add(Locale.ROOT); // guaranteed to be present
// return the chosen locales
return locales.stream()
.map(m -> new Locale[] {m})
.toArray(n -> new Object[n][0]);
}
/**
* Tests that the {@link Properties#store(Writer, String)} API writes out the properties
* in the expected order
*/
@ParameterizedTest
@MethodSource("createProps")
public void testStoreWriterKeyOrder(final Properties props, final String[] expectedOrder) throws Exception {
// Properties.store(...) to a temp file
final Path tmpFile = Files.createTempFile("8231640", "props");
try (final Writer writer = Files.newBufferedWriter(tmpFile)) {
props.store(writer, null);
}
testStoreKeyOrder(props, tmpFile, expectedOrder);
}
/**
* Tests that the {@link Properties#store(OutputStream, String)} API writes out the properties
* in the expected order
*/
@ParameterizedTest
@MethodSource("createProps")
public void testStoreOutputStreamKeyOrder(final Properties props, final String[] expectedOrder) throws Exception {
// Properties.store(...) to a temp file
final Path tmpFile = Files.createTempFile("8231640", "props");
try (final OutputStream os = Files.newOutputStream(tmpFile)) {
props.store(os, null);
}
testStoreKeyOrder(props, tmpFile, expectedOrder);
}
/**
* {@link Properties#load(InputStream) Loads a Properties instance} from the passed
* {@code Path} and then verifies that:
* - the loaded properties instance "equals" the passed (original) "props" instance
* - the order in which the properties appear in the file represented by the path
* is the same as the passed "expectedOrder"
*/
private void testStoreKeyOrder(final Properties props, final Path storedProps,
final String[] expectedOrder) throws Exception {
// Properties.load(...) from that stored file and verify that the loaded
// Properties has expected content
final Properties loaded = new Properties();
try (final InputStream is = Files.newInputStream(storedProps)) {
loaded.load(is);
}
Assertions.assertEquals(props, loaded, "Unexpected properties loaded from stored state");
// now read lines from the stored file and keep track of the order in which the keys were
// found in that file. Compare that order with the expected store order of the keys.
final List<String> actualOrder;
try (final BufferedReader reader = Files.newBufferedReader(storedProps)) {
actualOrder = readInOrder(reader);
}
Assertions.assertEquals(expectedOrder.length, actualOrder.size(),
"Unexpected number of keys read from stored properties");
if (!Arrays.equals(actualOrder.toArray(new String[0]), expectedOrder)) {
Assertions.fail("Unexpected order of stored property keys. Expected order: " + Arrays.toString(expectedOrder)
+ ", found order: " + actualOrder);
}
}
/**
* Tests that {@link Properties#store(Writer, String)} writes out a proper date comment
*/
@ParameterizedTest
@MethodSource("provideLocales")
public void testStoreWriterDateComment(final Locale testLocale) throws Exception {
// switch the default locale to the one being tested
Locale.setDefault(testLocale);
System.out.println("Using locale: " + testLocale + " for Properties#store(Writer) test");
try {
final Properties props = new Properties();
props.setProperty("a", "b");
final Path tmpFile = Files.createTempFile("8231640", "props");
try (final Writer writer = Files.newBufferedWriter(tmpFile)) {
props.store(writer, null);
}
testDateComment(tmpFile);
} finally {
// reset to the previous one
Locale.setDefault(PREV_LOCALE);
}
}
/**
* Tests that {@link Properties#store(OutputStream, String)} writes out a proper date comment
*/
@ParameterizedTest
@MethodSource("provideLocales")
public void testStoreOutputStreamDateComment(final Locale testLocale) throws Exception {
// switch the default locale to the one being tested
Locale.setDefault(testLocale);
System.out.println("Using locale: " + testLocale + " for Properties#store(OutputStream) test");
try {
final Properties props = new Properties();
props.setProperty("a", "b");
final Path tmpFile = Files.createTempFile("8231640", "props");
try (final Writer writer = Files.newBufferedWriter(tmpFile)) {
props.store(writer, null);
}
testDateComment(tmpFile);
} finally {
// reset to the previous one
Locale.setDefault(PREV_LOCALE);
}
}
/**
* Reads each line in the {@code file} and verifies that there is only one comment line
* and that comment line can be parsed into a {@link java.util.Date}
*/
private void testDateComment(Path file) throws Exception {
String comment = null;
try (final BufferedReader reader = Files.newBufferedReader(file)) {
String line = null;
while ((line = reader.readLine()) != null) {
if (line.startsWith("#")) {
if (comment != null) {
Assertions.fail("More than one comment line found in the stored properties file " + file);
}
comment = line.substring(1);
}
}
}
if (comment == null) {
Assertions.fail("No comment line found in the stored properties file " + file);
}
try {
FORMATTER.parse(comment);
} catch (DateTimeParseException pe) {
Assertions.fail("Unexpected date comment: " + comment, pe);
}
}
// returns the property keys in their natural order
private static String[] naturalOrder(final Properties props) {
return new TreeSet<>(props.stringPropertyNames()).toArray(new String[0]);
}
// reads each non-comment line and keeps track of the order in which the property key lines
// were read
private static List<String> readInOrder(final BufferedReader reader) throws IOException {
final List<String> readKeys = new ArrayList<>();
String line;
while ((line = reader.readLine()) != null) {
if (line.startsWith("#")) {
continue;
}
final String key = line.substring(0, line.indexOf("="));
// the Properties.store(...) APIs write out the keys in a specific format for certain
// special characters. Our test uses some of the keys which have those special characters.
// Here we handle such special character conversion (for only those characters that this test uses).
// replace the backslash character followed by the t character with the tab character
String replacedKey = key.replace("\\t", "\t");
// replace the backslash character followed by the n character with the newline character
replacedKey = replacedKey.replace("\\n", "\n");
// replace backslash character followed by the space character with the space character
replacedKey = replacedKey.replace("\\ ", " ");
readKeys.add(replacedKey);
}
return readKeys;
}
// Extends java.util.Properties and overrides entrySet() to return a reverse
// sorted entries set
private static class OverridesEntrySet extends Properties {
@Override
@SuppressWarnings("unchecked")
public Set<Map.Entry<Object, Object>> entrySet() {
// return a reverse sorted entries set
var entries = super.entrySet();
Comparator<Map.Entry<String, String>> comparator = Map.Entry.comparingByKey(Comparator.reverseOrder());
TreeSet<Map.Entry<String, String>> reverseSorted = new TreeSet<>(comparator);
reverseSorted.addAll((Set) entries);
return (Set) reverseSorted;
}
String[] expectedKeyOrder() {
// returns in reverse order of the property keys' natural ordering
var keys = new ArrayList<>(stringPropertyNames());
keys.sort(Comparator.reverseOrder());
return keys.toArray(new String[0]);
}
}
// Extends java.util.Properties and overrides entrySet() to just return "super.entrySet()"
private static class OverridesEntrySetCallsSuper extends Properties {
@Override
public Set<Map.Entry<Object, Object>> entrySet() {
return super.entrySet();
}
}
// Extends java.util.Properties but doesn't override entrySet() method
private static class DoesNotOverrideEntrySet extends Properties {
@Override
public String toString() {
return "DoesNotOverrideEntrySet - " + super.toString();
}
}
}

View file

@ -0,0 +1,508 @@
/*
* Copyright (c) 2018, 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
* @summary tests the load and store methods of Properties class
* @author Xueming Shen
* @bug 4094886 8224202
* @modules jdk.charsets
* @key randomness
*/
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.util.Properties;
import java.util.Random;
public class PropertiesTest {
private static boolean failure = false;
private static int failCount = 0;
/**
* Main to interpret arguments and run several tests.
*
*/
public static void main(String[] args) throws Exception {
BlankLines();
EscapeSpace();
LoadParsing();
SaveEncoding();
SaveLoadBasher();
SaveSeparator();
SaveClose();
SaveComments();
UnicodeEscape();
if (failure)
throw new RuntimeException("Failure in Properties testing.");
else
System.err.println("OKAY: All tests passed.");
}
private static void report(String testName) {
int spacesToAdd = 30 - testName.length();
StringBuffer paddedNameBuffer = new StringBuffer(testName);
for (int i=0; i<spacesToAdd; i++)
paddedNameBuffer.append(" ");
String paddedName = paddedNameBuffer.toString();
System.err.println(paddedName + ": " +
(failCount==0 ? "Passed":"Failed("+failCount+")"));
if (failCount > 0)
failure = true;
failCount = 0;
}
private static void check(Properties prop1, Properties prop2) {
if (!prop1.equals(prop2))
failCount++;
}
private static Reader getReader(String src, String csn)
throws Exception {
return new InputStreamReader(
new ByteArrayInputStream(src.getBytes()),
csn);
}
private static OutputStream getFOS(String name)
throws Exception
{
return new FileOutputStream(name);
}
private static Writer getFOSW(String name, String csn)
throws Exception
{
return new OutputStreamWriter(
new FileOutputStream(name),
csn);
}
private static Reader getReader(byte[] src, String csn)
throws Exception {
return new InputStreamReader(new ByteArrayInputStream(src), csn);
}
private static InputStream getInputStream(String src) {
return new ByteArrayInputStream(src.getBytes());
}
private static InputStream getInputStream(byte[] src) {
return new ByteArrayInputStream(src);
}
private static void BlankLines() throws Exception {
// write a single space to the output stream
ByteArrayOutputStream baos = new ByteArrayOutputStream();
baos.write(' ');
// test empty properties
Properties prop1 = new Properties();
// now load the file we just created, into a properties object.
// the properties object should have no elements, but due to a
// bug, it has an empty key/value. key = "", value = ""
Properties prop2 = new Properties();
prop2.load(getInputStream(baos.toByteArray()));
check(prop1, prop2);
// test reader
prop2 = new Properties();
prop2.load(getReader(baos.toByteArray(), "UTF-8"));
check(prop1, prop2);
report("BlinkLine");
}
private static void EscapeSpace() throws Exception {
String propsCases =
"key1=\\ \\ Value\\u4e001, has leading and trailing spaces\\ \n" +
"key2=Value\\u4e002,\\ does not have\\ leading or trailing\\ spaces\n" +
"key3=Value\\u4e003,has,no,spaces\n" +
"key4=Value\\u4e004, does not have leading spaces\\ \n" +
"key5=\\t\\ \\ Value\\u4e005, has leading tab and no trailing spaces\n" +
"key6=\\ \\ Value\\u4e006,doesnothaveembeddedspaces\\ \\ \n" +
"\\ key1\\ test\\ =key1, has leading and trailing spaces \n" +
"key2\\ test=key2, does not have leading or trailing spaces\n" +
"key3test=key3,has,no,spaces\n" +
"key4\\ test\\ =key4, does not have leading spaces \n" +
"\\t\\ key5\\ test=key5, has leading tab and no trailing spaces\n" +
"\\ \\ key6\\ \\ =\\ key6,doesnothaveembeddedspaces ";
// Put the same properties, but without the escape char for space in
// value part.
Properties props = new Properties();
props.put("key1", " Value\u4e001, has leading and trailing spaces ");
props.put("key2", "Value\u4e002, does not have leading or trailing spaces");
props.put("key3", "Value\u4e003,has,no,spaces");
props.put("key4", "Value\u4e004, does not have leading spaces ");
props.put("key5", "\t Value\u4e005, has leading tab and no trailing spaces");
props.put("key6", " Value\u4e006,doesnothaveembeddedspaces ");
props.put(" key1 test ", "key1, has leading and trailing spaces ");
props.put("key2 test", "key2, does not have leading or trailing spaces");
props.put("key3test", "key3,has,no,spaces");
props.put("key4 test ", "key4, does not have leading spaces ");
props.put("\t key5 test", "key5, has leading tab and no trailing spaces");
props.put(" key6 ", " key6,doesnothaveembeddedspaces ");
// Load properties with escape character '\' before space characters
Properties props1 = new Properties();
props1.load(getInputStream(propsCases));
check(props1, props);
// Test Reader
props1 = new Properties();
props1.load(getReader(propsCases, "UTF-8"));
check(props1, props);
// Also store the new properties to a storage
ByteArrayOutputStream baos = new ByteArrayOutputStream();
props.store(baos, "EscapeSpace Test");
props1 = new Properties();
props1.load(getInputStream(baos.toByteArray()));
check(props1, props);
// Reader should work as well
props1 = new Properties();
props1.load(getReader(baos.toByteArray(), "UTF-8"));
check(props1, props);
// Try Writer
baos = new ByteArrayOutputStream();
props.store(new OutputStreamWriter(baos, "UTF-8"),
"EscapeSpace Test");
props1 = new Properties();
props1.load(getReader(baos.toByteArray(), "UTF-8"));
check(props1, props);
report("EscapeSpace");
}
private static void LoadParsing() throws Exception {
File f = new File(System.getProperty("test.src", "."), "input.txt");
FileInputStream myIn = new FileInputStream(f);
Properties myProps = new Properties();
int size = 0;
try {
myProps.load(myIn);
} finally {
myIn.close();
}
if (!myProps.getProperty("key1").equals("value1") || // comment
!myProps.getProperty("key2").equals("abc\\defg\\") || // slash
!myProps.getProperty("key3").equals("value3") || // spaces in key
!myProps.getProperty("key4").equals(":value4") || // separator
// Does not recognize comments with leading spaces
(myProps.getProperty("#") != null) ||
// Wrong number of keys in Properties
((size=myProps.size()) != 4))
failCount++;
report("LoadParsing");
}
private static void SaveEncoding() throws Exception {
// Create a properties object to save
Properties props = new Properties();
props.put("signal", "val\u0019");
props.put("ABC 10", "value0");
props.put("\uff10test", "value\u0020");
props.put("key with spaces", "value with spaces");
props.put("key with space and Chinese_\u4e00", "valueWithChinese_\u4e00");
props.put(" special#=key ", "value3");
// Save the properties and check output
ByteArrayOutputStream baos = new ByteArrayOutputStream();
props.store(baos,"A test");
// Read properties file and verify \u0019
BufferedReader in = new BufferedReader(
new InputStreamReader(
new ByteArrayInputStream(
baos.toByteArray())));
String firstLine = "foo";
while (!firstLine.startsWith("signal"))
firstLine = in.readLine();
if (firstLine.length() != 16)
failCount++;
// Load the properties set
Properties newProps = new Properties();
newProps.load(getInputStream(baos.toByteArray()));
check(newProps, props);
// Store(Writer)/Load(Reader)
baos = new ByteArrayOutputStream();
props.store(new OutputStreamWriter(baos, "EUC_JP"), "A test");
newProps = new Properties();
newProps.load(getReader(baos.toByteArray(), "EUC_JP"));
check(newProps, props);
report("SaveEncoding");
}
/**
* This class tests to see if a properties object
* can successfully save and load properties
* using character encoding
*/
private static void SaveLoadBasher() throws Exception {
String keyValueSeparators = "=: \t\r\n\f#!\\";
Properties originalProps = new Properties();
Properties loadedProps = new Properties();
// Generate a unicode key and value
Random generator = new Random();
int achar=0;
StringBuffer aKeyBuffer = new StringBuffer(120);
StringBuffer aValueBuffer = new StringBuffer(120);
String aKey;
String aValue;
int maxKeyLen = 100;
int maxValueLen = 100;
int maxPropsNum = 300;
for (int x=0; x<maxPropsNum; x++) {
for(int y=0; y<maxKeyLen; y++) {
achar = generator.nextInt();
char test;
if(achar < 99999) {
test = (char)(achar);
}
else {
int zz = achar % 10;
test = keyValueSeparators.charAt(zz);
}
if (Character.isHighSurrogate(test)) {
aKeyBuffer.append(test);
aKeyBuffer.append('\udc00');
y++;
} else if (Character.isLowSurrogate(test)) {
aKeyBuffer.append('\ud800');
aKeyBuffer.append(test);
y++;
} else
aKeyBuffer.append(test);
}
aKey = aKeyBuffer.toString();
for(int y=0; y<maxValueLen; y++) {
achar = generator.nextInt();
char test = (char)(achar);
if (Character.isHighSurrogate(test)) {
aKeyBuffer.append(test);
aKeyBuffer.append('\udc00');
y++;
} else if (Character.isLowSurrogate(test)) {
aKeyBuffer.append('\ud800');
aKeyBuffer.append(test);
y++;
} else {
aValueBuffer.append(test);
}
}
aValue = aValueBuffer.toString();
// Attempt to add to original
try {
originalProps.put(aKey, aValue);
}
catch (IllegalArgumentException e) {
System.err.println("disallowing...");
}
aKeyBuffer.setLength(0);
aValueBuffer.setLength(0);
}
// Store(OutputStream)/Load(InputStream)
ByteArrayOutputStream baos = new ByteArrayOutputStream();
originalProps.store(baos, "test properties");
loadedProps.load(getInputStream(baos.toByteArray()));
check(loadedProps, originalProps);
// Store(Writer)/Load(Reader)
baos = new ByteArrayOutputStream();
originalProps.store(new OutputStreamWriter(baos, "UTF-8"),
"test properties");
loadedProps.load(getReader(baos.toByteArray(), "UTF-8"));
check(loadedProps, originalProps);
report("SaveLoadBasher");
}
/* Note: this regression test only detects incorrect line
* separator on platform running the test
*/
private static void SaveSeparator() throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Properties props = new Properties();
props.store(baos, "A test");
// Examine the result to verify that line.separator was used
String theSeparator = System.getProperty("line.separator");
String content = baos.toString();
if (!content.endsWith(theSeparator))
failCount++;
// store(Writer)
baos = new ByteArrayOutputStream();
props.store(new OutputStreamWriter(baos, "UTF-8"), "A test");
content = baos.toString();
if (!content.endsWith(theSeparator))
failCount++;
report("SaveSeparator");
}
// Ensure that the save method doesn't close its output stream
private static void SaveClose() throws Exception {
Properties p = new Properties();
p.put("Foo", "Bar");
class MyOS extends ByteArrayOutputStream {
boolean closed = false;
public void close() throws IOException {
this.closed = true;
}
}
MyOS myos = new MyOS();
p.store(myos, "Test");
if (myos.closed)
failCount++;
p.store(new OutputStreamWriter(myos, "UTF-8"), "Test");
if (myos.closed)
failCount++;
report ("SaveClose");
}
private static void UnicodeEscape() throws Exception {
checkMalformedUnicodeEscape("b=\\u012\n");
checkMalformedUnicodeEscape("b=\\u01\n");
checkMalformedUnicodeEscape("b=\\u0\n");
checkMalformedUnicodeEscape("b=\\u\n");
checkMalformedUnicodeEscape("a=\\u0123\nb=\\u012\n");
checkMalformedUnicodeEscape("a=\\u0123\nb=\\u01\n");
checkMalformedUnicodeEscape("a=\\u0123\nb=\\u0\n");
checkMalformedUnicodeEscape("a=\\u0123\nb=\\u\n");
checkMalformedUnicodeEscape("b=\\u012xyz\n");
checkMalformedUnicodeEscape("b=x\\u012yz\n");
checkMalformedUnicodeEscape("b=xyz\\u012\n");
}
private static void checkMalformedUnicodeEscape(String propString) throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(baos);
osw.write(propString);
osw.close();
Properties props = new Properties();
boolean failed = true;
try {
props.load(getInputStream(baos.toByteArray()));
} catch (IllegalArgumentException iae) {
failed = false;
}
if (failed)
failCount++;
failed = true;
props = new Properties();
try {
props.load(getReader(baos.toByteArray(), "UTF-8"));
} catch (IllegalArgumentException iae) {
failed = false;
}
if (failed)
failCount++;
report("UnicodeEscape");
}
private static void SaveComments() throws Exception {
String ls = System.getProperty("line.separator");
String[] input = new String[] {
"Comments with \u4e2d\u6587\u6c49\u5b57 included",
"Comments with \n Second comments line",
"Comments with \n# Second comments line",
"Comments with \n! Second comments line",
"Comments with last character is \n",
"Comments with last character is \r\n",
"Comments with last two characters are \n\n",
"Comments with last four characters are \r\n\r\n",
"Comments with \nkey4=value4",
"Comments with \n#key4=value4"};
String[] output = new String[] {
"#Comments with \\u4E2D\\u6587\\u6C49\\u5B57 included" + ls,
"#Comments with " + ls + "# Second comments line" + ls,
"#Comments with " + ls + "# Second comments line" + ls,
"#Comments with " + ls + "! Second comments line" + ls,
"#Comments with last character is " + ls+"#"+ls,
"#Comments with last character is " + ls+"#"+ls,
"#Comments with last two characters are " + ls+"#"+ls+"#"+ls,
"#Comments with last four characters are " + ls+"#"+ls+"#"+ls};
Properties props = new Properties();
ByteArrayOutputStream baos;
int i = 0;
for (i = 0; i < output.length; i++) {
baos = new ByteArrayOutputStream();
props.store(baos, input[i]);
String result = baos.toString("iso8859-1");
if (result.indexOf(output[i]) == -1) {
failCount++;
}
}
props.put("key1", "value1");
props.put("key2", "value2");
props.put("key3", "value3");
for (; i < input.length; i++) {
baos = new ByteArrayOutputStream();
props.store(baos, input[i]);
Properties propsNew = new Properties();
propsNew.load(getInputStream(baos.toByteArray()));
check(propsNew, props);
baos = new ByteArrayOutputStream();
props.store(new OutputStreamWriter(baos, "UTF-8"),
input[i]);
propsNew = new Properties();
propsNew.load(getReader(baos.toByteArray(), "UTF-8"));
check(propsNew, props);
}
report("SaveComments");
}
}

View file

@ -0,0 +1,74 @@
/*
* 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.
*/
/*
* @test
* @bug 4034428
* @summary Test for leading space in values output from properties
*/
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;
/**
* This class tests to see if the properties object saves
* leading space in the value of a property as it should
* do according to the JLS
*/
public class Save {
public static void main(String argv[]) {
int testSucceeded=0;
FileOutputStream myOutput;
// create a properties object to save
Properties myProperties = new Properties();
String value = " spacesfirst";
myProperties.put("atest", value);
try {
// save the object and check output
myOutput = new FileOutputStream("testout");
myProperties.store(myOutput,"A test");
myOutput.close();
//load the properties set
FileInputStream myIn = new FileInputStream("testout");
Properties myNewProps = new Properties();
try {
myNewProps.load(myIn);
} finally {
myIn.close();
}
//check the results
String newValue = (String) myNewProps.get("atest");
if (!newValue.equals(value))
throw new RuntimeException(
"Properties does not save leading spaces in values correctly.");
} catch (IOException e) { //do nothing
}
}
}

View file

@ -0,0 +1,64 @@
/*
* 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.
*/
/*
* @test
* @bug 4095273
* @summary Ensure that the save method doesn't close its output stream
* @author Mark Reinhold
*/
import java.util.Properties;
import java.io.OutputStream;
import java.io.FilterOutputStream;
import java.io.IOException;
public class SaveClose {
static class O extends FilterOutputStream {
boolean closed = false;
O(OutputStream o) {
super(o);
}
public void close() throws IOException {
this.closed = true;
}
}
public static void main(String argv[]) throws Exception {
Properties p = new Properties();
p.put("Foo", "Bar");
O o = new O(System.err);
p.store(o, "Test");
if (o.closed)
throw new Exception("Properties.save closed its output stream");
}
}

View file

@ -0,0 +1,97 @@
/*
* 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.
*/
/*
* @test
* @bug 5087448
* @summary Verify that property.save saves comments correctly
*/
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Properties;
public class SaveComments {
public static void main(String[] argv) throws IOException {
String ls = System.getProperty("line.separator");
String[] input = new String[] {
"Comments with \u4e2d\u6587\u6c49\u5b57 included",
"Comments with \n Second comments line",
"Comments with \n# Second comments line",
"Comments with \n! Second comments line",
"Comments with last character is \n",
"Comments with last character is \r\n",
"Comments with last two characters are \n\n",
"Comments with last four characters are \r\n\r\n",
"Comments with \nkey4=value4",
"Comments with \n#key4=value4"};
String[] output = new String[] {
"#Comments with \\u4E2D\\u6587\\u6C49\\u5B57 included" + ls,
"#Comments with " + ls + "# Second comments line" + ls,
"#Comments with " + ls + "# Second comments line" + ls,
"#Comments with " + ls + "! Second comments line" + ls,
"#Comments with last character is " + ls+"#"+ls,
"#Comments with last character is " + ls+"#"+ls,
"#Comments with last two characters are " + ls+"#"+ls+"#"+ls,
"#Comments with last four characters are " + ls+"#"+ls+"#"+ls};
Properties props = new Properties();
boolean failed = false;
int i = 0;
for (i = 0; i < output.length; i++) {
ByteArrayOutputStream baos = new ByteArrayOutputStream(200);
props.store(baos, input[i]);
String result = baos.toString("iso8859-1");
if (result.indexOf(output[i]) == -1) {
System.out.println("Wrong \"store()\" output:");
System.out.println(result);
failed = true;
}
}
props.put("key1", "value1");
props.put("key2", "value2");
props.put("key3", "value3");
for (; i < input.length; i++) {
ByteArrayOutputStream baos = new ByteArrayOutputStream(200);
props.store(baos, input[i]);
Properties propsNew = new Properties();
propsNew.load(new ByteArrayInputStream(baos.toByteArray()));
/*
Set<Map.Entry<Object, Object>> kvsetNew = propsNew.entrySet();
Set<Map.Entry<Object, Object>> kvset = props.entrySet();
if (!kvsetNew.containsAll(kvset) || !kvset.containsAll(kvsetNew)) {
*/
if (!props.equals (propsNew)) {
System.out.println("Wrong output:");
System.out.println(baos.toString("iso8859-1"));
failed = true;
}
}
if (failed)
throw new RuntimeException("Incorrect Properties Comment Output.");
}
}

View file

@ -0,0 +1,94 @@
/*
* 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.
*/
/*
* @test
* @bug 4026910 4011163 4077980 4096786 4213537
* @summary Test for saving and loading encoded keys and values
*/
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Properties;
/**
* This class tests to see if the properties object saves
* and loads keys and values properly
*/
public class SaveEncoding {
public static void main(String argv[]) {
int testSucceeded=0;
FileOutputStream myOutput;
// Create a properties object to save
Properties myProperties = new Properties();
myProperties.put("signal", "val\u0019");
myProperties.put("ABC 10", "value0");
myProperties.put("\uff10test", "value\u0020");
myProperties.put("key with spaces", "value with spaces");
myProperties.put(" special#=key ", "value3");
try {
// Destroy old test file if any
File myFile = new File("testout");
myFile.delete();
// Save the object and check output
myOutput = new FileOutputStream("testout");
myProperties.store(myOutput,"A test");
myOutput.close();
// Read properties file and verify \u0019
FileInputStream inFile = new FileInputStream("testout");
BufferedReader in = new BufferedReader(
new InputStreamReader(inFile));
String firstLine = "foo";
while (!firstLine.startsWith("signal"))
firstLine = in.readLine();
inFile.close();
if (firstLine.length() != 16)
throw new RuntimeException(
"Incorrect storage of values < 32.");
// Load the properties set
FileInputStream myIn = new FileInputStream("testout");
Properties myNewProps = new Properties();
try {
myNewProps.load(myIn);
} finally {
myIn.close();
}
// Check the results
if (!myNewProps.equals(myProperties))
throw new RuntimeException(
"Properties is not character encoding safe.");
} catch (IOException e) { // Do nothing
}
}
}

View file

@ -0,0 +1,117 @@
/*
* 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.
*/
/*
* @test
* @bug 4077980 4011163 4096786 4075955
* @summary Test properties save and load methods
* @key randomness
*/
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Properties;
import java.util.Random;
/**
* This class tests to see if a properties object
* can successfully save and load properties
* using character encoding
*/
public class SaveLoadBasher {
private static String keyValueSeparators = "=: \t\r\n\f#!\\";
public static void main(String[] args) throws Exception {
Properties originalProps = new Properties();
Properties loadedProps = new Properties();
// Generate a unicode key and value
Random generator = new Random();
int achar=0;
StringBuffer aKeyBuffer = new StringBuffer(120);
StringBuffer aValueBuffer = new StringBuffer(120);
String aKey;
String aValue;
for (int x=0; x<300; x++) {
for(int y=0; y<100; y++) {
achar = generator.nextInt();
char test;
if(achar < 99999) {
test = (char)(achar);
}
else {
int zz = achar % 10;
test = keyValueSeparators.charAt(zz);
}
aKeyBuffer.append(test);
}
aKey = aKeyBuffer.toString();
for(int y=0; y<100; y++) {
achar = generator.nextInt();
char test = (char)(achar);
aValueBuffer.append(test);
}
aValue = aValueBuffer.toString();
// Attempt to add to original
try {
originalProps.put(aKey, aValue);
}
catch (IllegalArgumentException e) {
System.err.println("disallowing...");
}
aKeyBuffer.setLength(0);
aValueBuffer.setLength(0);
}
// Destroy old test file if it exists
File oldTestFile = new File("props3");
oldTestFile.delete();
// Save original
System.out.println("Saving...");
OutputStream out = new FileOutputStream("props3");
originalProps.store(out, "test properties");
out.close();
// Load in the set
System.out.println("Loading...");
InputStream in = new FileInputStream("props3");
try {
loadedProps.load(in);
} finally {
in.close();
}
// Compare results
if (!originalProps.equals(loadedProps))
throw new RuntimeException("Properties load and save failed");
}
}

View file

@ -0,0 +1,52 @@
/*
* 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.
*/
/*
* @test
* @bug 4062657
* @summary Verify that property.save uses local lineseparator
*/
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Properties;
/* Note: this regression test only detects incorrect line
* separator on platform running the test
*/
public class SaveSeparator {
public static void main(String[] argv) throws IOException {
// Save a property set
Properties myProps = new Properties();
ByteArrayOutputStream myOut = new ByteArrayOutputStream(40);
myProps.store(myOut, "A test");
// Examine the result to verify that line.separator was used
String theSeparator = System.getProperty("line.separator");
String content = myOut.toString();
if (!content.endsWith(theSeparator))
throw new RuntimeException("Incorrect Properties line separator.");
}
}

View file

@ -0,0 +1,65 @@
/*
* Copyright (c) 2018, 2025, 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 6199320 8347841
* @summary Properties.store() causes deadlock when concurrently calling TimeZone apis
* @run main/timeout=20 StoreDeadlock
* @author Xueming Shen
*/
import java.io.IOException;
import java.util.Properties;
import java.util.TimeZone;
public class StoreDeadlock {
public StoreDeadlock() {
Properties sysproperty = System.getProperties();
Thread1 t1 = new Thread1(sysproperty);
Thread2 t2 = new Thread2();
t1.start();
t2.start();
}
public static void main(String[] args) {
StoreDeadlock deadlock = new StoreDeadlock();
}
class Thread1 extends Thread {
Properties sp;
public Thread1(Properties p) {
sp = p;
}
public void run() {
try {
sp.store(System.out, null);
} catch (IOException e) {
System.out.println("IOException : " + e);
}
}
}
class Thread2 extends Thread {
public void run() {
System.out.println("tz=" + TimeZone.getTimeZone("America/Los_Angeles"));
}
}
}

View file

@ -0,0 +1,407 @@
/*
* Copyright (c) 2021, 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.test.lib.process.OutputAnalyzer;
import jdk.test.lib.process.ProcessTools;
import java.io.BufferedReader;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Instant;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Properties;
import java.util.TimeZone;
/*
* @test
* @summary Tests that the Properties.store() APIs generate output that is reproducible
* @bug 8231640 8282023 8316540
* @comment The test launches several processes and in the presence of -Xcomp it's too slow
* and thus causes timeouts
* @requires vm.compMode != "Xcomp"
* @library /test/lib
* @run driver StoreReproducibilityTest
*/
public class StoreReproducibilityTest {
private static final String DATE_FORMAT_PATTERN = "EEE MMM dd HH:mm:ss zzz uuuu";
private static final String SYS_PROP_JAVA_PROPERTIES_DATE = "java.properties.date";
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern(DATE_FORMAT_PATTERN, Locale.ROOT)
.withZone(ZoneOffset.UTC);
public static void main(final String[] args) throws Exception {
// test that store method uses the java.properties.date system property
testStoreUsesPropValue();
// free form non-date value for java.properties.date system property
testNonDateSysPropValue();
// blank value for java.properties.date system property
testBlankSysPropValue();
// empty value for java.properties.date system property
testEmptySysPropValue();
// value for java.properties.date system property contains line terminator characters
testMultiLineSysPropValue();
// value for java.properties.date system property contains backslash character
testBackSlashInSysPropValue();
}
/**
* Launches a Java program which is responsible for using Properties.store() to write out the
* properties to a file. The launched Java program is passed a value for the
* {@code java.properties.date} system property and the date comment written out
* to the file is expected to use this value.
* The program is launched multiple times with the same value for {@code java.properties.date}
* and the output written by each run of this program is verified to be exactly the same.
* Additionally, the date comment that's written out is verified to be the expected date that
* corresponds to the passed {@code java.properties.date}.
*/
private static void testStoreUsesPropValue() throws Exception {
final List<Path> storedFiles = new ArrayList<>();
final String sysPropVal = FORMATTER.format(Instant.ofEpochSecond(243535322));
for (int i = 0; i < 5; i++) {
final Path tmpFile = Files.createTempFile("8231640", ".props");
storedFiles.add(tmpFile);
final ProcessBuilder processBuilder = ProcessTools.createTestJavaProcessBuilder(
"-D" + SYS_PROP_JAVA_PROPERTIES_DATE + "=" + sysPropVal,
StoreTest.class.getName(),
tmpFile.toString(),
i % 2 == 0 ? "--use-outputstream" : "--use-writer");
executeJavaProcess(processBuilder);
assertExpectedComment(tmpFile, sysPropVal);
if (!StoreTest.propsToStore.equals(loadProperties(tmpFile))) {
throw new RuntimeException("Unexpected properties stored in " + tmpFile);
}
}
assertAllFileContentsAreSame(storedFiles, sysPropVal);
}
/**
* Launches a Java program which is responsible for using Properties.store() to write out the
* properties to a file. The launched Java program is passed a {@link String#isBlank() blank} value
* for the {@code java.properties.date} system property.
* It is expected and verified in this test that such a value for the system property
* will cause a comment line to be written out with only whitespaces.
* The launched program is expected to complete without any errors.
*/
private static void testBlankSysPropValue() throws Exception {
final List<Path> storedFiles = new ArrayList<>();
final String sysPropVal = " \t";
for (int i = 0; i < 2; i++) {
final Path tmpFile = Files.createTempFile("8231640", ".props");
storedFiles.add(tmpFile);
final ProcessBuilder processBuilder = ProcessTools.createTestJavaProcessBuilder(
"-D" + SYS_PROP_JAVA_PROPERTIES_DATE + "=" + sysPropVal,
StoreTest.class.getName(),
tmpFile.toString(),
i % 2 == 0 ? "--use-outputstream" : "--use-writer");
executeJavaProcess(processBuilder);
if (!StoreTest.propsToStore.equals(loadProperties(tmpFile))) {
throw new RuntimeException("Unexpected properties stored in " + tmpFile);
}
String blankCommentLine = findNthComment(tmpFile, 2);
if (blankCommentLine == null) {
throw new RuntimeException("Comment line representing the value of "
+ SYS_PROP_JAVA_PROPERTIES_DATE + " system property is missing in file " + tmpFile);
}
if (!blankCommentLine.isBlank()) {
throw new RuntimeException("Expected comment line to be blank but was " + blankCommentLine);
}
}
assertAllFileContentsAreSame(storedFiles, sysPropVal);
}
/**
* Launches a Java program which is responsible for using Properties.store() to write out the
* properties to a file. The launched Java program is passed a {@link String#isEmpty() empty} value
* for the {@code java.properties.date} system property.
* It is expected and verified in this test that such a value for the system property
* will cause the current date and time to be written out as a comment.
* The launched program is expected to complete without any errors.
*/
private static void testEmptySysPropValue() throws Exception {
for (int i = 0; i < 2; i++) {
final Path tmpFile = Files.createTempFile("8231640", ".props");
final ProcessBuilder processBuilder = ProcessTools.createTestJavaProcessBuilder(
"-D" + SYS_PROP_JAVA_PROPERTIES_DATE + "=",
"-Duser.timezone=UTC",
StoreTest.class.getName(),
tmpFile.toString(),
i % 2 == 0 ? "--use-outputstream" : "--use-writer");
Date launchedAt = new Date();
// wait for a second before launching so that we can then expect
// the date written out by the store() APIs to be "after" this launch date
Thread.sleep(1000);
executeJavaProcess(processBuilder);
if (!StoreTest.propsToStore.equals(loadProperties(tmpFile))) {
throw new RuntimeException("Unexpected properties stored in " + tmpFile);
}
assertCurrentDate(tmpFile, launchedAt);
}
}
/**
* Launches a Java program which is responsible for using Properties.store() to write out the
* properties to a file. The launched Java program is passed the {@code java.properties.date}
* system property with a value that doesn't represent a formatted date.
* It is expected and verified in this test that such a value for the system property
* will cause the comment to use that value verbatim. The launched program is expected to complete
* without any errors.
*/
private static void testNonDateSysPropValue() throws Exception {
final String sysPropVal = "foo-bar";
final List<Path> storedFiles = new ArrayList<>();
for (int i = 0; i < 2; i++) {
final Path tmpFile = Files.createTempFile("8231640", ".props");
storedFiles.add(tmpFile);
final ProcessBuilder processBuilder = ProcessTools.createTestJavaProcessBuilder(
"-D" + SYS_PROP_JAVA_PROPERTIES_DATE + "=" + sysPropVal,
StoreTest.class.getName(),
tmpFile.toString(),
i % 2 == 0 ? "--use-outputstream" : "--use-writer");
executeJavaProcess(processBuilder);
if (!StoreTest.propsToStore.equals(loadProperties(tmpFile))) {
throw new RuntimeException("Unexpected properties stored in " + tmpFile);
}
assertExpectedComment(tmpFile, sysPropVal);
}
assertAllFileContentsAreSame(storedFiles, sysPropVal);
}
/**
* Launches a Java program which is responsible for using Properties.store() to write out the
* properties to a file. The launched Java program is passed the {@code java.properties.date}
* system property with a value that has line terminator characters.
* It is expected and verified in this test that such a value for the system property
* will cause the comment written out to be multiple separate comments. The launched program is expected
* to complete without any errors.
*/
private static void testMultiLineSysPropValue() throws Exception {
final String[] sysPropVals = {"hello-world\nc=d", "hello-world\rc=d", "hello-world\r\nc=d"};
for (final String sysPropVal : sysPropVals) {
final List<Path> storedFiles = new ArrayList<>();
for (int i = 0; i < 2; i++) {
final Path tmpFile = Files.createTempFile("8231640", ".props");
storedFiles.add(tmpFile);
final ProcessBuilder processBuilder = ProcessTools.createTestJavaProcessBuilder(
"-D" + SYS_PROP_JAVA_PROPERTIES_DATE + "=" + sysPropVal,
StoreTest.class.getName(),
tmpFile.toString(),
i % 2 == 0 ? "--use-outputstream" : "--use-writer");
executeJavaProcess(processBuilder);
if (!StoreTest.propsToStore.equals(loadProperties(tmpFile))) {
throw new RuntimeException("Unexpected properties stored in " + tmpFile);
}
// verify this results in 2 separate comment lines in the stored file
String commentLine1 = findNthComment(tmpFile, 2);
String commentLine2 = findNthComment(tmpFile, 3);
if (commentLine1 == null || commentLine2 == null) {
throw new RuntimeException("Did not find the expected multi-line comments in " + tmpFile);
}
if (!commentLine1.equals("hello-world")) {
throw new RuntimeException("Unexpected comment line " + commentLine1 + " in " + tmpFile);
}
if (!commentLine2.equals("c=d")) {
throw new RuntimeException("Unexpected comment line " + commentLine2 + " in " + tmpFile);
}
}
assertAllFileContentsAreSame(storedFiles, sysPropVal);
}
}
/**
* Launches a Java program which is responsible for using Properties.store() to write out the
* properties to a file. The launched Java program is passed the {@code java.properties.date}
* system property with a value that has backslash character.
* It is expected and verified in this test that such a value for the system property
* will not cause any malformed comments or introduce any new properties in the stored content.
* The launched program is expected to complete without any errors.
*/
private static void testBackSlashInSysPropValue() throws Exception {
final String[] sysPropVals = {"\\hello-world", "hello-world\\", "hello-world\\c=d",
"newline-plus-backslash\\\nc=d"};
for (final String sysPropVal : sysPropVals) {
final List<Path> storedFiles = new ArrayList<>();
for (int i = 0; i < 2; i++) {
final Path tmpFile = Files.createTempFile("8231640", ".props");
storedFiles.add(tmpFile);
final ProcessBuilder processBuilder = ProcessTools.createTestJavaProcessBuilder(
"-D" + SYS_PROP_JAVA_PROPERTIES_DATE + "=" + sysPropVal,
StoreTest.class.getName(),
tmpFile.toString(),
i % 2 == 0 ? "--use-outputstream" : "--use-writer");
executeJavaProcess(processBuilder);
if (!StoreTest.propsToStore.equals(loadProperties(tmpFile))) {
throw new RuntimeException("Unexpected properties stored in " + tmpFile);
}
String commentLine1 = findNthComment(tmpFile, 2);
if (commentLine1 == null) {
throw new RuntimeException("Did not find the expected comment line in " + tmpFile);
}
if (sysPropVal.contains("newline-plus-backslash")) {
if (!commentLine1.equals("newline-plus-backslash\\")) {
throw new RuntimeException("Unexpected comment line " + commentLine1 + " in " + tmpFile);
}
// we expect this specific system property value to be written out into 2 separate comment lines
String commentLine2 = findNthComment(tmpFile, 3);
if (commentLine2 == null) {
throw new RuntimeException(sysPropVal + " was expected to be split into 2 comment line, " +
"but wasn't, in " + tmpFile);
}
if (!commentLine2.equals("c=d")) {
throw new RuntimeException("Unexpected comment line " + commentLine2 + " in " + tmpFile);
}
} else {
if (!commentLine1.equals(sysPropVal)) {
throw new RuntimeException("Unexpected comment line " + commentLine1 + " in " + tmpFile);
}
}
}
assertAllFileContentsAreSame(storedFiles, sysPropVal);
}
}
// launches the java process and waits for it to exit. throws an exception if exit value is non-zero
private static void executeJavaProcess(ProcessBuilder pb) throws Exception {
final OutputAnalyzer outputAnalyzer = ProcessTools.executeProcess(pb);
try {
outputAnalyzer.shouldHaveExitValue(0);
} finally {
// print out any stdout/err that was generated in the launched program
outputAnalyzer.reportDiagnosticSummary();
}
}
// Properties.load() from the passed file and return the loaded Properties instance
private static Properties loadProperties(final Path file) throws IOException {
final Properties props = new Properties();
props.load(Files.newBufferedReader(file));
return props;
}
/**
* Verifies that the comment in the {@code destFile} is same as {@code expectedComment},
* instead of the default date comment.
*/
private static void assertExpectedComment(final Path destFile,
final String expectedComment) throws Exception {
final String actualComment = findNthComment(destFile, 2);
if (actualComment == null) {
throw new RuntimeException("Comment \"" + expectedComment + "\" not found in stored properties " + destFile);
}
if (!expectedComment.equals(actualComment)) {
throw new RuntimeException("Expected comment \"" + expectedComment + "\" but found \"" + actualComment + "\" " +
"in stored properties " + destFile);
}
}
/**
* Verifies that the date comment in the {@code destFile} can be parsed using the
* "EEE MMM dd HH:mm:ss zzz uuuu" format and the time represented by it is {@link Date#after(Date) after}
* the passed {@code date}
* The JVM runtime to invoke this method should set the time zone to UTC, i.e, specify
* "-Duser.timezone=UTC" at the command line. Otherwise, it will fail with some time
* zones that have ambiguous short names, such as "IST"
*/
private static void assertCurrentDate(final Path destFile, final Date date) throws Exception {
final String dateComment = findNthComment(destFile, 2);
if (dateComment == null) {
throw new RuntimeException("Date comment not found in stored properties " + destFile);
}
System.out.println("Found date comment " + dateComment + " in file " + destFile);
final Date parsedDate;
try {
Instant instant = Instant.from(FORMATTER.parse(dateComment));
parsedDate = new Date(instant.toEpochMilli());
} catch (DateTimeParseException pe) {
throw new RuntimeException("Unexpected date " + dateComment + " in stored properties " + destFile, pe);
}
if (!parsedDate.after(date)) {
throw new RuntimeException("Expected date comment " + dateComment + " to be after " + date
+ " but was " + parsedDate);
}
}
// returns the "Nth" comment from the file. Comment index starts from 1.
private static String findNthComment(Path file, int commentIndex) throws IOException {
List<String> comments = new ArrayList<>();
try (final BufferedReader reader = Files.newBufferedReader(file)) {
String line;
while ((line = reader.readLine()) != null) {
if (line.startsWith("#")) {
comments.add(line.substring(1));
if (comments.size() == commentIndex) {
return comments.get(commentIndex - 1);
}
}
}
}
return null;
}
// verifies the byte equality of the contents in each of the files
private static void assertAllFileContentsAreSame(final List<Path> files,
final String sysPropVal) throws Exception {
final byte[] file1Contents = Files.readAllBytes(files.get(0));
for (int i = 1; i < files.size(); i++) {
final byte[] otherFileContents = Files.readAllBytes(files.get(i));
if (!Arrays.equals(file1Contents, otherFileContents)) {
throw new RuntimeException("Properties.store() did not generate reproducible content when " +
SYS_PROP_JAVA_PROPERTIES_DATE + " was set to " + sysPropVal);
}
}
}
static class StoreTest {
private static final Properties propsToStore = new Properties();
static {
propsToStore.setProperty("a", "b");
}
/**
* Uses Properties.store() APIs to store the properties into file
*/
public static void main(final String[] args) throws Exception {
final Path destFile = Path.of(args[0]);
final String comment = "some user specified comment";
System.out.println("Current default timezone is " + TimeZone.getDefault());
if (args[1].equals("--use-outputstream")) {
try (var os = Files.newOutputStream(destFile)) {
propsToStore.store(os, comment);
}
} else {
try (var br = Files.newBufferedWriter(destFile)) {
propsToStore.store(br, comment);
}
}
}
}
}

View file

@ -0,0 +1,173 @@
/*
* 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.
*/
/*
* @test
* @bug 6253413 8059361
* @summary Test for Properties.stringPropertyNames() if the system
* properties contain another list of properties as the defaults.
* @author Mandy Chung
*
* @run build StringPropertyNames
* @run main StringPropertyNames
*/
import java.util.Properties;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Set;
public class StringPropertyNames {
private static int NUM_SHARE_PROPS = 2;
private static int NUM_PROPS1 = 3;
private static int NUM_PROPS2 = 5;
private static String KEY = "good.property.";
private static String VALUE = "good.value.";
public static void main(String[] argv) throws Exception {
Properties props1 = new Properties();
Properties props2 = new Properties(props1);
// add several new properties
for (int i = 0; i < NUM_PROPS1; i++) {
props1.put(KEY + "1." + i, VALUE + "1." + i);
}
for (int i = 0; i < NUM_PROPS2; i++) {
props2.put(KEY + "2." + i, VALUE + "2." + i);
}
// add the same properties in both props1 and props2
for (int i = 0; i < NUM_SHARE_PROPS; i++) {
props1.put(KEY + i, VALUE + "1." + i);
props2.put(KEY + i, VALUE + "2." + i);
}
checkProperties(props1,
NUM_PROPS1 + NUM_SHARE_PROPS, // size of props1
NUM_PROPS1 + NUM_SHARE_PROPS, // num of string keys
NUM_PROPS1 + NUM_SHARE_PROPS, // num of keys in propertyName(),
false);
checkProperties(props2,
NUM_PROPS2 + NUM_SHARE_PROPS, // size of props2
NUM_PROPS1 + NUM_PROPS2 + NUM_SHARE_PROPS, // num of string keys
NUM_PROPS1 + NUM_PROPS2 + NUM_SHARE_PROPS, // num of keys in propertyName(),
false);
// Add non-String value
props1.put(KEY + "9", new Integer(4));
checkProperties(props1,
NUM_PROPS1 + NUM_SHARE_PROPS + 1, // size of props1
NUM_PROPS1 + NUM_SHARE_PROPS, // num of string keys
NUM_PROPS1 + NUM_SHARE_PROPS + 1, // num of keys in propertyName(),
false);
checkProperties(props2,
NUM_PROPS2 + NUM_SHARE_PROPS, // size of props2
NUM_PROPS1 + NUM_PROPS2 + NUM_SHARE_PROPS, // num of string keys
NUM_PROPS1 + NUM_PROPS2 + NUM_SHARE_PROPS + 1, // num of keys in propertyName(),
false);
Object v = props1.remove(KEY + "9");
if (v == null) {
throw new RuntimeException("Test Failed: " +
"Key " + KEY + "9" + " not found");
}
// Add a non-String key
props1.put(new Integer(5), "good.value.5");
props2.put(new Object(), new Object());
checkProperties(props1,
NUM_PROPS1 + NUM_SHARE_PROPS + 1, // size of props1
NUM_PROPS1 + NUM_SHARE_PROPS, // num of string keys
NUM_PROPS1 + NUM_SHARE_PROPS + 1, // num of keys in propertyName(),
true);
checkProperties(props2,
NUM_PROPS2 + NUM_SHARE_PROPS + 1, // size of props2
NUM_PROPS1 + NUM_PROPS2 + NUM_SHARE_PROPS, // num of string keys
NUM_PROPS1 + NUM_PROPS2 + NUM_SHARE_PROPS + 2, // num of keys in propertyName(),
true);
System.out.println("Test passed.");
}
private static void checkProperties(Properties props,
int propSize,
int numStringKeys,
int enumerateSize,
boolean hasNonStringKeys) {
// check the size of the properties
if (props.size() != propSize) {
throw new RuntimeException("Test Failed: " +
"Expected number of properties = " +
propSize + " but found = " + props.size());
}
// check the number of properties whose key and value
// are both strings
Set<String> keys = props.stringPropertyNames();
if (keys.size() != numStringKeys) {
throw new RuntimeException("Test Failed: " +
"Expected number of String keys = " +
numStringKeys + " but found = " + keys.size());
}
boolean cceThrown = false;
try {
// check the number of properties whose key are strings
// but its value can be anything in the current impl
int count = 0;
Enumeration<?> e = props.propertyNames();
for (;e.hasMoreElements(); e.nextElement()) {
count++;
}
if (count != enumerateSize) {
throw new RuntimeException("Test Failed: " +
"Expected number of enumerated keys = " +
enumerateSize + " but found = " + count);
}
} catch (ClassCastException e) {
if (!hasNonStringKeys) {
RuntimeException re = new RuntimeException("Test Failed: " +
"ClassCastException is expected not to be thrown");
re.initCause(e);
throw re;
}
cceThrown = true;
}
if ((hasNonStringKeys && !cceThrown)) {
throw new RuntimeException("Test Failed: " +
"ClassCastException is expected to be thrown");
}
// make sure the set cannot be modified
try {
keys.add("xyzzy");
throw new RuntimeException("Test Failed: " +
"add() should have thrown UnsupportedOperationException");
} catch (UnsupportedOperationException ignore) { }
Iterator<String> it = keys.iterator();
if (it.hasNext()) {
try {
keys.remove(it.next());
throw new RuntimeException("Test Failed: " +
"remove() should have thrown UnsupportedOperationException");
} catch (UnsupportedOperationException ignore) { }
}
}
}

View file

@ -0,0 +1,59 @@
/*
* 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.
*/
/*
* @test
* @bug 4792682
* @summary Test for correct exception with a short unicode escape
*/
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.InputStream;
import java.util.Properties;
public class UnicodeEscape {
public static void main(String argv[]) throws Exception {
save();
load();
}
private static void save() throws Exception {
FileWriter out = new FileWriter("a.properties");
out.write("a=b\nb=\\u0\n");
out.close();
}
private static void load() throws Exception {
Properties properties = new Properties();
InputStream in = new FileInputStream("a.properties");
try {
properties.load(in);
} catch (IllegalArgumentException iae) {
// Correct result
} finally {
in.close();
}
}
}

View file

@ -0,0 +1,123 @@
/*
* 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.
*/
/*
* @test
* @bug 4749531 5015114 5055738
* @summary Test properties XML save and load methods
* @key randomness
*/
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Properties;
import java.util.Random;
/**
* This class tests to see if a properties object
* can successfully save and load properties in XML
*/
public class XMLSaveLoadBasher {
private static final int MAX_KEY_SIZE = 120;
private static final int MIN_KEY_SIZE = 1;
private static final int MAX_VALUE_SIZE = 120;
private static final int MIN_VALUE_SIZE = 0;
public static void main(String[] args) throws Exception {
testSaveLoad("UTF-8", "test save");
testSaveLoad("UTF-8", null);
testSaveLoad("ISO-8859-1", "test save");
testSaveLoad("KOI8-R", "test save");
}
private static void testSaveLoad(String encoding, String comment)
throws Exception
{
Properties originalProps = new Properties();
Properties loadedProps = new Properties();
// Generate a unicode key and value
Random generator = new Random();
for (int x=0; x<10; x++) {
String aKey;
String aValue;
// Assumes MAX_KEY_SIZE >> MIN_KEY_SIZE
int keyLen = generator.nextInt(MAX_KEY_SIZE - MIN_KEY_SIZE + 1) +
MIN_KEY_SIZE;
int valLen = generator.nextInt(
MAX_VALUE_SIZE - MIN_VALUE_SIZE + 1) + MIN_VALUE_SIZE;
StringBuffer aKeyBuffer = new StringBuffer(keyLen);
StringBuffer aValueBuffer = new StringBuffer(valLen);
for(int y=0; y<keyLen; y++) {
char test = (char)(generator.nextInt(6527) + 32);
aKeyBuffer.append(test);
}
aKey = aKeyBuffer.toString();
for(int y=0; y<valLen; y++) {
char test = (char)(generator.nextInt(6527) + 32);
aValueBuffer.append(test);
}
aValue = aValueBuffer.toString();
// Attempt to add to original
try {
originalProps.setProperty(aKey, aValue);
} catch (IllegalArgumentException e) {
System.err.println("disallowing...");
}
}
//originalProps.put("squid", "kraken");
//originalProps.put("demon", "furnace");
// Destroy old test file if it exists
File oldTestFile = new File("props3");
oldTestFile.delete();
// Save original
System.err.println("Saving...");
try (OutputStream out = new FileOutputStream("props3")) {
originalProps.storeToXML(out, comment, encoding);
}
// Load in the set
System.err.println("Loading...");
try (InputStream in = new FileInputStream("props3")) {
loadedProps.loadFromXML(in);
}
// Compare results
if (!originalProps.equals(loadedProps))
throw new RuntimeException("Properties load and save failed");
}
}

View file

@ -0,0 +1,10 @@
# this input file is used for the LoadParsing.java test
# comment ending with slash \
key1 = value1
key2 = abc\\\
def\
g\\
key3 = value3
key4 = :value4
# comment with leading space
#key = comment without line terminator

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<!-- XML tags are case sensitve, opening and closing tags must use same case -->
<properties>
<entry key="foo">bar</entry>
<entry key="gus">baz</entry>
</PROPERTIES>

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE namevaluepairs SYSTEM "http://java.sun.com/dtd/properties.dtd">
<!-- The root element for a XML properties document is properties -->
<properties>
<entry key="foo">bar</entry>
<entry key="gus">baz</entry>
</properties>

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf8" standalone="no"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<!-- XML tags are case sensitve, the root element should have been in lower case -->
<Properties>
<comment>comment</comment>
<entry key="firstKey">value of the first key</entry>
</Properties>

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf8" standalone="no"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<!-- The dtd allows zero or one comment element -->
<properties>
<comment>comment1</comment>
<comment>comment2</comment>
<entry key="firstKey">value of the first key</entry>
</properties>

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf8" standalone="no"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<!-- The dtd requires a properties root, but not element -->
<properties>
<comment>comment</comment>
<properties>
<entry key="firstKey">value of the first key</entry>
</properties>
</properties>

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf8" standalone="no"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<!-- The dtd requires 'entry' element, 'Entry' is illegal -->
<properties>
<comment>comment</comment>
<Entry key="firstKey">value of the first key</Entry>
</properties>

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf8" standalone="no"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<!-- 'entry1' is illegal as per the dtd -->
<properties>
<comment>comment1</comment>
<entry key="firstkey">value of the first key</entry>
<entry1 key="secondkey">value of the second key</entry1>
</properties>

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf8" standalone="no"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<!-- 'key' attribute is expected. 'key1' is mistyped -->
<properties>
<comment>comment1</comment>
<entry key1="typo">value of the first key</entry>
</properties>

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<!-- XML elements must having a closing tag -->
<properties>
<entry key="foo">bar</entry>
<entry key="gus">baz</entry>

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- An XML properties document has the DOCTYPE declaration with the properties root element -->
<properties>
<entry key="foo">bar</entry>
<entry key="gus">baz</entry>
</properties>

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf8" standalone="no"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<!-- namespace is not supported -->
<javautil:properties xmlns:javautil="http://java.sun.com/java/util/Properties">
<javautil:comment>comment1</javautil:comment>
<javautil:entry key="firstkey">value of the first key</javautil:entry>
<javautil:entry key="secondkey">value of the second key</javautil:entry>
</javautil:properties>

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<!-- XML documents must have a root element -->

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<!-- XML attribute values must be quoted -->
<properties>
<entry key=foo>bar</entry>
<entry key=gus>baz</entry>
</properties>

View file

@ -0,0 +1,5 @@
This directory contains test cases for the LoadAndStoreXML test case. Each file
in this directory should be a malformed XML document that should cause the
java.util.Properties loadFromXML method to throw InvalidPropertiesFormatException.

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd"
[<!ENTITY intEnt 'value3'> ]>
<?PITarget PIContent?>
<properties>
<comment>Property With Other Encoding</comment>
<entry key="Key1">value1</entry>
<entry key="Key2"><![CDATA[<value2>]]></entry>
<entry key="Key3">&intEnt;</entry>
</properties>

View file

@ -0,0 +1,35 @@
# testcases
key0=abcd\
\
key1=value1
key2 \= abcde
key3
#key4=abcde
key5 ===Arial,ANSI_CHARSET
key6= WingDings,SYMBOL_CHARSET \\\
abc
key7 Symbol,SYMBOL_CHARSET \
keyabcdef
key8notassign abcdef
key9\ Term=ABCDE
\\:key10=bar
\\\\:key11=bar2
\\\:key12=bar2
key13dialog.3=
key14_asdfa
key15 \ abcdef
key16\ b= \ abcdef
key17=\
#bar\
baz

View file

@ -0,0 +1,35 @@
# testcases
key0=abcd\
\
key1=value1
key2 \= abcde
key3
#key4=abcde
key5 ===Arial,ANSI_CHARSET
key6= WingDings,SYMBOL_CHARSET \\\
abc
key7 Symbol,SYMBOL_CHARSET \
keyabcdef
key8notassign abcdef
key9\ Term=ABCDE
\\:key10=bar
\\\\:key11=bar2
\\\:key12=bar2
key13dialog.3=
key14_asdfa
key15 \ abcdef
key16\ b= \ abcdef
key17=\
#bar\
baz

View file

@ -0,0 +1,4 @@
#
key1=-monotype-timesnewroman-regular-r---*-%d-*-*-p-*-iso8859-1serif.1a-monotype-timesnewroman-regular-r-normal--*-%d-*-*-p-*-iso8859-2serif.2a-b&h-LucidaBrightLat4-Normal-r-normal--*-%d-*-*-p-*-iso8859-4serif.3a-monotype-times-regular-r-normal--*-%d-*-*-p-*-iso8859-5serif.4a-monotype-timesnewromangreek-regular-r-normal--*-%d-*-*-p-*-iso8859-7serif.5a-monotype-times-regular-r-normal--*-%d-*-*-p-*-iso8859-9serif.6a-monotype-times-regular-r-normal--*-%d-*-*-p-*-iso8859-15serif.7a-hanyi-ming-medium-r-normal--*-%d-*-*-m-*-big5-1serif.8a-sun-song-medium-r-normal--*-%d-*-*-c-*-gb2312.1980-0serif.9a-ricoh-hgminchol-medium-r-normal--*-%d-*-*-m-*-jisx0201.1976-0serif.10a-ricoh-hgminchol-medium-r-normal--*-%d-*-*-m-*-jisx0208.1983-0serif.11a-ricoh-heiseimin-w3-r-normal--*-%d-*-*-m-*-jisx0212.1990-0serif.12a-hanyang-myeongjo-medium-r-normal--*-%d-*-*-m-*-ksc5601.1992-3serif.13a-urw-itczapfdingbats-medium-r-normal--*-%d-*-*-p-*-sun-fontspecificserif.14a-*-symbol-medium-r-normal--*-%d-*-*-p-*-sun-fontspecificbserif.italic.0=-monotype-timesbnewbroman-regular-i---*-%d-*-*-p-*-iso8859-1bserif.italic.1=-monotype-timesbnewbroman-regular-i-normal-italic-*-%d-*-*-p-*-iso8859-2
key2=-b&h-LucidaBrightLat4-normal-i-normal-Italic-*-%d-*-*-p-*-iso8859-4

View file

@ -0,0 +1,4 @@
#
key1=-monotype-timesnewroman-regular-r---*-%d-*-*-p-*-iso8859-1serif.1a-monotype-timesnewroman-regular-r-normal--*-%d-*-*-p-*-iso8859-2serif.2a-b&h-LucidaBrightLat4-Normal-r-normal--*-%d-*-*-p-*-iso8859-4serif.3a-monotype-times-regular-r-normal--*-%d-*-*-p-*-iso8859-5serif.4a-monotype-timesnewromangreek-regular-r-normal--*-%d-*-*-p-*-iso8859-7serif.5a-monotype-times-regular-r-normal--*-%d-*-*-p-*-iso8859-9serif.6a-monotype-times-regular-r-normal--*-%d-*-*-p-*-iso8859-15serif.7a-hanyi-ming-medium-r-normal--*-%d-*-*-m-*-big5-1serif.8a-sun-song-medium-r-normal--*-%d-*-*-c-*-gb2312.1980-0serif.9a-ricoh-hgminchol-medium-r-normal--*-%d-*-*-m-*-jisx0201.1976-0serif.10a-ricoh-hgminchol-medium-r-normal--*-%d-*-*-m-*-jisx0208.1983-0serif.11a-ricoh-heiseimin-w3-r-normal--*-%d-*-*-m-*-jisx0212.1990-0serif.12a-hanyang-myeongjo-medium-r-normal--*-%d-*-*-m-*-ksc5601.1992-3serif.13a-urw-itczapfdingbats-medium-r-normal--*-%d-*-*-p-*-sun-fontspecificserif.14a-*-symbol-medium-r-normal--*-%d-*-*-p-*-sun-fontspecificbserif.italic.0=-monotype-timesbnewbroman-regular-i---*-%d-*-*-p-*-iso8859-1bserif.italic.1=-monotype-timesbnewbroman-regular-i-normal-italic-*-%d-*-*-p-*-iso8859-2
key2=-b&h-LucidaBrightLat4-normal-i-normal-Italic-*-%d-*-*-p-*-iso8859-4

View file

@ -0,0 +1,29 @@
key1=\
-monotype-times new roman-regular-r---*-%d-*-*-p-*-iso8859-1, \
-monotype-times new roman-regular-r-normal--*-%d-*-*-p-*-iso8859-2, \
-b&h-LucidaBrightLat4-Normal-r-normal--*-%d-*-*-p-*-iso8859-4, \
-monotype-times-regular-r-normal--*-%d-*-*-p-*-iso8859-5, \
-monotype-times new roman greek-regular-r-normal--*-%d-*-*-p-*-iso8859-7, \
-monotype-times-regular-r-normal--*-%d-*-*-p-*-iso8859-9, \
-monotype-times-regular-r-normal--*-%d-*-*-p-*-iso8859-15, \
-hanyi-ming-medium-r-normal--*-%d-*-*-m-*-big5-1, \
-sun-song-medium-r-normal--*-%d-*-*-c-*-gb2312.1980-0, \
-ricoh-hg gothic b-medium-r-normal--*-%d-*-*-m-*-jisx0201.1976-0, \
-ricoh-hg gothic b-medium-r-normal-*-*-%d-*-*-m-*-jisx0208.1983-0, \
-ricoh-heiseimin-w3-r-normal--*-%d-*-*-m-*-jisx0212.1990-0, \
-hanyang-myeongjo-medium-r-normal--*-%d-*-*-m-*-ksc5601.1992-3
key2=\
-monotype-times new roman-regular-i---*-%d-*-*-p-*-iso8859-1, \
-monotype-times new roman-regular-i-normal-italic-*-%d-*-*-p-*-iso8859-2, \
-b&h-LucidaBrightLat4-normal-i-normal-Italic-*-%d-*-*-p-*-iso8859-4, \
-monotype-times-regular-i-normal-italic-*-%d-*-*-p-*-iso8859-5, \
-monotype-times new roman greek-regular-i-normal--*-%d-*-*-p-*-iso8859-7, \
-monotype-times-regular-i-normal-italic-*-%d-*-*-p-*-iso8859-9, \
-monotype-times-regular-i-normal--*-%d-*-*-p-*-iso8859-15, \
-hanyi-ming-medium-r-normal--*-%d-*-*-m-*-big5-1, \
-sun-song-medium-r-normal--*-%d-*-*-c-*-gb2312.1980-0, \
-ricoh-hg gothic b-medium-r-normal--*-%d-*-*-m-*-jisx0201.1976-0, \
-ricoh-hg gothic b-medium-r-normal-*-*-%d-*-*-m-*-jisx0208.1983-0, \
-ricoh-heiseimin-w3-r-normal--*-%d-*-*-m-*-jisx0212.1990-0, \
-hanyang-myeongjo-medium-r-normal--*-%d-*-*-m-*-ksc5601.1992-3