mirror of
https://github.com/openjdk/jdk.git
synced 2026-03-02 04:00:16 +00:00
8168075: Custom system class loader + security manager + malformed policy file = recursive initialization
Reviewed-by: mchung, mullan
This commit is contained in:
parent
cf31932ce4
commit
f3f3725fdd
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -32,7 +32,6 @@ import java.net.URL;
|
||||
import java.net.URI;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.*;
|
||||
import java.text.MessageFormat;
|
||||
import java.security.*;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.X509Certificate;
|
||||
@ -579,10 +578,9 @@ public class PolicyFile extends java.security.Policy {
|
||||
k.add(policy);
|
||||
return k;
|
||||
});
|
||||
MessageFormat form = new MessageFormat(ResourcesMgr.getString
|
||||
(POLICY + ".error.parsing.policy.message"));
|
||||
Object[] source = {policy, pe.getLocalizedMessage()};
|
||||
System.err.println(form.format(source));
|
||||
System.err.println(LocalizedMessage.getMessage
|
||||
(POLICY + ".error.parsing.policy.message", source));
|
||||
if (debug != null) {
|
||||
pe.printStackTrace();
|
||||
}
|
||||
@ -805,32 +803,30 @@ public class PolicyFile extends java.security.Policy {
|
||||
}
|
||||
}
|
||||
} catch (java.lang.reflect.InvocationTargetException ite) {
|
||||
MessageFormat form = new MessageFormat
|
||||
(ResourcesMgr.getString
|
||||
(POLICY +
|
||||
".error.adding.Permission.perm.message"));
|
||||
Object[] source = {pe.permission,
|
||||
ite.getTargetException().toString()};
|
||||
System.err.println(form.format(source));
|
||||
System.err.println(
|
||||
LocalizedMessage.getMessage(
|
||||
POLICY + ".error.adding.Permission.perm.message",
|
||||
source));
|
||||
} catch (Exception e) {
|
||||
MessageFormat form = new MessageFormat
|
||||
(ResourcesMgr.getString
|
||||
(POLICY +
|
||||
".error.adding.Permission.perm.message"));
|
||||
Object[] source = {pe.permission,
|
||||
e.toString()};
|
||||
System.err.println(form.format(source));
|
||||
System.err.println(
|
||||
LocalizedMessage.getMessage(
|
||||
POLICY + ".error.adding.Permission.perm.message",
|
||||
source));
|
||||
}
|
||||
}
|
||||
|
||||
// No need to sync because noone has access to newInfo yet
|
||||
newInfo.policyEntries.add(entry);
|
||||
} catch (Exception e) {
|
||||
MessageFormat form = new MessageFormat(ResourcesMgr.getString
|
||||
(POLICY
|
||||
+ ".error.adding.Entry.message"));
|
||||
Object[] source = {e.toString()};
|
||||
System.err.println(form.format(source));
|
||||
System.err.println(
|
||||
LocalizedMessage.getMessage(
|
||||
POLICY + ".error.adding.Entry.message",
|
||||
source));
|
||||
}
|
||||
if (debug != null)
|
||||
debug.println();
|
||||
@ -1803,29 +1799,29 @@ public class PolicyFile extends java.security.Policy {
|
||||
} else if (prefix.equalsIgnoreCase("alias")) {
|
||||
// get the suffix and perform keystore alias replacement
|
||||
if (colonIndex == -1) {
|
||||
MessageFormat form = new MessageFormat
|
||||
(ResourcesMgr.getString
|
||||
("alias.name.not.provided.pe.name."));
|
||||
Object[] source = {pe.name};
|
||||
throw new Exception(form.format(source));
|
||||
throw new Exception(
|
||||
LocalizedMessage.getMessage(
|
||||
"alias.name.not.provided.pe.name.",
|
||||
source));
|
||||
}
|
||||
suffix = value.substring(colonIndex+1);
|
||||
if ((suffix = getDN(suffix, keystore)) == null) {
|
||||
MessageFormat form = new MessageFormat
|
||||
(ResourcesMgr.getString
|
||||
("unable.to.perform.substitution.on.alias.suffix"));
|
||||
Object[] source = {value.substring(colonIndex+1)};
|
||||
throw new Exception(form.format(source));
|
||||
throw new Exception(
|
||||
LocalizedMessage.getMessage(
|
||||
"unable.to.perform.substitution.on.alias.suffix",
|
||||
source));
|
||||
}
|
||||
|
||||
sb.append(X500PRINCIPAL + " \"" + suffix + "\"");
|
||||
startIndex = e+2;
|
||||
} else {
|
||||
MessageFormat form = new MessageFormat
|
||||
(ResourcesMgr.getString
|
||||
("substitution.value.prefix.unsupported"));
|
||||
Object[] source = {prefix};
|
||||
throw new Exception(form.format(source));
|
||||
throw new Exception(
|
||||
LocalizedMessage.getMessage(
|
||||
"substitution.value.prefix.unsupported",
|
||||
source));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2039,7 +2035,7 @@ public class PolicyFile extends java.security.Policy {
|
||||
super(type);
|
||||
if (type == null) {
|
||||
throw new NullPointerException
|
||||
(ResourcesMgr.getString("type.can.t.be.null"));
|
||||
(LocalizedMessage.getMessage("type.can.t.be.null"));
|
||||
}
|
||||
this.type = type;
|
||||
this.name = name;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -26,18 +26,14 @@
|
||||
package sun.security.provider;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.RuntimePermission;
|
||||
import java.net.SocketPermission;
|
||||
import java.net.URL;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.Principal;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.*;
|
||||
import javax.security.auth.x500.X500Principal;
|
||||
|
||||
import sun.security.util.Debug;
|
||||
import sun.security.util.PropertyExpander;
|
||||
import sun.security.util.ResourcesMgr;
|
||||
import sun.security.util.LocalizedMessage;
|
||||
|
||||
/**
|
||||
* The policy for a Java runtime (specifying
|
||||
@ -209,13 +205,12 @@ public class PolicyParser {
|
||||
if (!domainEntries.containsKey(domainName)) {
|
||||
domainEntries.put(domainName, de);
|
||||
} else {
|
||||
MessageFormat form =
|
||||
new MessageFormat(ResourcesMgr.getString(
|
||||
"duplicate.keystore.domain.name"));
|
||||
LocalizedMessage localizedMsg =
|
||||
new LocalizedMessage("duplicate.keystore.domain.name");
|
||||
Object[] source = {domainName};
|
||||
String msg = "duplicate keystore domain name: " +
|
||||
domainName;
|
||||
throw new ParsingException(msg, form, source);
|
||||
throw new ParsingException(msg, localizedMsg, source);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -225,7 +220,7 @@ public class PolicyParser {
|
||||
}
|
||||
|
||||
if (keyStoreUrlString == null && storePassURL != null) {
|
||||
throw new ParsingException(ResourcesMgr.getString
|
||||
throw new ParsingException(LocalizedMessage.getMessage
|
||||
("keystorePasswordURL.can.not.be.specified.without.also.specifying.keystore"));
|
||||
}
|
||||
}
|
||||
@ -367,7 +362,7 @@ public class PolicyParser {
|
||||
keyStoreType = match("quoted string");
|
||||
} else {
|
||||
throw new ParsingException(st.lineno(),
|
||||
ResourcesMgr.getString("expected.keystore.type"));
|
||||
LocalizedMessage.getMessage("expected.keystore.type"));
|
||||
}
|
||||
|
||||
// parse keystore provider
|
||||
@ -380,7 +375,7 @@ public class PolicyParser {
|
||||
keyStoreProvider = match("quoted string");
|
||||
} else {
|
||||
throw new ParsingException(st.lineno(),
|
||||
ResourcesMgr.getString("expected.keystore.provider"));
|
||||
LocalizedMessage.getMessage("expected.keystore.provider"));
|
||||
}
|
||||
}
|
||||
|
||||
@ -430,7 +425,7 @@ public class PolicyParser {
|
||||
if (e.codeBase != null)
|
||||
throw new ParsingException(
|
||||
st.lineno(),
|
||||
ResourcesMgr.getString
|
||||
LocalizedMessage.getMessage
|
||||
("multiple.Codebase.expressions"));
|
||||
e.codeBase = match("quoted string");
|
||||
peekAndMatch(",");
|
||||
@ -438,8 +433,8 @@ public class PolicyParser {
|
||||
if (e.signedBy != null)
|
||||
throw new ParsingException(
|
||||
st.lineno(),
|
||||
ResourcesMgr.getString(
|
||||
"multiple.SignedBy.expressions"));
|
||||
LocalizedMessage.getMessage
|
||||
("multiple.SignedBy.expressions"));
|
||||
e.signedBy = match("quoted string");
|
||||
|
||||
// verify syntax of the aliases
|
||||
@ -457,8 +452,8 @@ public class PolicyParser {
|
||||
if (actr <= cctr)
|
||||
throw new ParsingException(
|
||||
st.lineno(),
|
||||
ResourcesMgr.getString(
|
||||
"SignedBy.has.empty.alias"));
|
||||
LocalizedMessage.getMessage
|
||||
("SignedBy.has.empty.alias"));
|
||||
|
||||
peekAndMatch(",");
|
||||
} else if (peekAndMatch("Principal")) {
|
||||
@ -500,7 +495,7 @@ public class PolicyParser {
|
||||
}
|
||||
throw new ParsingException
|
||||
(st.lineno(),
|
||||
ResourcesMgr.getString
|
||||
LocalizedMessage.getMessage
|
||||
("can.not.specify.Principal.with.a.wildcard.class.without.a.wildcard.name"));
|
||||
}
|
||||
}
|
||||
@ -537,8 +532,8 @@ public class PolicyParser {
|
||||
|
||||
} else {
|
||||
throw new ParsingException(st.lineno(),
|
||||
ResourcesMgr.getString(
|
||||
"expected.codeBase.or.SignedBy.or.Principal"));
|
||||
LocalizedMessage.getMessage
|
||||
("expected.codeBase.or.SignedBy.or.Principal"));
|
||||
}
|
||||
}
|
||||
|
||||
@ -561,8 +556,8 @@ public class PolicyParser {
|
||||
} else {
|
||||
throw new
|
||||
ParsingException(st.lineno(),
|
||||
ResourcesMgr.getString(
|
||||
"expected.permission.entry"));
|
||||
LocalizedMessage.getMessage
|
||||
("expected.permission.entry"));
|
||||
}
|
||||
}
|
||||
match("}");
|
||||
@ -738,15 +733,14 @@ public class PolicyParser {
|
||||
switch (lookahead) {
|
||||
case StreamTokenizer.TT_NUMBER:
|
||||
throw new ParsingException(st.lineno(), expect,
|
||||
ResourcesMgr.getString("number.") +
|
||||
String.valueOf(st.nval));
|
||||
LocalizedMessage.getMessage("number.") +
|
||||
String.valueOf(st.nval));
|
||||
case StreamTokenizer.TT_EOF:
|
||||
MessageFormat form = new MessageFormat(
|
||||
ResourcesMgr.getString
|
||||
("expected.expect.read.end.of.file."));
|
||||
LocalizedMessage localizedMsg = new LocalizedMessage
|
||||
("expected.expect.read.end.of.file.");
|
||||
Object[] source = {expect};
|
||||
String msg = "expected [" + expect + "], read [end of file]";
|
||||
throw new ParsingException(msg, form, source);
|
||||
throw new ParsingException(msg, localizedMsg, source);
|
||||
case StreamTokenizer.TT_WORD:
|
||||
if (expect.equalsIgnoreCase(st.sval)) {
|
||||
lookahead = st.nextToken();
|
||||
@ -832,10 +826,10 @@ public class PolicyParser {
|
||||
switch (lookahead) {
|
||||
case StreamTokenizer.TT_NUMBER:
|
||||
throw new ParsingException(st.lineno(), ";",
|
||||
ResourcesMgr.getString("number.") +
|
||||
String.valueOf(st.nval));
|
||||
LocalizedMessage.getMessage("number.") +
|
||||
String.valueOf(st.nval));
|
||||
case StreamTokenizer.TT_EOF:
|
||||
throw new ParsingException(ResourcesMgr.getString
|
||||
throw new ParsingException(LocalizedMessage.getMessage
|
||||
("expected.read.end.of.file."));
|
||||
default:
|
||||
lookahead = st.nextToken();
|
||||
@ -993,8 +987,8 @@ public class PolicyParser {
|
||||
*/
|
||||
public PrincipalEntry(String principalClass, String principalName) {
|
||||
if (principalClass == null || principalName == null)
|
||||
throw new NullPointerException(ResourcesMgr.getString(
|
||||
"null.principalClass.or.principalName"));
|
||||
throw new NullPointerException(LocalizedMessage.getMessage
|
||||
("null.principalClass.or.principalName"));
|
||||
this.principalClass = principalClass;
|
||||
this.principalName = principalName;
|
||||
}
|
||||
@ -1244,11 +1238,11 @@ public class PolicyParser {
|
||||
if (!entries.containsKey(keystoreName)) {
|
||||
entries.put(keystoreName, entry);
|
||||
} else {
|
||||
MessageFormat form = new MessageFormat(ResourcesMgr.getString(
|
||||
"duplicate.keystore.name"));
|
||||
LocalizedMessage localizedMsg = new LocalizedMessage
|
||||
("duplicate.keystore.name");
|
||||
Object[] source = {keystoreName};
|
||||
String msg = "duplicate keystore name: " + keystoreName;
|
||||
throw new ParsingException(msg, form, source);
|
||||
throw new ParsingException(msg, localizedMsg, source);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1320,7 +1314,7 @@ public class PolicyParser {
|
||||
private static final long serialVersionUID = -4330692689482574072L;
|
||||
|
||||
private String i18nMessage;
|
||||
private MessageFormat form;
|
||||
private LocalizedMessage localizedMsg;
|
||||
private Object[] source;
|
||||
|
||||
/**
|
||||
@ -1336,10 +1330,10 @@ public class PolicyParser {
|
||||
i18nMessage = msg;
|
||||
}
|
||||
|
||||
public ParsingException(String msg, MessageFormat form,
|
||||
public ParsingException(String msg, LocalizedMessage localizedMsg,
|
||||
Object[] source) {
|
||||
super(msg);
|
||||
this.form = form;
|
||||
this.localizedMsg = localizedMsg;
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
@ -1347,7 +1341,7 @@ public class PolicyParser {
|
||||
super("line " + line + ": " + msg);
|
||||
// don't call form.format unless getLocalizedMessage is called
|
||||
// to avoid unnecessary permission checks
|
||||
form = new MessageFormat(ResourcesMgr.getString("line.number.msg"));
|
||||
localizedMsg = new LocalizedMessage("line.number.msg");
|
||||
source = new Object[] {line, msg};
|
||||
}
|
||||
|
||||
@ -1356,14 +1350,14 @@ public class PolicyParser {
|
||||
"], found [" + actual + "]");
|
||||
// don't call form.format unless getLocalizedMessage is called
|
||||
// to avoid unnecessary permission checks
|
||||
form = new MessageFormat(ResourcesMgr.getString
|
||||
("line.number.expected.expect.found.actual."));
|
||||
localizedMsg = new LocalizedMessage
|
||||
("line.number.expected.expect.found.actual.");
|
||||
source = new Object[] {line, expect, actual};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLocalizedMessage() {
|
||||
return i18nMessage != null ? i18nMessage : form.format(source);
|
||||
return i18nMessage != null ? i18nMessage : localizedMsg.format(source);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.util;
|
||||
|
||||
/**
|
||||
* This class produces formatted and localized messages describing security
|
||||
* issues. Some messages may be required when the VM is not fully booted. In
|
||||
* this case, localization resources and classes used for message formatting
|
||||
* may not be available. When the VM is not booted, the message will not be
|
||||
* localized, and it will be formatted using simplified message formatting
|
||||
* code that is contained in this class.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Some of this code is executed before the VM is fully booted. Some import
|
||||
* statements have been omitted to help prevent accidental use of classes that
|
||||
* may not be available during boot.
|
||||
*/
|
||||
|
||||
public class LocalizedMessage {
|
||||
|
||||
private static final Resources resources = new Resources();
|
||||
|
||||
private final String key;
|
||||
|
||||
/**
|
||||
* A LocalizedMessage can be instantiated with a key and formatted with
|
||||
* arguments later in the style of MessageFormat. This organization
|
||||
* allows the actual formatting (and associated permission checks) to be
|
||||
* avoided unless the resulting string is needed.
|
||||
* @param key
|
||||
*/
|
||||
public LocalizedMessage(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a localized string corresponding to the key stored in this
|
||||
* object, formatted with the provided arguments. When the VM is booted,
|
||||
* this method will obtain the correct localized message and format it
|
||||
* using java.text.MessageFormat. Otherwise, a non-localized string is
|
||||
* returned, and the formatting is performed by simplified formatting code.
|
||||
*
|
||||
* @param arguments The arguments that should be placed in the message
|
||||
* @return A formatted message string
|
||||
*/
|
||||
public String format(Object... arguments) {
|
||||
return getMessage(key, arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a non-localized string corresponding to the provided key, and
|
||||
* formatted with the provided arguments. All strings are obtained from
|
||||
* sun.security.util.Resources, and the formatting only supports
|
||||
* simple positional argument replacement (e.g. {1}).
|
||||
*
|
||||
* @param key The key of the desired string in Resources
|
||||
* @param arguments The arguments that should be placed in the message
|
||||
* @return A formatted message string
|
||||
*/
|
||||
public static String getMessageUnbooted(String key,
|
||||
Object... arguments) {
|
||||
|
||||
String value = resources.getString(key);
|
||||
if (arguments == null || arguments.length == 0) {
|
||||
return value;
|
||||
}
|
||||
// Classes like StringTokenizer may not be loaded, so parsing
|
||||
// is performed with String methods
|
||||
StringBuilder sb = new StringBuilder();
|
||||
int nextBraceIndex;
|
||||
while ((nextBraceIndex = value.indexOf('{')) >= 0) {
|
||||
|
||||
String firstPart = value.substring(0, nextBraceIndex);
|
||||
sb.append(firstPart);
|
||||
value = value.substring(nextBraceIndex + 1);
|
||||
|
||||
// look for closing brace and argument index
|
||||
nextBraceIndex = value.indexOf('}');
|
||||
if (nextBraceIndex < 0) {
|
||||
// no closing brace
|
||||
// MessageFormat would throw IllegalArgumentException, but
|
||||
// that exception class may not be loaded yet
|
||||
throw new RuntimeException("Unmatched braces");
|
||||
}
|
||||
String indexStr = value.substring(0, nextBraceIndex);
|
||||
try {
|
||||
int index = Integer.parseInt(indexStr);
|
||||
sb.append(arguments[index]);
|
||||
}
|
||||
catch(NumberFormatException e) {
|
||||
// argument index is not an integer
|
||||
throw new RuntimeException("not an integer: " + indexStr);
|
||||
}
|
||||
value = value.substring(nextBraceIndex + 1);
|
||||
}
|
||||
sb.append(value);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a localized string corresponding to the provided key, and
|
||||
* formatted with the provided arguments. When the VM is booted, this
|
||||
* method will obtain the correct localized message and format it using
|
||||
* java.text.MessageFormat. Otherwise, a non-localized string is returned,
|
||||
* and the formatting is performed by simplified formatting code.
|
||||
*
|
||||
* @param key The key of the desired string in the security resource bundle
|
||||
* @param arguments The arguments that should be placed in the message
|
||||
* @return A formatted message string
|
||||
*/
|
||||
public static String getMessage(String key,
|
||||
Object... arguments) {
|
||||
|
||||
if (jdk.internal.misc.VM.isBooted()) {
|
||||
// Localization and formatting resources are available
|
||||
String value = ResourcesMgr.getString(key);
|
||||
if (arguments == null) {
|
||||
return value;
|
||||
}
|
||||
java.text.MessageFormat form = new java.text.MessageFormat(value);
|
||||
return form.format(arguments);
|
||||
} else {
|
||||
return getMessageUnbooted(key, arguments);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8168075
|
||||
* @summary Ensure that security messages can be formatted during system class
|
||||
* loader initialization.
|
||||
* @build CustomClassLoader
|
||||
* @run main/othervm/java.security.policy=error.policy -Djava.security.manager -Djava.system.class.loader=CustomClassLoader BootMessages
|
||||
*/
|
||||
|
||||
public class BootMessages {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,36 @@
|
||||
|
||||
/*
|
||||
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 class loader that can be used in tests that require a custom class
|
||||
* loader. Its behavior is identical to ClassLoader.
|
||||
*/
|
||||
|
||||
public class CustomClassLoader extends ClassLoader {
|
||||
public CustomClassLoader(ClassLoader parent) {
|
||||
super(parent);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.util.*;
|
||||
import sun.security.util.Resources;
|
||||
import sun.security.util.LocalizedMessage;
|
||||
import java.text.MessageFormat;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8168075
|
||||
* @summary Ensure that security message formatting code is capable of
|
||||
* displaying all messages.
|
||||
* @modules java.base/sun.security.util
|
||||
*/
|
||||
|
||||
public class MessageFormatting {
|
||||
|
||||
private static final Object[] MSG_ARGS = new Integer[]{0, 1, 2};
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
Resources resources = new Resources();
|
||||
Enumeration<String> keys = resources.getKeys();
|
||||
while (keys.hasMoreElements()) {
|
||||
String curKey = keys.nextElement();
|
||||
String formattedString = LocalizedMessage.getMessageUnbooted(curKey, MSG_ARGS);
|
||||
String msg = resources.getString(curKey);
|
||||
String expectedString = formatIfNecessary(msg, MSG_ARGS);
|
||||
if (!formattedString.equals(expectedString)) {
|
||||
System.err.println("Expected string:");
|
||||
System.err.println(expectedString);
|
||||
System.err.println("Actual string:");
|
||||
System.err.println(formattedString);
|
||||
throw new Exception("Incorrect message string");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static String formatIfNecessary(String str, Object[] args) {
|
||||
// message formatting code only formats messages with arguments
|
||||
if (str.indexOf('{') < 0) {
|
||||
return str;
|
||||
}
|
||||
MessageFormat format = new MessageFormat(str);
|
||||
return format.format(args);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
grant {
|
||||
permission java.lang.RuntimePermission "createClassLoader";
|
||||
permission java.lang.RuntimePermission "";
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user