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:
commit
0a580b313d
70422 changed files with 17213626 additions and 0 deletions
|
|
@ -0,0 +1,387 @@
|
|||
/*
|
||||
* Copyright (c) 2013, 2022, 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.ref.Reference;
|
||||
import java.util.Arrays;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.logging.Handler;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.LogRecord;
|
||||
import java.util.logging.Logger;
|
||||
import resources.ListBundle;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8013839
|
||||
* @summary tests Logger.logrb(..., ResourceBundle);
|
||||
* @build TestLogrbResourceBundle resources.ListBundle resources.ListBundle_fr
|
||||
* @run main TestLogrbResourceBundle
|
||||
* @author danielfuchs
|
||||
*/
|
||||
public class TestLogrbResourceBundle {
|
||||
|
||||
static final String LIST_BUNDLE_NAME = "resources.ListBundle";
|
||||
static final String PROPERTY_BUNDLE_NAME = "resources.PropertyBundle";
|
||||
|
||||
/**
|
||||
* A dummy handler class that we can use to check the bundle/bundle name
|
||||
* that was present in the last LogRecord instance published.
|
||||
*/
|
||||
static final class TestHandler extends Handler {
|
||||
ResourceBundle lastBundle = null;
|
||||
String lastBundleName = null;
|
||||
Object[] lastParams = null;
|
||||
Throwable lastThrown = null;
|
||||
String lastMessage = null;
|
||||
@Override
|
||||
public void publish(LogRecord record) {
|
||||
lastBundle = record.getResourceBundle();
|
||||
lastBundleName = record.getResourceBundleName();
|
||||
lastParams = record.getParameters();
|
||||
lastThrown = record.getThrown();
|
||||
lastMessage = record.getMessage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws SecurityException {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* We're going to do the same test with each of the different new logrb
|
||||
* forms.
|
||||
* <ul>
|
||||
* <li> LOGRB_NO_ARGS: calling logrb with no message argument.
|
||||
* <li> LOGRB_SINGLE_ARG: calling logrb with a single message argument.
|
||||
* <li> LOGRB_ARG_ARRAY: calling logrb with an array of message arguments.
|
||||
* <li> LOGRB_VARARGS: calling logrb with a variable list of message arguments.
|
||||
* <li> LOGRB_THROWABLE: calling logrb with an exception.
|
||||
* </ul>
|
||||
*/
|
||||
private static enum TestCase {
|
||||
LOGRB_NO_ARGS, LOGRB_SINGLE_ARG, LOGRB_ARG_ARRAY, LOGRB_VARARGS, LOGRB_THROWABLE;
|
||||
|
||||
public void logrb(Logger logger, ResourceBundle bundle) {
|
||||
switch(this) {
|
||||
case LOGRB_NO_ARGS:
|
||||
logger.logrb(Level.CONFIG,
|
||||
TestLogrbResourceBundle.class.getName(),
|
||||
"main", bundle, "dummy");
|
||||
break;
|
||||
case LOGRB_SINGLE_ARG:
|
||||
logger.logrb(Level.CONFIG,
|
||||
TestLogrbResourceBundle.class.getName(),
|
||||
"main", bundle, "dummy", "bar");
|
||||
break;
|
||||
case LOGRB_ARG_ARRAY:
|
||||
logger.logrb(Level.CONFIG,
|
||||
TestLogrbResourceBundle.class.getName(),
|
||||
"main", bundle, "dummy",
|
||||
new Object[] { "bar", "baz"} );
|
||||
break;
|
||||
case LOGRB_VARARGS:
|
||||
logger.logrb(Level.CONFIG,
|
||||
TestLogrbResourceBundle.class.getName(),
|
||||
"main", bundle, "dummy",
|
||||
"bar", "baz" );
|
||||
break;
|
||||
case LOGRB_THROWABLE:
|
||||
logger.logrb(Level.CONFIG,
|
||||
TestLogrbResourceBundle.class.getName(),
|
||||
"main", bundle, "dummy",
|
||||
new Exception("dummy exception") );
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the last published logged record had the expected data.
|
||||
* @param handler the TestHandler through which the record was published.
|
||||
*/
|
||||
public void checkLogged(TestHandler handler) {
|
||||
checkLogged(handler.lastMessage, handler.lastParams, handler.lastThrown);
|
||||
}
|
||||
|
||||
private void checkLogged(String message, Object[] parameters, Throwable thrown) {
|
||||
switch(this) {
|
||||
case LOGRB_NO_ARGS:
|
||||
if ("dummy".equals(message) && thrown == null
|
||||
&& (parameters == null || parameters.length == 0)) {
|
||||
return; // OK: all was as expected.
|
||||
}
|
||||
break;
|
||||
case LOGRB_SINGLE_ARG:
|
||||
if ("dummy".equals(message) && thrown == null
|
||||
&& parameters != null
|
||||
&& parameters.length == 1
|
||||
&& "bar".equals(parameters[0])) {
|
||||
return; // OK: all was as expected.
|
||||
}
|
||||
break;
|
||||
case LOGRB_VARARGS:
|
||||
case LOGRB_ARG_ARRAY:
|
||||
if ("dummy".equals(message) && thrown == null
|
||||
&& parameters != null
|
||||
&& parameters.length > 1
|
||||
&& Arrays.deepEquals(new Object[] { "bar", "baz"},
|
||||
parameters)) {
|
||||
return; // OK: all was as expected.
|
||||
}
|
||||
break;
|
||||
case LOGRB_THROWABLE:
|
||||
if ("dummy".equals(message) && thrown != null
|
||||
&& thrown.getClass() == Exception.class
|
||||
&& "dummy exception".equals(thrown.getMessage())) {
|
||||
return; // OK: all was as expected.
|
||||
}
|
||||
break;
|
||||
default:
|
||||
}
|
||||
|
||||
// We had some unexpected stuff: throw exception.
|
||||
throw new RuntimeException(this + ": "
|
||||
+ "Unexpected content in last published log record: "
|
||||
+ "\n\tmessage=\"" + message + "\""
|
||||
+ "\n\tparameters=" + Arrays.toString(parameters)
|
||||
+ "\n\tthrown=" + thrown);
|
||||
}
|
||||
}
|
||||
|
||||
static String getBaseName(ResourceBundle bundle) {
|
||||
return bundle == null ? null : bundle.getBaseBundleName();
|
||||
}
|
||||
|
||||
public static void main(String... args) throws Exception {
|
||||
|
||||
Locale defaultLocale = Locale.getDefault();
|
||||
|
||||
final ResourceBundle bundle = ResourceBundle.getBundle(LIST_BUNDLE_NAME);
|
||||
final ResourceBundle bundle_fr =
|
||||
ResourceBundle.getBundle(LIST_BUNDLE_NAME, Locale.FRENCH);
|
||||
final ResourceBundle propertyBundle = ResourceBundle.getBundle(PROPERTY_BUNDLE_NAME);
|
||||
final ResourceBundle propertyBundle_fr =
|
||||
ResourceBundle.getBundle(PROPERTY_BUNDLE_NAME, Locale.FRENCH);
|
||||
Logger foobar = Logger.getLogger("foo.bar");
|
||||
final TestHandler handler = new TestHandler();
|
||||
foobar.addHandler(handler);
|
||||
foobar.setLevel(Level.CONFIG);
|
||||
|
||||
final ResourceBundle anonBundle = new ListBundle();
|
||||
try {
|
||||
// First we're going to call logrb on a logger that
|
||||
// has no bundle set...
|
||||
|
||||
// For each possible logrb form...
|
||||
for (TestCase test : TestCase.values()) {
|
||||
// For various resource bundles
|
||||
for (ResourceBundle b : new ResourceBundle[] {
|
||||
anonBundle, bundle, bundle_fr, propertyBundle,
|
||||
anonBundle, null, propertyBundle_fr,
|
||||
}) {
|
||||
// Prints the resource bundle base name (can be null,
|
||||
// we don't enforce non-null names in logrb.
|
||||
final String baseName = getBaseName(b);
|
||||
System.out.println("Testing " + test + " with " + baseName);
|
||||
|
||||
// log in the 'foobar' logger using bundle 'b'
|
||||
test.logrb(foobar, b);
|
||||
|
||||
// check that the correct bundle was set in the published
|
||||
// LogRecord
|
||||
if (handler.lastBundle != b) {
|
||||
throw new RuntimeException("Unexpected bundle: "
|
||||
+ handler.lastBundle);
|
||||
}
|
||||
|
||||
// check that the correct bundle name was set in the published
|
||||
// LogRecord
|
||||
if (!Objects.equals(handler.lastBundleName, baseName)) {
|
||||
throw new RuntimeException("Unexpected bundle name: "
|
||||
+ handler.lastBundleName);
|
||||
}
|
||||
|
||||
// check that calling foobar.logrb() had no side effect on
|
||||
// the bundle used by foobar. foobar should still have no
|
||||
// bundle set.
|
||||
if (foobar.getResourceBundle() != null) {
|
||||
throw new RuntimeException("Unexpected bundle: "
|
||||
+ foobar.getResourceBundle());
|
||||
}
|
||||
if (foobar.getResourceBundleName() != null) {
|
||||
throw new RuntimeException("Unexpected bundle: "
|
||||
+ foobar.getResourceBundleName());
|
||||
}
|
||||
|
||||
// Test that the last published log record had all the
|
||||
// data that this test case had logged (message, parameters,
|
||||
// thrown...
|
||||
test.checkLogged(handler);
|
||||
}
|
||||
}
|
||||
|
||||
// No we're going to set a resource bundle on the foobar logger
|
||||
// and do it all again...
|
||||
|
||||
// For the same bundle in two different locales
|
||||
for (ResourceBundle propBundle : new ResourceBundle[] {
|
||||
propertyBundle, propertyBundle_fr,
|
||||
}) {
|
||||
|
||||
// set the bundle on foobar...
|
||||
foobar.setResourceBundle(propBundle);
|
||||
|
||||
// check the bundle was correctly set...
|
||||
if (!propBundle.equals(foobar.getResourceBundle())) {
|
||||
throw new RuntimeException("Unexpected bundle: "
|
||||
+ foobar.getResourceBundle());
|
||||
}
|
||||
if (!Objects.equals(getBaseName(propBundle), foobar.getResourceBundleName())) {
|
||||
throw new RuntimeException("Unexpected bundle name: "
|
||||
+ foobar.getResourceBundleName());
|
||||
}
|
||||
|
||||
System.out.println("Configuring " + foobar.getName() + " with "
|
||||
+ propBundle);
|
||||
|
||||
// for each possible logrb form...
|
||||
for (TestCase test : TestCase.values()) {
|
||||
|
||||
// for various resource bundles
|
||||
for (ResourceBundle b : new ResourceBundle[] {
|
||||
anonBundle, bundle, null, bundle_fr, propertyBundle,
|
||||
anonBundle, propertyBundle_fr,
|
||||
}) {
|
||||
|
||||
final String baseName = getBaseName(b);
|
||||
System.out.println("Testing " + test + " with " + baseName);
|
||||
|
||||
// call foobar.logrb
|
||||
test.logrb(foobar, b);
|
||||
|
||||
// check which resource bundle was used (should be
|
||||
// the one passed to logrb)
|
||||
if (handler.lastBundle != b) {
|
||||
throw new RuntimeException("Unexpected bundle: "
|
||||
+ handler.lastBundle);
|
||||
}
|
||||
if (!Objects.equals(handler.lastBundleName, baseName)) {
|
||||
throw new RuntimeException("Unexpected bundle name: "
|
||||
+ handler.lastBundleName);
|
||||
}
|
||||
|
||||
// Verify there was no side effect on the bundle that
|
||||
// had been previously set on the logger...
|
||||
if (foobar.getResourceBundle() != propBundle) {
|
||||
throw new RuntimeException("Unexpected bundle: "
|
||||
+ foobar.getResourceBundle());
|
||||
}
|
||||
if (!Objects.equals(getBaseName(propBundle),
|
||||
foobar.getResourceBundleName())) {
|
||||
throw new RuntimeException("Unexpected bundle name: "
|
||||
+ foobar.getResourceBundleName());
|
||||
}
|
||||
|
||||
// Checked that the published LogRecord had the
|
||||
// expected content logged by this test case.
|
||||
test.checkLogged(handler);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now we're going to the same thing, but with a logger which
|
||||
// has an inherited resource bundle.
|
||||
Logger foobaz = Logger.getLogger("foo.bar.baz");
|
||||
|
||||
// keep "foo.bar" logger alive until its child has
|
||||
// been created. A child logger has a strong
|
||||
// reference to its first parent.
|
||||
Reference.reachabilityFence(foobar);
|
||||
|
||||
// check that foobaz has no bundle set locally.
|
||||
if (foobaz.getResourceBundle() != null) {
|
||||
throw new RuntimeException("Unexpected bundle: "
|
||||
+ foobaz.getResourceBundle());
|
||||
}
|
||||
if (foobaz.getResourceBundleName() != null) {
|
||||
throw new RuntimeException("Unexpected bundle: "
|
||||
+ foobaz.getResourceBundle());
|
||||
}
|
||||
|
||||
// The current locale should have no effect on logrb.
|
||||
Locale.setDefault(Locale.GERMAN); // shouldn't change anything...
|
||||
|
||||
// for each possible logrb form
|
||||
for (TestCase test : TestCase.values()) {
|
||||
|
||||
// for various resource bundle
|
||||
for (ResourceBundle b : new ResourceBundle[] {
|
||||
anonBundle, bundle, bundle_fr, propertyBundle, null,
|
||||
anonBundle, propertyBundle_fr,
|
||||
}) {
|
||||
final String baseName = getBaseName(b);
|
||||
System.out.println("Testing " + test + " with "
|
||||
+ foobaz.getName() + " and "
|
||||
+ baseName);
|
||||
|
||||
// call foobaz.logrb with the bundle
|
||||
test.logrb(foobaz, b);
|
||||
|
||||
// check that the bundle passed to logrb was used.
|
||||
if (handler.lastBundle != b) {
|
||||
throw new RuntimeException("Unexpected bundle: "
|
||||
+ handler.lastBundle);
|
||||
}
|
||||
if (!Objects.equals(handler.lastBundleName, baseName)) {
|
||||
throw new RuntimeException("Unexpected bundle name: "
|
||||
+ handler.lastBundleName);
|
||||
}
|
||||
|
||||
// check that there was no effect on the bundle set
|
||||
// on foobaz: it should still be null.
|
||||
if (foobaz.getResourceBundle() != null) {
|
||||
throw new RuntimeException("Unexpected bundle: "
|
||||
+ foobaz.getResourceBundle());
|
||||
}
|
||||
if (foobaz.getResourceBundleName() != null) {
|
||||
throw new RuntimeException("Unexpected bundle: "
|
||||
+ foobaz.getResourceBundleName());
|
||||
}
|
||||
|
||||
// check that the last published log record had all the
|
||||
// data that was logged by this testcase.
|
||||
test.checkLogged(handler);
|
||||
}
|
||||
}
|
||||
|
||||
} finally {
|
||||
Locale.setDefault(defaultLocale);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue