Merge
This commit is contained in:
commit
02eb542660
jdk
make/mapfiles/libjava
src
java.base
share
classes
java
sun
nio/ch
reflect/generics
factory
parser
reflectiveObjects
repository
AbstractRepository.javaClassRepository.javaConstructorRepository.javaFieldRepository.javaMethodRepository.java
scope
tree
visitor
native
unix/native/libjimage
windows/native/libjimage
java.scripting/share/classes/javax/script
jdk.jconsole/share/classes
jdk.rmic/share/classes/sun/tools
test
com/sun
crypto/provider
CICO
CICOChainingTest.javaCICODESFuncTest.javaCICOSkipTest.java
PBEFunc
AESPBEWrapper.javaAbstractPBEWrapper.javaCICOPBEFuncTest.javaCICO_PBE_RW_Test.javaCICO_PBE_SKIP_Test.javaCICO_PBE_Test.javaCipherNCFuncTest.javaDefaultPBEWrapper.javaPBEAlgorithm.javaPBKDF2Wrapper.java
ReadModel.javaTestUtilities.javaCipher/DES
NSASuiteB
jndi/ldap
java
lang
nio/channels/FileChannel
security/Policy/ExtensiblePolicy
ExtensiblePolicyTest.javaExtensiblePolicyTest1.policyExtensiblePolicyTest2.policyExtensiblePolicyTest3.policyExtensiblePolicyWithJarTest.java
TVJar
util
javax
crypto/KeyGenerator
security/auth/login
sun/security
@ -157,7 +157,6 @@ SUNWprivate_1.1 {
|
||||
Java_java_lang_StrictMath_cosh;
|
||||
Java_java_lang_StrictMath_sinh;
|
||||
Java_java_lang_StrictMath_tanh;
|
||||
Java_java_lang_StrictMath_hypot;
|
||||
Java_java_lang_StrictMath_log1p;
|
||||
Java_java_lang_StrictMath_expm1;
|
||||
Java_java_lang_Object_getClass;
|
||||
|
@ -26,7 +26,8 @@
|
||||
package java.lang;
|
||||
|
||||
/**
|
||||
* Port of the "Freely Distributable Math Library", version 5.3, from C to Java.
|
||||
* Port of the "Freely Distributable Math Library", version 5.3, from
|
||||
* C to Java.
|
||||
*
|
||||
* <p>The C version of fdlibm relied on the idiom of pointer aliasing
|
||||
* a 64-bit double floating-point value as a two-element array of
|
||||
@ -37,7 +38,7 @@ package java.lang;
|
||||
* operated on as integer values, the standard library methods for
|
||||
* bitwise floating-point to integer conversion,
|
||||
* Double.longBitsToDouble and Double.doubleToRawLongBits, are directly
|
||||
* or indirectly used .
|
||||
* or indirectly used.
|
||||
*
|
||||
* <p>The C version of fdlibm also took some pains to signal the
|
||||
* correct IEEE 754 exceptional conditions divide by zero, invalid,
|
||||
@ -47,13 +48,21 @@ package java.lang;
|
||||
* handling is not supported natively in the JVM, such coding patterns
|
||||
* have been omitted from this port. For example, rather than {@code
|
||||
* return huge * huge}, this port will use {@code return INFINITY}.
|
||||
*
|
||||
* <p>Various comparison and arithmetic operations in fdlibm could be
|
||||
* done either based on the integer view of a value or directly on the
|
||||
* floating-point representation. Which idiom is faster may depend on
|
||||
* platform specific factors. However, for code clarity if no other
|
||||
* reason, this port will favor expressing the semantics of those
|
||||
* operations in terms of floating-point operations when convenient to
|
||||
* do so.
|
||||
*/
|
||||
class FdLibm {
|
||||
// Constants used by multiple algorithms
|
||||
private static final double INFINITY = Double.POSITIVE_INFINITY;
|
||||
|
||||
private FdLibm() {
|
||||
throw new UnsupportedOperationException("No instances for you.");
|
||||
throw new UnsupportedOperationException("No FdLibm instances for you.");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -90,6 +99,139 @@ class FdLibm {
|
||||
return Double.longBitsToDouble((transX & 0x0000_0000_FFFF_FFFFL)|( ((long)high)) << 32 );
|
||||
}
|
||||
|
||||
/**
|
||||
* hypot(x,y)
|
||||
*
|
||||
* Method :
|
||||
* If (assume round-to-nearest) z = x*x + y*y
|
||||
* has error less than sqrt(2)/2 ulp, than
|
||||
* sqrt(z) has error less than 1 ulp (exercise).
|
||||
*
|
||||
* So, compute sqrt(x*x + y*y) with some care as
|
||||
* follows to get the error below 1 ulp:
|
||||
*
|
||||
* Assume x > y > 0;
|
||||
* (if possible, set rounding to round-to-nearest)
|
||||
* 1. if x > 2y use
|
||||
* x1*x1 + (y*y + (x2*(x + x1))) for x*x + y*y
|
||||
* where x1 = x with lower 32 bits cleared, x2 = x - x1; else
|
||||
* 2. if x <= 2y use
|
||||
* t1*y1 + ((x-y) * (x-y) + (t1*y2 + t2*y))
|
||||
* where t1 = 2x with lower 32 bits cleared, t2 = 2x - t1,
|
||||
* y1= y with lower 32 bits chopped, y2 = y - y1.
|
||||
*
|
||||
* NOTE: scaling may be necessary if some argument is too
|
||||
* large or too tiny
|
||||
*
|
||||
* Special cases:
|
||||
* hypot(x,y) is INF if x or y is +INF or -INF; else
|
||||
* hypot(x,y) is NAN if x or y is NAN.
|
||||
*
|
||||
* Accuracy:
|
||||
* hypot(x,y) returns sqrt(x^2 + y^2) with error less
|
||||
* than 1 ulp (unit in the last place)
|
||||
*/
|
||||
public static class Hypot {
|
||||
public static final double TWO_MINUS_600 = 0x1.0p-600;
|
||||
public static final double TWO_PLUS_600 = 0x1.0p+600;
|
||||
|
||||
public static strictfp double compute(double x, double y) {
|
||||
double a = Math.abs(x);
|
||||
double b = Math.abs(y);
|
||||
|
||||
if (!Double.isFinite(a) || !Double.isFinite(b)) {
|
||||
if (a == INFINITY || b == INFINITY)
|
||||
return INFINITY;
|
||||
else
|
||||
return a + b; // Propagate NaN significand bits
|
||||
}
|
||||
|
||||
if (b > a) {
|
||||
double tmp = a;
|
||||
a = b;
|
||||
b = tmp;
|
||||
}
|
||||
assert a >= b;
|
||||
|
||||
// Doing bitwise conversion after screening for NaN allows
|
||||
// the code to not worry about the possibility of
|
||||
// "negative" NaN values.
|
||||
|
||||
// Note: the ha and hb variables are the high-order
|
||||
// 32-bits of a and b stored as integer values. The ha and
|
||||
// hb values are used first for a rough magnitude
|
||||
// comparison of a and b and second for simulating higher
|
||||
// precision by allowing a and b, respectively, to be
|
||||
// decomposed into non-overlapping portions. Both of these
|
||||
// uses could be eliminated. The magnitude comparison
|
||||
// could be eliminated by extracting and comparing the
|
||||
// exponents of a and b or just be performing a
|
||||
// floating-point divide. Splitting a floating-point
|
||||
// number into non-overlapping portions can be
|
||||
// accomplished by judicious use of multiplies and
|
||||
// additions. For details see T. J. Dekker, A Floating
|
||||
// Point Technique for Extending the Available Precision ,
|
||||
// Numerische Mathematik, vol. 18, 1971, pp.224-242 and
|
||||
// subsequent work.
|
||||
|
||||
int ha = __HI(a); // high word of a
|
||||
int hb = __HI(b); // high word of b
|
||||
|
||||
if ((ha - hb) > 0x3c00000) {
|
||||
return a + b; // x / y > 2**60
|
||||
}
|
||||
|
||||
int k = 0;
|
||||
if (a > 0x1.0p500) { // a > 2**500
|
||||
// scale a and b by 2**-600
|
||||
ha -= 0x25800000;
|
||||
hb -= 0x25800000;
|
||||
a = a * TWO_MINUS_600;
|
||||
b = b * TWO_MINUS_600;
|
||||
k += 600;
|
||||
}
|
||||
double t1, t2;
|
||||
if (b < 0x1.0p-500) { // b < 2**-500
|
||||
if (b < Double.MIN_NORMAL) { // subnormal b or 0 */
|
||||
if (b == 0.0)
|
||||
return a;
|
||||
t1 = 0x1.0p1022; // t1 = 2^1022
|
||||
b *= t1;
|
||||
a *= t1;
|
||||
k -= 1022;
|
||||
} else { // scale a and b by 2^600
|
||||
ha += 0x25800000; // a *= 2^600
|
||||
hb += 0x25800000; // b *= 2^600
|
||||
a = a * TWO_PLUS_600;
|
||||
b = b * TWO_PLUS_600;
|
||||
k -= 600;
|
||||
}
|
||||
}
|
||||
// medium size a and b
|
||||
double w = a - b;
|
||||
if (w > b) {
|
||||
t1 = 0;
|
||||
t1 = __HI(t1, ha);
|
||||
t2 = a - t1;
|
||||
w = Math.sqrt(t1*t1 - (b*(-b) - t2 * (a + t1)));
|
||||
} else {
|
||||
double y1, y2;
|
||||
a = a + a;
|
||||
y1 = 0;
|
||||
y1 = __HI(y1, hb);
|
||||
y2 = b - y1;
|
||||
t1 = 0;
|
||||
t1 = __HI(t1, ha + 0x00100000);
|
||||
t2 = a - t1;
|
||||
w = Math.sqrt(t1*y1 - (w*(-w) - (t1*y2 + t2*b)));
|
||||
}
|
||||
if (k != 0) {
|
||||
return Math.powerOfTwoD(k) * w;
|
||||
} else
|
||||
return w;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute x**y
|
||||
* n
|
||||
@ -97,7 +239,7 @@ class FdLibm {
|
||||
* 1. Compute and return log2(x) in two pieces:
|
||||
* log2(x) = w1 + w2,
|
||||
* where w1 has 53 - 24 = 29 bit trailing zeros.
|
||||
* 2. Perform y*log2(x) = n+y' by simulating muti-precision
|
||||
* 2. Perform y*log2(x) = n+y' by simulating multi-precision
|
||||
* arithmetic, where |y'| <= 0.5.
|
||||
* 3. Return x**y = 2**n*exp(y'*log2)
|
||||
*
|
||||
|
@ -500,7 +500,8 @@ public abstract class Process {
|
||||
|
||||
/**
|
||||
* Returns a snapshot of the direct children of the process.
|
||||
* A process that is {@link #isAlive not alive} has zero children.
|
||||
* The parent of a direct child process is the process.
|
||||
* Typically, a process that is {@link #isAlive not alive} has no children.
|
||||
* <p>
|
||||
* <em>Note that processes are created and terminate asynchronously.
|
||||
* There is no guarantee that a process is {@link #isAlive alive}.
|
||||
@ -510,8 +511,8 @@ public abstract class Process {
|
||||
* This implementation returns the direct children as:
|
||||
* {@link #toHandle toHandle().children()}.
|
||||
*
|
||||
* @return a Stream of ProcessHandles for processes that are direct children
|
||||
* of the process
|
||||
* @return a sequential Stream of ProcessHandles for processes that are
|
||||
* direct children of the process
|
||||
* @throws UnsupportedOperationException if the Process implementation
|
||||
* does not support this operation
|
||||
* @throws SecurityException if a security manager has been installed and
|
||||
@ -524,7 +525,9 @@ public abstract class Process {
|
||||
|
||||
/**
|
||||
* Returns a snapshot of the direct and indirect children of the process.
|
||||
* A process that is {@link #isAlive not alive} has zero children.
|
||||
* An indirect child is one whose parent is either a direct child or
|
||||
* another indirect child.
|
||||
* Typically, a process that is {@link #isAlive not alive} has no children.
|
||||
* <p>
|
||||
* <em>Note that processes are created and terminate asynchronously.
|
||||
* There is no guarantee that a process is {@link #isAlive alive}.
|
||||
@ -534,8 +537,8 @@ public abstract class Process {
|
||||
* This implementation returns all children as:
|
||||
* {@link #toHandle toHandle().allChildren()}.
|
||||
*
|
||||
* @return a Stream of ProcessHandles for processes that are direct and
|
||||
* indirect children of the process
|
||||
* @return a sequential Stream of ProcessHandles for processes that are
|
||||
* direct and indirect children of the process
|
||||
* @throws UnsupportedOperationException if the Process implementation
|
||||
* does not support this operation
|
||||
* @throws SecurityException if a security manager has been installed and
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 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
|
||||
@ -33,7 +33,8 @@ import java.util.Arrays;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
/**
|
||||
* This class is used to create operating system processes.
|
||||
*
|
||||
@ -445,6 +446,7 @@ public final class ProcessBuilder
|
||||
* <ul>
|
||||
* <li>the special value {@link #PIPE Redirect.PIPE}
|
||||
* <li>the special value {@link #INHERIT Redirect.INHERIT}
|
||||
* <li>the special value {@link #DISCARD Redirect.DISCARD}
|
||||
* <li>a redirection to read from a file, created by an invocation of
|
||||
* {@link Redirect#from Redirect.from(File)}
|
||||
* <li>a redirection to write to a file, created by an invocation of
|
||||
@ -459,6 +461,13 @@ public final class ProcessBuilder
|
||||
* @since 1.7
|
||||
*/
|
||||
public abstract static class Redirect {
|
||||
private static final File NULL_FILE = AccessController.doPrivileged(
|
||||
(PrivilegedAction<File>) () -> {
|
||||
return new File((System.getProperty("os.name")
|
||||
.startsWith("Windows") ? "NUL" : "/dev/null"));
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* The type of a {@link Redirect}.
|
||||
*/
|
||||
@ -529,6 +538,28 @@ public final class ProcessBuilder
|
||||
public Type type() { return Type.INHERIT; }
|
||||
public String toString() { return type().toString(); }};
|
||||
|
||||
|
||||
/**
|
||||
* Indicates that subprocess output will be discarded.
|
||||
* A typical implementation discards the output by writing to
|
||||
* an operating system specific "null file".
|
||||
*
|
||||
* <p>It will always be true that
|
||||
* <pre> {@code
|
||||
* Redirect.DISCARD.file() the filename appropriate for the operating system
|
||||
* and may be null &&
|
||||
* Redirect.DISCARD.type() == Redirect.Type.WRITE &&
|
||||
* Redirect.DISCARD.append() == false
|
||||
* }</pre>
|
||||
* @since 9
|
||||
*/
|
||||
public static final Redirect DISCARD = new Redirect() {
|
||||
public Type type() { return Type.WRITE; }
|
||||
public String toString() { return type().toString(); }
|
||||
public File file() { return NULL_FILE; }
|
||||
boolean append() { return false; }
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the {@link File} source or destination associated
|
||||
* with this redirect, or {@code null} if there is no such file.
|
||||
|
@ -149,14 +149,15 @@ public interface ProcessHandle extends Comparable<ProcessHandle> {
|
||||
|
||||
/**
|
||||
* Returns a snapshot of the current direct children of the process.
|
||||
* A process that is {@link #isAlive not alive} has zero children.
|
||||
* The {@link #parent} of a direct child process is the process.
|
||||
* Typically, a process that is {@link #isAlive not alive} has no children.
|
||||
* <p>
|
||||
* <em>Note that processes are created and terminate asynchronously.
|
||||
* There is no guarantee that a process is {@link #isAlive alive}.
|
||||
* </em>
|
||||
*
|
||||
* @return a Stream of ProcessHandles for processes that are direct children
|
||||
* of the process
|
||||
* @return a sequential Stream of ProcessHandles for processes that are
|
||||
* direct children of the process
|
||||
* @throws SecurityException if a security manager has been installed and
|
||||
* it denies RuntimePermission("manageProcess")
|
||||
*/
|
||||
@ -164,14 +165,16 @@ public interface ProcessHandle extends Comparable<ProcessHandle> {
|
||||
|
||||
/**
|
||||
* Returns a snapshot of the current direct and indirect children of the process.
|
||||
* A process that is {@link #isAlive not alive} has zero children.
|
||||
* An indirect child is one whose parent is either a direct child or
|
||||
* another indirect child.
|
||||
* Typically, a process that is {@link #isAlive not alive} has no children.
|
||||
* <p>
|
||||
* <em>Note that processes are created and terminate asynchronously.
|
||||
* There is no guarantee that a process is {@link #isAlive alive}.
|
||||
* </em>
|
||||
*
|
||||
* @return a Stream of ProcessHandles for processes that are direct and
|
||||
* indirect children of the process
|
||||
* @return a sequential Stream of ProcessHandles for processes that are
|
||||
* direct and indirect children of the process
|
||||
* @throws SecurityException if a security manager has been installed and
|
||||
* it denies RuntimePermission("manageProcess")
|
||||
*/
|
||||
|
@ -1329,7 +1329,9 @@ public final class StrictMath {
|
||||
* without intermediate overflow or underflow
|
||||
* @since 1.5
|
||||
*/
|
||||
public static native double hypot(double x, double y);
|
||||
public static double hypot(double x, double y) {
|
||||
return FdLibm.Hypot.compute(x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <i>e</i><sup>x</sup> -1. Note that for values of
|
||||
|
@ -404,6 +404,14 @@ import jdk.internal.org.objectweb.asm.Type;
|
||||
d = lookupCache(types);
|
||||
// Class loading must have upgraded the cache.
|
||||
assert(d != null && !d.isPlaceholder());
|
||||
if (OBSERVE_BMH_SPECIES_CREATION) {
|
||||
if (d == null) {
|
||||
throw new IllegalStateException("d == null");
|
||||
}
|
||||
if (d.isPlaceholder()) {
|
||||
throw new IllegalStateException("d is place holder");
|
||||
}
|
||||
}
|
||||
return d;
|
||||
}
|
||||
static SpeciesData getForClass(String types, Class<? extends BoundMethodHandle> clazz) {
|
||||
@ -415,6 +423,9 @@ import jdk.internal.org.objectweb.asm.Type;
|
||||
if (d != null) return d;
|
||||
d = new SpeciesData(types);
|
||||
assert(d.isPlaceholder());
|
||||
if (OBSERVE_BMH_SPECIES_CREATION && !d.isPlaceholder()) {
|
||||
throw new IllegalStateException("d is not place holder");
|
||||
}
|
||||
CACHE.put(types, d);
|
||||
return d;
|
||||
}
|
||||
@ -422,6 +433,15 @@ import jdk.internal.org.objectweb.asm.Type;
|
||||
SpeciesData d2;
|
||||
assert((d2 = CACHE.get(types)) == null || d2.isPlaceholder());
|
||||
assert(!d.isPlaceholder());
|
||||
if (OBSERVE_BMH_SPECIES_CREATION) {
|
||||
d2 = CACHE.get(types);
|
||||
if (d2 != null && !d2.isPlaceholder()) {
|
||||
throw new IllegalStateException("non-null d2 is not place holder");
|
||||
}
|
||||
if (d.isPlaceholder()) {
|
||||
throw new IllegalStateException("d is place holder");
|
||||
}
|
||||
}
|
||||
CACHE.put(types, d);
|
||||
return d;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 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
|
||||
@ -51,8 +51,12 @@ import sun.misc.Unsafe;
|
||||
static final boolean PROFILE_GWT;
|
||||
static final int CUSTOMIZE_THRESHOLD;
|
||||
|
||||
// This is a temporary property added for improved error reporting; it will
|
||||
// be removed once it has served its purpose.
|
||||
static final boolean OBSERVE_BMH_SPECIES_CREATION;
|
||||
|
||||
static {
|
||||
final Object[] values = new Object[9];
|
||||
final Object[] values = new Object[10];
|
||||
AccessController.doPrivileged(new PrivilegedAction<>() {
|
||||
public Void run() {
|
||||
values[0] = Boolean.getBoolean("java.lang.invoke.MethodHandle.DEBUG_NAMES");
|
||||
@ -64,6 +68,7 @@ import sun.misc.Unsafe;
|
||||
values[6] = Integer.getInteger("java.lang.invoke.MethodHandle.PROFILE_LEVEL", 0);
|
||||
values[7] = Boolean.parseBoolean(System.getProperty("java.lang.invoke.MethodHandle.PROFILE_GWT", "true"));
|
||||
values[8] = Integer.getInteger("java.lang.invoke.MethodHandle.CUSTOMIZE_THRESHOLD", 127);
|
||||
values[9] = Boolean.getBoolean("java.lang.invoke.MethodHandle.OBSERVE_BMH_SPECIES_CREATION");
|
||||
return null;
|
||||
}
|
||||
});
|
||||
@ -77,6 +82,8 @@ import sun.misc.Unsafe;
|
||||
PROFILE_GWT = (Boolean) values[7];
|
||||
CUSTOMIZE_THRESHOLD = (Integer) values[8];
|
||||
|
||||
OBSERVE_BMH_SPECIES_CREATION = (Boolean) values[9];
|
||||
|
||||
if (CUSTOMIZE_THRESHOLD < -1 || CUSTOMIZE_THRESHOLD > 127) {
|
||||
throw newInternalError("CUSTOMIZE_THRESHOLD should be in [-1...127] range");
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 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
|
||||
@ -379,7 +379,7 @@ public enum Month implements TemporalAccessor, TemporalAdjuster {
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* Returns the month-of-year that is the specified number of quarters after this one.
|
||||
* Returns the month-of-year that is the specified number of months after this one.
|
||||
* <p>
|
||||
* The calculation rolls around the end of the year from December to January.
|
||||
* The specified period may be negative.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 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
|
||||
@ -313,7 +313,7 @@ public final class TemporalAdjusters {
|
||||
|
||||
/**
|
||||
* Returns the day-of-week in month adjuster, which returns a new date
|
||||
* in the same month with the ordinal day-of-week.
|
||||
* with the ordinal day-of-week based on the month.
|
||||
* This is used for expressions like the 'second Tuesday in March'.
|
||||
* <p>
|
||||
* The ISO calendar system behaves as follows:<br>
|
||||
|
@ -825,7 +825,7 @@ public final class Locale implements Cloneable, Serializable {
|
||||
* setDefault(Locale.Category, Locale) method.
|
||||
*
|
||||
* @param category - the specified category to get the default locale
|
||||
* @throws NullPointerException - if category is null
|
||||
* @throws NullPointerException if category is null
|
||||
* @return the default locale for the specified Category for this instance
|
||||
* of the Java Virtual Machine
|
||||
* @see #setDefault(Locale.Category, Locale)
|
||||
@ -954,9 +954,9 @@ public final class Locale implements Cloneable, Serializable {
|
||||
*
|
||||
* @param category - the specified category to set the default locale
|
||||
* @param newLocale - the new default locale
|
||||
* @throws SecurityException - if a security manager exists and its
|
||||
* @throws SecurityException if a security manager exists and its
|
||||
* checkPermission method doesn't allow the operation.
|
||||
* @throws NullPointerException - if category and/or newLocale is null
|
||||
* @throws NullPointerException if category and/or newLocale is null
|
||||
* @see SecurityManager#checkPermission(java.security.Permission)
|
||||
* @see PropertyPermission
|
||||
* @see #getDefault(Locale.Category)
|
||||
|
@ -504,7 +504,7 @@ public final class Collectors {
|
||||
*/
|
||||
public static <T> Collector<T, ?, Long>
|
||||
counting() {
|
||||
return reducing(0L, e -> 1L, Long::sum);
|
||||
return summingLong(e -> 1L);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -328,6 +328,7 @@ public class FileChannelImpl
|
||||
int rv = -1;
|
||||
long p = -1;
|
||||
int ti = -1;
|
||||
long rp = -1;
|
||||
try {
|
||||
begin();
|
||||
ti = threads.add();
|
||||
@ -363,8 +364,8 @@ public class FileChannelImpl
|
||||
if (p > newSize)
|
||||
p = newSize;
|
||||
do {
|
||||
rv = (int)position0(fd, p);
|
||||
} while ((rv == IOStatus.INTERRUPTED) && isOpen());
|
||||
rp = position0(fd, p);
|
||||
} while ((rp == IOStatus.INTERRUPTED) && isOpen());
|
||||
return this;
|
||||
} finally {
|
||||
threads.remove(ti);
|
||||
|
@ -70,20 +70,20 @@ public class CoreReflectionFactory implements GenericsFactory {
|
||||
|
||||
/**
|
||||
* Factory for this class. Returns an instance of
|
||||
* <tt>CoreReflectionFactory</tt> for the declaration and scope
|
||||
* {@code CoreReflectionFactory} for the declaration and scope
|
||||
* provided.
|
||||
* This factory will produce reflective objects of the appropriate
|
||||
* kind. Classes produced will be those that would be loaded by the
|
||||
* defining class loader of the declaration <tt>d</tt> (if <tt>d</tt>
|
||||
* defining class loader of the declaration {@code d} (if {@code d}
|
||||
* is a type declaration, or by the defining loader of the declaring
|
||||
* class of <tt>d</tt> otherwise.
|
||||
* class of {@code d} otherwise.
|
||||
* <p> Type variables will be created or lookup as necessary in the
|
||||
* scope <tt> s</tt>.
|
||||
* scope {@code s}.
|
||||
* @param d - the generic declaration (class, interface, method or
|
||||
* constructor) that this factory services
|
||||
* @param s the scope in which the factory will allocate and search for
|
||||
* type variables
|
||||
* @return an instance of <tt>CoreReflectionFactory</tt>
|
||||
* @return an instance of {@code CoreReflectionFactory}
|
||||
*/
|
||||
public static CoreReflectionFactory make(GenericDeclaration d, Scope s) {
|
||||
return new CoreReflectionFactory(d, s);
|
||||
|
@ -47,32 +47,32 @@ import sun.reflect.generics.tree.FieldTypeSignature;
|
||||
*/
|
||||
public interface GenericsFactory {
|
||||
/**
|
||||
* Returns a new type variable declaration. Note that <tt>name</tt>
|
||||
* may be empty (but not <tt>null</tt>). If <tt>bounds</tt> is
|
||||
* empty, a bound of <tt>java.lang.Object</tt> is used.
|
||||
* Returns a new type variable declaration. Note that {@code name}
|
||||
* may be empty (but not {@code null}). If {@code bounds} is
|
||||
* empty, a bound of {@code java.lang.Object} is used.
|
||||
* @param name The name of the type variable
|
||||
* @param bounds An array of abstract syntax trees representing
|
||||
* the upper bound(s) on the type variable being declared
|
||||
* @return a new type variable declaration
|
||||
* @throws NullPointerException - if any of the actual parameters
|
||||
* or any of the elements of <tt>bounds</tt> are <tt>null</tt>.
|
||||
* @throws NullPointerException if any of the actual parameters
|
||||
* or any of the elements of {@code bounds} are {@code null}.
|
||||
*/
|
||||
TypeVariable<?> makeTypeVariable(String name,
|
||||
FieldTypeSignature[] bounds);
|
||||
/**
|
||||
* Returns an instance of the <tt>ParameterizedType</tt> interface
|
||||
* Returns an instance of the {@code ParameterizedType} interface
|
||||
* that corresponds to a generic type instantiation of the
|
||||
* generic declaration <tt>declaration</tt> with actual type arguments
|
||||
* <tt>typeArgs</tt>.
|
||||
* If <tt>owner</tt> is <tt>null</tt>, the declaring class of
|
||||
* <tt>declaration</tt> is used as the owner of this parameterized
|
||||
* generic declaration {@code declaration} with actual type arguments
|
||||
* {@code typeArgs}.
|
||||
* If {@code owner} is {@code null}, the declaring class of
|
||||
* {@code declaration} is used as the owner of this parameterized
|
||||
* type.
|
||||
* <p> This method throws a MalformedParameterizedTypeException
|
||||
* under the following circumstances:
|
||||
* If the type declaration does not represent a generic declaration
|
||||
* (i.e., it is not an instance of <tt>GenericDeclaration</tt>).
|
||||
* (i.e., it is not an instance of {@code GenericDeclaration}).
|
||||
* If the number of actual type arguments (i.e., the size of the
|
||||
* array <tt>typeArgs</tt>) does not correspond to the number of
|
||||
* array {@code typeArgs}) does not correspond to the number of
|
||||
* formal type arguments.
|
||||
* If any of the actual type arguments is not an instance of the
|
||||
* bounds on the corresponding formal.
|
||||
@ -81,39 +81,39 @@ public interface GenericsFactory {
|
||||
* @param typeArgs - the list of actual type arguments
|
||||
* @return - a parameterized type representing the instantiation
|
||||
* of the declaration with the actual type arguments
|
||||
* @throws MalformedParameterizedTypeException - if the instantiation
|
||||
* @throws MalformedParameterizedTypeException if the instantiation
|
||||
* is invalid
|
||||
* @throws NullPointerException - if any of <tt>declaration</tt>
|
||||
* , <tt>typeArgs</tt>
|
||||
* or any of the elements of <tt>typeArgs</tt> are <tt>null</tt>
|
||||
* @throws NullPointerException if any of {@code declaration},
|
||||
* {@code typeArgs}
|
||||
* or any of the elements of {@code typeArgs} are {@code null}
|
||||
*/
|
||||
ParameterizedType makeParameterizedType(Type declaration,
|
||||
Type[] typeArgs,
|
||||
Type owner);
|
||||
|
||||
/**
|
||||
* Returns the type variable with name <tt>name</tt>, if such
|
||||
* Returns the type variable with name {@code name}, if such
|
||||
* a type variable is declared in the
|
||||
* scope used to create this factory.
|
||||
* Returns <tt>null</tt> otherwise.
|
||||
* Returns {@code null} otherwise.
|
||||
* @param name - the name of the type variable to search for
|
||||
* @return - the type variable with name <tt>name</tt>, or <tt>null</tt>
|
||||
* @throws NullPointerException - if any of actual parameters are
|
||||
* <tt>null</tt>
|
||||
* @return - the type variable with name {@code name}, or {@code null}
|
||||
* @throws NullPointerException if any of actual parameters are
|
||||
* {@code null}
|
||||
*/
|
||||
TypeVariable<?> findTypeVariable(String name);
|
||||
|
||||
/**
|
||||
* Returns a new wildcard type variable. If
|
||||
* <tt>ubs</tt> is empty, a bound of <tt>java.lang.Object</tt> is used.
|
||||
* {@code ubs} is empty, a bound of {@code java.lang.Object} is used.
|
||||
* @param ubs An array of abstract syntax trees representing
|
||||
* the upper bound(s) on the type variable being declared
|
||||
* @param lbs An array of abstract syntax trees representing
|
||||
* the lower bound(s) on the type variable being declared
|
||||
* @return a new wildcard type variable
|
||||
* @throws NullPointerException - if any of the actual parameters
|
||||
* or any of the elements of <tt>ubs</tt> or <tt>lbs</tt>are
|
||||
* <tt>null</tt>
|
||||
* @throws NullPointerException if any of the actual parameters
|
||||
* or any of the elements of {@code ubs} or {@code lbs} are
|
||||
* {@code null}
|
||||
*/
|
||||
WildcardType makeWildcard(FieldTypeSignature[] ubs,
|
||||
FieldTypeSignature[] lbs);
|
||||
@ -127,64 +127,64 @@ public interface GenericsFactory {
|
||||
* a MalformedParameterizedTypeException is thrown.
|
||||
* @param componentType - the component type of the array
|
||||
* @return a (possibly generic) array type.
|
||||
* @throws MalformedParameterizedTypeException if <tt>componentType</tt>
|
||||
* @throws MalformedParameterizedTypeException if {@code componentType}
|
||||
* is a parameterized type with non-wildcard type arguments
|
||||
* @throws NullPointerException - if any of the actual parameters
|
||||
* are <tt>null</tt>
|
||||
* @throws NullPointerException if any of the actual parameters
|
||||
* are {@code null}
|
||||
*/
|
||||
Type makeArrayType(Type componentType);
|
||||
|
||||
/**
|
||||
* Returns the reflective representation of type <tt>byte</tt>.
|
||||
* @return the reflective representation of type <tt>byte</tt>.
|
||||
* Returns the reflective representation of type {@code byte}.
|
||||
* @return the reflective representation of type {@code byte}.
|
||||
*/
|
||||
Type makeByte();
|
||||
|
||||
/**
|
||||
* Returns the reflective representation of type <tt>boolean</tt>.
|
||||
* @return the reflective representation of type <tt>boolean</tt>.
|
||||
* Returns the reflective representation of type {@code boolean}.
|
||||
* @return the reflective representation of type {@code boolean}.
|
||||
*/
|
||||
Type makeBool();
|
||||
|
||||
/**
|
||||
* Returns the reflective representation of type <tt>short</tt>.
|
||||
* @return the reflective representation of type <tt>short</tt>.
|
||||
* Returns the reflective representation of type {@code short}.
|
||||
* @return the reflective representation of type {@code short}.
|
||||
*/
|
||||
Type makeShort();
|
||||
|
||||
/**
|
||||
* Returns the reflective representation of type <tt>char</tt>.
|
||||
* @return the reflective representation of type <tt>char</tt>.
|
||||
* Returns the reflective representation of type {@code char}.
|
||||
* @return the reflective representation of type {@code char}.
|
||||
*/
|
||||
Type makeChar();
|
||||
|
||||
/**
|
||||
* Returns the reflective representation of type <tt>int</tt>.
|
||||
* @return the reflective representation of type <tt>int</tt>.
|
||||
* Returns the reflective representation of type {@code int}.
|
||||
* @return the reflective representation of type {@code int}.
|
||||
*/
|
||||
Type makeInt();
|
||||
|
||||
/**
|
||||
* Returns the reflective representation of type <tt>long</tt>.
|
||||
* @return the reflective representation of type <tt>long</tt>.
|
||||
* Returns the reflective representation of type {@code long}.
|
||||
* @return the reflective representation of type {@code long}.
|
||||
*/
|
||||
Type makeLong();
|
||||
|
||||
/**
|
||||
* Returns the reflective representation of type <tt>float</tt>.
|
||||
* @return the reflective representation of type <tt>float</tt>.
|
||||
* Returns the reflective representation of type {@code float}.
|
||||
* @return the reflective representation of type {@code float}.
|
||||
*/
|
||||
Type makeFloat();
|
||||
|
||||
/**
|
||||
* Returns the reflective representation of type <tt>double</tt>.
|
||||
* @return the reflective representation of type <tt>double</tt>.
|
||||
* Returns the reflective representation of type {@code double}.
|
||||
* @return the reflective representation of type {@code double}.
|
||||
*/
|
||||
Type makeDouble();
|
||||
|
||||
/**
|
||||
* Returns the reflective representation of <tt>void</tt>.
|
||||
* @return the reflective representation of <tt>void</tt>.
|
||||
* Returns the reflective representation of {@code void}.
|
||||
* @return the reflective representation of {@code void}.
|
||||
*/
|
||||
Type makeVoid();
|
||||
}
|
||||
|
@ -135,7 +135,7 @@ public class SignatureParser {
|
||||
|
||||
/**
|
||||
* Static factory method. Produces a parser instance.
|
||||
* @return an instance of <tt>SignatureParser</tt>
|
||||
* @return an instance of {@code SignatureParser}
|
||||
*/
|
||||
public static SignatureParser make() {
|
||||
return new SignatureParser();
|
||||
|
@ -53,10 +53,10 @@ public class GenericArrayTypeImpl
|
||||
|
||||
|
||||
/**
|
||||
* Returns a <tt>Type</tt> object representing the component type
|
||||
* Returns a {@code Type} object representing the component type
|
||||
* of this array.
|
||||
*
|
||||
* @return a <tt>Type</tt> object representing the component type
|
||||
* @return a {@code Type} object representing the component type
|
||||
* of this array
|
||||
* @since 1.5
|
||||
*/
|
||||
|
@ -46,7 +46,7 @@ import sun.reflect.generics.visitor.Reifier;
|
||||
import sun.reflect.misc.ReflectUtil;
|
||||
|
||||
/**
|
||||
* Implementation of <tt>java.lang.reflect.TypeVariable</tt> interface
|
||||
* Implementation of {@code java.lang.reflect.TypeVariable} interface
|
||||
* for core reflection.
|
||||
*/
|
||||
public class TypeVariableImpl<D extends GenericDeclaration>
|
||||
@ -99,9 +99,9 @@ public class TypeVariableImpl<D extends GenericDeclaration>
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of <tt>Type</tt> objects representing the
|
||||
* Returns an array of {@code Type} objects representing the
|
||||
* upper bound(s) of this type variable. Note that if no upper bound is
|
||||
* explicitly declared, the upper bound is <tt>Object</tt>.
|
||||
* explicitly declared, the upper bound is {@code Object}.
|
||||
*
|
||||
* <p>For each upper bound B:
|
||||
* <ul>
|
||||
@ -111,9 +111,9 @@ public class TypeVariableImpl<D extends GenericDeclaration>
|
||||
* <li>Otherwise, B is resolved.
|
||||
* </ul>
|
||||
*
|
||||
* @throws <tt>TypeNotPresentException</tt> if any of the
|
||||
* @throws {@code TypeNotPresentException} if any of the
|
||||
* bounds refers to a non-existent type declaration
|
||||
* @throws <tt>MalformedParameterizedTypeException</tt> if any of the
|
||||
* @throws {@code MalformedParameterizedTypeException} if any of the
|
||||
* bounds refer to a parameterized type that cannot be instantiated
|
||||
* for any reason
|
||||
* @return an array of Types representing the upper bound(s) of this
|
||||
@ -129,7 +129,7 @@ public class TypeVariableImpl<D extends GenericDeclaration>
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the <tt>GenericDeclaration</tt> object representing the
|
||||
* Returns the {@code GenericDeclaration} object representing the
|
||||
* generic declaration that declared this type variable.
|
||||
*
|
||||
* @return the generic declaration that declared this type variable.
|
||||
|
@ -78,9 +78,9 @@ public class WildcardTypeImpl extends LazyReflectiveObjectGenerator
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of <tt>Type</tt> objects representing the upper
|
||||
* Returns an array of {@code Type} objects representing the upper
|
||||
* bound(s) of this type variable. Note that if no upper bound is
|
||||
* explicitly declared, the upper bound is <tt>Object</tt>.
|
||||
* explicitly declared, the upper bound is {@code Object}.
|
||||
*
|
||||
* <p>For each upper bound B :
|
||||
* <ul>
|
||||
@ -92,9 +92,9 @@ public class WildcardTypeImpl extends LazyReflectiveObjectGenerator
|
||||
*
|
||||
* @return an array of Types representing the upper bound(s) of this
|
||||
* type variable
|
||||
* @throws <tt>TypeNotPresentException</tt> if any of the
|
||||
* @throws {@code TypeNotPresentException} if any of the
|
||||
* bounds refers to a non-existent type declaration
|
||||
* @throws <tt>MalformedParameterizedTypeException</tt> if any of the
|
||||
* @throws {@code MalformedParameterizedTypeException} if any of the
|
||||
* bounds refer to a parameterized type that cannot be instantiated
|
||||
* for any reason
|
||||
*/
|
||||
@ -108,9 +108,9 @@ public class WildcardTypeImpl extends LazyReflectiveObjectGenerator
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of <tt>Type</tt> objects representing the
|
||||
* Returns an array of {@code Type} objects representing the
|
||||
* lower bound(s) of this type variable. Note that if no lower bound is
|
||||
* explicitly declared, the lower bound is the type of <tt>null</tt>.
|
||||
* explicitly declared, the lower bound is the type of {@code null}.
|
||||
* In this case, a zero length array is returned.
|
||||
*
|
||||
* <p>For each lower bound B :
|
||||
@ -123,9 +123,9 @@ public class WildcardTypeImpl extends LazyReflectiveObjectGenerator
|
||||
*
|
||||
* @return an array of Types representing the lower bound(s) of this
|
||||
* type variable
|
||||
* @throws <tt>TypeNotPresentException</tt> if any of the
|
||||
* @throws {@code TypeNotPresentException} if any of the
|
||||
* bounds refers to a non-existent type declaration
|
||||
* @throws <tt>MalformedParameterizedTypeException</tt> if any of the
|
||||
* @throws {@code MalformedParameterizedTypeException} if any of the
|
||||
* bounds refer to a parameterized type that cannot be instantiated
|
||||
* for any reason
|
||||
*/
|
||||
|
@ -48,15 +48,15 @@ public abstract class AbstractRepository<T extends Tree> {
|
||||
private GenericsFactory getFactory() { return factory;}
|
||||
|
||||
/**
|
||||
* Accessor for <tt>tree</tt>.
|
||||
* Accessor for {@code tree}.
|
||||
* @return the cached AST this repository holds
|
||||
*/
|
||||
protected T getTree(){ return tree;}
|
||||
|
||||
/**
|
||||
* Returns a <tt>Reifier</tt> used to convert parts of the
|
||||
* Returns a {@code Reifier} used to convert parts of the
|
||||
* AST into reflective objects.
|
||||
* @return a <tt>Reifier</tt> used to convert parts of the
|
||||
* @return a {@code Reifier} used to convert parts of the
|
||||
* AST into reflective objects
|
||||
*/
|
||||
protected Reifier getReifier(){return Reifier.make(getFactory());}
|
||||
|
@ -63,8 +63,8 @@ public class ClassRepository extends GenericDeclRepository<ClassSignature> {
|
||||
* that this repository is servicing
|
||||
* @param f - a factory that will provide instances of reflective
|
||||
* objects when this repository converts its AST
|
||||
* @return a <tt>ClassRepository</tt> that manages the generic type
|
||||
* information represented in the signature <tt>rawSig</tt>
|
||||
* @return a {@code ClassRepository} that manages the generic type
|
||||
* information represented in the signature {@code rawSig}
|
||||
*/
|
||||
public static ClassRepository make(String rawSig, GenericsFactory f) {
|
||||
return new ClassRepository(rawSig, f);
|
||||
|
@ -64,8 +64,8 @@ public class ConstructorRepository
|
||||
* that this repository is servicing
|
||||
* @param f - a factory that will provide instances of reflective
|
||||
* objects when this repository converts its AST
|
||||
* @return a <tt>ConstructorRepository</tt> that manages the generic type
|
||||
* information represented in the signature <tt>rawSig</tt>
|
||||
* @return a {@code ConstructorRepository} that manages the generic type
|
||||
* information represented in the signature {@code rawSig}
|
||||
*/
|
||||
public static ConstructorRepository make(String rawSig, GenericsFactory f) {
|
||||
return new ConstructorRepository(rawSig, f);
|
||||
|
@ -59,8 +59,8 @@ public class FieldRepository extends AbstractRepository<TypeSignature> {
|
||||
* that this repository is servicing
|
||||
* @param f - a factory that will provide instances of reflective
|
||||
* objects when this repository converts its AST
|
||||
* @return a <tt>FieldRepository</tt> that manages the generic type
|
||||
* information represented in the signature <tt>rawSig</tt>
|
||||
* @return a {@code FieldRepository} that manages the generic type
|
||||
* information represented in the signature {@code rawSig}
|
||||
*/
|
||||
public static FieldRepository make(String rawSig, GenericsFactory f) {
|
||||
return new FieldRepository(rawSig, f);
|
||||
|
@ -53,8 +53,8 @@ public class MethodRepository extends ConstructorRepository {
|
||||
* that this repository is servicing
|
||||
* @param f - a factory that will provide instances of reflective
|
||||
* objects when this repository converts its AST
|
||||
* @return a <tt>MethodRepository</tt> that manages the generic type
|
||||
* information represented in the signature <tt>rawSig</tt>
|
||||
* @return a {@code MethodRepository} that manages the generic type
|
||||
* information represented in the signature {@code rawSig}
|
||||
*/
|
||||
public static MethodRepository make(String rawSig, GenericsFactory f) {
|
||||
return new MethodRepository(rawSig, f);
|
||||
|
@ -32,10 +32,10 @@ import java.lang.reflect.TypeVariable;
|
||||
/**
|
||||
* Abstract superclass for lazy scope objects, used when building
|
||||
* factories for generic information repositories.
|
||||
* The type parameter <tt>D</tt> represents the type of reflective
|
||||
* The type parameter {@code D} represents the type of reflective
|
||||
* object whose scope this class is representing.
|
||||
* <p> To subclass this, all one needs to do is implement
|
||||
* <tt>computeEnclosingScope</tt> and the subclass' constructor.
|
||||
* {@code computeEnclosingScope} and the subclass' constructor.
|
||||
*/
|
||||
public abstract class AbstractScope<D extends GenericDeclaration>
|
||||
implements Scope {
|
||||
@ -54,9 +54,9 @@ public abstract class AbstractScope<D extends GenericDeclaration>
|
||||
protected AbstractScope(D decl){ recvr = decl;}
|
||||
|
||||
/**
|
||||
* Accessor for the receiver - the object whose scope this <tt>Scope</tt>
|
||||
* Accessor for the receiver - the object whose scope this {@code Scope}
|
||||
* object represents.
|
||||
* @return The object whose scope this <tt>Scope</tt> object represents
|
||||
* @return The object whose scope this {@code Scope} object represents
|
||||
*/
|
||||
protected D getRecvr() {return recvr;}
|
||||
|
||||
|
@ -73,7 +73,7 @@ public class ClassScope extends AbstractScope<Class<?>> implements Scope {
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method. Takes a <tt>Class</tt> object and creates a
|
||||
* Factory method. Takes a {@code Class} object and creates a
|
||||
* scope for it.
|
||||
* @param c - a Class whose scope we want to obtain
|
||||
* @return The type-variable scope for the class c
|
||||
|
@ -29,9 +29,9 @@ import java.lang.reflect.TypeVariable;
|
||||
|
||||
/**
|
||||
* This class is used to provide enclosing scopes for top level classes.
|
||||
* We cannot use <tt>null</tt> to represent such a scope, since the
|
||||
* We cannot use {@code null} to represent such a scope, since the
|
||||
* enclosing scope is computed lazily, and so the field storing it is
|
||||
* null until it has been computed. Therefore, <tt>null</tt> is reserved
|
||||
* null until it has been computed. Therefore, {@code null} is reserved
|
||||
* to represent an as-yet-uncomputed scope, and cannot be used for any
|
||||
* other kind of scope.
|
||||
*/
|
||||
@ -53,7 +53,7 @@ public class DummyScope implements Scope {
|
||||
|
||||
/**
|
||||
* Lookup a type variable in the scope, using its name. Always returns
|
||||
* <tt>null</tt>.
|
||||
* {@code null}.
|
||||
* @param name - the name of the type variable being looked up
|
||||
* @return null
|
||||
*/
|
||||
|
@ -56,7 +56,7 @@ public class MethodScope extends AbstractScope<Method> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method. Takes a <tt>Method</tt> object and creates a
|
||||
* Factory method. Takes a {@code Method} object and creates a
|
||||
* scope for it.
|
||||
* @param m - A Method whose scope we want to obtain
|
||||
* @return The type-variable scope for the method m
|
||||
|
@ -33,7 +33,7 @@ import sun.reflect.generics.visitor.TypeTreeVisitor;
|
||||
public interface TypeTree extends Tree {
|
||||
/**
|
||||
* Accept method for the visitor pattern.
|
||||
* @param v - a <tt>TypeTreeVisitor</tt> that will process this
|
||||
* @param v a {@code TypeTreeVisitor} that will process this
|
||||
* tree
|
||||
*/
|
||||
void accept(TypeTreeVisitor<?> v);
|
||||
|
@ -50,7 +50,7 @@ public class Reifier implements TypeTreeVisitor<Type> {
|
||||
/**
|
||||
* Factory method. The resulting visitor will convert an AST
|
||||
* representing generic signatures into corresponding reflective
|
||||
* objects, using the provided factory, <tt>f</tt>.
|
||||
* objects, using the provided factory, {@code f}.
|
||||
* @param f - a factory that can be used to manufacture reflective
|
||||
* objects returned by this visitor
|
||||
* @return A visitor that can be used to reify ASTs representing
|
||||
|
@ -1,128 +0,0 @@
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998, 2001, 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.
|
||||
*/
|
||||
|
||||
/* __ieee754_hypot(x,y)
|
||||
*
|
||||
* Method :
|
||||
* If (assume round-to-nearest) z=x*x+y*y
|
||||
* has error less than sqrt(2)/2 ulp, than
|
||||
* sqrt(z) has error less than 1 ulp (exercise).
|
||||
*
|
||||
* So, compute sqrt(x*x+y*y) with some care as
|
||||
* follows to get the error below 1 ulp:
|
||||
*
|
||||
* Assume x>y>0;
|
||||
* (if possible, set rounding to round-to-nearest)
|
||||
* 1. if x > 2y use
|
||||
* x1*x1+(y*y+(x2*(x+x1))) for x*x+y*y
|
||||
* where x1 = x with lower 32 bits cleared, x2 = x-x1; else
|
||||
* 2. if x <= 2y use
|
||||
* t1*y1+((x-y)*(x-y)+(t1*y2+t2*y))
|
||||
* where t1 = 2x with lower 32 bits cleared, t2 = 2x-t1,
|
||||
* y1= y with lower 32 bits chopped, y2 = y-y1.
|
||||
*
|
||||
* NOTE: scaling may be necessary if some argument is too
|
||||
* large or too tiny
|
||||
*
|
||||
* Special cases:
|
||||
* hypot(x,y) is INF if x or y is +INF or -INF; else
|
||||
* hypot(x,y) is NAN if x or y is NAN.
|
||||
*
|
||||
* Accuracy:
|
||||
* hypot(x,y) returns sqrt(x^2+y^2) with error less
|
||||
* than 1 ulps (units in the last place)
|
||||
*/
|
||||
|
||||
#include "fdlibm.h"
|
||||
|
||||
#ifdef __STDC__
|
||||
double __ieee754_hypot(double x, double y)
|
||||
#else
|
||||
double __ieee754_hypot(x,y)
|
||||
double x, y;
|
||||
#endif
|
||||
{
|
||||
double a=x,b=y,t1,t2,y1,y2,w;
|
||||
int j,k,ha,hb;
|
||||
|
||||
ha = __HI(x)&0x7fffffff; /* high word of x */
|
||||
hb = __HI(y)&0x7fffffff; /* high word of y */
|
||||
if(hb > ha) {a=y;b=x;j=ha; ha=hb;hb=j;} else {a=x;b=y;}
|
||||
__HI(a) = ha; /* a <- |a| */
|
||||
__HI(b) = hb; /* b <- |b| */
|
||||
if((ha-hb)>0x3c00000) {return a+b;} /* x/y > 2**60 */
|
||||
k=0;
|
||||
if(ha > 0x5f300000) { /* a>2**500 */
|
||||
if(ha >= 0x7ff00000) { /* Inf or NaN */
|
||||
w = a+b; /* for sNaN */
|
||||
if(((ha&0xfffff)|__LO(a))==0) w = a;
|
||||
if(((hb^0x7ff00000)|__LO(b))==0) w = b;
|
||||
return w;
|
||||
}
|
||||
/* scale a and b by 2**-600 */
|
||||
ha -= 0x25800000; hb -= 0x25800000; k += 600;
|
||||
__HI(a) = ha;
|
||||
__HI(b) = hb;
|
||||
}
|
||||
if(hb < 0x20b00000) { /* b < 2**-500 */
|
||||
if(hb <= 0x000fffff) { /* subnormal b or 0 */
|
||||
if((hb|(__LO(b)))==0) return a;
|
||||
t1=0;
|
||||
__HI(t1) = 0x7fd00000; /* t1=2^1022 */
|
||||
b *= t1;
|
||||
a *= t1;
|
||||
k -= 1022;
|
||||
} else { /* scale a and b by 2^600 */
|
||||
ha += 0x25800000; /* a *= 2^600 */
|
||||
hb += 0x25800000; /* b *= 2^600 */
|
||||
k -= 600;
|
||||
__HI(a) = ha;
|
||||
__HI(b) = hb;
|
||||
}
|
||||
}
|
||||
/* medium size a and b */
|
||||
w = a-b;
|
||||
if (w>b) {
|
||||
t1 = 0;
|
||||
__HI(t1) = ha;
|
||||
t2 = a-t1;
|
||||
w = sqrt(t1*t1-(b*(-b)-t2*(a+t1)));
|
||||
} else {
|
||||
a = a+a;
|
||||
y1 = 0;
|
||||
__HI(y1) = hb;
|
||||
y2 = b - y1;
|
||||
t1 = 0;
|
||||
__HI(t1) = ha+0x00100000;
|
||||
t2 = a - t1;
|
||||
w = sqrt(t1*y1-(w*(-w)-(t1*y2+t2*b)));
|
||||
}
|
||||
if(k!=0) {
|
||||
t1 = 1.0;
|
||||
__HI(t1) += (k<<20);
|
||||
return t1*w;
|
||||
} else return w;
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998, 2001, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* wrapper hypot(x,y)
|
||||
*/
|
||||
|
||||
#include "fdlibm.h"
|
||||
|
||||
|
||||
#ifdef __STDC__
|
||||
double hypot(double x, double y)/* wrapper hypot */
|
||||
#else
|
||||
double hypot(x,y) /* wrapper hypot */
|
||||
double x,y;
|
||||
#endif
|
||||
{
|
||||
#ifdef _IEEE_LIBM
|
||||
return __ieee754_hypot(x,y);
|
||||
#else
|
||||
double z;
|
||||
z = __ieee754_hypot(x,y);
|
||||
if(_LIB_VERSION == _IEEE_) return z;
|
||||
if((!finite(z))&&finite(x)&&finite(y))
|
||||
return __kernel_standard(x,y,4); /* hypot overflow */
|
||||
else
|
||||
return z;
|
||||
#endif
|
||||
}
|
@ -126,14 +126,6 @@ Java_java_lang_StrictMath_tanh(JNIEnv *env, jclass unused, jdouble d)
|
||||
return (jdouble) jtanh((double)d);
|
||||
}
|
||||
|
||||
JNIEXPORT jdouble JNICALL
|
||||
Java_java_lang_StrictMath_hypot(JNIEnv *env, jclass unused, jdouble x, jdouble y)
|
||||
{
|
||||
return (jdouble) jhypot((double)x, (double)y);
|
||||
}
|
||||
|
||||
|
||||
|
||||
JNIEXPORT jdouble JNICALL
|
||||
Java_java_lang_StrictMath_log1p(JNIEnv *env, jclass unused, jdouble d)
|
||||
{
|
||||
|
@ -4,7 +4,9 @@
|
||||
*
|
||||
* 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.
|
||||
* 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
|
||||
@ -19,7 +21,6 @@
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
@ -4,11 +4,13 @@
|
||||
*
|
||||
* 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.
|
||||
* 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
|
||||
* 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).
|
||||
*
|
||||
@ -19,7 +21,6 @@
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "endian.hpp"
|
||||
@ -27,20 +28,20 @@
|
||||
|
||||
// Most modern compilers optimize the bswap routines to native instructions.
|
||||
inline static u2 bswap_16(u2 x) {
|
||||
return ((x & 0xFF) << 8) |
|
||||
((x >> 8) & 0xFF);
|
||||
return ((x & 0xFF) << 8) |
|
||||
((x >> 8) & 0xFF);
|
||||
}
|
||||
|
||||
inline static u4 bswap_32(u4 x) {
|
||||
return ((x & 0xFF) << 24) |
|
||||
((x & 0xFF00) << 8) |
|
||||
((x >> 8) & 0xFF00) |
|
||||
((x >> 24) & 0xFF);
|
||||
return ((x & 0xFF) << 24) |
|
||||
((x & 0xFF00) << 8) |
|
||||
((x >> 8) & 0xFF00) |
|
||||
((x >> 24) & 0xFF);
|
||||
}
|
||||
|
||||
inline static u8 bswap_64(u8 x) {
|
||||
return (u8)bswap_32((u4)x) << 32 |
|
||||
(u8)bswap_32((u4)(x >> 32));
|
||||
return (u8)bswap_32((u4)x) << 32 |
|
||||
(u8)bswap_32((u4)(x >> 32));
|
||||
}
|
||||
|
||||
u2 NativeEndian::get(u2 x) { return x; }
|
||||
@ -76,27 +77,27 @@ void SwappingEndian::set(s8& x, s8 y) { x = bswap_64(y); }
|
||||
SwappingEndian SwappingEndian::_swapping;
|
||||
|
||||
Endian* Endian::get_handler(bool big_endian) {
|
||||
// If requesting little endian on a little endian machine or
|
||||
// big endian on a big endian machine use native handler
|
||||
if (big_endian == is_big_endian()) {
|
||||
return NativeEndian::get_native();
|
||||
} else {
|
||||
// Use swapping handler.
|
||||
return SwappingEndian::get_swapping();
|
||||
}
|
||||
// If requesting little endian on a little endian machine or
|
||||
// big endian on a big endian machine use native handler
|
||||
if (big_endian == is_big_endian()) {
|
||||
return NativeEndian::get_native();
|
||||
} else {
|
||||
// Use swapping handler.
|
||||
return SwappingEndian::get_swapping();
|
||||
}
|
||||
}
|
||||
|
||||
// Return a platform u2 from an array in which Big Endian is applied.
|
||||
u2 Endian::get_java(u1* x) {
|
||||
return (u2) (x[0]<<8 | x[1]);
|
||||
return (u2) (x[0]<<8 | x[1]);
|
||||
}
|
||||
|
||||
// Add a platform u2 to the array as a Big Endian u2
|
||||
void Endian::set_java(u1* p, u2 x) {
|
||||
p[0] = (x >> 8) & 0xff;
|
||||
p[1] = x & 0xff;
|
||||
p[0] = (x >> 8) & 0xff;
|
||||
p[1] = x & 0xff;
|
||||
}
|
||||
|
||||
Endian* Endian::get_native_handler() {
|
||||
return NativeEndian::get_native();
|
||||
return NativeEndian::get_native();
|
||||
}
|
||||
|
@ -4,11 +4,13 @@
|
||||
*
|
||||
* 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.
|
||||
* 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
|
||||
* 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).
|
||||
*
|
||||
@ -19,7 +21,6 @@
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LIBJIMAGE_ENDIAN_HPP
|
||||
@ -36,89 +37,89 @@
|
||||
// To retrieve a value using the approprate endian, use one of the overloaded
|
||||
// calls to get. To set a value, then use one of the overloaded set calls.
|
||||
// Ex.
|
||||
// s4 value; // Imported value;
|
||||
// ...
|
||||
// Endian* endian = Endian::get_handler(true); // Use big endian
|
||||
// s4 corrected = endian->get(value);
|
||||
// endian->set(value, 1);
|
||||
// s4 value; // Imported value;
|
||||
// ...
|
||||
// Endian* endian = Endian::get_handler(true); // Use big endian
|
||||
// s4 corrected = endian->get(value);
|
||||
// endian->set(value, 1);
|
||||
//
|
||||
class Endian {
|
||||
public:
|
||||
virtual u2 get(u2 x) = 0;
|
||||
virtual u4 get(u4 x) = 0;
|
||||
virtual u8 get(u8 x) = 0;
|
||||
virtual s2 get(s2 x) = 0;
|
||||
virtual s4 get(s4 x) = 0;
|
||||
virtual s8 get(s8 x) = 0;
|
||||
virtual u2 get(u2 x) = 0;
|
||||
virtual u4 get(u4 x) = 0;
|
||||
virtual u8 get(u8 x) = 0;
|
||||
virtual s2 get(s2 x) = 0;
|
||||
virtual s4 get(s4 x) = 0;
|
||||
virtual s8 get(s8 x) = 0;
|
||||
|
||||
virtual void set(u2& x, u2 y) = 0;
|
||||
virtual void set(u4& x, u4 y) = 0;
|
||||
virtual void set(u8& x, u8 y) = 0;
|
||||
virtual void set(s2& x, s2 y) = 0;
|
||||
virtual void set(s4& x, s4 y) = 0;
|
||||
virtual void set(s8& x, s8 y) = 0;
|
||||
virtual void set(u2& x, u2 y) = 0;
|
||||
virtual void set(u4& x, u4 y) = 0;
|
||||
virtual void set(u8& x, u8 y) = 0;
|
||||
virtual void set(s2& x, s2 y) = 0;
|
||||
virtual void set(s4& x, s4 y) = 0;
|
||||
virtual void set(s8& x, s8 y) = 0;
|
||||
|
||||
// Quick little endian test.
|
||||
static bool is_little_endian() { u4 x = 1; return *(u1 *)&x != 0; }
|
||||
// Quick little endian test.
|
||||
static bool is_little_endian() { u4 x = 1; return *(u1 *)&x != 0; }
|
||||
|
||||
// Quick big endian test.
|
||||
static bool is_big_endian() { return !is_little_endian(); }
|
||||
// Quick big endian test.
|
||||
static bool is_big_endian() { return !is_little_endian(); }
|
||||
|
||||
// Select an appropriate endian handler.
|
||||
static Endian* get_handler(bool big_endian);
|
||||
// Select an appropriate endian handler.
|
||||
static Endian* get_handler(bool big_endian);
|
||||
|
||||
// Return the native endian handler.
|
||||
static Endian* get_native_handler();
|
||||
// Return the native endian handler.
|
||||
static Endian* get_native_handler();
|
||||
|
||||
// get platform u2 from Java Big endian
|
||||
static u2 get_java(u1* x);
|
||||
// set platform u2 to Java Big endian
|
||||
static void set_java(u1* p, u2 x);
|
||||
// get platform u2 from Java Big endian
|
||||
static u2 get_java(u1* x);
|
||||
// set platform u2 to Java Big endian
|
||||
static void set_java(u1* p, u2 x);
|
||||
};
|
||||
|
||||
// Normal endian handling.
|
||||
class NativeEndian : public Endian {
|
||||
private:
|
||||
static NativeEndian _native;
|
||||
static NativeEndian _native;
|
||||
|
||||
public:
|
||||
u2 get(u2 x);
|
||||
u4 get(u4 x);
|
||||
u8 get(u8 x);
|
||||
s2 get(s2 x);
|
||||
s4 get(s4 x);
|
||||
s8 get(s8 x);
|
||||
u2 get(u2 x);
|
||||
u4 get(u4 x);
|
||||
u8 get(u8 x);
|
||||
s2 get(s2 x);
|
||||
s4 get(s4 x);
|
||||
s8 get(s8 x);
|
||||
|
||||
void set(u2& x, u2 y);
|
||||
void set(u4& x, u4 y);
|
||||
void set(u8& x, u8 y);
|
||||
void set(s2& x, s2 y);
|
||||
void set(s4& x, s4 y);
|
||||
void set(s8& x, s8 y);
|
||||
void set(u2& x, u2 y);
|
||||
void set(u4& x, u4 y);
|
||||
void set(u8& x, u8 y);
|
||||
void set(s2& x, s2 y);
|
||||
void set(s4& x, s4 y);
|
||||
void set(s8& x, s8 y);
|
||||
|
||||
static Endian* get_native() { return &_native; }
|
||||
static Endian* get_native() { return &_native; }
|
||||
};
|
||||
|
||||
// Swapping endian handling.
|
||||
class SwappingEndian : public Endian {
|
||||
private:
|
||||
static SwappingEndian _swapping;
|
||||
static SwappingEndian _swapping;
|
||||
|
||||
public:
|
||||
u2 get(u2 x);
|
||||
u4 get(u4 x);
|
||||
u8 get(u8 x);
|
||||
s2 get(s2 x);
|
||||
s4 get(s4 x);
|
||||
s8 get(s8 x);
|
||||
u2 get(u2 x);
|
||||
u4 get(u4 x);
|
||||
u8 get(u8 x);
|
||||
s2 get(s2 x);
|
||||
s4 get(s4 x);
|
||||
s8 get(s8 x);
|
||||
|
||||
void set(u2& x, u2 y);
|
||||
void set(u4& x, u4 y);
|
||||
void set(u8& x, u8 y);
|
||||
void set(s2& x, s2 y);
|
||||
void set(s4& x, s4 y);
|
||||
void set(s8& x, s8 y);
|
||||
void set(u2& x, u2 y);
|
||||
void set(u4& x, u4 y);
|
||||
void set(u8& x, u8 y);
|
||||
void set(s2& x, s2 y);
|
||||
void set(s4& x, s4 y);
|
||||
void set(s8& x, s8 y);
|
||||
|
||||
static Endian* get_swapping() { return &_swapping; }
|
||||
static Endian* get_swapping() { return &_swapping; }
|
||||
};
|
||||
#endif // LIBJIMAGE_ENDIAN_HPP
|
||||
|
@ -4,11 +4,13 @@
|
||||
*
|
||||
* 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.
|
||||
* 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
|
||||
* 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).
|
||||
*
|
||||
@ -19,10 +21,8 @@
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "jni.h"
|
||||
#include "imageDecompressor.hpp"
|
||||
#include "endian.hpp"
|
||||
@ -32,16 +32,17 @@
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
typedef jboolean (JNICALL *ZipInflateFully_t)(void *inBuf, jlong inLen, void *outBuf, jlong outLen, char **pmsg);
|
||||
static ZipInflateFully_t ZipInflateFully = NULL;
|
||||
typedef jboolean (JNICALL *ZipInflateFully_t)(void *inBuf, jlong inLen,
|
||||
void *outBuf, jlong outLen, char **pmsg);
|
||||
static ZipInflateFully_t ZipInflateFully = NULL;
|
||||
|
||||
#ifndef WIN32
|
||||
#define JNI_LIB_PREFIX "lib"
|
||||
#ifdef __APPLE__
|
||||
#define JNI_LIB_SUFFIX ".dylib"
|
||||
#else
|
||||
#define JNI_LIB_SUFFIX ".so"
|
||||
#endif
|
||||
#define JNI_LIB_PREFIX "lib"
|
||||
#ifdef __APPLE__
|
||||
#define JNI_LIB_SUFFIX ".dylib"
|
||||
#else
|
||||
#define JNI_LIB_SUFFIX ".so"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
@ -50,21 +51,21 @@ static ZipInflateFully_t ZipInflateFully = NULL;
|
||||
* @return the address of the entry point or NULL
|
||||
*/
|
||||
static void* findEntry(const char* name) {
|
||||
void *addr = NULL;
|
||||
void *addr = NULL;
|
||||
#ifdef WIN32
|
||||
HMODULE handle = GetModuleHandle("zip.dll");
|
||||
if (handle == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
addr = (void*) GetProcAddress(handle, name);
|
||||
return addr;
|
||||
HMODULE handle = GetModuleHandle("zip.dll");
|
||||
if (handle == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
addr = (void*) GetProcAddress(handle, name);
|
||||
return addr;
|
||||
#else
|
||||
addr = dlopen(JNI_LIB_PREFIX "zip" JNI_LIB_SUFFIX, RTLD_GLOBAL|RTLD_LAZY);
|
||||
if (addr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
addr = dlsym(addr, name);
|
||||
return addr;
|
||||
addr = dlopen(JNI_LIB_PREFIX "zip" JNI_LIB_SUFFIX, RTLD_GLOBAL|RTLD_LAZY);
|
||||
if (addr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
addr = dlsym(addr, name);
|
||||
return addr;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -74,87 +75,87 @@ static void* findEntry(const char* name) {
|
||||
int ImageDecompressor::_decompressors_num = 0;
|
||||
ImageDecompressor** ImageDecompressor::_decompressors = NULL;
|
||||
void ImageDecompressor::image_decompressor_init() {
|
||||
if (_decompressors == NULL) {
|
||||
ZipInflateFully = (ZipInflateFully_t) findEntry("ZIP_InflateFully");
|
||||
assert(ZipInflateFully != NULL && "ZIP decompressor not found.");
|
||||
_decompressors_num = 2;
|
||||
_decompressors = new ImageDecompressor*[_decompressors_num];
|
||||
_decompressors[0] = new ZipDecompressor("zip");
|
||||
_decompressors[1] = new SharedStringDecompressor("compact-cp");
|
||||
}
|
||||
if (_decompressors == NULL) {
|
||||
ZipInflateFully = (ZipInflateFully_t) findEntry("ZIP_InflateFully");
|
||||
assert(ZipInflateFully != NULL && "ZIP decompressor not found.");
|
||||
_decompressors_num = 2;
|
||||
_decompressors = new ImageDecompressor*[_decompressors_num];
|
||||
_decompressors[0] = new ZipDecompressor("zip");
|
||||
_decompressors[1] = new SharedStringDecompressor("compact-cp");
|
||||
}
|
||||
}
|
||||
|
||||
void ImageDecompressor::image_decompressor_close() {
|
||||
delete _decompressors;
|
||||
delete _decompressors;
|
||||
}
|
||||
|
||||
/*
|
||||
* Locate decompressor.
|
||||
*/
|
||||
ImageDecompressor* ImageDecompressor::get_decompressor(const char * decompressor_name) {
|
||||
image_decompressor_init();
|
||||
for (int i = 0; i < _decompressors_num; i++) {
|
||||
ImageDecompressor* decompressor = _decompressors[i];
|
||||
assert(decompressor != NULL && "Decompressors not initialized.");
|
||||
if (strcmp(decompressor->get_name(), decompressor_name) == 0) {
|
||||
return decompressor;
|
||||
image_decompressor_init();
|
||||
for (int i = 0; i < _decompressors_num; i++) {
|
||||
ImageDecompressor* decompressor = _decompressors[i];
|
||||
assert(decompressor != NULL && "Decompressors not initialized.");
|
||||
if (strcmp(decompressor->get_name(), decompressor_name) == 0) {
|
||||
return decompressor;
|
||||
}
|
||||
}
|
||||
}
|
||||
assert(false && "No decompressor found.");
|
||||
return NULL;
|
||||
assert(false && "No decompressor found.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Decompression entry point. Called from ImageFileReader::get_resource.
|
||||
*/
|
||||
void ImageDecompressor::decompress_resource(u1* compressed, u1* uncompressed,
|
||||
u4 uncompressed_size, const ImageStrings* strings) {
|
||||
bool has_header = false;
|
||||
u1* decompressed_resource = compressed;
|
||||
u1* compressed_resource = compressed;
|
||||
u4 uncompressed_size, const ImageStrings* strings) {
|
||||
bool has_header = false;
|
||||
u1* decompressed_resource = compressed;
|
||||
u1* compressed_resource = compressed;
|
||||
|
||||
// Resource could have been transformed by a stack of decompressors.
|
||||
// Iterate and decompress resources until there is no more header.
|
||||
do {
|
||||
ResourceHeader _header;
|
||||
memcpy(&_header, compressed_resource, sizeof (ResourceHeader));
|
||||
has_header = _header._magic == ResourceHeader::resource_header_magic;
|
||||
if (has_header) {
|
||||
// decompressed_resource array contains the result of decompression
|
||||
decompressed_resource = new u1[_header._uncompressed_size];
|
||||
// Retrieve the decompressor name
|
||||
const char* decompressor_name = strings->get(_header._decompressor_name_offset);
|
||||
assert(decompressor_name && "image decompressor not found");
|
||||
// Retrieve the decompressor instance
|
||||
ImageDecompressor* decompressor = get_decompressor(decompressor_name);
|
||||
assert(decompressor && "image decompressor not found");
|
||||
u1* compressed_resource_base = compressed_resource;
|
||||
compressed_resource += ResourceHeader::resource_header_length;
|
||||
// Ask the decompressor to decompress the compressed content
|
||||
decompressor->decompress_resource(compressed_resource, decompressed_resource,
|
||||
&_header, strings);
|
||||
if (compressed_resource_base != compressed) {
|
||||
delete compressed_resource_base;
|
||||
}
|
||||
compressed_resource = decompressed_resource;
|
||||
}
|
||||
} while (has_header);
|
||||
memcpy(uncompressed, decompressed_resource, uncompressed_size);
|
||||
delete decompressed_resource;
|
||||
// Resource could have been transformed by a stack of decompressors.
|
||||
// Iterate and decompress resources until there is no more header.
|
||||
do {
|
||||
ResourceHeader _header;
|
||||
memcpy(&_header, compressed_resource, sizeof (ResourceHeader));
|
||||
has_header = _header._magic == ResourceHeader::resource_header_magic;
|
||||
if (has_header) {
|
||||
// decompressed_resource array contains the result of decompression
|
||||
decompressed_resource = new u1[_header._uncompressed_size];
|
||||
// Retrieve the decompressor name
|
||||
const char* decompressor_name = strings->get(_header._decompressor_name_offset);
|
||||
assert(decompressor_name && "image decompressor not found");
|
||||
// Retrieve the decompressor instance
|
||||
ImageDecompressor* decompressor = get_decompressor(decompressor_name);
|
||||
assert(decompressor && "image decompressor not found");
|
||||
u1* compressed_resource_base = compressed_resource;
|
||||
compressed_resource += ResourceHeader::resource_header_length;
|
||||
// Ask the decompressor to decompress the compressed content
|
||||
decompressor->decompress_resource(compressed_resource, decompressed_resource,
|
||||
&_header, strings);
|
||||
if (compressed_resource_base != compressed) {
|
||||
delete compressed_resource_base;
|
||||
}
|
||||
compressed_resource = decompressed_resource;
|
||||
}
|
||||
} while (has_header);
|
||||
memcpy(uncompressed, decompressed_resource, uncompressed_size);
|
||||
delete decompressed_resource;
|
||||
}
|
||||
|
||||
// Zip decompressor
|
||||
|
||||
void ZipDecompressor::decompress_resource(u1* data, u1* uncompressed,
|
||||
ResourceHeader* header, const ImageStrings* strings) {
|
||||
char* msg = NULL;
|
||||
jboolean res = ZipDecompressor::decompress(data, header->_size, uncompressed,
|
||||
header->_uncompressed_size, &msg);
|
||||
assert(res && "decompression failed");
|
||||
ResourceHeader* header, const ImageStrings* strings) {
|
||||
char* msg = NULL;
|
||||
jboolean res = ZipDecompressor::decompress(data, header->_size, uncompressed,
|
||||
header->_uncompressed_size, &msg);
|
||||
assert(res && "decompression failed");
|
||||
}
|
||||
|
||||
jboolean ZipDecompressor::decompress(void *in, u8 inSize, void *out, u8 outSize, char **pmsg) {
|
||||
return (*ZipInflateFully)(in, inSize, out, outSize, pmsg);
|
||||
return (*ZipInflateFully)(in, inSize, out, outSize, pmsg);
|
||||
}
|
||||
|
||||
// END Zip Decompressor
|
||||
@ -163,141 +164,143 @@ jboolean ZipDecompressor::decompress(void *in, u8 inSize, void *out, u8 outSize,
|
||||
|
||||
// array index is the constant pool tag. value is size.
|
||||
// eg: array[5] = 8; means size of long is 8 bytes.
|
||||
const u1 SharedStringDecompressor::sizes[] = {0, 0, 0, 4, 4, 8, 8, 2, 2, 4, 4, 4, 4, 0, 0, 3, 2, 0, 4};
|
||||
const u1 SharedStringDecompressor::sizes[] = {
|
||||
0, 0, 0, 4, 4, 8, 8, 2, 2, 4, 4, 4, 4, 0, 0, 3, 2, 0, 4
|
||||
};
|
||||
/**
|
||||
* Recreate the class by reconstructing the constant pool.
|
||||
*/
|
||||
void SharedStringDecompressor::decompress_resource(u1* data,
|
||||
u1* uncompressed_resource,
|
||||
ResourceHeader* header, const ImageStrings* strings) {
|
||||
u1* uncompressed_base = uncompressed_resource;
|
||||
u1* data_base = data;
|
||||
int header_size = 8; // magic + major + minor
|
||||
memcpy(uncompressed_resource, data, header_size + 2); //+ cp count
|
||||
uncompressed_resource += header_size + 2;
|
||||
data += header_size;
|
||||
u2 cp_count = Endian::get_java(data);
|
||||
data += 2;
|
||||
for (int i = 1; i < cp_count; i++) {
|
||||
u1 tag = *data;
|
||||
data += 1;
|
||||
switch (tag) {
|
||||
u1* uncompressed_resource,
|
||||
ResourceHeader* header, const ImageStrings* strings) {
|
||||
u1* uncompressed_base = uncompressed_resource;
|
||||
u1* data_base = data;
|
||||
int header_size = 8; // magic + major + minor
|
||||
memcpy(uncompressed_resource, data, header_size + 2); //+ cp count
|
||||
uncompressed_resource += header_size + 2;
|
||||
data += header_size;
|
||||
u2 cp_count = Endian::get_java(data);
|
||||
data += 2;
|
||||
for (int i = 1; i < cp_count; i++) {
|
||||
u1 tag = *data;
|
||||
data += 1;
|
||||
switch (tag) {
|
||||
|
||||
case externalized_string:
|
||||
{ // String in Strings table
|
||||
*uncompressed_resource = 1;
|
||||
uncompressed_resource += 1;
|
||||
int i = decompress_int(data);
|
||||
const char * string = strings->get(i);
|
||||
int str_length = (int) strlen(string);
|
||||
Endian::set_java(uncompressed_resource, str_length);
|
||||
uncompressed_resource += 2;
|
||||
memcpy(uncompressed_resource, string, str_length);
|
||||
uncompressed_resource += str_length;
|
||||
break;
|
||||
}
|
||||
// Descriptor String has been split and types added to Strings table
|
||||
case externalized_string_descriptor:
|
||||
{
|
||||
*uncompressed_resource = 1;
|
||||
uncompressed_resource += 1;
|
||||
int descriptor_index = decompress_int(data);
|
||||
int indexes_length = decompress_int(data);
|
||||
u1* length_address = uncompressed_resource;
|
||||
uncompressed_resource += 2;
|
||||
int desc_length = 0;
|
||||
const char * desc_string = strings->get(descriptor_index);
|
||||
if (indexes_length > 0) {
|
||||
u1* indexes_base = data;
|
||||
data += indexes_length;
|
||||
char c = *desc_string;
|
||||
do {
|
||||
*uncompressed_resource = c;
|
||||
uncompressed_resource++;
|
||||
desc_length += 1;
|
||||
/*
|
||||
* Every L character is the marker we are looking at in order
|
||||
* to reconstruct the descriptor. Each time an L is found, then
|
||||
* we retrieve the couple token/token at the current index and
|
||||
* add it to the descriptor.
|
||||
* "(L;I)V" and "java/lang","String" couple of tokens,
|
||||
* this becomes "(Ljava/lang/String;I)V"
|
||||
*/
|
||||
if (c == 'L') {
|
||||
int index = decompress_int(indexes_base);
|
||||
const char * pkg = strings->get(index);
|
||||
int str_length = (int) strlen(pkg);
|
||||
// the case where we have a package.
|
||||
// reconstruct the type full name
|
||||
if (str_length > 0) {
|
||||
int len = str_length + 1;
|
||||
char* fullpkg = new char[len];
|
||||
char* pkg_base = fullpkg;
|
||||
memcpy(fullpkg, pkg, str_length);
|
||||
fullpkg += str_length;
|
||||
*fullpkg = '/';
|
||||
memcpy(uncompressed_resource, pkg_base, len);
|
||||
uncompressed_resource += len;
|
||||
delete pkg_base;
|
||||
desc_length += len;
|
||||
} else { // Empty package
|
||||
// Nothing to do.
|
||||
}
|
||||
int classIndex = decompress_int(indexes_base);
|
||||
const char * clazz = strings->get(classIndex);
|
||||
int clazz_length = (int) strlen(clazz);
|
||||
memcpy(uncompressed_resource, clazz, clazz_length);
|
||||
uncompressed_resource += clazz_length;
|
||||
desc_length += clazz_length;
|
||||
case externalized_string:
|
||||
{ // String in Strings table
|
||||
*uncompressed_resource = 1;
|
||||
uncompressed_resource += 1;
|
||||
int i = decompress_int(data);
|
||||
const char * string = strings->get(i);
|
||||
int str_length = (int) strlen(string);
|
||||
Endian::set_java(uncompressed_resource, str_length);
|
||||
uncompressed_resource += 2;
|
||||
memcpy(uncompressed_resource, string, str_length);
|
||||
uncompressed_resource += str_length;
|
||||
break;
|
||||
}
|
||||
// Descriptor String has been split and types added to Strings table
|
||||
case externalized_string_descriptor:
|
||||
{
|
||||
*uncompressed_resource = 1;
|
||||
uncompressed_resource += 1;
|
||||
int descriptor_index = decompress_int(data);
|
||||
int indexes_length = decompress_int(data);
|
||||
u1* length_address = uncompressed_resource;
|
||||
uncompressed_resource += 2;
|
||||
int desc_length = 0;
|
||||
const char * desc_string = strings->get(descriptor_index);
|
||||
if (indexes_length > 0) {
|
||||
u1* indexes_base = data;
|
||||
data += indexes_length;
|
||||
char c = *desc_string;
|
||||
do {
|
||||
*uncompressed_resource = c;
|
||||
uncompressed_resource++;
|
||||
desc_length += 1;
|
||||
/*
|
||||
* Every L character is the marker we are looking at in order
|
||||
* to reconstruct the descriptor. Each time an L is found, then
|
||||
* we retrieve the couple token/token at the current index and
|
||||
* add it to the descriptor.
|
||||
* "(L;I)V" and "java/lang","String" couple of tokens,
|
||||
* this becomes "(Ljava/lang/String;I)V"
|
||||
*/
|
||||
if (c == 'L') {
|
||||
int index = decompress_int(indexes_base);
|
||||
const char * pkg = strings->get(index);
|
||||
int str_length = (int) strlen(pkg);
|
||||
// the case where we have a package.
|
||||
// reconstruct the type full name
|
||||
if (str_length > 0) {
|
||||
int len = str_length + 1;
|
||||
char* fullpkg = new char[len];
|
||||
char* pkg_base = fullpkg;
|
||||
memcpy(fullpkg, pkg, str_length);
|
||||
fullpkg += str_length;
|
||||
*fullpkg = '/';
|
||||
memcpy(uncompressed_resource, pkg_base, len);
|
||||
uncompressed_resource += len;
|
||||
delete pkg_base;
|
||||
desc_length += len;
|
||||
} else { // Empty package
|
||||
// Nothing to do.
|
||||
}
|
||||
int classIndex = decompress_int(indexes_base);
|
||||
const char * clazz = strings->get(classIndex);
|
||||
int clazz_length = (int) strlen(clazz);
|
||||
memcpy(uncompressed_resource, clazz, clazz_length);
|
||||
uncompressed_resource += clazz_length;
|
||||
desc_length += clazz_length;
|
||||
}
|
||||
desc_string += 1;
|
||||
c = *desc_string;
|
||||
} while (c != '\0');
|
||||
} else {
|
||||
desc_length = (int) strlen(desc_string);
|
||||
memcpy(uncompressed_resource, desc_string, desc_length);
|
||||
uncompressed_resource += desc_length;
|
||||
}
|
||||
Endian::set_java(length_address, desc_length);
|
||||
break;
|
||||
}
|
||||
|
||||
case constant_utf8:
|
||||
{ // UTF-8
|
||||
*uncompressed_resource = tag;
|
||||
uncompressed_resource += 1;
|
||||
u2 str_length = Endian::get_java(data);
|
||||
int len = str_length + 2;
|
||||
memcpy(uncompressed_resource, data, len);
|
||||
uncompressed_resource += len;
|
||||
data += len;
|
||||
break;
|
||||
}
|
||||
|
||||
case constant_long:
|
||||
case constant_double:
|
||||
{
|
||||
i++;
|
||||
}
|
||||
default:
|
||||
{
|
||||
*uncompressed_resource = tag;
|
||||
uncompressed_resource += 1;
|
||||
int size = sizes[tag];
|
||||
memcpy(uncompressed_resource, data, size);
|
||||
uncompressed_resource += size;
|
||||
data += size;
|
||||
}
|
||||
desc_string += 1;
|
||||
c = *desc_string;
|
||||
} while (c != '\0');
|
||||
} else {
|
||||
desc_length = (int) strlen(desc_string);
|
||||
memcpy(uncompressed_resource, desc_string, desc_length);
|
||||
uncompressed_resource += desc_length;
|
||||
}
|
||||
Endian::set_java(length_address, desc_length);
|
||||
break;
|
||||
}
|
||||
|
||||
case constant_utf8:
|
||||
{ // UTF-8
|
||||
*uncompressed_resource = tag;
|
||||
uncompressed_resource += 1;
|
||||
u2 str_length = Endian::get_java(data);
|
||||
int len = str_length + 2;
|
||||
memcpy(uncompressed_resource, data, len);
|
||||
uncompressed_resource += len;
|
||||
data += len;
|
||||
break;
|
||||
}
|
||||
|
||||
case constant_long:
|
||||
case constant_double:
|
||||
{
|
||||
i++;
|
||||
}
|
||||
default:
|
||||
{
|
||||
*uncompressed_resource = tag;
|
||||
uncompressed_resource += 1;
|
||||
int size = sizes[tag];
|
||||
memcpy(uncompressed_resource, data, size);
|
||||
uncompressed_resource += size;
|
||||
data += size;
|
||||
}
|
||||
}
|
||||
}
|
||||
u4 remain = header->_size - (int)(data - data_base);
|
||||
u4 computed = (u4)(uncompressed_resource - uncompressed_base) + remain;
|
||||
if (header->_uncompressed_size != computed)
|
||||
printf("Failure, expecting %d but getting %d\n", header->_uncompressed_size,
|
||||
computed);
|
||||
assert(header->_uncompressed_size == computed &&
|
||||
"Constant Pool reconstruction failed");
|
||||
memcpy(uncompressed_resource, data, remain);
|
||||
u4 remain = header->_size - (int)(data - data_base);
|
||||
u4 computed = (u4)(uncompressed_resource - uncompressed_base) + remain;
|
||||
if (header->_uncompressed_size != computed)
|
||||
printf("Failure, expecting %d but getting %d\n", header->_uncompressed_size,
|
||||
computed);
|
||||
assert(header->_uncompressed_size == computed &&
|
||||
"Constant Pool reconstruction failed");
|
||||
memcpy(uncompressed_resource, data, remain);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -308,25 +311,25 @@ void SharedStringDecompressor::decompress_resource(u1* data,
|
||||
* Example of compression: 1 is compressed on 1 byte: 10100001
|
||||
*/
|
||||
int SharedStringDecompressor::decompress_int(unsigned char*& value) {
|
||||
int len = 4;
|
||||
int res = 0;
|
||||
char b1 = *value;
|
||||
if (is_compressed((signed char)b1)) { // compressed
|
||||
len = get_compressed_length(b1);
|
||||
char clearedValue = b1 &= 0x1F;
|
||||
if (len == 1) {
|
||||
res = clearedValue;
|
||||
int len = 4;
|
||||
int res = 0;
|
||||
char b1 = *value;
|
||||
if (is_compressed((signed char)b1)) { // compressed
|
||||
len = get_compressed_length(b1);
|
||||
char clearedValue = b1 &= 0x1F;
|
||||
if (len == 1) {
|
||||
res = clearedValue;
|
||||
} else {
|
||||
res = (clearedValue & 0xFF) << 8 * (len - 1);
|
||||
for (int i = 1; i < len; i++) {
|
||||
res |= (value[i]&0xFF) << 8 * (len - i - 1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
res = (clearedValue & 0xFF) << 8 * (len - 1);
|
||||
for (int i = 1; i < len; i++) {
|
||||
res |= (value[i]&0xFF) << 8 * (len - i - 1);
|
||||
}
|
||||
res = (value[0] & 0xFF) << 24 | (value[1]&0xFF) << 16 |
|
||||
(value[2]&0xFF) << 8 | (value[3]&0xFF);
|
||||
}
|
||||
} else {
|
||||
res = (value[0] & 0xFF) << 24 | (value[1]&0xFF) << 16 |
|
||||
(value[2]&0xFF) << 8 | (value[3]&0xFF);
|
||||
}
|
||||
value += len;
|
||||
return res;
|
||||
value += len;
|
||||
return res;
|
||||
}
|
||||
// END Shared String decompressor
|
||||
|
@ -4,11 +4,13 @@
|
||||
*
|
||||
* 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.
|
||||
* 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
|
||||
* 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).
|
||||
*
|
||||
@ -19,7 +21,6 @@
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LIBJIMAGE_IMAGEDECOMPRESSOR_HPP
|
||||
@ -47,16 +48,16 @@
|
||||
* have been used to compress the resource.
|
||||
*/
|
||||
struct ResourceHeader {
|
||||
/* Length of header, needed to retrieve content offset */
|
||||
static const u1 resource_header_length = 21;
|
||||
/* magic bytes that identifies a compressed resource header*/
|
||||
static const u4 resource_header_magic = 0xCAFEFAFA;
|
||||
u4 _magic; // Resource header
|
||||
u4 _size; // Resource size
|
||||
u4 _uncompressed_size; // Expected uncompressed size
|
||||
u4 _decompressor_name_offset; // Strings table decompressor offset
|
||||
u4 _decompressor_config_offset; // Strings table config offset
|
||||
u1 _is_terminal; // Last decompressor 1, otherwise 0.
|
||||
/* Length of header, needed to retrieve content offset */
|
||||
static const u1 resource_header_length = 21;
|
||||
/* magic bytes that identifies a compressed resource header*/
|
||||
static const u4 resource_header_magic = 0xCAFEFAFA;
|
||||
u4 _magic; // Resource header
|
||||
u4 _size; // Resource size
|
||||
u4 _uncompressed_size; // Expected uncompressed size
|
||||
u4 _decompressor_name_offset; // Strings table decompressor offset
|
||||
u4 _decompressor_config_offset; // Strings table config offset
|
||||
u1 _is_terminal; // Last decompressor 1, otherwise 0.
|
||||
};
|
||||
|
||||
/*
|
||||
@ -77,36 +78,36 @@ struct ResourceHeader {
|
||||
class ImageDecompressor {
|
||||
|
||||
private:
|
||||
const char* _name;
|
||||
const char* _name;
|
||||
|
||||
/*
|
||||
* Array of concrete decompressors. This array is used to retrieve the decompressor
|
||||
* that can handle resource decompression.
|
||||
*/
|
||||
static ImageDecompressor** _decompressors;
|
||||
/**
|
||||
* Num of decompressors
|
||||
*/
|
||||
static int _decompressors_num;
|
||||
/*
|
||||
* Identifier of a decompressor. This name is the identification key to retrieve
|
||||
* decompressor from a resource header.
|
||||
*/
|
||||
inline const char* get_name() const { return _name; }
|
||||
/*
|
||||
* Array of concrete decompressors. This array is used to retrieve the decompressor
|
||||
* that can handle resource decompression.
|
||||
*/
|
||||
static ImageDecompressor** _decompressors;
|
||||
/**
|
||||
* Num of decompressors
|
||||
*/
|
||||
static int _decompressors_num;
|
||||
/*
|
||||
* Identifier of a decompressor. This name is the identification key to retrieve
|
||||
* decompressor from a resource header.
|
||||
*/
|
||||
inline const char* get_name() const { return _name; }
|
||||
|
||||
|
||||
protected:
|
||||
ImageDecompressor(const char* name) : _name(name) {
|
||||
}
|
||||
virtual void decompress_resource(u1* data, u1* uncompressed,
|
||||
ResourceHeader* header, const ImageStrings* strings) = 0;
|
||||
ImageDecompressor(const char* name) : _name(name) {
|
||||
}
|
||||
virtual void decompress_resource(u1* data, u1* uncompressed,
|
||||
ResourceHeader* header, const ImageStrings* strings) = 0;
|
||||
|
||||
public:
|
||||
static void image_decompressor_init();
|
||||
static void image_decompressor_close();
|
||||
static ImageDecompressor* get_decompressor(const char * decompressor_name) ;
|
||||
static void decompress_resource(u1* compressed, u1* uncompressed,
|
||||
u4 uncompressed_size, const ImageStrings* strings);
|
||||
static void image_decompressor_init();
|
||||
static void image_decompressor_close();
|
||||
static ImageDecompressor* get_decompressor(const char * decompressor_name) ;
|
||||
static void decompress_resource(u1* compressed, u1* uncompressed,
|
||||
u4 uncompressed_size, const ImageStrings* strings);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -114,10 +115,10 @@ public:
|
||||
*/
|
||||
class ZipDecompressor : public ImageDecompressor {
|
||||
public:
|
||||
ZipDecompressor(const char* sym) : ImageDecompressor(sym) { }
|
||||
void decompress_resource(u1* data, u1* uncompressed, ResourceHeader* header,
|
||||
const ImageStrings* strings);
|
||||
static jboolean decompress(void *in, u8 inSize, void *out, u8 outSize, char **pmsg);
|
||||
ZipDecompressor(const char* sym) : ImageDecompressor(sym) { }
|
||||
void decompress_resource(u1* data, u1* uncompressed, ResourceHeader* header,
|
||||
const ImageStrings* strings);
|
||||
static jboolean decompress(void *in, u8 inSize, void *out, u8 outSize, char **pmsg);
|
||||
};
|
||||
|
||||
/*
|
||||
@ -131,32 +132,34 @@ public:
|
||||
*/
|
||||
class SharedStringDecompressor : public ImageDecompressor {
|
||||
private:
|
||||
// the constant pool tag for UTF8 string located in strings table
|
||||
static const int externalized_string = 23;
|
||||
// the constant pool tag for UTF8 descriptors string located in strings table
|
||||
static const int externalized_string_descriptor = 25;
|
||||
// the constant pool tag for UTF8
|
||||
static const int constant_utf8 = 1;
|
||||
// the constant pool tag for long
|
||||
static const int constant_long = 5;
|
||||
// the constant pool tag for double
|
||||
static const int constant_double = 6;
|
||||
// array index is the constant pool tag. value is size.
|
||||
// eg: array[5] = 8; means size of long is 8 bytes.
|
||||
static const u1 sizes[];
|
||||
// bit 5 and 6 are used to store the length of the compressed integer.
|
||||
// size can be 1 (01), 2 (10), 3 (11).
|
||||
// 0x60 ==> 0110000
|
||||
static const int compressed_index_size_mask = 0x60;
|
||||
/*
|
||||
* mask the length bits (5 and 6) and move to the right 5 bits.
|
||||
*/
|
||||
inline static int get_compressed_length(char c) { return ((char) (c & compressed_index_size_mask) >> 5); }
|
||||
inline static bool is_compressed(signed char b1) { return b1 < 0; }
|
||||
static int decompress_int(unsigned char*& value);
|
||||
// the constant pool tag for UTF8 string located in strings table
|
||||
static const int externalized_string = 23;
|
||||
// the constant pool tag for UTF8 descriptors string located in strings table
|
||||
static const int externalized_string_descriptor = 25;
|
||||
// the constant pool tag for UTF8
|
||||
static const int constant_utf8 = 1;
|
||||
// the constant pool tag for long
|
||||
static const int constant_long = 5;
|
||||
// the constant pool tag for double
|
||||
static const int constant_double = 6;
|
||||
// array index is the constant pool tag. value is size.
|
||||
// eg: array[5] = 8; means size of long is 8 bytes.
|
||||
static const u1 sizes[];
|
||||
// bit 5 and 6 are used to store the length of the compressed integer.
|
||||
// size can be 1 (01), 2 (10), 3 (11).
|
||||
// 0x60 ==> 0110000
|
||||
static const int compressed_index_size_mask = 0x60;
|
||||
/*
|
||||
* mask the length bits (5 and 6) and move to the right 5 bits.
|
||||
*/
|
||||
inline static int get_compressed_length(char c) {
|
||||
return ((char) (c & compressed_index_size_mask) >> 5);
|
||||
}
|
||||
inline static bool is_compressed(signed char b1) { return b1 < 0; }
|
||||
static int decompress_int(unsigned char*& value);
|
||||
public:
|
||||
SharedStringDecompressor(const char* sym) : ImageDecompressor(sym){}
|
||||
void decompress_resource(u1* data, u1* uncompressed, ResourceHeader* header,
|
||||
const ImageStrings* strings);
|
||||
SharedStringDecompressor(const char* sym) : ImageDecompressor(sym){}
|
||||
void decompress_resource(u1* data, u1* uncompressed, ResourceHeader* header,
|
||||
const ImageStrings* strings);
|
||||
};
|
||||
#endif // LIBJIMAGE_IMAGEDECOMPRESSOR_HPP
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,14 +1,16 @@
|
||||
/*
|
||||
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* 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.
|
||||
* 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
|
||||
* 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).
|
||||
*
|
||||
@ -19,7 +21,6 @@
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LIBJIMAGE_IMAGEFILE_HPP
|
||||
@ -145,52 +146,52 @@ class ImageFileReader; // forward declaration
|
||||
// Manage image file string table.
|
||||
class ImageStrings {
|
||||
private:
|
||||
u1* _data; // Data bytes for strings.
|
||||
u4 _size; // Number of bytes in the string table.
|
||||
u1* _data; // Data bytes for strings.
|
||||
u4 _size; // Number of bytes in the string table.
|
||||
public:
|
||||
enum {
|
||||
// Not found result from find routine.
|
||||
NOT_FOUND = -1,
|
||||
// Prime used to generate hash for Perfect Hashing.
|
||||
HASH_MULTIPLIER = 0x01000193
|
||||
};
|
||||
enum {
|
||||
// Not found result from find routine.
|
||||
NOT_FOUND = -1,
|
||||
// Prime used to generate hash for Perfect Hashing.
|
||||
HASH_MULTIPLIER = 0x01000193
|
||||
};
|
||||
|
||||
ImageStrings(u1* data, u4 size) : _data(data), _size(size) {}
|
||||
ImageStrings(u1* data, u4 size) : _data(data), _size(size) {}
|
||||
|
||||
// Return the UTF-8 string beginning at offset.
|
||||
inline const char* get(u4 offset) const {
|
||||
assert(offset < _size && "offset exceeds string table size");
|
||||
return (const char*)(_data + offset);
|
||||
}
|
||||
// Return the UTF-8 string beginning at offset.
|
||||
inline const char* get(u4 offset) const {
|
||||
assert(offset < _size && "offset exceeds string table size");
|
||||
return (const char*)(_data + offset);
|
||||
}
|
||||
|
||||
// Compute the Perfect Hashing hash code for the supplied UTF-8 string.
|
||||
inline static u4 hash_code(const char* string) {
|
||||
return hash_code(string, HASH_MULTIPLIER);
|
||||
}
|
||||
// Compute the Perfect Hashing hash code for the supplied UTF-8 string.
|
||||
inline static u4 hash_code(const char* string) {
|
||||
return hash_code(string, HASH_MULTIPLIER);
|
||||
}
|
||||
|
||||
// Compute the Perfect Hashing hash code for the supplied string, starting at seed.
|
||||
static s4 hash_code(const char* string, s4 seed);
|
||||
// Compute the Perfect Hashing hash code for the supplied string, starting at seed.
|
||||
static s4 hash_code(const char* string, s4 seed);
|
||||
|
||||
// Match up a string in a perfect hash table. Result still needs validation
|
||||
// for precise match.
|
||||
static s4 find(Endian* endian, const char* name, s4* redirect, u4 length);
|
||||
// Match up a string in a perfect hash table. Result still needs validation
|
||||
// for precise match.
|
||||
static s4 find(Endian* endian, const char* name, s4* redirect, u4 length);
|
||||
|
||||
// Test to see if UTF-8 string begins with the start UTF-8 string. If so,
|
||||
// return non-NULL address of remaining portion of string. Otherwise, return
|
||||
// NULL. Used to test sections of a path without copying from image string
|
||||
// table.
|
||||
static const char* starts_with(const char* string, const char* start);
|
||||
// Test to see if UTF-8 string begins with the start UTF-8 string. If so,
|
||||
// return non-NULL address of remaining portion of string. Otherwise, return
|
||||
// NULL. Used to test sections of a path without copying from image string
|
||||
// table.
|
||||
static const char* starts_with(const char* string, const char* start);
|
||||
|
||||
// Test to see if UTF-8 string begins with start char. If so, return non-NULL
|
||||
// address of remaining portion of string. Otherwise, return NULL. Used
|
||||
// to test a character of a path without copying.
|
||||
inline static const char* starts_with(const char* string, const char ch) {
|
||||
return *string == ch ? string + 1 : NULL;
|
||||
}
|
||||
// Test to see if UTF-8 string begins with start char. If so, return non-NULL
|
||||
// address of remaining portion of string. Otherwise, return NULL. Used
|
||||
// to test a character of a path without copying.
|
||||
inline static const char* starts_with(const char* string, const char ch) {
|
||||
return *string == ch ? string + 1 : NULL;
|
||||
}
|
||||
};
|
||||
|
||||
// Manage image file location attribute data. Within an image, a location's
|
||||
// attributes are compressed into a stream of bytes. An attribute stream is
|
||||
// Manage image file location attribute data. Within an image, a location's
|
||||
// attributes are compressed into a stream of bytes. An attribute stream is
|
||||
// composed of individual attribute sequences. Each attribute sequence begins with
|
||||
// a header byte containing the attribute 'kind' (upper 5 bits of header) and the
|
||||
// 'length' less 1 (lower 3 bits of header) of bytes that follow containing the
|
||||
@ -208,91 +209,91 @@ public:
|
||||
//
|
||||
// Notes:
|
||||
// - Even though ATTRIBUTE_END is used to mark the end of the attribute stream,
|
||||
// streams will contain zero byte values to represent lesser significant bits.
|
||||
// Thus, detecting a zero byte is not sufficient to detect the end of an attribute
|
||||
// stream.
|
||||
// streams will contain zero byte values to represent lesser significant bits.
|
||||
// Thus, detecting a zero byte is not sufficient to detect the end of an attribute
|
||||
// stream.
|
||||
// - ATTRIBUTE_OFFSET represents the number of bytes from the beginning of the region
|
||||
// storing the resources. Thus, in an image this represents the number of bytes
|
||||
// after the index.
|
||||
// storing the resources. Thus, in an image this represents the number of bytes
|
||||
// after the index.
|
||||
// - Currently, compressed resources are represented by having a non-zero
|
||||
// ATTRIBUTE_COMPRESSED value. This represents the number of bytes stored in the
|
||||
// image, and the value of ATTRIBUTE_UNCOMPRESSED represents number of bytes of the
|
||||
// inflated resource in memory. If the ATTRIBUTE_COMPRESSED is zero then the value
|
||||
// of ATTRIBUTE_UNCOMPRESSED represents both the number of bytes in the image and
|
||||
// in memory. In the future, additional compression techniques will be used and
|
||||
// represented differently.
|
||||
// ATTRIBUTE_COMPRESSED value. This represents the number of bytes stored in the
|
||||
// image, and the value of ATTRIBUTE_UNCOMPRESSED represents number of bytes of the
|
||||
// inflated resource in memory. If the ATTRIBUTE_COMPRESSED is zero then the value
|
||||
// of ATTRIBUTE_UNCOMPRESSED represents both the number of bytes in the image and
|
||||
// in memory. In the future, additional compression techniques will be used and
|
||||
// represented differently.
|
||||
// - Package strings include trailing slash and extensions include prefix period.
|
||||
//
|
||||
class ImageLocation {
|
||||
public:
|
||||
enum {
|
||||
ATTRIBUTE_END, // End of attribute stream marker
|
||||
ATTRIBUTE_MODULE, // String table offset of module name
|
||||
ATTRIBUTE_PARENT, // String table offset of resource path parent
|
||||
ATTRIBUTE_BASE, // String table offset of resource path base
|
||||
ATTRIBUTE_EXTENSION, // String table offset of resource path extension
|
||||
ATTRIBUTE_OFFSET, // Container byte offset of resource
|
||||
ATTRIBUTE_COMPRESSED, // In image byte size of the compressed resource
|
||||
ATTRIBUTE_UNCOMPRESSED, // In memory byte size of the uncompressed resource
|
||||
ATTRIBUTE_COUNT // Number of attribute kinds
|
||||
};
|
||||
enum {
|
||||
ATTRIBUTE_END, // End of attribute stream marker
|
||||
ATTRIBUTE_MODULE, // String table offset of module name
|
||||
ATTRIBUTE_PARENT, // String table offset of resource path parent
|
||||
ATTRIBUTE_BASE, // String table offset of resource path base
|
||||
ATTRIBUTE_EXTENSION, // String table offset of resource path extension
|
||||
ATTRIBUTE_OFFSET, // Container byte offset of resource
|
||||
ATTRIBUTE_COMPRESSED, // In image byte size of the compressed resource
|
||||
ATTRIBUTE_UNCOMPRESSED, // In memory byte size of the uncompressed resource
|
||||
ATTRIBUTE_COUNT // Number of attribute kinds
|
||||
};
|
||||
|
||||
private:
|
||||
// Values of inflated attributes.
|
||||
u8 _attributes[ATTRIBUTE_COUNT];
|
||||
// Values of inflated attributes.
|
||||
u8 _attributes[ATTRIBUTE_COUNT];
|
||||
|
||||
// Return the attribute value number of bytes.
|
||||
inline static u1 attribute_length(u1 data) {
|
||||
return (data & 0x7) + 1;
|
||||
}
|
||||
|
||||
// Return the attribute kind.
|
||||
inline static u1 attribute_kind(u1 data) {
|
||||
u1 kind = data >> 3;
|
||||
assert(kind < ATTRIBUTE_COUNT && "invalid attribute kind");
|
||||
return kind;
|
||||
}
|
||||
|
||||
// Return the attribute length.
|
||||
inline static u8 attribute_value(u1* data, u1 n) {
|
||||
assert(0 < n && n <= 8 && "invalid attribute value length");
|
||||
u8 value = 0;
|
||||
// Most significant bytes first.
|
||||
for (u1 i = 0; i < n; i++) {
|
||||
value <<= 8;
|
||||
value |= data[i];
|
||||
// Return the attribute value number of bytes.
|
||||
inline static u1 attribute_length(u1 data) {
|
||||
return (data & 0x7) + 1;
|
||||
}
|
||||
|
||||
// Return the attribute kind.
|
||||
inline static u1 attribute_kind(u1 data) {
|
||||
u1 kind = data >> 3;
|
||||
assert(kind < ATTRIBUTE_COUNT && "invalid attribute kind");
|
||||
return kind;
|
||||
}
|
||||
|
||||
// Return the attribute length.
|
||||
inline static u8 attribute_value(u1* data, u1 n) {
|
||||
assert(0 < n && n <= 8 && "invalid attribute value length");
|
||||
u8 value = 0;
|
||||
// Most significant bytes first.
|
||||
for (u1 i = 0; i < n; i++) {
|
||||
value <<= 8;
|
||||
value |= data[i];
|
||||
}
|
||||
return value;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public:
|
||||
ImageLocation() {
|
||||
clear_data();
|
||||
}
|
||||
ImageLocation() {
|
||||
clear_data();
|
||||
}
|
||||
|
||||
ImageLocation(u1* data) {
|
||||
clear_data();
|
||||
set_data(data);
|
||||
}
|
||||
ImageLocation(u1* data) {
|
||||
clear_data();
|
||||
set_data(data);
|
||||
}
|
||||
|
||||
// Inflates the attribute stream into individual values stored in the long
|
||||
// array _attributes. This allows an attribute value to be quickly accessed by
|
||||
// direct indexing. Unspecified values default to zero.
|
||||
void set_data(u1* data);
|
||||
// Inflates the attribute stream into individual values stored in the long
|
||||
// array _attributes. This allows an attribute value to be quickly accessed by
|
||||
// direct indexing. Unspecified values default to zero.
|
||||
void set_data(u1* data);
|
||||
|
||||
// Zero all attribute values.
|
||||
void clear_data();
|
||||
// Zero all attribute values.
|
||||
void clear_data();
|
||||
|
||||
// Retrieve an attribute value from the inflated array.
|
||||
inline u8 get_attribute(u1 kind) const {
|
||||
assert(ATTRIBUTE_END < kind && kind < ATTRIBUTE_COUNT && "invalid attribute kind");
|
||||
return _attributes[kind];
|
||||
}
|
||||
// Retrieve an attribute value from the inflated array.
|
||||
inline u8 get_attribute(u1 kind) const {
|
||||
assert(ATTRIBUTE_END < kind && kind < ATTRIBUTE_COUNT && "invalid attribute kind");
|
||||
return _attributes[kind];
|
||||
}
|
||||
|
||||
// Retrieve an attribute string value from the inflated array.
|
||||
inline const char* get_attribute(u4 kind, const ImageStrings& strings) const {
|
||||
return strings.get((u4)get_attribute(kind));
|
||||
}
|
||||
// Retrieve an attribute string value from the inflated array.
|
||||
inline const char* get_attribute(u4 kind, const ImageStrings& strings) const {
|
||||
return strings.get((u4)get_attribute(kind));
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
@ -306,133 +307,133 @@ public:
|
||||
// padding for hash table lookup.)
|
||||
//
|
||||
// Format:
|
||||
// Count of package to module entries
|
||||
// Count of module to package entries
|
||||
// Perfect Hash redirect table[Count of package to module entries]
|
||||
// Package to module entries[Count of package to module entries]
|
||||
// Offset to package name in string table
|
||||
// Offset to module name in string table
|
||||
// Perfect Hash redirect table[Count of module to package entries]
|
||||
// Module to package entries[Count of module to package entries]
|
||||
// Offset to module name in string table
|
||||
// Count of packages in module
|
||||
// Offset to first package in packages table
|
||||
// Packages[]
|
||||
// Offset to package name in string table
|
||||
// Count of package to module entries
|
||||
// Count of module to package entries
|
||||
// Perfect Hash redirect table[Count of package to module entries]
|
||||
// Package to module entries[Count of package to module entries]
|
||||
// Offset to package name in string table
|
||||
// Offset to module name in string table
|
||||
// Perfect Hash redirect table[Count of module to package entries]
|
||||
// Module to package entries[Count of module to package entries]
|
||||
// Offset to module name in string table
|
||||
// Count of packages in module
|
||||
// Offset to first package in packages table
|
||||
// Packages[]
|
||||
// Offset to package name in string table
|
||||
//
|
||||
// Manage the image module meta data.
|
||||
class ImageModuleData {
|
||||
class Header {
|
||||
private:
|
||||
u4 _ptm_count; // Count of package to module entries
|
||||
u4 _mtp_count; // Count of module to package entries
|
||||
public:
|
||||
inline u4 ptm_count(Endian* endian) const { return endian->get(_ptm_count); }
|
||||
inline u4 mtp_count(Endian* endian) const { return endian->get(_mtp_count); }
|
||||
};
|
||||
class Header {
|
||||
private:
|
||||
u4 _ptm_count; // Count of package to module entries
|
||||
u4 _mtp_count; // Count of module to package entries
|
||||
public:
|
||||
inline u4 ptm_count(Endian* endian) const { return endian->get(_ptm_count); }
|
||||
inline u4 mtp_count(Endian* endian) const { return endian->get(_mtp_count); }
|
||||
};
|
||||
|
||||
// Hashtable entry
|
||||
class HashData {
|
||||
private:
|
||||
u4 _name_offset; // Name offset in string table
|
||||
public:
|
||||
inline s4 name_offset(Endian* endian) const { return endian->get(_name_offset); }
|
||||
};
|
||||
// Hashtable entry
|
||||
class HashData {
|
||||
private:
|
||||
u4 _name_offset; // Name offset in string table
|
||||
public:
|
||||
inline s4 name_offset(Endian* endian) const { return endian->get(_name_offset); }
|
||||
};
|
||||
|
||||
// Package to module hashtable entry
|
||||
class PTMData : public HashData {
|
||||
private:
|
||||
u4 _module_name_offset; // Module name offset in string table
|
||||
public:
|
||||
inline s4 module_name_offset(Endian* endian) const { return endian->get(_module_name_offset); }
|
||||
};
|
||||
// Package to module hashtable entry
|
||||
class PTMData : public HashData {
|
||||
private:
|
||||
u4 _module_name_offset; // Module name offset in string table
|
||||
public:
|
||||
inline s4 module_name_offset(Endian* endian) const { return endian->get(_module_name_offset); }
|
||||
};
|
||||
|
||||
// Module to package hashtable entry
|
||||
class MTPData : public HashData {
|
||||
private:
|
||||
u4 _package_count; // Number of packages in module
|
||||
u4 _package_offset; // Offset in package list
|
||||
public:
|
||||
inline u4 package_count(Endian* endian) const { return endian->get(_package_count); }
|
||||
inline u4 package_offset(Endian* endian) const { return endian->get(_package_offset); }
|
||||
};
|
||||
// Module to package hashtable entry
|
||||
class MTPData : public HashData {
|
||||
private:
|
||||
u4 _package_count; // Number of packages in module
|
||||
u4 _package_offset; // Offset in package list
|
||||
public:
|
||||
inline u4 package_count(Endian* endian) const { return endian->get(_package_count); }
|
||||
inline u4 package_offset(Endian* endian) const { return endian->get(_package_offset); }
|
||||
};
|
||||
|
||||
const ImageFileReader* _image_file; // Source image file
|
||||
Endian* _endian; // Endian handler
|
||||
ImageStrings _strings; // Image file strings
|
||||
u1* _data; // Module data resource data
|
||||
u8 _data_size; // Size of resource data
|
||||
Header* _header; // Module data header
|
||||
s4* _ptm_redirect; // Package to module hashtable redirect
|
||||
PTMData* _ptm_data; // Package to module data
|
||||
s4* _mtp_redirect; // Module to packages hashtable redirect
|
||||
MTPData* _mtp_data; // Module to packages data
|
||||
s4* _mtp_packages; // Package data (name offsets)
|
||||
const ImageFileReader* _image_file; // Source image file
|
||||
Endian* _endian; // Endian handler
|
||||
ImageStrings _strings; // Image file strings
|
||||
u1* _data; // Module data resource data
|
||||
u8 _data_size; // Size of resource data
|
||||
Header* _header; // Module data header
|
||||
s4* _ptm_redirect; // Package to module hashtable redirect
|
||||
PTMData* _ptm_data; // Package to module data
|
||||
s4* _mtp_redirect; // Module to packages hashtable redirect
|
||||
MTPData* _mtp_data; // Module to packages data
|
||||
s4* _mtp_packages; // Package data (name offsets)
|
||||
|
||||
// Return a string from the string table.
|
||||
inline const char* get_string(u4 offset) {
|
||||
return _strings.get(offset);
|
||||
}
|
||||
// Return a string from the string table.
|
||||
inline const char* get_string(u4 offset) {
|
||||
return _strings.get(offset);
|
||||
}
|
||||
|
||||
inline u4 mtp_package(u4 index) {
|
||||
return _endian->get(_mtp_packages[index]);
|
||||
}
|
||||
inline u4 mtp_package(u4 index) {
|
||||
return _endian->get(_mtp_packages[index]);
|
||||
}
|
||||
|
||||
public:
|
||||
ImageModuleData(const ImageFileReader* image_file, const char* module_data_name);
|
||||
~ImageModuleData();
|
||||
ImageModuleData(const ImageFileReader* image_file, const char* module_data_name);
|
||||
~ImageModuleData();
|
||||
|
||||
// Return the name of the module data resource.
|
||||
static void module_data_name(char* buffer, const char* image_file_name);
|
||||
// Return the name of the module data resource.
|
||||
static void module_data_name(char* buffer, const char* image_file_name);
|
||||
|
||||
// Return the module in which a package resides. Returns NULL if not found.
|
||||
const char* package_to_module(const char* package_name);
|
||||
// Return the module in which a package resides. Returns NULL if not found.
|
||||
const char* package_to_module(const char* package_name);
|
||||
|
||||
// Returns all the package names in a module in a NULL terminated array.
|
||||
// Returns NULL if module not found.
|
||||
const char** module_to_packages(const char* module_name);
|
||||
// Returns all the package names in a module in a NULL terminated array.
|
||||
// Returns NULL if module not found.
|
||||
const char** module_to_packages(const char* module_name);
|
||||
};
|
||||
|
||||
// Image file header, starting at offset 0.
|
||||
class ImageHeader {
|
||||
private:
|
||||
u4 _magic; // Image file marker
|
||||
u4 _version; // Image file major version number
|
||||
u4 _flags; // Image file flags
|
||||
u4 _resource_count; // Number of resources in file
|
||||
u4 _table_length; // Number of slots in index tables
|
||||
u4 _locations_size; // Number of bytes in attribute table
|
||||
u4 _strings_size; // Number of bytes in string table
|
||||
u4 _magic; // Image file marker
|
||||
u4 _version; // Image file major version number
|
||||
u4 _flags; // Image file flags
|
||||
u4 _resource_count; // Number of resources in file
|
||||
u4 _table_length; // Number of slots in index tables
|
||||
u4 _locations_size; // Number of bytes in attribute table
|
||||
u4 _strings_size; // Number of bytes in string table
|
||||
|
||||
public:
|
||||
u4 magic() const { return _magic; }
|
||||
u4 magic(Endian* endian) const { return endian->get(_magic); }
|
||||
void set_magic(Endian* endian, u4 magic) { return endian->set(_magic, magic); }
|
||||
u4 magic() const { return _magic; }
|
||||
u4 magic(Endian* endian) const { return endian->get(_magic); }
|
||||
void set_magic(Endian* endian, u4 magic) { return endian->set(_magic, magic); }
|
||||
|
||||
u4 major_version(Endian* endian) const { return endian->get(_version) >> 16; }
|
||||
u4 minor_version(Endian* endian) const { return endian->get(_version) & 0xFFFF; }
|
||||
void set_version(Endian* endian, u4 major_version, u4 minor_version) {
|
||||
return endian->set(_version, major_version << 16 | minor_version);
|
||||
}
|
||||
u4 major_version(Endian* endian) const { return endian->get(_version) >> 16; }
|
||||
u4 minor_version(Endian* endian) const { return endian->get(_version) & 0xFFFF; }
|
||||
void set_version(Endian* endian, u4 major_version, u4 minor_version) {
|
||||
return endian->set(_version, major_version << 16 | minor_version);
|
||||
}
|
||||
|
||||
u4 flags(Endian* endian) const { return endian->get(_flags); }
|
||||
void set_flags(Endian* endian, u4 value) { return endian->set(_flags, value); }
|
||||
u4 flags(Endian* endian) const { return endian->get(_flags); }
|
||||
void set_flags(Endian* endian, u4 value) { return endian->set(_flags, value); }
|
||||
|
||||
u4 resource_count(Endian* endian) const { return endian->get(_resource_count); }
|
||||
void set_resource_count(Endian* endian, u4 count) { return endian->set(_resource_count, count); }
|
||||
u4 resource_count(Endian* endian) const { return endian->get(_resource_count); }
|
||||
void set_resource_count(Endian* endian, u4 count) { return endian->set(_resource_count, count); }
|
||||
|
||||
u4 table_length(Endian* endian) const { return endian->get(_table_length); }
|
||||
void set_table_length(Endian* endian, u4 count) { return endian->set(_table_length, count); }
|
||||
u4 table_length(Endian* endian) const { return endian->get(_table_length); }
|
||||
void set_table_length(Endian* endian, u4 count) { return endian->set(_table_length, count); }
|
||||
|
||||
u4 locations_size(Endian* endian) const { return endian->get(_locations_size); }
|
||||
void set_locations_size(Endian* endian, u4 size) { return endian->set(_locations_size, size); }
|
||||
u4 locations_size(Endian* endian) const { return endian->get(_locations_size); }
|
||||
void set_locations_size(Endian* endian, u4 size) { return endian->set(_locations_size, size); }
|
||||
|
||||
u4 strings_size(Endian* endian) const { return endian->get(_strings_size); }
|
||||
void set_strings_size(Endian* endian, u4 size) { return endian->set(_strings_size, size); }
|
||||
u4 strings_size(Endian* endian) const { return endian->get(_strings_size); }
|
||||
void set_strings_size(Endian* endian, u4 size) { return endian->set(_strings_size, size); }
|
||||
};
|
||||
|
||||
// Max path length limit independent of platform. Windows max path is 1024,
|
||||
// other platforms use 4096. The JCK fails several tests when 1024 is used.
|
||||
// Max path length limit independent of platform. Windows max path is 1024,
|
||||
// other platforms use 4096. The JCK fails several tests when 1024 is used.
|
||||
#define IMAGE_MAX_PATH 4096
|
||||
|
||||
class ImageFileReader;
|
||||
@ -441,29 +442,29 @@ class ImageFileReader;
|
||||
// to share an open image.
|
||||
class ImageFileReaderTable {
|
||||
private:
|
||||
const static u4 _growth = 8; // Growth rate of the table
|
||||
u4 _count; // Number of entries in the table
|
||||
u4 _max; // Maximum number of entries allocated
|
||||
ImageFileReader** _table; // Growable array of entries
|
||||
const static u4 _growth = 8; // Growth rate of the table
|
||||
u4 _count; // Number of entries in the table
|
||||
u4 _max; // Maximum number of entries allocated
|
||||
ImageFileReader** _table; // Growable array of entries
|
||||
|
||||
public:
|
||||
ImageFileReaderTable();
|
||||
~ImageFileReaderTable();
|
||||
ImageFileReaderTable();
|
||||
~ImageFileReaderTable();
|
||||
|
||||
// Return the number of entries.
|
||||
inline u4 count() { return _count; }
|
||||
// Return the number of entries.
|
||||
inline u4 count() { return _count; }
|
||||
|
||||
// Return the ith entry from the table.
|
||||
inline ImageFileReader* get(u4 i) { return _table[i]; }
|
||||
// Return the ith entry from the table.
|
||||
inline ImageFileReader* get(u4 i) { return _table[i]; }
|
||||
|
||||
// Add a new image entry to the table.
|
||||
void add(ImageFileReader* image);
|
||||
// Add a new image entry to the table.
|
||||
void add(ImageFileReader* image);
|
||||
|
||||
// Remove an image entry from the table.
|
||||
void remove(ImageFileReader* image);
|
||||
// Remove an image entry from the table.
|
||||
void remove(ImageFileReader* image);
|
||||
|
||||
// Determine if image entry is in table.
|
||||
bool contains(ImageFileReader* image);
|
||||
// Determine if image entry is in table.
|
||||
bool contains(ImageFileReader* image);
|
||||
};
|
||||
|
||||
// Manage the image file.
|
||||
@ -473,176 +474,176 @@ public:
|
||||
// index is then memory mapped to allow load on demand and sharing. The
|
||||
// -XX:+MemoryMapImage flag determines if the entire file is loaded (server use.)
|
||||
// An image can be used by Hotspot and multiple reference points in the JDK, thus
|
||||
// it is desirable to share a reader. To accomodate sharing, a share table is
|
||||
// it is desirable to share a reader. To accomodate sharing, a share table is
|
||||
// defined (see ImageFileReaderTable in imageFile.cpp) To track the number of
|
||||
// uses, ImageFileReader keeps a use count (_use). Use is incremented when
|
||||
// 'opened' by reference point and decremented when 'closed'. Use of zero
|
||||
// 'opened' by reference point and decremented when 'closed'. Use of zero
|
||||
// leads the ImageFileReader to be actually closed and discarded.
|
||||
class ImageFileReader {
|
||||
private:
|
||||
// Manage a number of image files such that an image can be shared across
|
||||
// multiple uses (ex. loader.)
|
||||
static ImageFileReaderTable _reader_table;
|
||||
// Manage a number of image files such that an image can be shared across
|
||||
// multiple uses (ex. loader.)
|
||||
static ImageFileReaderTable _reader_table;
|
||||
|
||||
char* _name; // Name of image
|
||||
s4 _use; // Use count
|
||||
int _fd; // File descriptor
|
||||
Endian* _endian; // Endian handler
|
||||
u8 _file_size; // File size in bytes
|
||||
ImageHeader _header; // Image header
|
||||
size_t _index_size; // Total size of index
|
||||
u1* _index_data; // Raw index data
|
||||
s4* _redirect_table; // Perfect hash redirect table
|
||||
u4* _offsets_table; // Location offset table
|
||||
u1* _location_bytes; // Location attributes
|
||||
u1* _string_bytes; // String table
|
||||
ImageModuleData *module_data; // The ImageModuleData for this image
|
||||
char* _name; // Name of image
|
||||
s4 _use; // Use count
|
||||
int _fd; // File descriptor
|
||||
Endian* _endian; // Endian handler
|
||||
u8 _file_size; // File size in bytes
|
||||
ImageHeader _header; // Image header
|
||||
size_t _index_size; // Total size of index
|
||||
u1* _index_data; // Raw index data
|
||||
s4* _redirect_table; // Perfect hash redirect table
|
||||
u4* _offsets_table; // Location offset table
|
||||
u1* _location_bytes; // Location attributes
|
||||
u1* _string_bytes; // String table
|
||||
ImageModuleData *module_data; // The ImageModuleData for this image
|
||||
|
||||
ImageFileReader(const char* name, bool big_endian);
|
||||
~ImageFileReader();
|
||||
ImageFileReader(const char* name, bool big_endian);
|
||||
~ImageFileReader();
|
||||
|
||||
// Compute number of bytes in image file index.
|
||||
inline size_t index_size() {
|
||||
return sizeof(ImageHeader) +
|
||||
table_length() * sizeof(u4) * 2 + locations_size() + strings_size();
|
||||
}
|
||||
// Compute number of bytes in image file index.
|
||||
inline size_t index_size() {
|
||||
return sizeof(ImageHeader) +
|
||||
table_length() * sizeof(u4) * 2 + locations_size() + strings_size();
|
||||
}
|
||||
|
||||
public:
|
||||
enum {
|
||||
// Image file marker.
|
||||
IMAGE_MAGIC = 0xCAFEDADA,
|
||||
// Endian inverted Image file marker.
|
||||
IMAGE_MAGIC_INVERT = 0xDADAFECA,
|
||||
// Image file major version number.
|
||||
MAJOR_VERSION = 1,
|
||||
// Image file minor version number.
|
||||
MINOR_VERSION = 0
|
||||
};
|
||||
enum {
|
||||
// Image file marker.
|
||||
IMAGE_MAGIC = 0xCAFEDADA,
|
||||
// Endian inverted Image file marker.
|
||||
IMAGE_MAGIC_INVERT = 0xDADAFECA,
|
||||
// Image file major version number.
|
||||
MAJOR_VERSION = 1,
|
||||
// Image file minor version number.
|
||||
MINOR_VERSION = 0
|
||||
};
|
||||
|
||||
// Open an image file, reuse structure if file already open.
|
||||
static ImageFileReader* open(const char* name, bool big_endian = Endian::is_big_endian());
|
||||
// Open an image file, reuse structure if file already open.
|
||||
static ImageFileReader* open(const char* name, bool big_endian = Endian::is_big_endian());
|
||||
|
||||
// Close an image file if the file is not in use elsewhere.
|
||||
static void close(ImageFileReader *reader);
|
||||
// Close an image file if the file is not in use elsewhere.
|
||||
static void close(ImageFileReader *reader);
|
||||
|
||||
// Return an id for the specifed ImageFileReader.
|
||||
static u8 readerToID(ImageFileReader *reader);
|
||||
// Return an id for the specifed ImageFileReader.
|
||||
static u8 readerToID(ImageFileReader *reader);
|
||||
|
||||
// Validate the image id.
|
||||
static bool idCheck(u8 id);
|
||||
// Validate the image id.
|
||||
static bool idCheck(u8 id);
|
||||
|
||||
// Return an id for the specifed ImageFileReader.
|
||||
static ImageFileReader* idToReader(u8 id);
|
||||
// Return an id for the specifed ImageFileReader.
|
||||
static ImageFileReader* idToReader(u8 id);
|
||||
|
||||
// Open image file for read access.
|
||||
bool open();
|
||||
// Open image file for read access.
|
||||
bool open();
|
||||
|
||||
// Close image file.
|
||||
void close();
|
||||
// Close image file.
|
||||
void close();
|
||||
|
||||
// Read directly from the file.
|
||||
bool read_at(u1* data, u8 size, u8 offset) const;
|
||||
// Read directly from the file.
|
||||
bool read_at(u1* data, u8 size, u8 offset) const;
|
||||
|
||||
inline Endian* endian() const { return _endian; }
|
||||
inline Endian* endian() const { return _endian; }
|
||||
|
||||
// Retrieve name of image file.
|
||||
inline const char* name() const {
|
||||
return _name;
|
||||
}
|
||||
// Retrieve name of image file.
|
||||
inline const char* name() const {
|
||||
return _name;
|
||||
}
|
||||
|
||||
// Retrieve size of image file.
|
||||
inline u8 file_size() const {
|
||||
return _file_size;
|
||||
}
|
||||
// Retrieve size of image file.
|
||||
inline u8 file_size() const {
|
||||
return _file_size;
|
||||
}
|
||||
|
||||
// Return first address of index data.
|
||||
inline u1* get_index_address() const {
|
||||
return _index_data;
|
||||
}
|
||||
// Return first address of index data.
|
||||
inline u1* get_index_address() const {
|
||||
return _index_data;
|
||||
}
|
||||
|
||||
// Return first address of resource data.
|
||||
inline u1* get_data_address() const {
|
||||
return _index_data + _index_size;
|
||||
}
|
||||
// Return first address of resource data.
|
||||
inline u1* get_data_address() const {
|
||||
return _index_data + _index_size;
|
||||
}
|
||||
|
||||
// Get the size of the index data.
|
||||
size_t get_index_size() const {
|
||||
return _index_size;
|
||||
}
|
||||
// Get the size of the index data.
|
||||
size_t get_index_size() const {
|
||||
return _index_size;
|
||||
}
|
||||
|
||||
inline u4 table_length() const {
|
||||
return _header.table_length(_endian);
|
||||
}
|
||||
inline u4 table_length() const {
|
||||
return _header.table_length(_endian);
|
||||
}
|
||||
|
||||
inline u4 locations_size() const {
|
||||
return _header.locations_size(_endian);
|
||||
}
|
||||
inline u4 locations_size() const {
|
||||
return _header.locations_size(_endian);
|
||||
}
|
||||
|
||||
inline u4 strings_size()const {
|
||||
return _header.strings_size(_endian);
|
||||
}
|
||||
inline u4 strings_size()const {
|
||||
return _header.strings_size(_endian);
|
||||
}
|
||||
|
||||
inline u4* offsets_table() const {
|
||||
return _offsets_table;
|
||||
}
|
||||
inline u4* offsets_table() const {
|
||||
return _offsets_table;
|
||||
}
|
||||
|
||||
// Increment use count.
|
||||
inline void inc_use() {
|
||||
_use++;
|
||||
}
|
||||
// Increment use count.
|
||||
inline void inc_use() {
|
||||
_use++;
|
||||
}
|
||||
|
||||
// Decrement use count.
|
||||
inline bool dec_use() {
|
||||
return --_use == 0;
|
||||
}
|
||||
// Decrement use count.
|
||||
inline bool dec_use() {
|
||||
return --_use == 0;
|
||||
}
|
||||
|
||||
// Return a string table accessor.
|
||||
inline const ImageStrings get_strings() const {
|
||||
return ImageStrings(_string_bytes, _header.strings_size(_endian));
|
||||
}
|
||||
// Return a string table accessor.
|
||||
inline const ImageStrings get_strings() const {
|
||||
return ImageStrings(_string_bytes, _header.strings_size(_endian));
|
||||
}
|
||||
|
||||
// Return location attribute stream at offset.
|
||||
inline u1* get_location_offset_data(u4 offset) const {
|
||||
assert((u4)offset < _header.locations_size(_endian) &&
|
||||
"offset exceeds location attributes size");
|
||||
return offset != 0 ? _location_bytes + offset : NULL;
|
||||
}
|
||||
// Return location attribute stream at offset.
|
||||
inline u1* get_location_offset_data(u4 offset) const {
|
||||
assert((u4)offset < _header.locations_size(_endian) &&
|
||||
"offset exceeds location attributes size");
|
||||
return offset != 0 ? _location_bytes + offset : NULL;
|
||||
}
|
||||
|
||||
// Return location attribute stream for location i.
|
||||
inline u1* get_location_data(u4 index) const {
|
||||
return get_location_offset_data(get_location_offset(index));
|
||||
}
|
||||
// Return location attribute stream for location i.
|
||||
inline u1* get_location_data(u4 index) const {
|
||||
return get_location_offset_data(get_location_offset(index));
|
||||
}
|
||||
|
||||
// Return the location offset for index.
|
||||
inline u4 get_location_offset(u4 index) const {
|
||||
assert((u4)index < _header.table_length(_endian) &&
|
||||
"index exceeds location count");
|
||||
return _endian->get(_offsets_table[index]);
|
||||
}
|
||||
// Return the location offset for index.
|
||||
inline u4 get_location_offset(u4 index) const {
|
||||
assert((u4)index < _header.table_length(_endian) &&
|
||||
"index exceeds location count");
|
||||
return _endian->get(_offsets_table[index]);
|
||||
}
|
||||
|
||||
// Find the location attributes associated with the path. Returns true if
|
||||
// the location is found, false otherwise.
|
||||
bool find_location(const char* path, ImageLocation& location) const;
|
||||
// Find the location attributes associated with the path. Returns true if
|
||||
// the location is found, false otherwise.
|
||||
bool find_location(const char* path, ImageLocation& location) const;
|
||||
|
||||
// Find the location index and size associated with the path.
|
||||
// Returns the location index and size if the location is found,
|
||||
// ImageFileReader::NOT_FOUND otherwise.
|
||||
u4 find_location_index(const char* path, u8 *size) const;
|
||||
// Find the location index and size associated with the path.
|
||||
// Returns the location index and size if the location is found,
|
||||
// ImageFileReader::NOT_FOUND otherwise.
|
||||
u4 find_location_index(const char* path, u8 *size) const;
|
||||
|
||||
// Assemble the location path.
|
||||
void location_path(ImageLocation& location, char* path, size_t max) const;
|
||||
// Assemble the location path.
|
||||
void location_path(ImageLocation& location, char* path, size_t max) const;
|
||||
|
||||
// Verify that a found location matches the supplied path.
|
||||
bool verify_location(ImageLocation& location, const char* path) const;
|
||||
// Verify that a found location matches the supplied path.
|
||||
bool verify_location(ImageLocation& location, const char* path) const;
|
||||
|
||||
// Return the resource for the supplied location index.
|
||||
void get_resource(u4 index, u1* uncompressed_data) const;
|
||||
// Return the resource for the supplied location index.
|
||||
void get_resource(u4 index, u1* uncompressed_data) const;
|
||||
|
||||
// Return the resource for the supplied path.
|
||||
void get_resource(ImageLocation& location, u1* uncompressed_data) const;
|
||||
// Return the resource for the supplied path.
|
||||
void get_resource(ImageLocation& location, u1* uncompressed_data) const;
|
||||
|
||||
// Return the ImageModuleData for this image
|
||||
ImageModuleData * get_image_module_data();
|
||||
// Return the ImageModuleData for this image
|
||||
ImageModuleData * get_image_module_data();
|
||||
|
||||
};
|
||||
#endif // LIBJIMAGE_IMAGEFILE_HPP
|
||||
|
@ -4,7 +4,9 @@
|
||||
*
|
||||
* 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.
|
||||
* 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
|
||||
@ -19,7 +21,6 @@
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LIBJIMAGE_INTTYPES_HPP
|
||||
|
@ -1,10 +1,12 @@
|
||||
/*
|
||||
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* 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.
|
||||
* 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
|
||||
@ -19,7 +21,6 @@
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
@ -97,7 +98,8 @@ extern "C" const char* JIMAGE_PackageToModule(JImageFile* image, const char* pac
|
||||
*
|
||||
* Ex.
|
||||
* jlong size;
|
||||
* JImageLocationRef location = (*JImageFindResource)(image, "java.base", "9.0", "java/lang/String.class", &size);
|
||||
* JImageLocationRef location = (*JImageFindResource)(image,
|
||||
* "java.base", "9.0", "java/lang/String.class", &size);
|
||||
*/
|
||||
extern "C" JImageLocationRef JIMAGE_FindResource(JImageFile* image,
|
||||
const char* module_name, const char* version, const char* name,
|
||||
@ -129,7 +131,8 @@ extern "C" JImageLocationRef JIMAGE_FindResource(JImageFile* image,
|
||||
*
|
||||
* Ex.
|
||||
* jlong size;
|
||||
* JImageLocationRef* location = (*JImageFindResource)(image, "java.base", "9.0", "java/lang/String.class", &size);
|
||||
* JImageLocationRef location = (*JImageFindResource)(image,
|
||||
* "java.base", "9.0", "java/lang/String.class", &size);
|
||||
* char* buffer = new char[size];
|
||||
* (*JImageGetResource)(image, location, buffer, size);
|
||||
*/
|
||||
@ -148,7 +151,8 @@ extern "C" jlong JIMAGE_GetResource(JImageFile* image, JImageLocationRef locatio
|
||||
* required. All strings are utf-8, zero byte terminated.file.
|
||||
*
|
||||
* Ex.
|
||||
* bool ctw_visitor(JImageFile* jimage, const char* module_name, const char* version, const char* package, const char* name, const char* extension, void* arg) {
|
||||
* bool ctw_visitor(JImageFile* jimage, const char* module_name, const char* version,
|
||||
* const char* package, const char* name, const char* extension, void* arg) {
|
||||
* if (strcmp(extension, “class”) == 0) {
|
||||
* char path[JIMAGE_MAX_PATH];
|
||||
* Thread* THREAD = Thread::current();
|
||||
|
@ -4,7 +4,9 @@
|
||||
*
|
||||
* 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.
|
||||
* 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
|
||||
@ -19,7 +21,6 @@
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "jni.h"
|
||||
@ -111,7 +112,8 @@ typedef const char* (*JImagePackageToModule_t)(JImageFile* jimage, const char* p
|
||||
*
|
||||
* Ex.
|
||||
* jlong size;
|
||||
* JImageLocationRef location = (*JImageFindResource)(image, "java.base", "9.0", "java/lang/String.class", &size);
|
||||
* JImageLocationRef location = (*JImageFindResource)(image,
|
||||
* "java.base", "9.0", "java/lang/String.class", &size);
|
||||
*/
|
||||
extern "C" JImageLocationRef JIMAGE_FindResource(JImageFile* jimage,
|
||||
const char* module_name, const char* version, const char* name,
|
||||
@ -132,7 +134,8 @@ typedef JImageLocationRef(*JImageFindResource_t)(JImageFile* jimage,
|
||||
*
|
||||
* Ex.
|
||||
* jlong size;
|
||||
* JImageLocationRef location = (*JImageFindResource)(image, "java.base", "9.0", "java/lang/String.class", &size);
|
||||
* JImageLocationRef location = (*JImageFindResource)(image,
|
||||
* "java.base", "9.0", "java/lang/String.class", &size);
|
||||
* char* buffer = new char[size];
|
||||
* (*JImageGetResource)(image, location, buffer, size);
|
||||
*/
|
||||
@ -152,7 +155,8 @@ typedef jlong(*JImageGetResource_t)(JImageFile* jimage, JImageLocationRef locati
|
||||
* required. All strings are utf-8, zero byte terminated.file.
|
||||
*
|
||||
* Ex.
|
||||
* bool ctw_visitor(JImageFile* jimage, const char* module_name, const char* version, const char* package, const char* name, const char* extension, void* arg) {
|
||||
* bool ctw_visitor(JImageFile* jimage, const char* module_name, const char* version,
|
||||
* const char* package, const char* name, const char* extension, void* arg) {
|
||||
* if (strcmp(extension, “class”) == 0) {
|
||||
* char path[JIMAGE_MAX_PATH];
|
||||
* Thread* THREAD = Thread::current();
|
||||
|
@ -4,7 +4,9 @@
|
||||
*
|
||||
* 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.
|
||||
* 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
|
||||
@ -19,7 +21,6 @@
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LIBJIMAGE_OSSUPPORT_HPP
|
||||
|
@ -4,7 +4,9 @@
|
||||
*
|
||||
* 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.
|
||||
* 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
|
||||
@ -19,10 +21,8 @@
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
|
@ -4,7 +4,9 @@
|
||||
*
|
||||
* 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.
|
||||
* 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
|
||||
@ -19,7 +21,6 @@
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
|
@ -28,7 +28,7 @@ import java.util.Map;
|
||||
|
||||
/**
|
||||
* A mapping of key/value pairs, all of whose keys are
|
||||
* <code>Strings</code>.
|
||||
* {@code Strings}.
|
||||
*
|
||||
* @author Mike Grogan
|
||||
* @since 1.6
|
||||
@ -49,8 +49,8 @@ public interface Bindings extends Map<String, Object> {
|
||||
public Object put(String name, Object value);
|
||||
|
||||
/**
|
||||
* Adds all the mappings in a given <code>Map</code> to this <code>Bindings</code>.
|
||||
* @param toMerge The <code>Map</code> to merge with this one.
|
||||
* Adds all the mappings in a given {@code Map} to this {@code Bindings}.
|
||||
* @param toMerge The {@code Map} to merge with this one.
|
||||
*
|
||||
* @throws NullPointerException
|
||||
* if toMerge map is null or if some key in the map is null.
|
||||
@ -60,14 +60,14 @@ public interface Bindings extends Map<String, Object> {
|
||||
public void putAll(Map<? extends String, ? extends Object> toMerge);
|
||||
|
||||
/**
|
||||
* Returns <tt>true</tt> if this map contains a mapping for the specified
|
||||
* key. More formally, returns <tt>true</tt> if and only if
|
||||
* this map contains a mapping for a key <tt>k</tt> such that
|
||||
* <tt>(key==null ? k==null : key.equals(k))</tt>. (There can be
|
||||
* Returns {@code true} if this map contains a mapping for the specified
|
||||
* key. More formally, returns {@code true} if and only if
|
||||
* this map contains a mapping for a key {@code k} such that
|
||||
* {@code (key==null ? k==null : key.equals(k))}. (There can be
|
||||
* at most one such mapping.)
|
||||
*
|
||||
* @param key key whose presence in this map is to be tested.
|
||||
* @return <tt>true</tt> if this map contains a mapping for the specified
|
||||
* @return {@code true} if this map contains a mapping for the specified
|
||||
* key.
|
||||
*
|
||||
* @throws NullPointerException if key is null
|
||||
@ -78,20 +78,21 @@ public interface Bindings extends Map<String, Object> {
|
||||
|
||||
/**
|
||||
* Returns the value to which this map maps the specified key. Returns
|
||||
* <tt>null</tt> if the map contains no mapping for this key. A return
|
||||
* value of <tt>null</tt> does not <i>necessarily</i> indicate that the
|
||||
* {@code null} if the map contains no mapping for this key. A return
|
||||
* value of {@code null} does not <i>necessarily</i> indicate that the
|
||||
* map contains no mapping for the key; it's also possible that the map
|
||||
* explicitly maps the key to <tt>null</tt>. The <tt>containsKey</tt>
|
||||
* explicitly maps the key to {@code null}. The {@code containsKey}
|
||||
* operation may be used to distinguish these two cases.
|
||||
*
|
||||
* <p>More formally, if this map contains a mapping from a key
|
||||
* <tt>k</tt> to a value <tt>v</tt> such that <tt>(key==null ? k==null :
|
||||
* key.equals(k))</tt>, then this method returns <tt>v</tt>; otherwise
|
||||
* it returns <tt>null</tt>. (There can be at most one such mapping.)
|
||||
* {@code k} to a value {@code v} such that
|
||||
* {@code (key==null ? k==null : key.equals(k))},
|
||||
* then this method returns {@code v}; otherwise
|
||||
* it returns {@code null}. (There can be at most one such mapping.)
|
||||
*
|
||||
* @param key key whose associated value is to be returned.
|
||||
* @return the value to which this map maps the specified key, or
|
||||
* <tt>null</tt> if the map contains no mapping for this key.
|
||||
* {@code null} if the map contains no mapping for this key.
|
||||
*
|
||||
* @throws NullPointerException if key is null
|
||||
* @throws ClassCastException if key is not String
|
||||
@ -102,19 +103,19 @@ public interface Bindings extends Map<String, Object> {
|
||||
/**
|
||||
* Removes the mapping for this key from this map if it is present
|
||||
* (optional operation). More formally, if this map contains a mapping
|
||||
* from key <tt>k</tt> to value <tt>v</tt> such that
|
||||
* <code>(key==null ? k==null : key.equals(k))</code>, that mapping
|
||||
* from key {@code k} to value {@code v} such that
|
||||
* {@code (key==null ? k==null : key.equals(k))}, that mapping
|
||||
* is removed. (The map can contain at most one such mapping.)
|
||||
*
|
||||
* <p>Returns the value to which the map previously associated the key, or
|
||||
* <tt>null</tt> if the map contained no mapping for this key. (A
|
||||
* <tt>null</tt> return can also indicate that the map previously
|
||||
* associated <tt>null</tt> with the specified key if the implementation
|
||||
* supports <tt>null</tt> values.) The map will not contain a mapping for
|
||||
* {@code null} if the map contained no mapping for this key. (A
|
||||
* {@code null} return can also indicate that the map previously
|
||||
* associated {@code null} with the specified key if the implementation
|
||||
* supports {@code null} values.) The map will not contain a mapping for
|
||||
* the specified key once the call returns.
|
||||
*
|
||||
* @param key key whose mapping is to be removed from the map.
|
||||
* @return previous value associated with specified key, or <tt>null</tt>
|
||||
* @return previous value associated with specified key, or {@code null}
|
||||
* if there was no mapping for key.
|
||||
*
|
||||
* @throws NullPointerException if key is null
|
||||
|
@ -32,7 +32,7 @@ import java.util.Set;
|
||||
|
||||
/**
|
||||
* A simple implementation of Bindings backed by
|
||||
* a <code>HashMap</code> or some other specified <code>Map</code>.
|
||||
* a {@code HashMap} or some other specified {@code Map}.
|
||||
*
|
||||
* @author Mike Grogan
|
||||
* @since 1.6
|
||||
@ -40,13 +40,13 @@ import java.util.Set;
|
||||
public class SimpleBindings implements Bindings {
|
||||
|
||||
/**
|
||||
* The <code>Map</code> field stores the attributes.
|
||||
* The {@code Map} field stores the attributes.
|
||||
*/
|
||||
private Map<String,Object> map;
|
||||
|
||||
/**
|
||||
* Constructor uses an existing <code>Map</code> to store the values.
|
||||
* @param m The <code>Map</code> backing this <code>SimpleBindings</code>.
|
||||
* Constructor uses an existing {@code Map} to store the values.
|
||||
* @param m The {@code Map} backing this {@code SimpleBindings}.
|
||||
* @throws NullPointerException if m is null
|
||||
*/
|
||||
public SimpleBindings(Map<String,Object> m) {
|
||||
@ -57,14 +57,14 @@ public class SimpleBindings implements Bindings {
|
||||
}
|
||||
|
||||
/**
|
||||
* Default constructor uses a <code>HashMap</code>.
|
||||
* Default constructor uses a {@code HashMap}.
|
||||
*/
|
||||
public SimpleBindings() {
|
||||
this(new HashMap<String,Object>());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the specified key/value in the underlying <code>map</code> field.
|
||||
* Sets the specified key/value in the underlying {@code map} field.
|
||||
*
|
||||
* @param name Name of value
|
||||
* @param value Value to set.
|
||||
@ -81,9 +81,9 @@ public class SimpleBindings implements Bindings {
|
||||
}
|
||||
|
||||
/**
|
||||
* <code>putAll</code> is implemented using <code>Map.putAll</code>.
|
||||
* {@code putAll} is implemented using {@code Map.putAll}.
|
||||
*
|
||||
* @param toMerge The <code>Map</code> of values to add.
|
||||
* @param toMerge The {@code Map} of values to add.
|
||||
*
|
||||
* @throws NullPointerException
|
||||
* if toMerge map is null or if some key in the map is null.
|
||||
@ -107,14 +107,14 @@ public class SimpleBindings implements Bindings {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <tt>true</tt> if this map contains a mapping for the specified
|
||||
* key. More formally, returns <tt>true</tt> if and only if
|
||||
* this map contains a mapping for a key <tt>k</tt> such that
|
||||
* <tt>(key==null ? k==null : key.equals(k))</tt>. (There can be
|
||||
* Returns {@code true} if this map contains a mapping for the specified
|
||||
* key. More formally, returns {@code true} if and only if
|
||||
* this map contains a mapping for a key {@code k} such that
|
||||
* {@code (key==null ? k==null : key.equals(k))}. (There can be
|
||||
* at most one such mapping.)
|
||||
*
|
||||
* @param key key whose presence in this map is to be tested.
|
||||
* @return <tt>true</tt> if this map contains a mapping for the specified
|
||||
* @return {@code true} if this map contains a mapping for the specified
|
||||
* key.
|
||||
*
|
||||
* @throws NullPointerException if key is null
|
||||
@ -138,20 +138,21 @@ public class SimpleBindings implements Bindings {
|
||||
|
||||
/**
|
||||
* Returns the value to which this map maps the specified key. Returns
|
||||
* <tt>null</tt> if the map contains no mapping for this key. A return
|
||||
* value of <tt>null</tt> does not <i>necessarily</i> indicate that the
|
||||
* {@code null} if the map contains no mapping for this key. A return
|
||||
* value of {@code null} does not <i>necessarily</i> indicate that the
|
||||
* map contains no mapping for the key; it's also possible that the map
|
||||
* explicitly maps the key to <tt>null</tt>. The <tt>containsKey</tt>
|
||||
* explicitly maps the key to {@code null}. The {@code containsKey}
|
||||
* operation may be used to distinguish these two cases.
|
||||
*
|
||||
* <p>More formally, if this map contains a mapping from a key
|
||||
* <tt>k</tt> to a value <tt>v</tt> such that <tt>(key==null ? k==null :
|
||||
* key.equals(k))</tt>, then this method returns <tt>v</tt>; otherwise
|
||||
* it returns <tt>null</tt>. (There can be at most one such mapping.)
|
||||
* {@code k} to a value {@code v} such that
|
||||
* {@code (key==null ? k==null : key.equals(k))},
|
||||
* then this method returns {@code v}; otherwise
|
||||
* it returns {@code null}. (There can be at most one such mapping.)
|
||||
*
|
||||
* @param key key whose associated value is to be returned.
|
||||
* @return the value to which this map maps the specified key, or
|
||||
* <tt>null</tt> if the map contains no mapping for this key.
|
||||
* {@code null} if the map contains no mapping for this key.
|
||||
*
|
||||
* @throws NullPointerException if key is null
|
||||
* @throws ClassCastException if key is not String
|
||||
@ -175,19 +176,19 @@ public class SimpleBindings implements Bindings {
|
||||
/**
|
||||
* Removes the mapping for this key from this map if it is present
|
||||
* (optional operation). More formally, if this map contains a mapping
|
||||
* from key <tt>k</tt> to value <tt>v</tt> such that
|
||||
* <code>(key==null ? k==null : key.equals(k))</code>, that mapping
|
||||
* from key {@code k} to value {@code v} such that
|
||||
* {@code (key==null ? k==null : key.equals(k))}, that mapping
|
||||
* is removed. (The map can contain at most one such mapping.)
|
||||
*
|
||||
* <p>Returns the value to which the map previously associated the key, or
|
||||
* <tt>null</tt> if the map contained no mapping for this key. (A
|
||||
* <tt>null</tt> return can also indicate that the map previously
|
||||
* associated <tt>null</tt> with the specified key if the implementation
|
||||
* supports <tt>null</tt> values.) The map will not contain a mapping for
|
||||
* {@code null} if the map contained no mapping for this key. (A
|
||||
* {@code null} return can also indicate that the map previously
|
||||
* associated {@code null} with the specified key if the implementation
|
||||
* supports {@code null} values.) The map will not contain a mapping for
|
||||
* the specified key once the call returns.
|
||||
*
|
||||
* @param key key whose mapping is to be removed from the map.
|
||||
* @return previous value associated with specified key, or <tt>null</tt>
|
||||
* @return previous value associated with specified key, or {@code null}
|
||||
* if there was no mapping for key.
|
||||
*
|
||||
* @throws NullPointerException if key is null
|
||||
|
@ -54,7 +54,7 @@ import javax.swing.SwingWorker;
|
||||
* <blockquote><pre>
|
||||
* jconsole -pluginpath <plugin-path> </pre></blockquote>
|
||||
*
|
||||
* <p> where <tt><plugin-path></tt> specifies the paths of JConsole
|
||||
* <p> where {@code <plugin-path>} specifies the paths of JConsole
|
||||
* plugins to look up which can be a directory or a jar file. Multiple
|
||||
* paths are separated by the path separator character of the platform.
|
||||
*
|
||||
@ -106,7 +106,7 @@ public abstract class JConsolePlugin {
|
||||
|
||||
/**
|
||||
* Returns the {@link JConsoleContext JConsoleContext} object representing
|
||||
* the connection to an application. This method may return <tt>null</tt>
|
||||
* the connection to an application. This method may return {@code null}
|
||||
* if it is called before the {@link #setContext context} is initialized.
|
||||
*
|
||||
* @return the {@link JConsoleContext JConsoleContext} object representing
|
||||
@ -146,24 +146,24 @@ public abstract class JConsolePlugin {
|
||||
* method to schedule the returned {@code SwingWorker} for execution
|
||||
* if:
|
||||
* <ul>
|
||||
* <li> the <tt>SwingWorker</tt> object has not been executed
|
||||
* <li> the {@code SwingWorker} object has not been executed
|
||||
* (i.e. the {@link SwingWorker#getState} method
|
||||
* returns {@link javax.swing.SwingWorker.StateValue#PENDING PENDING}
|
||||
* state); and</li>
|
||||
* <li> the <tt>SwingWorker</tt> object returned in the previous
|
||||
* update has completed the task if it was not <tt>null</tt>
|
||||
* <li> the {@code SwingWorker} object returned in the previous
|
||||
* update has completed the task if it was not {@code null}
|
||||
* (i.e. the {@link SwingWorker#isDone SwingWorker.isDone} method
|
||||
* returns <tt>true</tt>).</li>
|
||||
* returns {@code true}).</li>
|
||||
* </ul>
|
||||
* <br>
|
||||
* Otherwise, <tt>SwingWorker</tt> object will not be scheduled to work.
|
||||
* Otherwise, {@code SwingWorker} object will not be scheduled to work.
|
||||
*
|
||||
* <p>
|
||||
* A plugin can schedule its own GUI update and this method
|
||||
* will return <tt>null</tt>.
|
||||
* will return {@code null}.
|
||||
*
|
||||
* @return a <tt>SwingWorker</tt> to perform the GUI update; or
|
||||
* <tt>null</tt>.
|
||||
* @return a {@code SwingWorker} to perform the GUI update; or
|
||||
* {@code null}.
|
||||
*/
|
||||
public abstract SwingWorker<?,?> newSwingWorker();
|
||||
|
||||
|
@ -581,7 +581,7 @@ public class ProxyClient implements JConsoleContext {
|
||||
|
||||
/**
|
||||
* Returns a map of MBeans with ObjectName as the key and MBeanInfo value
|
||||
* of a given domain. If domain is <tt>null</tt>, all MBeans
|
||||
* of a given domain. If domain is {@code null}, all MBeans
|
||||
* are returned. If no MBean found, an empty map is returned.
|
||||
*
|
||||
*/
|
||||
|
@ -259,7 +259,7 @@ class ClassDefinition implements Constants {
|
||||
* Tell if the class is inner.
|
||||
* This predicate also returns true for top-level nested types.
|
||||
* To test for a true inner class as seen by the programmer,
|
||||
* use <tt>!isTopLevel()</tt>.
|
||||
* use {@code !isTopLevel()}.
|
||||
*/
|
||||
public final boolean isInnerClass() {
|
||||
return outerClass != null;
|
||||
@ -911,7 +911,7 @@ class ClassDefinition implements Constants {
|
||||
}
|
||||
|
||||
/**
|
||||
* Note that this class is being used somehow by <tt>ref</tt>.
|
||||
* Note that this class is being used somehow by {@code ref}.
|
||||
* Report deprecation errors, etc.
|
||||
*/
|
||||
public void noteUsedBy(ClassDefinition ref, long where, Environment env) {
|
||||
|
@ -200,7 +200,7 @@ class Identifier implements Constants {
|
||||
/** A space character, which precedes the first inner class
|
||||
* name in a qualified name, and thus marks the qualification
|
||||
* as involving inner classes, instead of merely packages.<p>
|
||||
* Ex: <tt>java.util.Vector. Enumerator</tt>.
|
||||
* Ex: {@code java.util.Vector. Enumerator}.
|
||||
*/
|
||||
public static final char INNERCLASS_PREFIX = ' ';
|
||||
|
||||
@ -229,7 +229,7 @@ class Identifier implements Constants {
|
||||
* and with any nesting flattened into a new qualfication structure.
|
||||
* If the original identifier is inner,
|
||||
* the result will be qualified, and can be further
|
||||
* decomposed by means of <tt>getQualifier</tt> and <tt>getName</tt>.
|
||||
* decomposed by means of {@code getQualifier} and {@code getName}.
|
||||
* <p>
|
||||
* For example:
|
||||
* <pre>
|
||||
|
@ -394,7 +394,7 @@ class SourceMember extends MemberDefinition implements Constants {
|
||||
* <p>
|
||||
* This is the method which requests checking.
|
||||
* The real work is done by
|
||||
* <tt>Vset check(Environment, Context, Vset)</tt>.
|
||||
* {@code Vset check(Environment, Context, Vset)}.
|
||||
*/
|
||||
public void check(Environment env) throws ClassNotFound {
|
||||
if (tracing) env.dtEnter("SourceMember.check: " +
|
||||
|
@ -210,8 +210,8 @@ class Expression extends Node {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a <code>FieldUpdater</code> object to be used in updating the
|
||||
* value of the location denoted by <code>this</code>, which must be an
|
||||
* Return a {@code FieldUpdater} object to be used in updating the
|
||||
* value of the location denoted by {@code this}, which must be an
|
||||
* expression suitable for the left-hand side of an assignment.
|
||||
* This is used for implementing assignments to private fields for which
|
||||
* an access method is required. Returns null if no access method is
|
||||
@ -228,8 +228,8 @@ class Expression extends Node {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a <code>FieldUpdater</code> object to be used in updating the value of the
|
||||
* location denoted by <code>this</code>, which must be an expression suitable for the
|
||||
* Return a {@code FieldUpdater} object to be used in updating the value of the
|
||||
* location denoted by {@code this}, which must be an expression suitable for the
|
||||
* left-hand side of an assignment. This is used for implementing the assignment
|
||||
* operators and the increment/decrement operators on private fields that require an
|
||||
* access method, e.g., uplevel from an inner class. Returns null if no access method
|
||||
@ -260,9 +260,9 @@ class Expression extends Node {
|
||||
* <li> a type name followed by fields or types
|
||||
* <li> a package name followed a type and then fields or types
|
||||
* </nl>
|
||||
* If a type name is found, it rewrites itself as a <tt>TypeExpression</tt>.
|
||||
* If a type name is found, it rewrites itself as a {@code TypeExpression}.
|
||||
* If a node decides it can only be a package prefix, it sets its
|
||||
* type to <tt>Type.tPackage</tt>. The caller must detect this
|
||||
* type to {@code Type.tPackage}. The caller must detect this
|
||||
* and act appropriately to verify the full package name.
|
||||
* @arg loc the expression containing the ambiguous expression
|
||||
*/
|
||||
|
116
jdk/test/com/sun/crypto/provider/CICO/CICOChainingTest.java
Normal file
116
jdk/test/com/sun/crypto/provider/CICO/CICOChainingTest.java
Normal file
@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 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.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PipedInputStream;
|
||||
import java.io.PipedOutputStream;
|
||||
import java.util.Arrays;
|
||||
import javax.crypto.CipherInputStream;
|
||||
import javax.crypto.CipherOutputStream;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8048604
|
||||
* @summary This test verifies the assertion "The chaining feature of
|
||||
* Filter streams should be supported." for feature "CipherInputStream &
|
||||
* CipherOutputStream"
|
||||
* @run main CICOChainingTest
|
||||
*/
|
||||
public class CICOChainingTest {
|
||||
/**
|
||||
* Plain text length.
|
||||
*/
|
||||
private static final int PLAIN_TEXT_LENGTH = 200;
|
||||
|
||||
public static void main(String argv[]) throws Exception {
|
||||
CICOChainingTest test = new CICOChainingTest();
|
||||
test.chainTest(true);
|
||||
test.chainTest(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Chain CipherInputStream/CipherOutputStream with other stream, encrypt
|
||||
* the text and decrypt it, recovered text is supposed to be same as
|
||||
* original text.
|
||||
* @param useInt true if read byte by byte false if read with buffer.
|
||||
* @throws IOException any I/O operation failed.
|
||||
*/
|
||||
public void chainTest(boolean useInt) throws IOException {
|
||||
byte[] plainText = TestUtilities.generateBytes(PLAIN_TEXT_LENGTH);
|
||||
byte[] recoveredText = new byte[plainText.length];
|
||||
// Do initialization
|
||||
try (MyNullCipherInputStream ciInput1 = new MyNullCipherInputStream(
|
||||
new ByteArrayInputStream(plainText));
|
||||
PipedOutputStream piOut = new PipedOutputStream();
|
||||
MyNullCipherInputStream ciInput2 = new MyNullCipherInputStream(
|
||||
new PipedInputStream(piOut));
|
||||
MyNullCipherOutputStream ciOut = new MyNullCipherOutputStream(
|
||||
piOut);) {
|
||||
if (useInt) {
|
||||
int buffer = ciInput1.read();
|
||||
while (buffer != -1) {
|
||||
piOut.write(buffer);
|
||||
buffer = ciInput1.read();
|
||||
}
|
||||
} else {
|
||||
byte[] buffer = new byte[20];
|
||||
int len = ciInput1.read(buffer);
|
||||
while (len != -1) {
|
||||
ciOut.write(buffer, 0, len);
|
||||
len = ciInput1.read(buffer);
|
||||
}
|
||||
}
|
||||
ciOut.flush();
|
||||
piOut.flush();
|
||||
// Get the output
|
||||
ciInput2.read(recoveredText);
|
||||
if (ciInput2.available() > 0) {
|
||||
throw new RuntimeException("Expected no data from ciInput2, but"
|
||||
+ " ciInput2.available() = " + ciInput2.available());
|
||||
}
|
||||
}
|
||||
// Verify output is same to input.
|
||||
if (!Arrays.equals(plainText, recoveredText)) {
|
||||
throw new RuntimeException("plainText:" + new String(plainText)
|
||||
+ " recoveredText:" + new String(recoveredText)
|
||||
+ " Test failed due to result compare fail");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class MyNullCipherInputStream extends CipherInputStream {
|
||||
|
||||
public MyNullCipherInputStream(InputStream is) {
|
||||
super(is);
|
||||
}
|
||||
}
|
||||
|
||||
class MyNullCipherOutputStream extends CipherOutputStream {
|
||||
|
||||
public MyNullCipherOutputStream(OutputStream os) {
|
||||
super(os);
|
||||
}
|
||||
}
|
142
jdk/test/com/sun/crypto/provider/CICO/CICODESFuncTest.java
Normal file
142
jdk/test/com/sun/crypto/provider/CICO/CICODESFuncTest.java
Normal file
@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 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 static java.lang.System.out;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.Provider;
|
||||
import java.security.Security;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.util.Arrays;
|
||||
import javax.crypto.CipherInputStream;
|
||||
import javax.crypto.CipherOutputStream;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8048604
|
||||
* @summary to verify cipherInputStream and cipherInputStream cipher function
|
||||
* @run main CICODESFuncTest
|
||||
*/
|
||||
public class CICODESFuncTest {
|
||||
/**
|
||||
* Algorithms name.
|
||||
*/
|
||||
private static final String[] ALGORITHMS = { "DES", "DESede", "Blowfish" };
|
||||
private static final String[] MODES = { "ECB", "CBC", "CFB", "CFB24",
|
||||
"CFB32", "CFB40", "CFB72", "OFB", "OFB20", "OFB48", "OFB56",
|
||||
"OFB64", "PCBC" };
|
||||
/**
|
||||
* Padding mode.
|
||||
*/
|
||||
private static final String[] PADDINGS = { "noPadding", "pkcs5padding" };
|
||||
/**
|
||||
* Plain text length.
|
||||
*/
|
||||
private static final int TEXT_LENGTH = 80;
|
||||
/**
|
||||
* Initialization vector length.
|
||||
*/
|
||||
private static final int IV_LENGTH = 8;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
Provider provider = Security.getProvider("SunJCE");
|
||||
if (provider == null) {
|
||||
throw new RuntimeException("SunJCE provider does not exist.");
|
||||
}
|
||||
for (String algorithm : ALGORITHMS) {
|
||||
for (String mode : MODES) {
|
||||
// We only test noPadding and pkcs5padding for CFB72, OFB20, ECB
|
||||
// PCBC and CBC. Otherwise test noPadding only.
|
||||
int padKinds = 1;
|
||||
if (mode.equalsIgnoreCase("CFB72")
|
||||
|| mode.equalsIgnoreCase("OFB20")
|
||||
|| mode.equalsIgnoreCase("ECB")
|
||||
|| mode.equalsIgnoreCase("PCBC")
|
||||
|| mode.equalsIgnoreCase("CBC")) {
|
||||
padKinds = PADDINGS.length;
|
||||
}
|
||||
// PKCS5padding is meaningful only for ECB, CBC, PCBC
|
||||
for (int k = 0; k < padKinds; k++) {
|
||||
for (ReadModel readMode : ReadModel.values()) {
|
||||
runTest(provider, algorithm, mode, PADDINGS[k], readMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void runTest(Provider p, String algo, String mo, String pad,
|
||||
ReadModel whichRead) throws GeneralSecurityException, IOException {
|
||||
// Do initialization
|
||||
byte[] plainText = TestUtilities.generateBytes(TEXT_LENGTH);
|
||||
byte[] iv = TestUtilities.generateBytes(IV_LENGTH);
|
||||
AlgorithmParameterSpec aps = new IvParameterSpec(iv);
|
||||
try {
|
||||
KeyGenerator kg = KeyGenerator.getInstance(algo, p);
|
||||
out.println(algo + "/" + mo + "/" + pad + "/" + whichRead);
|
||||
SecretKey key = kg.generateKey();
|
||||
Cipher ci1 = Cipher.getInstance(algo + "/" + mo + "/" + pad, p);
|
||||
if ("CFB72".equalsIgnoreCase(mo) || "OFB20".equalsIgnoreCase(mo)) {
|
||||
throw new RuntimeException(
|
||||
"NoSuchAlgorithmException not throw when mode"
|
||||
+ " is CFB72 or OFB20");
|
||||
}
|
||||
Cipher ci2 = Cipher.getInstance(algo + "/" + mo + "/" + pad, p);
|
||||
if ("ECB".equalsIgnoreCase(mo)) {
|
||||
ci1.init(Cipher.ENCRYPT_MODE, key);
|
||||
ci2.init(Cipher.DECRYPT_MODE, key);
|
||||
} else {
|
||||
ci1.init(Cipher.ENCRYPT_MODE, key, aps);
|
||||
ci2.init(Cipher.DECRYPT_MODE, key, aps);
|
||||
}
|
||||
ByteArrayOutputStream baOutput = new ByteArrayOutputStream();
|
||||
try (CipherInputStream cInput
|
||||
= new CipherInputStream(
|
||||
new ByteArrayInputStream(plainText), ci1);
|
||||
CipherOutputStream ciOutput
|
||||
= new CipherOutputStream(baOutput, ci2);) {
|
||||
// Read from the input and write to the output using 2 types
|
||||
// of buffering : byte[] and int
|
||||
whichRead.read(cInput, ciOutput, ci1, plainText.length);
|
||||
}
|
||||
// Verify input and output are same.
|
||||
if (!Arrays.equals(plainText, baOutput.toByteArray())) {
|
||||
throw new RuntimeException("Test failed due to compare fail ");
|
||||
}
|
||||
} catch (NoSuchAlgorithmException nsaEx) {
|
||||
if ("CFB72".equalsIgnoreCase(mo) || "OFB20".equalsIgnoreCase(mo)) {
|
||||
out.println("NoSuchAlgorithmException is expected for CFB72 and OFB20");
|
||||
} else {
|
||||
throw new RuntimeException("Unexpected exception testing: "
|
||||
+ algo + "/" + mo + "/" + pad + "/" + whichRead, nsaEx);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
270
jdk/test/com/sun/crypto/provider/CICO/CICOSkipTest.java
Normal file
270
jdk/test/com/sun/crypto/provider/CICO/CICOSkipTest.java
Normal file
@ -0,0 +1,270 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 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 static java.lang.System.out;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.Provider;
|
||||
import java.security.Security;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.CipherInputStream;
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.NoSuchPaddingException;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.SecretKeyFactory;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.PBEKeySpec;
|
||||
import javax.crypto.spec.PBEParameterSpec;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8048604
|
||||
* @summary This test verifies the assertion "The skip feature of Filter
|
||||
* streams should be supported." for feature
|
||||
* CipherInputStream and CipherOutputStream
|
||||
*/
|
||||
public class CICOSkipTest {
|
||||
/**
|
||||
* Block length.
|
||||
*/
|
||||
private static final int BLOCK = 50;
|
||||
|
||||
/**
|
||||
* Saving bytes length.
|
||||
*/
|
||||
private static final int SAVE = 45;
|
||||
|
||||
/**
|
||||
* Plain text length.
|
||||
*/
|
||||
private static final int PLAIN_TEXT_LENGTH = 800;
|
||||
|
||||
/**
|
||||
* Skip reading byte size. This should be same to BLOCK - SAVE
|
||||
*/
|
||||
private static final int DISCARD = BLOCK - SAVE;
|
||||
|
||||
private static final String[] ALGOS = {"DES", "DESede", "Blowfish"};
|
||||
private static final String[] MODES = {"ECB", "CBC", "CFB", "CFB32",
|
||||
"OFB", "OFB64", "PCBC"};
|
||||
private static final String[] PADDINGS = {"NoPadding", "Pkcs5Padding"};
|
||||
private static final String[] PBE_ALGOS = {"PBEWithMD5AndDES",
|
||||
"PBEWithMD5AndDES/CBC/PKCS5Padding"};
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
// how many kinds of padding mode such as PKCS5padding and NoPadding
|
||||
for (String algo : ALGOS) {
|
||||
for (String mode : MODES) {
|
||||
int padKinds = 1;
|
||||
if (mode.equalsIgnoreCase("ECB")
|
||||
|| mode.equalsIgnoreCase("PCBC")
|
||||
|| mode.equalsIgnoreCase("CBC")) {
|
||||
padKinds = PADDINGS.length;
|
||||
}
|
||||
// PKCS5padding is meaningful only for ECB, CBC, PCBC
|
||||
for (int k = 0; k < padKinds; k++) {
|
||||
String info = algo + "/" + mode + "/" + PADDINGS[k];
|
||||
try {
|
||||
CipherGenerator cg = new CipherGenerator(algo, mode,
|
||||
PADDINGS[k]);
|
||||
for (ReadMethod model : ReadMethod.values()) {
|
||||
runTest(cg.getPair(), info, model);
|
||||
}
|
||||
} catch (LengthLimitException exp) {
|
||||
// skip this if this key length is larger than what's
|
||||
// configured in the jce jurisdiction policy files
|
||||
out.println(exp.getMessage() + " is expected.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (String pbeAlgo : PBE_ALGOS) {
|
||||
for (ReadMethod model : ReadMethod.values()) {
|
||||
System.out.println("Testing Algorithm : " + pbeAlgo
|
||||
+ " ReadMethod : " + model);
|
||||
runTest(new CipherGenerator(pbeAlgo).getPair(), pbeAlgo, model);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void runTest(Cipher[] pair, String info, ReadMethod whichRead)
|
||||
throws IOException {
|
||||
byte[] plainText = TestUtilities.generateBytes(PLAIN_TEXT_LENGTH);
|
||||
out.println("Testing: " + info + "/" + whichRead);
|
||||
try (ByteArrayInputStream baInput = new ByteArrayInputStream(plainText);
|
||||
CipherInputStream ciInput1 = new CipherInputStream(baInput,
|
||||
pair[0]);
|
||||
CipherInputStream ciInput2 = new CipherInputStream(ciInput1,
|
||||
pair[1]);) {
|
||||
// Skip 5 bytes after read 45 bytes and repeat until finish
|
||||
// (Read from the input and write to the output using 2 types
|
||||
// of buffering : byte[] and int)
|
||||
// So output has size:
|
||||
// (OVERALL/BLOCK)* SAVE = (800 / 50) * 45 = 720 bytes
|
||||
int numOfBlocks = plainText.length / BLOCK;
|
||||
|
||||
// Output buffer.
|
||||
byte[] outputText = new byte[numOfBlocks * SAVE];
|
||||
int index = 0;
|
||||
for (int i = 0; i < numOfBlocks; i++) {
|
||||
index = whichRead.readByte(ciInput2, outputText, SAVE, index);
|
||||
// If available is more than expected discard byte size. Skip
|
||||
// discard bytes, otherwise try to read discard bytes by read.
|
||||
if (ciInput2.available() >= DISCARD) {
|
||||
ciInput2.skip(DISCARD);
|
||||
} else {
|
||||
for (int k = 0; k < DISCARD; k++) {
|
||||
ciInput2.read();
|
||||
}
|
||||
}
|
||||
}
|
||||
// Verify output is same as input
|
||||
if (!TestUtilities
|
||||
.equalsBlockPartial(plainText, outputText, BLOCK, SAVE)) {
|
||||
throw new RuntimeException("Test failed with compare fail");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class CipherGenerator {
|
||||
/**
|
||||
* Initialization vector length.
|
||||
*/
|
||||
private static final int IV_LENGTH = 8;
|
||||
|
||||
private static final String PASSWD = "Sesame!(@#$%^&*)";
|
||||
|
||||
private final Cipher[] pair = new Cipher[2];
|
||||
|
||||
// For DES/DESede ciphers
|
||||
CipherGenerator(String algo, String mo, String pad)
|
||||
throws NoSuchAlgorithmException,
|
||||
InvalidAlgorithmParameterException, InvalidKeyException,
|
||||
NoSuchPaddingException, SecurityException, LengthLimitException {
|
||||
// Do initialization
|
||||
KeyGenerator kg = KeyGenerator.getInstance(algo);
|
||||
SecretKey key = kg.generateKey();
|
||||
if (key.getEncoded().length * 8 > Cipher.getMaxAllowedKeyLength(algo)) {
|
||||
// skip this if this key length is larger than what's
|
||||
// configured in the jce jurisdiction policy files
|
||||
throw new LengthLimitException(
|
||||
"Skip this test if key length is larger than what's"
|
||||
+ "configured in the jce jurisdiction policy files");
|
||||
}
|
||||
AlgorithmParameterSpec aps = null;
|
||||
if (!mo.equalsIgnoreCase("ECB")) {
|
||||
byte[] iv = TestUtilities.generateBytes(IV_LENGTH);
|
||||
aps = new IvParameterSpec(iv);
|
||||
}
|
||||
initCiphers(algo + "/" + mo + "/" + pad, key, aps);
|
||||
}
|
||||
|
||||
// For PBE ciphers
|
||||
CipherGenerator(String algo) throws NoSuchAlgorithmException,
|
||||
InvalidAlgorithmParameterException, InvalidKeyException,
|
||||
NoSuchPaddingException, InvalidKeySpecException {
|
||||
// Do initialization
|
||||
byte[] salt = TestUtilities.generateBytes(IV_LENGTH);
|
||||
int iterCnt = 6;
|
||||
SecretKeyFactory skf = SecretKeyFactory.getInstance(algo.split("/")[0]);
|
||||
SecretKey key = skf
|
||||
.generateSecret(new PBEKeySpec(PASSWD.toCharArray()));
|
||||
AlgorithmParameterSpec aps = new PBEParameterSpec(salt, iterCnt);
|
||||
initCiphers(algo, key, aps);
|
||||
}
|
||||
|
||||
private void initCiphers(String algo, SecretKey key,
|
||||
AlgorithmParameterSpec aps) throws NoSuchAlgorithmException,
|
||||
NoSuchPaddingException, InvalidKeyException,
|
||||
InvalidAlgorithmParameterException {
|
||||
Provider provider = Security.getProvider("SunJCE");
|
||||
if (provider == null) {
|
||||
throw new RuntimeException("SunJCE provider does not exist.");
|
||||
}
|
||||
Cipher ci1 = Cipher.getInstance(algo, provider);
|
||||
ci1.init(Cipher.ENCRYPT_MODE, key, aps);
|
||||
pair[0] = ci1;
|
||||
Cipher ci2 = Cipher.getInstance(algo, provider);
|
||||
ci2.init(Cipher.DECRYPT_MODE, key, aps);
|
||||
pair[1] = ci2;
|
||||
}
|
||||
|
||||
Cipher[] getPair() {
|
||||
return pair;
|
||||
}
|
||||
}
|
||||
|
||||
enum ReadMethod {
|
||||
// read one byte at a time for save times
|
||||
READ_ONE_BYTE {
|
||||
@Override
|
||||
int readByte(CipherInputStream ciIn2, byte[] outputText, int save,
|
||||
int index) throws IOException {
|
||||
for (int j = 0; j < save; j++, index++) {
|
||||
int buffer0 = ciIn2.read();
|
||||
if (buffer0 != -1) {
|
||||
outputText[index] = (byte) buffer0;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return index;
|
||||
}
|
||||
},
|
||||
// read a chunk of save bytes if possible
|
||||
READ_BLOCK {
|
||||
@Override
|
||||
int readByte(CipherInputStream ciIn2, byte[] outputText, int save,
|
||||
int index) throws IOException {
|
||||
int len1 = ciIn2.read(outputText, index, save);
|
||||
out.println("Init: index=" + index + ",len=" + len1);
|
||||
// read more until save bytes
|
||||
index += len1;
|
||||
int len2 = 0;
|
||||
while (len1 != save && len2 != -1) {
|
||||
len2 = ciIn2.read(outputText, index, save - len1);
|
||||
out.println("Cont: index=" + index + ",len=" + len2);
|
||||
len1 += len2;
|
||||
index += len2;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
};
|
||||
|
||||
abstract int readByte(CipherInputStream ciIn2, byte[] outputText, int save,
|
||||
int index) throws IOException;
|
||||
};
|
||||
|
||||
class LengthLimitException extends Exception {
|
||||
|
||||
public LengthLimitException(String string) {
|
||||
super(string);
|
||||
}
|
||||
}
|
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 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.security.AlgorithmParameters;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.Provider;
|
||||
import java.security.Security;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.SecretKeyFactory;
|
||||
import javax.crypto.spec.PBEKeySpec;
|
||||
|
||||
/**
|
||||
* Wrapper class to test a given AES-based PBE algorithm.
|
||||
*/
|
||||
public class AESPBEWrapper extends AbstractPBEWrapper {
|
||||
/**
|
||||
* the algorithm parameters.
|
||||
*/
|
||||
private AlgorithmParameters pbeParams;
|
||||
|
||||
/**
|
||||
* the encryption key.
|
||||
*/
|
||||
private final SecretKey key;
|
||||
|
||||
/**
|
||||
* The Wrapper constructor. Instantiate Cipher using the given AES-based PBE
|
||||
* algorithm.
|
||||
*
|
||||
* @param algo AES-based PBE algorithm.
|
||||
* @param passwd password phrase.
|
||||
* @throws GeneralSecurityException all security exceptions are thrown.
|
||||
*/
|
||||
public AESPBEWrapper(PBEAlgorithm algo, String passwd)
|
||||
throws GeneralSecurityException {
|
||||
// salt and iteration count will be generated during encryption
|
||||
super(algo, passwd, 0);
|
||||
|
||||
// Generate secret key. We expect no mode and padding specified.
|
||||
SecretKeyFactory skf = SecretKeyFactory.getInstance(algo.baseAlgo);
|
||||
key = skf.generateSecret(new PBEKeySpec(passwd.toCharArray()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiate the Cipher object using given "mode".
|
||||
* @return a cipher object.
|
||||
* @throws GeneralSecurityException all security exceptions are thrown.
|
||||
*/
|
||||
@Override
|
||||
protected Cipher initCipher(int mode) throws GeneralSecurityException {
|
||||
Provider provider = Security.getProvider("SunJCE");
|
||||
if (provider == null) {
|
||||
throw new RuntimeException("SunJCE provider does not exist.");
|
||||
}
|
||||
// get Cipher instance
|
||||
Cipher ci = Cipher.getInstance(transformation, provider);
|
||||
if (Cipher.ENCRYPT_MODE == mode) {
|
||||
ci.init(Cipher.ENCRYPT_MODE, key);
|
||||
pbeParams = ci.getParameters();
|
||||
} else {
|
||||
ci.init(Cipher.DECRYPT_MODE, key, pbeParams);
|
||||
}
|
||||
return ci;
|
||||
}
|
||||
}
|
@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 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.security.GeneralSecurityException;
|
||||
import javax.crypto.Cipher;
|
||||
|
||||
/**
|
||||
* PBEWrapper is an abstract class for all concrete PBE Cipher wrappers.
|
||||
*/
|
||||
public abstract class AbstractPBEWrapper {
|
||||
/**
|
||||
* Iteration count.
|
||||
*/
|
||||
public static final int DEFAULT_ITERATION = 1000;
|
||||
|
||||
public static final String PBKDF2 = "PBKDF2";
|
||||
public static final String AES = "AES";
|
||||
public static final String DEFAULT = "default";
|
||||
|
||||
/**
|
||||
* transformation the name of the transformation, e.g.,
|
||||
* DES/CBC/PKCS5Padding
|
||||
*/
|
||||
protected final String transformation;
|
||||
|
||||
/**
|
||||
* the standard name of the requested secret-key algorithm.
|
||||
*/
|
||||
protected final String baseAlgo;
|
||||
|
||||
/**
|
||||
* The contents of salt are copied to protect against subsequent
|
||||
* modification.
|
||||
*/
|
||||
protected final byte[] salt;
|
||||
|
||||
/**
|
||||
* Password.
|
||||
*/
|
||||
protected final String password;
|
||||
|
||||
/**
|
||||
* PBEWrapper creator.
|
||||
*
|
||||
* @param algo PBE algorithm to test
|
||||
* @param passwd a password phrase
|
||||
* @return PBEWrapper in accordance to requested algo.
|
||||
* @throws GeneralSecurityException all exceptions are thrown.
|
||||
*/
|
||||
public static AbstractPBEWrapper createWrapper(PBEAlgorithm algo, String passwd)
|
||||
throws GeneralSecurityException {
|
||||
switch (algo.type) {
|
||||
case PBKDF2:
|
||||
return new PBKDF2Wrapper(algo, passwd);
|
||||
case AES:
|
||||
return new AESPBEWrapper(algo, passwd);
|
||||
default:
|
||||
return new DefaultPBEWrapper(algo, passwd);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* PBEWrapper constructor.
|
||||
*
|
||||
* @param algo algorithm to wrap
|
||||
* @param password password phrase
|
||||
* @param saltSize salt size (defined in subclasses)
|
||||
*/
|
||||
protected AbstractPBEWrapper(PBEAlgorithm algo, String password, int saltSize) {
|
||||
this.transformation = algo.getTransformation();
|
||||
this.baseAlgo = algo.baseAlgo;
|
||||
this.salt = TestUtilities.generateBytes(saltSize);
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize Cipher object for the operation requested in the mode parameter.
|
||||
*
|
||||
* @param mode encryption or decryption
|
||||
* @return a cipher initialize by mode.
|
||||
* @throws GeneralSecurityException all security exceptions are thrown.
|
||||
*/
|
||||
protected abstract Cipher initCipher(int mode) throws GeneralSecurityException;
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8048604
|
||||
* @summary This test verifies the assertion "The encrypt/decrypt
|
||||
* mechanism of cipher should perform correctly." for feature
|
||||
* "CipherInputStream & CipherOutputStream".
|
||||
* @library ../
|
||||
* @run main CICOPBEFuncTest
|
||||
*/
|
||||
|
||||
import java.util.Arrays;
|
||||
import javax.crypto.Cipher;
|
||||
|
||||
public class CICOPBEFuncTest {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
for (PBEAlgorithm algorithm : PBEAlgorithm.values()) {
|
||||
// int buffertin test
|
||||
String algo = algorithm.baseAlgo.toUpperCase();
|
||||
if (!algo.contains("TRIPLEDES") && !algo.contains("AES_256")
|
||||
|| Cipher.getMaxAllowedKeyLength(algo) > 128) {
|
||||
// skip this if this key length is larger than what's
|
||||
// configured in the jce jurisdiction policy files
|
||||
System.out.println("Testing " + algorithm.getTransformation());
|
||||
for (String type : Arrays.asList(CICO_PBE_Test.INT_BYTE_BUFFER,
|
||||
CICO_PBE_Test.BYTE_ARR_BUFFER)) {
|
||||
new CICO_PBE_RW_Test(algorithm)
|
||||
.proceedTest(type);
|
||||
new CICO_PBE_SKIP_Test(algorithm)
|
||||
.proceedTest(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 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.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.security.GeneralSecurityException;
|
||||
|
||||
import javax.crypto.CipherOutputStream;
|
||||
|
||||
/**
|
||||
* CICO PBE Read/Write functional test.
|
||||
*
|
||||
* Verifies for the given PBE algorithm if the encrypt/decrypt mechanism is
|
||||
* performed correctly for CipherInputStream and CipherOutputStream.
|
||||
*
|
||||
* Test scenario:
|
||||
* 1. initializes plain text with random generated data.
|
||||
* 2. for the given PBE algorithm instantiates encrypt and decrypt Ciphers.
|
||||
* 3. instantiates CipherInputStream with the encrypt Cipher.
|
||||
* 4. instantiates CipherOutputStream with the decrypt Cipher.
|
||||
* 5. performs reading from the CipherInputStream (encryption data) and writing
|
||||
* to the CipherOutputStream (decryption). As a result the output of the
|
||||
* CipherOutputStream should be the same as an original plain text.
|
||||
* 6. compares if the original plain text is the same as the output of the
|
||||
* CipherOutputStream.
|
||||
*
|
||||
* The test implements 2 test cases in accordance with buffering type:
|
||||
* 1. byte array buffering
|
||||
* 2. int buffering
|
||||
*/
|
||||
public class CICO_PBE_RW_Test extends CICO_PBE_Test {
|
||||
|
||||
public CICO_PBE_RW_Test(PBEAlgorithm pbeAlgo)
|
||||
throws GeneralSecurityException {
|
||||
super(pbeAlgo);
|
||||
}
|
||||
|
||||
/**
|
||||
* The CICO PBE RW test specific part of the super.doTest(). Implements the
|
||||
* scenario in accordance to the class description.
|
||||
* @param type byteArrayBuffering or intByteBuffering
|
||||
* @throws IOException any I/O operation failed.
|
||||
* @throws GeneralSecurityException any security error.
|
||||
*/
|
||||
@Override
|
||||
public void proceedTest(String type) throws IOException,
|
||||
GeneralSecurityException {
|
||||
ByteArrayOutputStream baOutput = new ByteArrayOutputStream();
|
||||
try (CipherOutputStream ciOutput = new CipherOutputStream(baOutput,
|
||||
getDecryptCipher())) {
|
||||
if (type.equals(CICO_PBE_Test.BYTE_ARR_BUFFER)) {
|
||||
proceedTestUsingByteArrayBuffer(ciOutput);
|
||||
} else {
|
||||
proceedTestUsingIntBuffer(ciOutput);
|
||||
}
|
||||
ciOutput.flush();
|
||||
}
|
||||
// Compare input and output
|
||||
if (!TestUtilities.equalsBlock(plainText, baOutput.toByteArray(), TEXT_SIZE)) {
|
||||
throw new RuntimeException("outputText not same with expectedText"
|
||||
+ " when test " + type);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements byte array buffering type test case of the CICO PBE RW test.
|
||||
* @param ciOutput output stream for data written.
|
||||
* @throws java.io.IOException any I/O operation failed.
|
||||
*/
|
||||
public void proceedTestUsingByteArrayBuffer(
|
||||
CipherOutputStream ciOutput) throws IOException {
|
||||
byte[] buffer = new byte[TEXT_SIZE];
|
||||
int len = getCiInput().read(buffer);
|
||||
while (len != -1) {
|
||||
ciOutput.write(buffer, 0, len);
|
||||
len = getCiInput().read(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements int buffering type test case.
|
||||
* @param ciOutput output stream for data written.
|
||||
* @throws java.io.IOException any I/O operation failed.
|
||||
*/
|
||||
public void proceedTestUsingIntBuffer(CipherOutputStream ciOutput)
|
||||
throws IOException {
|
||||
int buffer = getCiInput().read();
|
||||
while (buffer != -1) {
|
||||
ciOutput.write(buffer);
|
||||
buffer = getCiInput().read();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 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.IOException;
|
||||
import java.security.GeneralSecurityException;
|
||||
import javax.crypto.CipherInputStream;
|
||||
|
||||
/**
|
||||
* CICO PBE SKIP functional test.
|
||||
*
|
||||
* Verifies for the given PBE algorithm if the encrypt/decrypt mechanism is
|
||||
* performed correctly for CipherInputStream when skip() method is used.
|
||||
*
|
||||
* Test scenario:
|
||||
* 1. initializes plain text with random generated data with length TEXT_SIZE.
|
||||
* 2. for the given PBE algorithm instantiates encrypt and decrypt Ciphers.
|
||||
* 3. instantiates CipherInputStream 1 with the encrypt Cipher.
|
||||
* 4. instantiates CipherInputStream 2 with the CipherInputStream 1 and decrypt
|
||||
* Cipher.
|
||||
* 5. the plain text is divided on TEXT_SIZE/BLOCK blocks. Reading from
|
||||
* CipherInputStream 2 one block at time. The last BLOCK - SAVE bytes are
|
||||
* skipping for each block. Therefor the plain text data go through
|
||||
* CipherInputStream 1 (encrypting) and CipherInputStream 2 (decrypting).
|
||||
* As a result the output should equal to the original text except DISCARD
|
||||
* byte for each block are skipped.
|
||||
* 6. get the standard output.
|
||||
* 7. compares the expected standard output with the output of the
|
||||
* CipherInputStream 2. If it is the same the test passed. Otherwise it
|
||||
* failed. Any uncaught exceptions should be considered as an error.
|
||||
* The test implements 2 test cases in accordance with a buffering type:
|
||||
* 1. byte array buffering
|
||||
* 2. int buffering
|
||||
*/
|
||||
public class CICO_PBE_SKIP_Test extends CICO_PBE_Test {
|
||||
/**
|
||||
* Block size.
|
||||
*/
|
||||
private static final int BLOCK = 50;
|
||||
|
||||
/**
|
||||
* Valid reading byte size.
|
||||
*/
|
||||
private static final int SAVE = 45;
|
||||
|
||||
/**
|
||||
* Skip reading byte size. This should be same to BLOCK - SAVE
|
||||
*/
|
||||
private static final int DISCARD = BLOCK - SAVE;
|
||||
|
||||
/**
|
||||
* Number of blocks.
|
||||
*/
|
||||
private static final int NUMBER_OF_BLOCKS = TEXT_SIZE / BLOCK;
|
||||
|
||||
private final byte[] outputText;
|
||||
/**
|
||||
* CICO PBE Skip test constructor
|
||||
*
|
||||
* @param pbeAlgo the PBE algorithm to test.
|
||||
* @throws java.security.GeneralSecurityException
|
||||
*/
|
||||
public CICO_PBE_SKIP_Test(PBEAlgorithm pbeAlgo)
|
||||
throws GeneralSecurityException {
|
||||
super(pbeAlgo);
|
||||
outputText = new byte[NUMBER_OF_BLOCKS * SAVE];
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements byte array buffering type test case of the CICO SKIP test.
|
||||
*
|
||||
* @param blockNum block number to read.
|
||||
*/
|
||||
private void proceedSkipTestUsingByteArrayBufferingType(
|
||||
CipherInputStream ciIn2, int blockNum) throws IOException {
|
||||
int index = blockNum * SAVE;
|
||||
int len1 = ciIn2.read(outputText, index, SAVE);
|
||||
// read more until SAVE bytes
|
||||
index += len1;
|
||||
int len2 = 0;
|
||||
int totalRead = len1;
|
||||
while (len1 != SAVE && len2 != -1) {
|
||||
len2 = ciIn2.read(outputText, index, SAVE - len1);
|
||||
len1 += len2;
|
||||
index += len2;
|
||||
totalRead += len2;
|
||||
}
|
||||
if (totalRead != SAVE) {
|
||||
throw new RuntimeException("Read bytes number " + totalRead
|
||||
+ " does not equal to given number " + SAVE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements int buffering type test case of the CICO SKIP test.
|
||||
*
|
||||
* @param blockNum block number to read.
|
||||
*/
|
||||
private void proceedSkipTestUsingIntBufferingType(CipherInputStream ciIn2,
|
||||
int blockNum) throws IOException {
|
||||
int index = blockNum * SAVE;
|
||||
int totalRead = 0;
|
||||
for (int j = 0; j < SAVE; j++, index++) {
|
||||
int buffer0 = ciIn2.read();
|
||||
if (buffer0 != -1) {
|
||||
outputText[index] = (byte) buffer0;
|
||||
totalRead++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (totalRead != SAVE) {
|
||||
throw new RuntimeException("Read bytes number " + totalRead
|
||||
+ " does not equal to given number " + SAVE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The CICO PBE SKIP test specific part of the super.doTest(). Implements
|
||||
* the scenario in accordance to the class description.
|
||||
* @throws java.io.IOException any I/O failed.
|
||||
*/
|
||||
@Override
|
||||
public void proceedTest(String type) throws IOException {
|
||||
System.out.println("Test type: " + type);
|
||||
// init second input stream with decrypt Cipher
|
||||
try (CipherInputStream ciIn2 = new CipherInputStream(getCiInput(),
|
||||
getDecryptCipher())) {
|
||||
for (int i = 0; i < NUMBER_OF_BLOCKS; i++) {
|
||||
if (type.equals(CICO_PBE_Test.BYTE_ARR_BUFFER)) {
|
||||
proceedSkipTestUsingByteArrayBufferingType(ciIn2, i);
|
||||
} else {
|
||||
proceedSkipTestUsingIntBufferingType(ciIn2, i);
|
||||
}
|
||||
if (ciIn2.available() >= DISCARD) {
|
||||
ciIn2.skip(DISCARD);
|
||||
} else {
|
||||
for (int k = 0; k < DISCARD; k++) {
|
||||
ciIn2.read();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!TestUtilities.equalsBlockPartial(plainText, outputText, BLOCK, SAVE)) {
|
||||
throw new RuntimeException("outputText not same with expectedText"
|
||||
+ " when test " + type);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 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.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.security.GeneralSecurityException;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.CipherInputStream;
|
||||
|
||||
/**
|
||||
* This is an abstract class for CipherInputStream/CipherOutputStream PBE
|
||||
* functional tests.
|
||||
*/
|
||||
public abstract class CICO_PBE_Test {
|
||||
/**
|
||||
* Sample string for byte buffer.
|
||||
*/
|
||||
public static final String BYTE_ARR_BUFFER = "byteArrayBuffering";
|
||||
|
||||
/**
|
||||
* Sample string for int buffer.
|
||||
*/
|
||||
public static final String INT_BYTE_BUFFER = "intByteBuffering";
|
||||
public static final String PASS_PHRASE = "Some password phrase!";
|
||||
|
||||
/**
|
||||
* Text string size.
|
||||
*/
|
||||
public static final int TEXT_SIZE = 800;
|
||||
|
||||
protected final byte[] plainText;
|
||||
private final Cipher encryptCipher, decryptCipher;
|
||||
|
||||
/**
|
||||
* An CipherInputStream for reading cipher and plain text.
|
||||
*/
|
||||
private final CipherInputStream ciInput;
|
||||
|
||||
/**
|
||||
* Constructor by algorithm.
|
||||
* @param pbeAlgo PBE algorithm to test.
|
||||
* @throws GeneralSecurityException if any security error.
|
||||
*/
|
||||
public CICO_PBE_Test(PBEAlgorithm pbeAlgo) throws GeneralSecurityException {
|
||||
// Do initialization of the plainText
|
||||
plainText = TestUtilities.generateBytes(TEXT_SIZE);
|
||||
// Do initialization of the ciphers
|
||||
AbstractPBEWrapper pbeWrap = AbstractPBEWrapper.createWrapper(pbeAlgo, PASS_PHRASE);
|
||||
encryptCipher = pbeWrap.initCipher(Cipher.ENCRYPT_MODE);
|
||||
decryptCipher = pbeWrap.initCipher(Cipher.DECRYPT_MODE);
|
||||
// init cipher input stream
|
||||
ciInput = new CipherInputStream(new ByteArrayInputStream(plainText),
|
||||
encryptCipher);
|
||||
}
|
||||
|
||||
protected byte[] getPlainText() {
|
||||
return plainText;
|
||||
}
|
||||
|
||||
/**
|
||||
* The body of the test. Should be defined in subclasses.
|
||||
* @param type byteArrayBuffering or intByteBuffering
|
||||
* @throws IOException I/O operation failed.
|
||||
* @throws GeneralSecurityException all exceptions thrown.
|
||||
*/
|
||||
protected abstract void proceedTest(String type)
|
||||
throws IOException, GeneralSecurityException;
|
||||
|
||||
protected Cipher getEncryptCipher() {
|
||||
return encryptCipher;
|
||||
}
|
||||
|
||||
public CipherInputStream getCiInput() {
|
||||
return ciInput;
|
||||
}
|
||||
|
||||
public Cipher getDecryptCipher() {
|
||||
return decryptCipher;
|
||||
}
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 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.
|
||||
*/
|
||||
/*
|
||||
* @test
|
||||
* @bug 8048604
|
||||
* @library ../ /lib/testlibrary
|
||||
* @summary This test verifies the assertion "There should be no transformation
|
||||
* on the plaintext/ciphertext in encryption/decryption mechanism" for
|
||||
* feature "NullCipher".
|
||||
*/
|
||||
import javax.crypto.BadPaddingException;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.IllegalBlockSizeException;
|
||||
import javax.crypto.NullCipher;
|
||||
import javax.crypto.ShortBufferException;
|
||||
import jdk.testlibrary.RandomFactory;
|
||||
|
||||
public class CipherNCFuncTest {
|
||||
public static void main(String[] args) throws ShortBufferException,
|
||||
IllegalBlockSizeException, BadPaddingException {
|
||||
byte[] plainText = new byte[801];
|
||||
// Initialization
|
||||
RandomFactory.getRandom().nextBytes(plainText);
|
||||
Cipher ci = new NullCipher();
|
||||
// Encryption
|
||||
byte[] cipherText = new byte[ci.getOutputSize(plainText.length)];
|
||||
int offset = ci.update(plainText, 0, plainText.length, cipherText, 0);
|
||||
ci.doFinal(cipherText, offset);
|
||||
// Decryption
|
||||
byte[] recoveredText = new byte[ci.getOutputSize(cipherText.length)];
|
||||
int len = ci.doFinal(cipherText, 0, cipherText.length, recoveredText);
|
||||
// Comparison
|
||||
if (len != plainText.length ||
|
||||
!TestUtilities.equalsBlock(plainText, cipherText, len) ||
|
||||
!TestUtilities.equalsBlock(plainText, recoveredText, len)) {
|
||||
throw new RuntimeException(
|
||||
"Test failed because plainText not equal to cipherText and revoveredText");
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 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.security.GeneralSecurityException;
|
||||
import java.security.Provider;
|
||||
import java.security.Security;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.SecretKeyFactory;
|
||||
import javax.crypto.spec.PBEKeySpec;
|
||||
import javax.crypto.spec.PBEParameterSpec;
|
||||
|
||||
/**
|
||||
* Default wrapper for a password based encryption Cipher.
|
||||
*/
|
||||
|
||||
public class DefaultPBEWrapper extends AbstractPBEWrapper {
|
||||
/**
|
||||
* Define default SALT size as 8.
|
||||
*/
|
||||
private static final int PBE_SALT_SIZE = 8;
|
||||
|
||||
/**
|
||||
* Default PBE wrapper constructor.
|
||||
*
|
||||
* @param algo PGE algorithm to wrap.
|
||||
* @param passwd password phrase
|
||||
*/
|
||||
public DefaultPBEWrapper(PBEAlgorithm algo, String passwd) {
|
||||
super(algo, passwd, PBE_SALT_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate Cipher for the PBE algorithm.
|
||||
*
|
||||
* @param mode Cipher mode: encrypt or decrypt.
|
||||
* @return Cipher in accordance to the PBE algorithm
|
||||
* @throws java.security.GeneralSecurityException
|
||||
*/
|
||||
@Override
|
||||
protected Cipher initCipher(int mode) throws GeneralSecurityException {
|
||||
Provider provider = Security.getProvider("SunJCE");
|
||||
if (provider == null) {
|
||||
throw new RuntimeException("SunJCE provider does not exist.");
|
||||
}
|
||||
SecretKey key = SecretKeyFactory.getInstance(baseAlgo)
|
||||
.generateSecret(new PBEKeySpec(password.toCharArray()));
|
||||
Cipher ci = Cipher.getInstance(transformation, provider);
|
||||
ci.init(mode, key, new PBEParameterSpec(salt, DEFAULT_ITERATION));
|
||||
return ci;
|
||||
}
|
||||
}
|
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 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.util.StringJoiner;
|
||||
|
||||
public enum PBEAlgorithm {
|
||||
MD5_DES("PBEWithMD5ANDdes", "", "", AbstractPBEWrapper.DEFAULT),
|
||||
MD5_DES_CBC_PKCS5("PBEWithMD5AndDES", "CBC", "PKCS5Padding",
|
||||
AbstractPBEWrapper.DEFAULT),
|
||||
MD5_TRIPLEDES("PBEWithMD5ANDtripledes", "", "", AbstractPBEWrapper.DEFAULT),
|
||||
MD5_TRIPLEDES_CBC_PKCS5("PBEWithMD5AndTRIPLEDES", "CBC", "PKCS5Padding",
|
||||
AbstractPBEWrapper.DEFAULT),
|
||||
SHA1_DESEDE("PBEwithSHA1AndDESede", "", "", AbstractPBEWrapper.DEFAULT),
|
||||
SHA1_DESEDE_CBC_PKCS5("PBEwithSHA1AndDESede", "CBC", "PKCS5Padding",
|
||||
AbstractPBEWrapper.DEFAULT),
|
||||
SHA1_RC2_40("PBEwithSHA1AndRC2_40", "", "", AbstractPBEWrapper.DEFAULT),
|
||||
SHA1_RC2_40_PKCS5("PBEwithSHA1Andrc2_40", "CBC", "PKCS5Padding",
|
||||
AbstractPBEWrapper.DEFAULT),
|
||||
SHA1_RC2_128("PBEWithSHA1AndRC2_128", "", "", AbstractPBEWrapper.DEFAULT),
|
||||
SHA1_RC2_128_PKCS5("PBEWithSHA1andRC2_128", "CBC", "PKCS5Padding",
|
||||
AbstractPBEWrapper.DEFAULT),
|
||||
SHA1_RC4_40("PBEWithSHA1AndRC4_40", "", "", AbstractPBEWrapper.DEFAULT),
|
||||
SHA1_RC4_40_ECB_NOPADDING("PBEWithsha1AndRC4_40", "ECB", "NoPadding",
|
||||
AbstractPBEWrapper.DEFAULT),
|
||||
SHA1_RC4_128("PBEWithSHA1AndRC4_128", "", "", AbstractPBEWrapper.DEFAULT),
|
||||
SHA1_RC4_128_ECB_NOPADDING("pbeWithSHA1AndRC4_128", "ECB", "NoPadding",
|
||||
AbstractPBEWrapper.DEFAULT),
|
||||
HMAC_SHA1_AES_128("PBEWithHmacSHA1AndAES_128", "", "", AbstractPBEWrapper.AES),
|
||||
HMAC_SHA224_AES_128("PBEWithHmacSHA224AndAES_128", "", "", AbstractPBEWrapper.AES),
|
||||
HMAC_SHA256_AES_128("PBEWithHmacSHA256AndAES_128", "", "", AbstractPBEWrapper.AES),
|
||||
HMAC_SHA384_AES_128("PBEWithHmacSHA384AndAES_128", "", "", AbstractPBEWrapper.AES),
|
||||
HMAC_SHA512_AES_128("PBEWithHmacSHA512AndAES_128", "", "", AbstractPBEWrapper.AES),
|
||||
HMAC_SHA1_AES_256("PBEWithHmacSHA1AndAES_256", "", "", AbstractPBEWrapper.AES),
|
||||
HMAC_SHA224_AES_256("PBEWithHmacSHA224AndAES_256", "", "", AbstractPBEWrapper.AES),
|
||||
HMAC_SHA256_AES_256("PBEWithHmacSHA256AndAES_256", "", "", AbstractPBEWrapper.AES),
|
||||
HMAC_SHA384_AES_256("PBEWithHmacSHA384AndAES_256", "", "", AbstractPBEWrapper.AES),
|
||||
HMAC_SHA512_AES_256("PBEWithHmacSHA512AndAES_256", "", "", AbstractPBEWrapper.AES),
|
||||
PBKDF_HMAC_SHA1("PBKDF2WithHmacSHA1", "", "", AbstractPBEWrapper.PBKDF2),
|
||||
PBKDF_HMAC_SHA224("PBKDF2WithHmacSHA224", "", "", AbstractPBEWrapper.PBKDF2),
|
||||
PBKDF_HMAC_SHA256("PBKDF2WithHmacSHA256", "", "", AbstractPBEWrapper.PBKDF2),
|
||||
PBKDF_HMAC_SHA384("PBKDF2WithHmacSHA384", "", "", AbstractPBEWrapper.PBKDF2),
|
||||
PBKDF_HMAC_SHA512("PBKDF2WithHmacSHA512", "", "", AbstractPBEWrapper.PBKDF2);
|
||||
final String baseAlgo;
|
||||
final String mode;
|
||||
final String padding;
|
||||
final String type;
|
||||
|
||||
PBEAlgorithm(String alg, String mode, String padding, String type) {
|
||||
this.baseAlgo = alg;
|
||||
this.mode = mode;
|
||||
this.padding = padding;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getTransformation() {
|
||||
StringJoiner sj = new StringJoiner("/");
|
||||
sj.add(baseAlgo);
|
||||
if (!mode.equals("")) {
|
||||
sj.add(this.mode);
|
||||
}
|
||||
if (!padding.equals("")) {
|
||||
sj.add(this.padding);
|
||||
}
|
||||
return sj.toString();
|
||||
}
|
||||
}
|
109
jdk/test/com/sun/crypto/provider/CICO/PBEFunc/PBKDF2Wrapper.java
Normal file
109
jdk/test/com/sun/crypto/provider/CICO/PBEFunc/PBKDF2Wrapper.java
Normal file
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 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.security.GeneralSecurityException;
|
||||
import java.security.Provider;
|
||||
import java.security.Security;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.SecretKeyFactory;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.PBEKeySpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
/**
|
||||
* Wrapper class to test a given SecretKeyFactory.PBKDF2 algorithm.
|
||||
*/
|
||||
public class PBKDF2Wrapper extends AbstractPBEWrapper {
|
||||
/**
|
||||
* Default salt size.
|
||||
*/
|
||||
public static final int PBKDF2_SALT_SIZE = 64;
|
||||
|
||||
/**
|
||||
* Default key length.
|
||||
*/
|
||||
public static final int PKDF2_DEFAULT_KEY_LEN = 128;
|
||||
|
||||
/**
|
||||
* Default transformation.
|
||||
*/
|
||||
public static final String CIPHER_TRANSFORMATION = "AES/CBC/PKCS5Padding";
|
||||
|
||||
/**
|
||||
* Algorithm name.
|
||||
*/
|
||||
public static final String KEY_ALGORITHM = "AES";
|
||||
|
||||
/**
|
||||
* Initialization vector length.
|
||||
*/
|
||||
private static final int IV_LENGTH = 16;
|
||||
|
||||
/**
|
||||
* The buffer with the IV.
|
||||
*/
|
||||
private final byte[] iv;
|
||||
|
||||
/**
|
||||
* PBKDF2Wrapper constructor. Instantiate Cipher using
|
||||
* "AES/CBC/PKCS5Padding" transformation. Generate a secret key using PKDF2
|
||||
* algorithms given in the "algo" parameter.
|
||||
*
|
||||
* @param algo AES-based PBE algorithm.
|
||||
* @param passwd password phrase.
|
||||
* @throws GeneralSecurityException all security exceptions are thrown.
|
||||
*/
|
||||
public PBKDF2Wrapper(PBEAlgorithm algo, String passwd)
|
||||
throws GeneralSecurityException {
|
||||
super(algo, passwd, PBKDF2_SALT_SIZE);
|
||||
iv = TestUtilities.generateBytes(IV_LENGTH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiate the Cipher object for PBKDF2 algorithm using given "mode".
|
||||
*
|
||||
* @param mode Cipher mode: encrypt or decrypt
|
||||
* @return Cipher object for PBKDF2 algorithm
|
||||
* @throws GeneralSecurityException all security exceptions are thrown.
|
||||
*/
|
||||
@Override
|
||||
protected Cipher initCipher(int mode) throws GeneralSecurityException {
|
||||
Provider provider = Security.getProvider("SunJCE");
|
||||
if (provider == null) {
|
||||
throw new RuntimeException("SunJCE provider does not exist.");
|
||||
}
|
||||
// Generate secret key
|
||||
PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray(),
|
||||
salt, DEFAULT_ITERATION, PKDF2_DEFAULT_KEY_LEN);
|
||||
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(baseAlgo);
|
||||
SecretKey key = keyFactory.generateSecret(pbeKeySpec);
|
||||
|
||||
// get Cipher instance
|
||||
Cipher cipher = Cipher.getInstance(CIPHER_TRANSFORMATION, provider);
|
||||
cipher.init(mode,
|
||||
new SecretKeySpec(key.getEncoded(),KEY_ALGORITHM),
|
||||
new IvParameterSpec(iv));
|
||||
return cipher;
|
||||
}
|
||||
}
|
77
jdk/test/com/sun/crypto/provider/CICO/ReadModel.java
Normal file
77
jdk/test/com/sun/crypto/provider/CICO/ReadModel.java
Normal file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 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.IOException;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.CipherInputStream;
|
||||
import javax.crypto.CipherOutputStream;
|
||||
|
||||
/**
|
||||
* ReadModel provides different way to test
|
||||
* CipherInputStream.read()/read(byte[])/read(byte[], int, int) and
|
||||
* CipherOutputStream.write(int)/write(byte[], int, int)/read(byte[]) API
|
||||
*/
|
||||
enum ReadModel {
|
||||
READ_BYTE {
|
||||
@Override
|
||||
public void read(CipherInputStream cInput, CipherOutputStream ciOutput,
|
||||
Cipher ciIn, int inputLen) throws IOException {
|
||||
int buffer0 = cInput.read();
|
||||
while (buffer0 != -1) {
|
||||
ciOutput.write(buffer0);
|
||||
buffer0 = cInput.read();
|
||||
}
|
||||
}
|
||||
},
|
||||
READ_BUFFER {
|
||||
@Override
|
||||
public void read(CipherInputStream cInput, CipherOutputStream ciOutput,
|
||||
Cipher ciIn, int inputLen) throws IOException {
|
||||
byte[] buffer1 = new byte[20];
|
||||
int len1;
|
||||
while ((len1 = cInput.read(buffer1)) != -1) {
|
||||
ciOutput.write(buffer1, 0, len1);
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
READ_BUFFER_OFFSET {
|
||||
@Override
|
||||
public void read(CipherInputStream cInput, CipherOutputStream ciOutput,
|
||||
Cipher ciIn, int inputLen) throws IOException {
|
||||
byte[] buffer2 = new byte[ciIn.getOutputSize(inputLen)];
|
||||
int offset2 = 0;
|
||||
int len2 = 0;
|
||||
while (len2 != -1) {
|
||||
len2 = cInput.read(buffer2, offset2, buffer2.length - offset2);
|
||||
offset2 += len2;
|
||||
}
|
||||
ciOutput.write(buffer2);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
abstract public void read(CipherInputStream cInput,
|
||||
CipherOutputStream ciOutput, Cipher ciIn, int inputLen)
|
||||
throws IOException;
|
||||
}
|
90
jdk/test/com/sun/crypto/provider/CICO/TestUtilities.java
Normal file
90
jdk/test/com/sun/crypto/provider/CICO/TestUtilities.java
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* utility class
|
||||
*/
|
||||
|
||||
public class TestUtilities {
|
||||
public static boolean equalsBlock(byte[] b1, byte[] b2, int len) {
|
||||
for (int i = 0; i < len; i++) {
|
||||
if (b1[i] != b2[i]) {
|
||||
System.err.println("b1[" + i + "] : " + b1[i]
|
||||
+ " b2[" + i + "] : " + b2[i]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean equals(byte[] b1, byte[] b2) {
|
||||
if (b2.length != b1.length) {
|
||||
System.err.println("b1.length = " + b1.length
|
||||
+ " b2.length = " + b2.length );
|
||||
return false;
|
||||
}
|
||||
return equalsBlock(b1, b2, b1.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify b1's partial part is same as b2. compares b1 and b2 by chopping up
|
||||
* b1 into blocks of b1BKSize and b2 into blocks of b2BKSize, and then
|
||||
* compare the first b2BKSize bytes of each block, return true if they equal
|
||||
* , otherwise return false.
|
||||
* @param b1 byte array to be compared.
|
||||
* @param b2 saved byte array.
|
||||
* @param b1BKSize b1's block size.
|
||||
* @param b2BKSize b2's block size.
|
||||
* @return true is same. false otherwise.
|
||||
*/
|
||||
public static boolean equalsBlockPartial(byte[] b1, byte[] b2, int b1BKSize,
|
||||
int b2BKSize) {
|
||||
int numOfBlock = b1.length / b1BKSize;
|
||||
for (int b = 0; b < numOfBlock; b++) {
|
||||
for (int i = 0; i < b2BKSize; i++) {
|
||||
int j1 = b * b1BKSize + i;
|
||||
int j2 = b * b2BKSize + i;
|
||||
if (b1[j1] != b2[j2]) {
|
||||
System.err.println("Compare failed at b1[" + j1 + "]:" +
|
||||
b1[j1] + " b2[" + j2 + "]:" + b2[j2]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a byte block by given length. The content of byte block
|
||||
* is determined by the index.
|
||||
* @param length length of byte array
|
||||
* @return a byte array
|
||||
*/
|
||||
public static byte[] generateBytes(int length) {
|
||||
byte[] bytes = new byte[length];
|
||||
for (int i = 0; i < length; i++) {
|
||||
bytes[i] = (byte) (i & 0xff);
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8048604
|
||||
* @summary This test checks boundary conditions for testing
|
||||
* ShortBufferException.
|
||||
*/
|
||||
import static java.lang.System.out;
|
||||
|
||||
import java.security.AlgorithmParameters;
|
||||
import java.security.Provider;
|
||||
import java.security.Security;
|
||||
import javax.crypto.BadPaddingException;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.SecretKey;
|
||||
|
||||
public class TextPKCS5PaddingTest {
|
||||
/**
|
||||
* Test plain text.
|
||||
*/
|
||||
private static final byte[] PLAIN_TEXT = {
|
||||
0b10001, 0b10001, 0b10001, 0b10001,
|
||||
0b10001, 0b10001, 0b11, 0b11
|
||||
};
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
Provider provider = Security.getProvider("SunJCE");
|
||||
if (provider == null) {
|
||||
throw new RuntimeException("SunJCE provider not exist");
|
||||
}
|
||||
// generate no-padding cipher with secret key
|
||||
Cipher c = Cipher.getInstance("DES/CBC/NoPadding", provider);
|
||||
KeyGenerator kgen = KeyGenerator.getInstance("DES", provider);
|
||||
SecretKey skey = kgen.generateKey();
|
||||
// this is the improperly padded plaintext
|
||||
|
||||
c.init(Cipher.ENCRYPT_MODE, skey);
|
||||
// encrypt plaintext
|
||||
byte[] cipher = c.doFinal(PLAIN_TEXT);
|
||||
AlgorithmParameters params = c.getParameters();
|
||||
// generate cipher that enforces PKCS5 padding
|
||||
c = Cipher.getInstance("DES/CBC/PKCS5Padding", provider);
|
||||
c.init(Cipher.DECRYPT_MODE, skey, params);
|
||||
try {
|
||||
c.doFinal(cipher);
|
||||
throw new RuntimeException(
|
||||
"ERROR: Expected BadPaddingException not thrown");
|
||||
} catch (BadPaddingException expected) {
|
||||
out.println("Expected BadPaddingException thrown");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
194
jdk/test/com/sun/crypto/provider/NSASuiteB/TestAESOids.java
Normal file
194
jdk/test/com/sun/crypto/provider/NSASuiteB/TestAESOids.java
Normal file
@ -0,0 +1,194 @@
|
||||
/*
|
||||
* 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 static javax.crypto.Cipher.ENCRYPT_MODE;
|
||||
import static javax.crypto.Cipher.getMaxAllowedKeyLength;
|
||||
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.NoSuchProviderException;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import javax.crypto.BadPaddingException;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.IllegalBlockSizeException;
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.NoSuchPaddingException;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.ShortBufferException;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8075286
|
||||
* @summary Test the AES algorithm OIDs in JDK.
|
||||
* OID and Algorithm transformation string should match.
|
||||
* Both could be able to be used to generate the algorithm instance.
|
||||
* @run main TestAESOids
|
||||
*/
|
||||
public class TestAESOids {
|
||||
|
||||
private static final String PROVIDER_NAME = "SunJCE";
|
||||
private static final byte[] INPUT = "1234567890123456".getBytes();
|
||||
|
||||
private static final List<DataTuple> DATA = Arrays.asList(
|
||||
new DataTuple("2.16.840.1.101.3.4.1.1", "AES_128/ECB/NoPadding",
|
||||
128, "ECB"),
|
||||
new DataTuple("2.16.840.1.101.3.4.1.2", "AES_128/CBC/NoPadding",
|
||||
128, "CBC"),
|
||||
new DataTuple("2.16.840.1.101.3.4.1.3", "AES_128/OFB/NoPadding",
|
||||
128, "OFB"),
|
||||
new DataTuple("2.16.840.1.101.3.4.1.4", "AES_128/CFB/NoPadding",
|
||||
128, "CFB"),
|
||||
new DataTuple("2.16.840.1.101.3.4.1.21", "AES_192/ECB/NoPadding",
|
||||
192, "ECB"),
|
||||
new DataTuple("2.16.840.1.101.3.4.1.22", "AES_192/CBC/NoPadding",
|
||||
192, "CBC"),
|
||||
new DataTuple("2.16.840.1.101.3.4.1.23", "AES_192/OFB/NoPadding",
|
||||
192, "OFB"),
|
||||
new DataTuple("2.16.840.1.101.3.4.1.24", "AES_192/CFB/NoPadding",
|
||||
192, "CFB"),
|
||||
new DataTuple("2.16.840.1.101.3.4.1.41", "AES_256/ECB/NoPadding",
|
||||
256, "ECB"),
|
||||
new DataTuple("2.16.840.1.101.3.4.1.42", "AES_256/CBC/NoPadding",
|
||||
256, "CBC"),
|
||||
new DataTuple("2.16.840.1.101.3.4.1.43", "AES_256/OFB/NoPadding",
|
||||
256, "OFB"),
|
||||
new DataTuple("2.16.840.1.101.3.4.1.44", "AES_256/CFB/NoPadding",
|
||||
256, "CFB"));
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
for (DataTuple dataTuple : DATA) {
|
||||
int maxAllowedKeyLength =
|
||||
getMaxAllowedKeyLength(dataTuple.algorithm);
|
||||
boolean supportedKeyLength =
|
||||
maxAllowedKeyLength >= dataTuple.keyLength;
|
||||
|
||||
try {
|
||||
runTest(dataTuple, supportedKeyLength);
|
||||
System.out.println("passed");
|
||||
} catch (InvalidKeyException ike) {
|
||||
if (supportedKeyLength) {
|
||||
throw new RuntimeException(String.format(
|
||||
"The key length %d is supported, but test failed.",
|
||||
dataTuple.keyLength), ike);
|
||||
} else {
|
||||
System.out.printf(
|
||||
"Catch expected InvalidKeyException due "
|
||||
+ "to the key length %d is greater than "
|
||||
+ "max supported key length %d%n",
|
||||
dataTuple.keyLength, maxAllowedKeyLength);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void runTest(DataTuple dataTuple,
|
||||
boolean supportedKeyLength) throws NoSuchAlgorithmException,
|
||||
NoSuchProviderException, NoSuchPaddingException,
|
||||
InvalidKeyException, ShortBufferException,
|
||||
IllegalBlockSizeException, BadPaddingException,
|
||||
InvalidAlgorithmParameterException {
|
||||
Cipher algorithmCipher = Cipher.getInstance(dataTuple.algorithm,
|
||||
PROVIDER_NAME);
|
||||
Cipher oidCipher = Cipher.getInstance(dataTuple.oid, PROVIDER_NAME);
|
||||
|
||||
if (algorithmCipher == null) {
|
||||
throw new RuntimeException(
|
||||
String.format("Test failed: algorithm string %s getInstance"
|
||||
+ " failed.%n", dataTuple.algorithm));
|
||||
}
|
||||
|
||||
if (oidCipher == null) {
|
||||
throw new RuntimeException(
|
||||
String.format("Test failed: OID %s getInstance failed.%n",
|
||||
dataTuple.oid));
|
||||
}
|
||||
|
||||
if (!algorithmCipher.getAlgorithm().equals(dataTuple.algorithm)) {
|
||||
throw new RuntimeException(String.format(
|
||||
"Test failed: algorithm string %s getInstance "
|
||||
+ "doesn't generate expected algorithm.%n",
|
||||
dataTuple.algorithm));
|
||||
}
|
||||
|
||||
KeyGenerator kg = KeyGenerator.getInstance("AES");
|
||||
kg.init(dataTuple.keyLength);
|
||||
SecretKey key = kg.generateKey();
|
||||
|
||||
// encrypt
|
||||
algorithmCipher.init(ENCRYPT_MODE, key);
|
||||
if (!supportedKeyLength) {
|
||||
throw new RuntimeException(String.format(
|
||||
"The key length %d is not supported, so the initialization "
|
||||
+ "of algorithmCipher should fail.%n",
|
||||
dataTuple.keyLength));
|
||||
}
|
||||
|
||||
byte[] cipherText = new byte[algorithmCipher.getOutputSize(INPUT.length)];
|
||||
int offset = algorithmCipher.update(INPUT, 0, INPUT.length,
|
||||
cipherText, 0);
|
||||
algorithmCipher.doFinal(cipherText, offset);
|
||||
|
||||
AlgorithmParameterSpec aps = null;
|
||||
if (!dataTuple.mode.equalsIgnoreCase("ECB")) {
|
||||
aps = new IvParameterSpec(algorithmCipher.getIV());
|
||||
}
|
||||
|
||||
oidCipher.init(Cipher.DECRYPT_MODE, key, aps);
|
||||
if (!supportedKeyLength) {
|
||||
throw new RuntimeException(String.format(
|
||||
"The key length %d is not supported, so the "
|
||||
+ "initialization of oidCipher should fail.%n",
|
||||
dataTuple.keyLength));
|
||||
}
|
||||
|
||||
byte[] recoveredText = new byte[oidCipher.getOutputSize(cipherText.length)];
|
||||
oidCipher.doFinal(cipherText, 0, cipherText.length, recoveredText);
|
||||
|
||||
// Comparison
|
||||
if (!Arrays.equals(INPUT, recoveredText)) {
|
||||
throw new RuntimeException(
|
||||
"Decrypted data is not the same as the original text");
|
||||
}
|
||||
}
|
||||
|
||||
private static class DataTuple {
|
||||
|
||||
private final String oid;
|
||||
private final String algorithm;
|
||||
private final int keyLength;
|
||||
private final String mode;
|
||||
|
||||
private DataTuple(String oid, String algorithm, int keyLength,
|
||||
String mode) {
|
||||
this.oid = oid;
|
||||
this.algorithm = algorithm;
|
||||
this.keyLength = keyLength;
|
||||
this.mode = mode;
|
||||
}
|
||||
}
|
||||
}
|
154
jdk/test/com/sun/crypto/provider/NSASuiteB/TestAESWrapOids.java
Normal file
154
jdk/test/com/sun/crypto/provider/NSASuiteB/TestAESWrapOids.java
Normal file
@ -0,0 +1,154 @@
|
||||
/*
|
||||
* 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 static javax.crypto.Cipher.getMaxAllowedKeyLength;
|
||||
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.Key;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.NoSuchProviderException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.IllegalBlockSizeException;
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.NoSuchPaddingException;
|
||||
import javax.crypto.SecretKey;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8075286
|
||||
* @summary Test the AESWrap algorithm OIDs in JDK.
|
||||
* OID and Algorithm transformation string should match.
|
||||
* Both could be able to be used to generate the algorithm instance.
|
||||
* @run main TestAESWrapOids
|
||||
*/
|
||||
public class TestAESWrapOids {
|
||||
|
||||
private static final String PROVIDER_NAME = "SunJCE";
|
||||
|
||||
private static final List<DataTuple> DATA = Arrays.asList(
|
||||
new DataTuple("2.16.840.1.101.3.4.1.5", "AESWrap_128", 128),
|
||||
new DataTuple("2.16.840.1.101.3.4.1.25", "AESWrap_192", 192),
|
||||
new DataTuple("2.16.840.1.101.3.4.1.45", "AESWrap_256", 256));
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
for (DataTuple dataTuple : DATA) {
|
||||
int maxAllowedKeyLength = getMaxAllowedKeyLength(
|
||||
dataTuple.algorithm);
|
||||
boolean supportedKeyLength =
|
||||
maxAllowedKeyLength >= dataTuple.keyLength;
|
||||
|
||||
try {
|
||||
runTest(dataTuple, supportedKeyLength);
|
||||
System.out.println("passed");
|
||||
} catch (InvalidKeyException ike) {
|
||||
if (supportedKeyLength) {
|
||||
throw new RuntimeException(String.format(
|
||||
"The key length %d is supported, but test failed.",
|
||||
dataTuple.keyLength), ike);
|
||||
} else {
|
||||
System.out.printf(
|
||||
"Catch expected InvalidKeyException "
|
||||
+ "due to the key length %d is greater "
|
||||
+ "than max supported key length %d%n",
|
||||
dataTuple.keyLength, maxAllowedKeyLength);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void runTest(DataTuple dataTuple, boolean supportedKeyLength)
|
||||
throws NoSuchAlgorithmException, NoSuchProviderException,
|
||||
NoSuchPaddingException, InvalidKeyException,
|
||||
IllegalBlockSizeException {
|
||||
Cipher algorithmCipher = Cipher.getInstance(
|
||||
dataTuple.algorithm, PROVIDER_NAME);
|
||||
Cipher oidCipher = Cipher.getInstance(dataTuple.oid, PROVIDER_NAME);
|
||||
|
||||
if (algorithmCipher == null) {
|
||||
throw new RuntimeException(String.format(
|
||||
"Test failed: algorithm string %s getInstance failed.%n",
|
||||
dataTuple.algorithm));
|
||||
}
|
||||
|
||||
if (oidCipher == null) {
|
||||
throw new RuntimeException(
|
||||
String.format("Test failed: OID %s getInstance failed.%n",
|
||||
dataTuple.oid));
|
||||
}
|
||||
|
||||
if (!algorithmCipher.getAlgorithm().equals(
|
||||
dataTuple.algorithm)) {
|
||||
throw new RuntimeException(String.format(
|
||||
"Test failed: algorithm string %s getInstance "
|
||||
+ "doesn't generate expected algorithm.%n",
|
||||
dataTuple.oid));
|
||||
}
|
||||
|
||||
KeyGenerator kg = KeyGenerator.getInstance("AES");
|
||||
kg.init(dataTuple.keyLength);
|
||||
SecretKey key = kg.generateKey();
|
||||
|
||||
// Wrap the key
|
||||
algorithmCipher.init(Cipher.WRAP_MODE, key);
|
||||
if (!supportedKeyLength) {
|
||||
throw new RuntimeException(String.format(
|
||||
"The key length %d is not supported, so the initialization"
|
||||
+ " of algorithmCipher should fail.%n",
|
||||
dataTuple.keyLength));
|
||||
}
|
||||
|
||||
// Unwrap the key
|
||||
oidCipher.init(Cipher.UNWRAP_MODE, key);
|
||||
if (!supportedKeyLength) {
|
||||
throw new RuntimeException(String.format(
|
||||
"The key length %d is not supported, so the initialization"
|
||||
+ " of oidCipher should fail.%n",
|
||||
dataTuple.keyLength));
|
||||
}
|
||||
|
||||
byte[] keyWrapper = algorithmCipher.wrap(key);
|
||||
Key unwrappedKey = oidCipher.unwrap(keyWrapper, "AES",
|
||||
Cipher.SECRET_KEY);
|
||||
|
||||
// Comparison
|
||||
if (!Arrays.equals(key.getEncoded(), unwrappedKey.getEncoded())) {
|
||||
throw new RuntimeException("Key comparison failed");
|
||||
}
|
||||
}
|
||||
|
||||
private static class DataTuple {
|
||||
|
||||
private final String oid;
|
||||
private final String algorithm;
|
||||
private final int keyLength;
|
||||
|
||||
private DataTuple(String oid, String algorithm, int keyLength) {
|
||||
this.oid = oid;
|
||||
this.algorithm = algorithm;
|
||||
this.keyLength = keyLength;
|
||||
}
|
||||
}
|
||||
}
|
116
jdk/test/com/sun/crypto/provider/NSASuiteB/TestHmacSHAOids.java
Normal file
116
jdk/test/com/sun/crypto/provider/NSASuiteB/TestHmacSHAOids.java
Normal file
@ -0,0 +1,116 @@
|
||||
/*
|
||||
* 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.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.NoSuchProviderException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.SecretKey;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8075286
|
||||
* @summary Test the HmacSHA algorithm OIDs in JDK.
|
||||
* OID and Algorithm transformation string should match.
|
||||
* Both could be able to be used to generate the algorithm instance.
|
||||
* @run main TestHmacSHAOids
|
||||
*/
|
||||
public class TestHmacSHAOids {
|
||||
|
||||
private static final String PROVIDER_NAME = "SunJCE";
|
||||
private static final byte[] INPUT = "1234567890".getBytes();
|
||||
|
||||
private static final List<DataTuple> DATA = Arrays.asList(
|
||||
new DataTuple("1.2.840.113549.2.7", "HmacSHA1"),
|
||||
new DataTuple("1.2.840.113549.2.8", "HmacSHA224"),
|
||||
new DataTuple("1.2.840.113549.2.9", "HmacSHA256"),
|
||||
new DataTuple("1.2.840.113549.2.10", "HmacSHA384"),
|
||||
new DataTuple("1.2.840.113549.2.11", "HmacSHA512"));
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
for (DataTuple dataTuple : DATA) {
|
||||
runTest(dataTuple);
|
||||
System.out.println("passed");
|
||||
}
|
||||
System.out.println("All tests passed");
|
||||
}
|
||||
|
||||
private static void runTest(DataTuple dataTuple)
|
||||
throws NoSuchAlgorithmException, NoSuchProviderException,
|
||||
InvalidKeyException {
|
||||
Mac mcAlgorithm = Mac.getInstance(dataTuple.algorithm,
|
||||
PROVIDER_NAME);
|
||||
Mac mcOid = Mac.getInstance(dataTuple.oid, PROVIDER_NAME);
|
||||
|
||||
if (mcAlgorithm == null) {
|
||||
throw new RuntimeException(String.format(
|
||||
"Test failed: Mac using algorithm "
|
||||
+ "string %s getInstance failed.%n",
|
||||
dataTuple.algorithm));
|
||||
}
|
||||
|
||||
if (mcOid == null) {
|
||||
throw new RuntimeException(String.format(
|
||||
"Test failed: Mac using OID %s getInstance failed.%n",
|
||||
dataTuple.oid));
|
||||
}
|
||||
|
||||
if (!mcAlgorithm.getAlgorithm().equals(dataTuple.algorithm)) {
|
||||
throw new RuntimeException(String.format(
|
||||
"Test failed: Mac using algorithm string %s getInstance "
|
||||
+ "doesn't generate expected algorithm.%n",
|
||||
dataTuple.algorithm));
|
||||
}
|
||||
|
||||
KeyGenerator kg = KeyGenerator.getInstance(dataTuple.algorithm,
|
||||
PROVIDER_NAME);
|
||||
SecretKey key = kg.generateKey();
|
||||
|
||||
mcAlgorithm.init(key);
|
||||
mcAlgorithm.update(INPUT);
|
||||
|
||||
mcOid.init(key);
|
||||
mcOid.update(INPUT);
|
||||
|
||||
// Comparison
|
||||
if (!Arrays.equals(mcAlgorithm.doFinal(), mcOid.doFinal())) {
|
||||
throw new RuntimeException("Digest comparison failed: "
|
||||
+ "the two MACs are not the same");
|
||||
}
|
||||
}
|
||||
|
||||
private static class DataTuple {
|
||||
|
||||
private final String oid;
|
||||
private final String algorithm;
|
||||
|
||||
private DataTuple(String oid, String algorithm) {
|
||||
this.oid = oid;
|
||||
this.algorithm = algorithm;
|
||||
}
|
||||
}
|
||||
}
|
@ -412,11 +412,14 @@ public class LdapTimeoutTest {
|
||||
|
||||
// run the ReadServerTest with connect / read timeouts set
|
||||
// this should exit after the connect timeout expires
|
||||
System.out.println("Running read timeout test with 10ms connect timeout, 3000ms read timeout");
|
||||
Hashtable env4 = createEnv();
|
||||
env4.put("com.sun.jndi.ldap.connect.timeout", "10");
|
||||
env4.put("com.sun.jndi.ldap.read.timeout", "3000");
|
||||
results.add(testPool.submit(new ReadServerTimeoutTest(env4)));
|
||||
//
|
||||
// NOTE: commenting this test out as it is failing intermittently.
|
||||
//
|
||||
// System.out.println("Running read timeout test with 10ms connect timeout, 3000ms read timeout");
|
||||
// Hashtable env4 = createEnv();
|
||||
// env4.put("com.sun.jndi.ldap.connect.timeout", "10");
|
||||
// env4.put("com.sun.jndi.ldap.read.timeout", "3000");
|
||||
// results.add(testPool.submit(new ReadServerTimeoutTest(env4)));
|
||||
|
||||
// run the DeadServerTest with connect timeout set
|
||||
// this should exit after the connect timeout expires
|
||||
|
@ -738,7 +738,7 @@ public class Basic {
|
||||
* Remove it from the list of env variables
|
||||
*/
|
||||
private static String removeAixExpectedVars(String vars) {
|
||||
return vars.replace("AIXTHREAD_GUARDPAGES=0,","");
|
||||
return vars.replace("AIXTHREAD_GUARDPAGES=0,", "");
|
||||
}
|
||||
|
||||
private static String sortByLinesWindowsly(String text) {
|
||||
@ -785,8 +785,8 @@ public class Basic {
|
||||
equal(entry.getKey(), key);
|
||||
equal(entry.getValue(), value);
|
||||
}
|
||||
check(! kIter.hasNext() &&
|
||||
! vIter.hasNext());
|
||||
check(!kIter.hasNext() &&
|
||||
!vIter.hasNext());
|
||||
|
||||
} catch (Throwable t) { unexpected(t); }
|
||||
}
|
||||
@ -815,9 +815,9 @@ public class Basic {
|
||||
|
||||
static void checkRedirects(ProcessBuilder pb,
|
||||
Redirect in, Redirect out, Redirect err) {
|
||||
equal(pb.redirectInput(), in);
|
||||
equal(pb.redirectInput(), in);
|
||||
equal(pb.redirectOutput(), out);
|
||||
equal(pb.redirectError(), err);
|
||||
equal(pb.redirectError(), err);
|
||||
}
|
||||
|
||||
static void redirectIO(ProcessBuilder pb,
|
||||
@ -862,6 +862,7 @@ public class Basic {
|
||||
Redirect[] redirects =
|
||||
{ PIPE,
|
||||
INHERIT,
|
||||
DISCARD,
|
||||
Redirect.from(ifile),
|
||||
Redirect.to(ifile),
|
||||
Redirect.appendTo(ifile),
|
||||
@ -884,6 +885,10 @@ public class Basic {
|
||||
equal(INHERIT.toString(), "INHERIT");
|
||||
equal(INHERIT.file(), null);
|
||||
|
||||
equal(DISCARD.type(), Redirect.Type.WRITE);
|
||||
equal(DISCARD.toString(), "WRITE");
|
||||
equal(DISCARD.file(), new File((Windows.is() ? "NUL" : "/dev/null")));
|
||||
|
||||
equal(Redirect.from(ifile).type(), Redirect.Type.READ);
|
||||
equal(Redirect.from(ifile).toString(),
|
||||
"redirect to read from file \"ifile\"");
|
||||
@ -925,6 +930,12 @@ public class Basic {
|
||||
pb.inheritIO();
|
||||
checkRedirects(pb, INHERIT, INHERIT, INHERIT);
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Check DISCARD for stdout,stderr
|
||||
//----------------------------------------------------------------
|
||||
redirectIO(pb, INHERIT, DISCARD, DISCARD);
|
||||
checkRedirects(pb, INHERIT, DISCARD, DISCARD);
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Check setters and getters agree
|
||||
//----------------------------------------------------------------
|
||||
@ -943,7 +954,8 @@ public class Basic {
|
||||
THROWS(IllegalArgumentException.class,
|
||||
() -> pb.redirectInput(Redirect.to(ofile)),
|
||||
() -> pb.redirectOutput(Redirect.from(ifile)),
|
||||
() -> pb.redirectError(Redirect.from(ifile)));
|
||||
() -> pb.redirectError(Redirect.from(ifile)),
|
||||
() -> pb.redirectInput(DISCARD));
|
||||
|
||||
THROWS(NullPointerException.class,
|
||||
() -> pb.redirectInput((File)null),
|
||||
@ -980,7 +992,7 @@ public class Basic {
|
||||
ProcessResults r = run(pb);
|
||||
equal(r.exitValue(), 0);
|
||||
equal(fileContents(ofile),
|
||||
"standard error" + "standard output");
|
||||
"standard error" + "standard output");
|
||||
equal(fileContents(efile), "");
|
||||
equal(r.out(), "");
|
||||
equal(r.err(), "");
|
||||
@ -1050,6 +1062,79 @@ public class Basic {
|
||||
efile.delete();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// DISCARDing output
|
||||
//----------------------------------------------------------------
|
||||
{
|
||||
setFileContents(ifile, "standard input");
|
||||
pb.redirectOutput(DISCARD);
|
||||
pb.redirectError(DISCARD);
|
||||
ProcessResults r = run(pb);
|
||||
equal(r.exitValue(), 0);
|
||||
equal(r.out(), "");
|
||||
equal(r.err(), "");
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// DISCARDing output and redirecting error
|
||||
//----------------------------------------------------------------
|
||||
{
|
||||
setFileContents(ifile, "standard input");
|
||||
setFileContents(ofile, "ofile-contents");
|
||||
setFileContents(efile, "efile-contents");
|
||||
pb.redirectOutput(DISCARD);
|
||||
pb.redirectError(efile);
|
||||
ProcessResults r = run(pb);
|
||||
equal(r.exitValue(), 0);
|
||||
equal(fileContents(ofile), "ofile-contents");
|
||||
equal(fileContents(efile), "standard error");
|
||||
equal(r.out(), "");
|
||||
equal(r.err(), "");
|
||||
ofile.delete();
|
||||
efile.delete();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// DISCARDing error and redirecting output
|
||||
//----------------------------------------------------------------
|
||||
{
|
||||
setFileContents(ifile, "standard input");
|
||||
setFileContents(ofile, "ofile-contents");
|
||||
setFileContents(efile, "efile-contents");
|
||||
pb.redirectOutput(ofile);
|
||||
pb.redirectError(DISCARD);
|
||||
ProcessResults r = run(pb);
|
||||
equal(r.exitValue(), 0);
|
||||
equal(fileContents(ofile), "standard output");
|
||||
equal(fileContents(efile), "efile-contents");
|
||||
equal(r.out(), "");
|
||||
equal(r.err(), "");
|
||||
ofile.delete();
|
||||
efile.delete();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// DISCARDing output and merging error into output
|
||||
//----------------------------------------------------------------
|
||||
{
|
||||
setFileContents(ifile, "standard input");
|
||||
setFileContents(ofile, "ofile-contents");
|
||||
setFileContents(efile, "efile-contents");
|
||||
pb.redirectOutput(DISCARD);
|
||||
pb.redirectErrorStream(true);
|
||||
pb.redirectError(efile);
|
||||
ProcessResults r = run(pb);
|
||||
equal(r.exitValue(), 0);
|
||||
equal(fileContents(ofile), "ofile-contents"); // untouched
|
||||
equal(fileContents(efile), ""); // empty
|
||||
equal(r.out(), "");
|
||||
equal(r.err(), "");
|
||||
ifile.delete();
|
||||
ofile.delete();
|
||||
efile.delete();
|
||||
pb.redirectErrorStream(false); // reset for next test
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Testing INHERIT is harder.
|
||||
// Note that this requires __FOUR__ nested JVMs involved in one test,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 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
|
||||
@ -42,9 +42,37 @@
|
||||
public class HypotTests {
|
||||
private HypotTests(){}
|
||||
|
||||
/**
|
||||
* The hypot implementation is commutative, {@code hypot(a, b) ==
|
||||
* hypot(b, a)}, and independent of sign, {@code hypot(a, b) ==
|
||||
* hypot(-a, b) == hypot(a, -b) == hypot(-a, -b)}.
|
||||
*/
|
||||
static int testHypotCase(double input1, double input2, double expected) {
|
||||
return Tests.test("StrictMath.hypot(double)", input1, input2,
|
||||
StrictMath.hypot(input1, input2), expected);
|
||||
int failures = 0;
|
||||
failures += Tests.test("StrictMath.hypot(double)", input1, input2,
|
||||
StrictMath.hypot(input1, input2), expected);
|
||||
|
||||
failures += Tests.test("StrictMath.hypot(double)", input2, input1,
|
||||
StrictMath.hypot(input2, input1), expected);
|
||||
|
||||
failures += Tests.test("StrictMath.hypot(double)", -input1, input2,
|
||||
StrictMath.hypot(-input1, input2), expected);
|
||||
|
||||
failures += Tests.test("StrictMath.hypot(double)", input2, -input1,
|
||||
StrictMath.hypot(input2, -input1), expected);
|
||||
|
||||
failures += Tests.test("StrictMath.hypot(double)", input1, -input2,
|
||||
StrictMath.hypot(input1, -input2), expected);
|
||||
|
||||
failures += Tests.test("StrictMath.hypot(double)", -input2, input1,
|
||||
StrictMath.hypot(-input2, input1), expected);
|
||||
|
||||
failures += Tests.test("StrictMath.hypot(double)", -input1, -input2,
|
||||
StrictMath.hypot(-input1, -input2), expected);
|
||||
|
||||
failures += Tests.test("StrictMath.hypot(double)", -input2, -input1,
|
||||
StrictMath.hypot(-input2, -input1), expected);
|
||||
return failures;
|
||||
}
|
||||
|
||||
static int testHypot() {
|
||||
@ -611,21 +639,60 @@ public class HypotTests {
|
||||
{0x1.8p1, 0x1.8bffffffffff6p6, 0x1.8c2e88e6f44b1p6},
|
||||
{0x1.8p1, 0x1.8ffffffffffe8p6, 0x1.902e11d3b5549p6},
|
||||
{0x1.8p1, 0x1.8fffffffffffep6, 0x1.902e11d3b556p6},
|
||||
|
||||
// Test near decision points of the fdlibm algorithm
|
||||
{0x1.0000000000001p501, 0x1.000000000000p501, 0x1.6a09e667f3bcdp501},
|
||||
{0x1.0p501, 0x1.0p499, 0x1.07e0f66afed07p501},
|
||||
|
||||
{0x1.0p500, 0x1.0p450, 0x1.0p500},
|
||||
{0x1.0000000000001p500, 0x1.0p450, 0x1.0000000000001p500},
|
||||
|
||||
{0x1.0p500, 0x1.0p440, 0x1.0p500},
|
||||
{0x1.0000000000001p500, 0x1.0p440, 0x1.0000000000001p500},
|
||||
{0x1.0p500, 0x1.0p439, 0x1.0p500},
|
||||
{0x1.0000000000001p500, 0x1.0p439, 0x1.0000000000001p500},
|
||||
|
||||
{0x1.0p-450, 0x1.0p-500, 0x1.0p-450},
|
||||
{0x1.0000000000001p-450, 0x1.0p-500, 0x1.0000000000001p-450},
|
||||
{0x1.0p-450, 0x1.fffffffffffffp-499, 0x1.0p-450},
|
||||
{0x1.0000000000001p-450, 0x1.fffffffffffffp-499, 0x1.0000000000001p-450},
|
||||
|
||||
|
||||
{0x1.0p-450, 0x1.0p-500, 0x1.0p-450},
|
||||
{0x1.0000000000001p-450, 0x1.0p-500, 0x1.0000000000001p-450},
|
||||
{0x1.0p-450, 0x1.fffffffffffffp-499, 0x1.0p-450},
|
||||
{0x1.0000000000001p-450, 0x1.fffffffffffffp-499, 0x1.0000000000001p-450},
|
||||
|
||||
// 0x1.0p-1022 is MIN_NORMAL
|
||||
{0x1.0000000000001p-1022, 0x1.0000000000001p-1022, 0x1.6a09e667f3bcep-1022},
|
||||
{0x1.0000000000001p-1022, 0x1.0p-1022, 0x1.6a09e667f3bcdp-1022},
|
||||
{0x1.0000000000001p-1022, 0x0.fffffffffffffp-1022, 0x1.6a09e667f3bcdp-1022},
|
||||
{0x1.0000000000001p-1022, 0x0.0000000000001P-1022, 0x1.0000000000001p-1022},
|
||||
{0x1.0000000000001p-1022, 0.0, 0x1.0000000000001p-1022},
|
||||
|
||||
{0x1.0000000000000p-1022, 0x0.fffffffffffffp-1022, 0x1.6a09e667f3bccp-1022},
|
||||
{0x1.0000000000000p-1021, 0x0.fffffffffffffp-1022, 0x1.1e3779b97f4a8p-1021},
|
||||
{0x1.0000000000000p-1020, 0x0.fffffffffffffp-1022, 0x1.07e0f66afed07p-1020},
|
||||
|
||||
// 0x0.0000000000001P-1022 is MIN_VALUE (smallest nonzero number)
|
||||
{0x0.0000000000001p-1022, 0x0.0000000000001p-1022, 0x0.0000000000001p-1022},
|
||||
{0x0.0000000000002p-1022, 0x0.0000000000001p-1022, 0x0.0000000000002p-1022},
|
||||
{0x0.0000000000003p-1022, 0x0.0000000000002p-1022, 0x0.0000000000004p-1022},
|
||||
};
|
||||
|
||||
for (double[] testCase: testCases)
|
||||
failures+=testHypotCase(testCase[0], testCase[1], testCase[2]);
|
||||
failures += testHypotCase(testCase[0], testCase[1], testCase[2]);
|
||||
|
||||
return failures;
|
||||
}
|
||||
|
||||
public static void main(String [] argv) {
|
||||
public static void main(String... args) {
|
||||
int failures = 0;
|
||||
|
||||
failures += testHypot();
|
||||
|
||||
if (failures > 0) {
|
||||
System.err.println("Testing log1p incurred "
|
||||
System.err.println("Testing hypot incurred "
|
||||
+ failures + " failures.");
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
@ -32,7 +32,7 @@
|
||||
* @build LambdaFormTestCase
|
||||
* @build LFCachingTestCase
|
||||
* @build LFMultiThreadCachingTest
|
||||
* @run main/othervm LFMultiThreadCachingTest
|
||||
* @run main/othervm -Djava.lang.invoke.MethodHandle.OBSERVE_BMH_SPECIES_CREATION=true LFMultiThreadCachingTest
|
||||
*/
|
||||
|
||||
import java.lang.invoke.MethodHandle;
|
||||
|
66
jdk/test/java/nio/channels/FileChannel/LoopingTruncate.java
Normal file
66
jdk/test/java/nio/channels/FileChannel/LoopingTruncate.java
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8137121
|
||||
* @summary (fc) Infinite loop FileChannel.truncate
|
||||
* @run main/othervm LoopingTruncate
|
||||
*/
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import static java.nio.file.StandardOpenOption.*;
|
||||
|
||||
public class LoopingTruncate {
|
||||
|
||||
// (int)FATEFUL_SIZE == -3 == IOStatus.INTERRUPTED
|
||||
static long FATEFUL_SIZE = 0x1FFFFFFFDL;
|
||||
|
||||
static long TIMEOUT = 10_000; // 10 seconds
|
||||
|
||||
public static void main(String[] args) throws Throwable {
|
||||
Path path = Files.createTempFile("LoopingTruncate.tmp", null);
|
||||
try {
|
||||
Thread th = new Thread(() -> {
|
||||
try (FileChannel fc = FileChannel.open(path, CREATE, WRITE)) {
|
||||
fc.position(FATEFUL_SIZE + 1L);
|
||||
fc.write(ByteBuffer.wrap(new byte[] {0}));
|
||||
fc.truncate(FATEFUL_SIZE);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}});
|
||||
th.start();
|
||||
th.join(TIMEOUT);
|
||||
|
||||
if (th.isAlive()) {
|
||||
th.interrupt();
|
||||
throw new RuntimeException("Failed to complete on time");
|
||||
}
|
||||
} finally {
|
||||
Files.deleteIfExists(path);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* 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 TVJar.TVPermission;
|
||||
import java.security.AccessController;
|
||||
|
||||
/**
|
||||
* @test @bug 8050402
|
||||
* @summary Check policy is extensible with user defined permissions
|
||||
* @run main/othervm/policy=ExtensiblePolicyTest1.policy
|
||||
* ExtensiblePolicyTest false
|
||||
* @run main/othervm/policy=ExtensiblePolicyTest2.policy
|
||||
* ExtensiblePolicyTest true
|
||||
* @run main/othervm/policy=ExtensiblePolicyTest3.policy
|
||||
* ExtensiblePolicyTest true
|
||||
*/
|
||||
public class ExtensiblePolicyTest {
|
||||
|
||||
public static void main(String args[]) throws Throwable {
|
||||
// ExtensiblePolicyTest1.policy: policy file grants permission to
|
||||
// watch TVChannel 3-6
|
||||
// ExtensiblePolicyTest2.policy: policy file grants permission to
|
||||
// watch TVChanel 4
|
||||
// ExtensiblePolicyTest3.policy: policy file grants permission signed
|
||||
// by duke2 to watch TVChanel 5
|
||||
|
||||
TVPermission perm = new TVPermission("channel:5", "watch");
|
||||
boolean getException = false;
|
||||
String exceptionMessage = null;
|
||||
boolean expectException = Boolean.parseBoolean(args[0]);
|
||||
try {
|
||||
AccessController.checkPermission(perm);
|
||||
} catch (SecurityException se) {
|
||||
getException = true;
|
||||
exceptionMessage = se.getMessage();
|
||||
}
|
||||
|
||||
if (expectException ^ getException) {
|
||||
throw new RuntimeException("Test Failed: expectException = "
|
||||
+ expectException + " getException = " + getException
|
||||
+ "\n" + exceptionMessage);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
grant {
|
||||
permission TVJar.TVPermission "channel:3-6", "watch";
|
||||
};
|
||||
|
@ -0,0 +1,3 @@
|
||||
grant {
|
||||
permission TVJar.TVPermission "channel:4", "watch";
|
||||
};
|
@ -0,0 +1,5 @@
|
||||
keystore "file:${user.dir}/epkeystore";
|
||||
|
||||
grant {
|
||||
permission TVJar.TVPermission "channel:5", "watch", SignedBy "duke2";
|
||||
};
|
@ -0,0 +1,113 @@
|
||||
/*
|
||||
* 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 TVJar.TVPermission;
|
||||
import java.io.File;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.security.AccessController;
|
||||
import jdk.testlibrary.ProcessTools;
|
||||
import jdk.testlibrary.JarUtils;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8050402
|
||||
* @summary Check policy is extensible with user defined permissions
|
||||
* @library /lib/testlibrary
|
||||
* @compile TVJar/TVPermission.java
|
||||
* @run main ExtensiblePolicyWithJarTest
|
||||
*/
|
||||
public class ExtensiblePolicyWithJarTest {
|
||||
|
||||
public static void main(String args[]) throws Throwable {
|
||||
final String FS = File.separator;
|
||||
final String PS = File.pathSeparator;
|
||||
final String POL = "ExtensiblePolicyTest3.policy";
|
||||
final String JAVA_HOME = System.getProperty("test.jdk");
|
||||
final String KEYTOOL = JAVA_HOME + FS + "bin" + FS + "keytool";
|
||||
final String JARSIGNER = JAVA_HOME + FS + "bin" + FS + "jarsigner";
|
||||
final String KEYSTORE = "epkeystore";
|
||||
final String PASSWORD = "password";
|
||||
final String ALIAS = "duke2";
|
||||
final String CLASSPATH = System.getProperty("test.class.path", "");
|
||||
final String TESTCLASSES = System.getProperty("test.classes", "");
|
||||
final String TVPERMJAR = "tvPerm.jar";
|
||||
final String PATHTOJAR = System.getProperty("user.dir", "")
|
||||
+ FS + TVPERMJAR;
|
||||
|
||||
// create jar file for TVpermission
|
||||
new File("TVJar").mkdir();
|
||||
Files.copy(Paths.get(TESTCLASSES + FS + "TVJar", "TVPermission.class"),
|
||||
Paths.get("TVJar", "TVPermission.class"));
|
||||
Files.copy(Paths.get(TESTCLASSES + FS + "TVJar",
|
||||
"TVPermissionCollection.class"),
|
||||
Paths.get("TVJar", "TVPermissionCollection.class"));
|
||||
JarUtils.createJar(TVPERMJAR, "TVJar/TVPermission.class",
|
||||
"TVJar/TVPermissionCollection.class");
|
||||
|
||||
// create key pair for jar signing
|
||||
ProcessTools.executeCommand(KEYTOOL,
|
||||
"-genkey",
|
||||
"-alias", ALIAS,
|
||||
"-keystore", KEYSTORE,
|
||||
"-storetype", "JKS",
|
||||
"-keypass", PASSWORD,
|
||||
"-dname", "cn=Blah",
|
||||
"-storepass", PASSWORD
|
||||
).shouldHaveExitValue(0);
|
||||
// sign jar
|
||||
ProcessTools.executeCommand(JARSIGNER,
|
||||
"-keystore", KEYSTORE,
|
||||
"-storepass", PASSWORD,
|
||||
"-keypass", PASSWORD,
|
||||
TVPERMJAR,
|
||||
ALIAS).shouldHaveExitValue(0);
|
||||
// add jar file to classpath
|
||||
String cp = PATHTOJAR + PS + CLASSPATH;
|
||||
|
||||
// policy file grants permission signed by duke2 to watch TVChanel 5
|
||||
try {
|
||||
String[] cmd = {
|
||||
"-classpath", cp,
|
||||
"-Djava.security.manager",
|
||||
"-Djava.security.policy=" + POL,
|
||||
"ExtensiblePolicyTest_orig$TestMain"};
|
||||
ProcessTools.executeTestJvm(cmd).shouldHaveExitValue(0);
|
||||
} catch (Exception ex) {
|
||||
System.out.println("ExtensiblePolicyWithJarTest Failed");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class TestMain {
|
||||
public static void main(String args[]) {
|
||||
TVPermission perm = new TVPermission("channel:5", "watch");
|
||||
try {
|
||||
AccessController.checkPermission(perm);
|
||||
} catch (SecurityException se) {
|
||||
throw new RuntimeException(se);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,358 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 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.
|
||||
*/
|
||||
package TVJar;
|
||||
|
||||
import java.security.Permission;
|
||||
import java.security.PermissionCollection;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
import java.util.StringJoiner;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
public class TVPermission extends Permission {
|
||||
|
||||
/**
|
||||
* Watch
|
||||
*/
|
||||
private final static int WATCH = 0x1;
|
||||
|
||||
/**
|
||||
* Preview
|
||||
*/
|
||||
private final static int PREVIEW = 0x2;
|
||||
|
||||
/**
|
||||
* No actions
|
||||
*/
|
||||
private final static int NONE = 0x0;
|
||||
|
||||
/**
|
||||
* All actions
|
||||
*/
|
||||
private final static int ALL = WATCH | PREVIEW;
|
||||
|
||||
// the actions mask
|
||||
private int mask;
|
||||
|
||||
// the actions string
|
||||
private String actions;
|
||||
|
||||
// the canonical name of the channel
|
||||
private String cname;
|
||||
|
||||
// true if the channelname is a wildcard
|
||||
private boolean wildcard;
|
||||
|
||||
// num range on channel
|
||||
private int[] numrange;
|
||||
|
||||
// various num constants
|
||||
private final static int NUM_MIN = 1;
|
||||
private final static int NUM_MAX = 128;
|
||||
|
||||
public TVPermission(String channel, String action) {
|
||||
this(channel, getMask(action));
|
||||
}
|
||||
|
||||
TVPermission(String channel, int mask) {
|
||||
super(channel);
|
||||
init(channel, mask);
|
||||
}
|
||||
|
||||
private synchronized int[] parseNum(String num)
|
||||
throws Exception {
|
||||
|
||||
if (num == null || num.equals("") || num.equals("*")) {
|
||||
wildcard = true;
|
||||
return new int[]{NUM_MIN, NUM_MAX};
|
||||
}
|
||||
|
||||
int dash = num.indexOf('-');
|
||||
|
||||
if (dash == -1) {
|
||||
int p = 0;
|
||||
try {
|
||||
p = Integer.parseInt(num);
|
||||
} catch (NumberFormatException nfe) {
|
||||
throw new IllegalArgumentException("invalid input" + num);
|
||||
}
|
||||
return new int[]{p, p};
|
||||
} else {
|
||||
String low = num.substring(0, dash);
|
||||
String high = num.substring(dash + 1);
|
||||
int l, h;
|
||||
|
||||
if (low.equals("")) {
|
||||
l = NUM_MIN;
|
||||
} else {
|
||||
try {
|
||||
l = Integer.parseInt(low);
|
||||
} catch (NumberFormatException nfe) {
|
||||
throw new IllegalArgumentException("invalid input" + num);
|
||||
}
|
||||
}
|
||||
|
||||
if (high.equals("")) {
|
||||
h = NUM_MAX;
|
||||
} else {
|
||||
try {
|
||||
h = Integer.parseInt(high);
|
||||
} catch (NumberFormatException nfe) {
|
||||
throw new IllegalArgumentException("invalid input" + num);
|
||||
}
|
||||
}
|
||||
if (h < l || l < NUM_MIN || h > NUM_MAX) {
|
||||
throw new IllegalArgumentException("invalid num range");
|
||||
}
|
||||
|
||||
return new int[]{l, h};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the TVPermission object.
|
||||
*/
|
||||
private synchronized void init(String channel, int mask) {
|
||||
|
||||
// Parse the channel name.
|
||||
int sep = channel.indexOf(':');
|
||||
|
||||
if (sep != -1) {
|
||||
String num = channel.substring(sep + 1);
|
||||
cname = channel.substring(0, sep);
|
||||
try {
|
||||
numrange = parseNum(num);
|
||||
} catch (Exception e) {
|
||||
throw new IllegalArgumentException("invalid num range: " + num);
|
||||
}
|
||||
} else {
|
||||
numrange = new int[]{NUM_MIN, NUM_MAX};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an action string to an integer actions mask.
|
||||
*
|
||||
* @param action the action string
|
||||
* @return the action mask
|
||||
*/
|
||||
private synchronized static int getMask(String action) {
|
||||
int mask = NONE;
|
||||
|
||||
if (action == null) {
|
||||
return mask;
|
||||
}
|
||||
|
||||
StringTokenizer st = new StringTokenizer(action.toLowerCase(), ",");
|
||||
while (st.hasMoreTokens()) {
|
||||
String token = st.nextToken();
|
||||
if (token.equals("watch")) {
|
||||
mask |= WATCH;
|
||||
} else if (token.equals("preview")) {
|
||||
mask |= PREVIEW;
|
||||
} else {
|
||||
throw new IllegalArgumentException("invalid TV permission: " + token);
|
||||
}
|
||||
}
|
||||
return mask;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean implies(Permission p) {
|
||||
if (!(p instanceof TVPermission)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.wildcard) {
|
||||
return true;
|
||||
}
|
||||
|
||||
TVPermission that = (TVPermission) p;
|
||||
|
||||
if ((this.mask & that.mask) != that.mask) {
|
||||
System.out.println("Masks are not ok this = "
|
||||
+ this.mask + "THat = " + that.mask);
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((this.numrange[0] > that.numrange[0])
|
||||
|| (this.numrange[1] < that.numrange[1])) {
|
||||
|
||||
System.out.println("This 0= " + this.numrange[0]
|
||||
+ " 1 = " + this.numrange[1]);
|
||||
System.out.println("That 0= " + that.numrange[0]
|
||||
+ " 1 = " + that.numrange[1]);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks two TVPermission objects for equality.
|
||||
* <p>
|
||||
* @param obj the object we are testing for equality.
|
||||
* @return true if obj is a TVPermission, and has the same channelname and
|
||||
* action mask as this TVPermission object.
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == this) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(obj instanceof TVPermission)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
TVPermission that = (TVPermission) obj;
|
||||
|
||||
// check the mask first
|
||||
if (this.mask != that.mask) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// now check the num range...
|
||||
if ((this.numrange[0] != that.numrange[0])
|
||||
|| (this.numrange[1] != that.numrange[1])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.getName().equals(that.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hash code value for this object.
|
||||
*
|
||||
* @return a hash code value for this object.
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.getName().hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the canonical string representation of the actions. Always returns
|
||||
* actions in the following order: watch,preview.
|
||||
*
|
||||
* @param mask a specific integer action mask to translate into a string
|
||||
* @return the canonical string representation of the actions
|
||||
*/
|
||||
private synchronized static String getActions(int mask) {
|
||||
StringJoiner sj = new StringJoiner(",");
|
||||
if ((mask & WATCH) == WATCH) {
|
||||
sj.add("watch");
|
||||
}
|
||||
if ((mask & PREVIEW) == PREVIEW) {
|
||||
sj.add("preview");
|
||||
}
|
||||
return sj.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the canonical string representation of the actions. Always returns
|
||||
* actions in the following order: watch,preview.
|
||||
*
|
||||
* @return the canonical string representation of the actions.
|
||||
*/
|
||||
@Override
|
||||
public String getActions() {
|
||||
if (actions == null) {
|
||||
actions = getActions(this.mask);
|
||||
}
|
||||
|
||||
return actions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString() + "\n"
|
||||
+ "cname = " + cname + "\n"
|
||||
+ "wildcard = " + wildcard + "\n"
|
||||
+ "numrange = " + numrange[0] + "," + numrange[1] + "\n";
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public PermissionCollection newPermissionCollection() {
|
||||
return new TVPermissionCollection();
|
||||
}
|
||||
}
|
||||
|
||||
final class TVPermissionCollection extends PermissionCollection {
|
||||
|
||||
/**
|
||||
* The TVPermissions for this set.
|
||||
*/
|
||||
private final ArrayList<TVPermission> permissions = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Adds a permission to the TVPermissions. The key for the hash is the name
|
||||
* in the case of wildcards, or all the IP addresses.
|
||||
*
|
||||
* @param permission the Permission object to add.
|
||||
*/
|
||||
@Override
|
||||
public void add(Permission permission) {
|
||||
if (!(permission instanceof TVPermission)) {
|
||||
throw new IllegalArgumentException("invalid permission: " + permission);
|
||||
}
|
||||
permissions.add((TVPermission) permission);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check and see if this collection of permissions implies the permissions
|
||||
* expressed in "permission".
|
||||
*
|
||||
* @param p the Permission object to compare
|
||||
*
|
||||
* @return true if "permission" is a proper subset of a permission in the
|
||||
* collection, false if not.
|
||||
*/
|
||||
@Override
|
||||
public boolean implies(Permission p) {
|
||||
if (!(p instanceof TVPermission)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Iterator<TVPermission> i = permissions.iterator();
|
||||
while (i.hasNext()) {
|
||||
if (((TVPermission) i.next()).implies(p)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an enumeration of all the TVPermission objects in the container.
|
||||
*
|
||||
* @return an enumeration of all the TVPermission objects.
|
||||
*/
|
||||
@Override
|
||||
public Enumeration elements() {
|
||||
return Collections.enumeration(permissions);
|
||||
}
|
||||
|
||||
}
|
@ -23,7 +23,7 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8005471 8008577 8129881 8130845
|
||||
* @bug 8005471 8008577 8129881 8130845 8136518
|
||||
* @run main/othervm -Djava.locale.providers=CLDR CLDRDisplayNamesTest
|
||||
* @summary Make sure that localized time zone names of CLDR are used
|
||||
* if specified.
|
||||
@ -93,7 +93,7 @@ public class CLDRDisplayNamesTest {
|
||||
|
||||
// for 8129881
|
||||
tz = TimeZone.getTimeZone("Europe/Vienna");
|
||||
String name = tz.getDisplayName(false, SHORT);
|
||||
String name = tz.getDisplayName(false, SHORT, Locale.ENGLISH);
|
||||
if (!"CET".equals(name)) {
|
||||
System.err.printf("error: got '%s' expected 'CET' %n", name);
|
||||
errors++;
|
||||
|
@ -31,6 +31,7 @@ package org.openjdk.tests.java.util.stream;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.DoubleStream;
|
||||
import java.util.stream.DoubleStreamTestDataProvider;
|
||||
import java.util.stream.IntStream;
|
||||
@ -61,6 +62,12 @@ public class CountTest extends OpTestCase {
|
||||
expectedResult(expectedCount).
|
||||
exercise();
|
||||
|
||||
// Test counting collector
|
||||
withData(data).
|
||||
terminal(s -> s, s -> s.collect(Collectors.counting())).
|
||||
expectedResult(expectedCount).
|
||||
exercise();
|
||||
|
||||
// Test with stateful distinct op that is a barrier or lazy
|
||||
// depending if source is not already distinct and encounter order is
|
||||
// preserved or not
|
||||
|
@ -34,6 +34,7 @@ import static java.lang.System.out;
|
||||
* @test
|
||||
* @bug 8048607
|
||||
* @compile ../../../com/sun/crypto/provider/Cipher/DES/TestUtility.java
|
||||
* @run main TestKGParity
|
||||
* @summary Test key generation of DES and DESEDE
|
||||
* @key randomness
|
||||
*/
|
||||
|
@ -0,0 +1,57 @@
|
||||
|
||||
/**
|
||||
* Copyright (c) 2007, 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 javax.security.auth.login.LoginContext;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8050461
|
||||
* @summary Test should throw Configuration error if configuration file contains
|
||||
* syntax error
|
||||
* @build SampleLoginModule JAASConfigSyntaxTest
|
||||
* @run main/othervm -Djava.security.auth.login.config=file:${test.src}/JAASSynWithOutApplication.config JAASConfigSyntaxTest
|
||||
* @run main/othervm -Djava.security.auth.login.config=file:${test.src}/JAASSynWithOutBraces.config JAASConfigSyntaxTest
|
||||
* @run main/othervm -Djava.security.auth.login.config=file:${test.src}/JAASSynWithOutFlag.config JAASConfigSyntaxTest
|
||||
* @run main/othervm -Djava.security.auth.login.config=file:${test.src}/JAASSynWithOutLoginModule.config JAASConfigSyntaxTest
|
||||
* @run main/othervm -Djava.security.auth.login.config=file:${test.src}/JAASSynWithOutSemiColen.config JAASConfigSyntaxTest
|
||||
*/
|
||||
public class JAASConfigSyntaxTest {
|
||||
|
||||
private static final String TEST_NAME = "JAASConfigSyntaxTest";
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
try {
|
||||
LoginContext lc = new LoginContext(TEST_NAME);
|
||||
lc.login();
|
||||
throw new RuntimeException("Test Case Failed, did not get "
|
||||
+ "expected exception");
|
||||
} catch (Exception ex) {
|
||||
if (ex.getMessage().contains("java.io.IOException: "
|
||||
+ "Configuration Error:")) {
|
||||
System.out.println("Test case passed");
|
||||
} else {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
5
jdk/test/javax/security/auth/login/JAASConfigSyntaxCheck/JAASSynWithOutApplication.config
Normal file
5
jdk/test/javax/security/auth/login/JAASConfigSyntaxCheck/JAASSynWithOutApplication.config
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
SampleLoginModule Required;
|
||||
SampleLoginModule Required;
|
||||
SampleLoginModule Required;
|
||||
};
|
@ -0,0 +1,5 @@
|
||||
JAASConfigSyntaxTest
|
||||
SampleLoginModule Required;
|
||||
SampleLoginModule Required;
|
||||
SampleLoginModule Required;
|
||||
;
|
@ -0,0 +1,5 @@
|
||||
JAASConfigSyntaxTest{
|
||||
SampleLoginModule ;
|
||||
SampleLoginModule ;
|
||||
SampleLoginModule ;
|
||||
};
|
5
jdk/test/javax/security/auth/login/JAASConfigSyntaxCheck/JAASSynWithOutLoginModule.config
Normal file
5
jdk/test/javax/security/auth/login/JAASConfigSyntaxCheck/JAASSynWithOutLoginModule.config
Normal file
@ -0,0 +1,5 @@
|
||||
JAASConfigSyntaxTest{
|
||||
;
|
||||
;
|
||||
;
|
||||
};
|
5
jdk/test/javax/security/auth/login/JAASConfigSyntaxCheck/JAASSynWithOutSemiColen.config
Normal file
5
jdk/test/javax/security/auth/login/JAASConfigSyntaxCheck/JAASSynWithOutSemiColen.config
Normal file
@ -0,0 +1,5 @@
|
||||
JAASConfigSyntaxTest{
|
||||
SampleLoginModule Required;
|
||||
SampleLoginModule Required
|
||||
SampleLoginModule Required;
|
||||
};
|
@ -0,0 +1,75 @@
|
||||
/**
|
||||
* Copyright (c) 2007, 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 static java.lang.System.out;
|
||||
import java.util.Map;
|
||||
import javax.security.auth.Subject;
|
||||
import javax.security.auth.callback.CallbackHandler;
|
||||
import javax.security.auth.login.LoginException;
|
||||
import javax.security.auth.spi.LoginModule;
|
||||
|
||||
/**
|
||||
* Login module which passes all the time
|
||||
*/
|
||||
|
||||
public class SampleLoginModule implements LoginModule {
|
||||
|
||||
private final String name;
|
||||
|
||||
public SampleLoginModule() {
|
||||
name = this.getClass().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(Subject subject, CallbackHandler callbackHandler,
|
||||
Map<String, ?> sharedState, Map<String, ?> options) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean login() throws LoginException {
|
||||
out.println(name + " Login method of AbstractLoginModule is called ");
|
||||
out.println(name + ":login:PASS");
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean commit() throws LoginException {
|
||||
out.println("Commit of AbstractLoginModule is called");
|
||||
out.println(name + ":commit:PASS");
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean abort() throws LoginException {
|
||||
out.println("Abourt is called in AbstractLoginModule");
|
||||
out.println(name + ":abort:PASS");
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean logout() throws LoginException {
|
||||
out.println("logout is called in AbstractLoginModule");
|
||||
out.println(name + ":logout:PASS");
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 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 javax.security.auth.login.LoginException;
|
||||
|
||||
/**
|
||||
* Login module which passes all the time
|
||||
*/
|
||||
|
||||
public class DummyLoginModule extends SmartLoginModule {
|
||||
private final String header;
|
||||
|
||||
public DummyLoginModule() {
|
||||
header = "DummyLoginModule: ";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean login() throws LoginException {
|
||||
System.out.println("\t\t" + header + " login method is called ");
|
||||
System.out.println("\t\t" + header + " login:PASS");
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean commit() throws LoginException {
|
||||
System.out.println("\t\t" + header + " commit method is called");
|
||||
System.out.println("\t\t" + header + " commit:PASS");
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean abort() throws LoginException {
|
||||
System.out.println("\t\t" + header + " abort method is called ");
|
||||
System.out.println("\t\t" + header + " abort:PASS");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean logout() throws LoginException {
|
||||
System.out.println("\t\t" + header + " logout method is called");
|
||||
System.out.println("\t\t" + header + " logout:PASS");
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,165 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 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.IOException;
|
||||
import javax.security.auth.Subject;
|
||||
import javax.security.auth.callback.Callback;
|
||||
import javax.security.auth.callback.CallbackHandler;
|
||||
import javax.security.auth.callback.NameCallback;
|
||||
import javax.security.auth.callback.PasswordCallback;
|
||||
import javax.security.auth.callback.UnsupportedCallbackException;
|
||||
import javax.security.auth.login.Configuration;
|
||||
import javax.security.auth.login.LoginContext;
|
||||
import javax.security.auth.login.LoginException;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8050427 4703361
|
||||
* @summary Test case for RFE: 4703361. Tests the Dynamic Configuration of
|
||||
* Authentication Modules with different methods
|
||||
* @compile SmartLoginModule.java DummyLoginModule.java MyConfiguration.java
|
||||
* @run main/othervm DynamicConfigurationTest
|
||||
*/
|
||||
public class DynamicConfigurationTest {
|
||||
|
||||
public static void main(String... args) {
|
||||
String rightConfigName = "PT";
|
||||
String wrongConfigName = "NT";
|
||||
char[] rightPwd = new char[]{'t', 'e', 's', 't', 'P', 'a', 's', 's',
|
||||
'w', 'o', 'r', 'd', '1'};
|
||||
char[] wrongPwd = new char[]{'w', 'r', 'o', 'n', 'g', 'P', 'a', 's',
|
||||
's','w', 'o', 'r', 'd'};
|
||||
|
||||
// Test with wrong configuration name
|
||||
// Expect LoginException when initiate a new LoginContext object
|
||||
testConfigName(wrongConfigName, true);
|
||||
System.out.println("Wrong Config Name Test passed ");
|
||||
|
||||
// Spedify two loginModules: SmartLoginModule and DummyLoginModule
|
||||
// Flags: required-required
|
||||
// Test with right password for SmartLoginModule
|
||||
// No exception is expected
|
||||
Configuration cf = new MyConfiguration();
|
||||
testLogin(rightConfigName, rightPwd, cf, false);
|
||||
System.out.println("Positive test passed");
|
||||
|
||||
// Spedify two loginModules: SmartLoginModule and DummyLoginModule
|
||||
// Flags: required-required
|
||||
// Test with wrong password for SmartLoginModule
|
||||
// Expect LoginException by calling LoginContext.login() method
|
||||
testLogin(rightConfigName, wrongPwd, cf, true);
|
||||
System.out.println("Should fail test passed");
|
||||
|
||||
// Spedify two loginModules: SmartLoginModule and DummyLoginModule
|
||||
// Change the flags from required-required to optional-sufficient
|
||||
// Test with wrong password for SmartLoginModule, while DummyLoginModule
|
||||
// always passes
|
||||
// No Exception is expected
|
||||
cf = new MyConfiguration(true);
|
||||
testLogin(rightConfigName, wrongPwd, cf, false);
|
||||
System.out.println("One module fails where are other module succeeeds "
|
||||
+ "Test passed with optional-sufficient flags");
|
||||
}
|
||||
|
||||
public static void testConfigName(String confName,
|
||||
boolean expectException) {
|
||||
String expectedMsg = "No LoginModules configured for " + confName;
|
||||
try {
|
||||
LoginContext lc = new LoginContext(confName, new Subject(),
|
||||
new MyCallbackHandler(), new MyConfiguration());
|
||||
|
||||
if (expectException) {
|
||||
throw new RuntimeException("Wrong Config Name Test failed: "
|
||||
+ "expected LoginException not thrown.");
|
||||
}
|
||||
} catch (LoginException le) {
|
||||
if (!expectException || !le.getMessage().equals(expectedMsg)) {
|
||||
System.out.println("Wrong Config Name Test failed: "
|
||||
+ "received Unexpected exception.");
|
||||
throw new RuntimeException(le);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void testLogin(String confName, char[] passwd,
|
||||
Configuration cf, boolean expectException) {
|
||||
try {
|
||||
CallbackHandler ch = new MyCallbackHandler("testUser", passwd);
|
||||
LoginContext lc = new LoginContext(confName, new Subject(),
|
||||
ch, cf);
|
||||
lc.login();
|
||||
if (expectException) {
|
||||
throw new RuntimeException("Login Test failed: "
|
||||
+ "expected LoginException not thrown");
|
||||
}
|
||||
} catch (LoginException le) {
|
||||
if (!expectException) {
|
||||
System.out.println("Login Test failed: "
|
||||
+ "received Unexpected exception.");
|
||||
throw new RuntimeException(le);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The application simulates the CallbackHandler. It simulates! which means all
|
||||
* process to get username and password is ignored. We have to take this
|
||||
* approach for automation purpose. So, this is not a real world example at all.
|
||||
*/
|
||||
class MyCallbackHandler implements CallbackHandler {
|
||||
|
||||
String userName;
|
||||
char[] password;
|
||||
|
||||
/**
|
||||
* This is simply a workaround approach for IO approach to get username and
|
||||
* password. For automation purpose only.
|
||||
*/
|
||||
public MyCallbackHandler() {
|
||||
super();
|
||||
}
|
||||
|
||||
public MyCallbackHandler(String username, char[] password) {
|
||||
super();
|
||||
userName = username;
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Callback[] callbacks) throws IOException,
|
||||
UnsupportedCallbackException {
|
||||
for (Callback callback : callbacks) {
|
||||
if (callback instanceof NameCallback) {
|
||||
NameCallback nc = (NameCallback) callback;
|
||||
nc.setName(userName);
|
||||
} else if (callback instanceof PasswordCallback) {
|
||||
PasswordCallback pc = (PasswordCallback) callback;
|
||||
pc.setPassword(password);
|
||||
} else {
|
||||
throw new UnsupportedCallbackException(callback,
|
||||
"Unrecognized Callback");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 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.util.HashMap;
|
||||
import javax.security.auth.login.AppConfigurationEntry;
|
||||
import static javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag.OPTIONAL;
|
||||
import static javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag.REQUIRED;
|
||||
import static javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag.SUFFICIENT;
|
||||
import javax.security.auth.login.Configuration;
|
||||
|
||||
/**
|
||||
* This class is used to test LoginContext constructor API. It simply contains
|
||||
* one configuration entry: PT.
|
||||
*/
|
||||
public class MyConfiguration extends Configuration {
|
||||
|
||||
private static final AppConfigurationEntry[] ptAE
|
||||
= new AppConfigurationEntry[2];
|
||||
private static final HashMap<String, String> map = new HashMap<>();
|
||||
private boolean optionOrder = false;
|
||||
|
||||
public MyConfiguration() {
|
||||
setupConfiguration();
|
||||
}
|
||||
|
||||
public MyConfiguration(boolean optionOrder) {
|
||||
this.optionOrder = optionOrder;
|
||||
setupConfiguration();
|
||||
}
|
||||
|
||||
private void setupConfiguration() {
|
||||
ptAE[0] = new AppConfigurationEntry("SmartLoginModule",
|
||||
optionOrder ? OPTIONAL : REQUIRED,
|
||||
map);
|
||||
ptAE[1] = new AppConfigurationEntry("DummyLoginModule",
|
||||
optionOrder ? SUFFICIENT : REQUIRED,
|
||||
map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AppConfigurationEntry[]
|
||||
getAppConfigurationEntry(String applicationName) {
|
||||
if (applicationName.equals("PT")) {
|
||||
return ptAE;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,253 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 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.security.Principal;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import javax.security.auth.Subject;
|
||||
import javax.security.auth.callback.Callback;
|
||||
import javax.security.auth.callback.CallbackHandler;
|
||||
import javax.security.auth.callback.NameCallback;
|
||||
import javax.security.auth.callback.PasswordCallback;
|
||||
import javax.security.auth.callback.UnsupportedCallbackException;
|
||||
import javax.security.auth.login.FailedLoginException;
|
||||
import javax.security.auth.login.LoginException;
|
||||
import javax.security.auth.spi.LoginModule;
|
||||
|
||||
/**
|
||||
* This code was based on JAAS demo code, small modification is made for testing
|
||||
* purpose.
|
||||
*/
|
||||
public class SmartLoginModule implements LoginModule {
|
||||
|
||||
// initial state
|
||||
private Subject subject;
|
||||
private CallbackHandler callbackHandler;
|
||||
|
||||
// the authentication status
|
||||
private boolean succeeded = false;
|
||||
private boolean commitSucceeded = false;
|
||||
|
||||
// username and password
|
||||
private String username;
|
||||
private char[] password;
|
||||
|
||||
// Default values for this login module. In real world,
|
||||
// don't do it in this way!
|
||||
private String myUsername;
|
||||
private char[] myPassword;
|
||||
private String header;
|
||||
|
||||
// testUser's SamplePrincipal
|
||||
private SamplePrincipal userPrincipal;
|
||||
|
||||
public SmartLoginModule() {
|
||||
this("testUser",
|
||||
new char[]{'t', 'e', 's', 't', 'P', 'a', 's', 's',
|
||||
'w', 'o', 'r', 'd', '1'},
|
||||
"SmartLoginModule1: ");
|
||||
}
|
||||
|
||||
public SmartLoginModule(String userName, char[] password, String header) {
|
||||
myUsername = userName;
|
||||
myPassword = password;
|
||||
this.header = header;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean abort() throws LoginException {
|
||||
if (!succeeded) {
|
||||
return false;
|
||||
} else if (succeeded && !commitSucceeded) {
|
||||
// login succeeded but overall authentication failed
|
||||
succeeded = false;
|
||||
username = null;
|
||||
password = null;
|
||||
userPrincipal = null;
|
||||
} else {
|
||||
// overall authentication succeeded and commit succeeded,
|
||||
// but someone else's commit failed
|
||||
logout();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean commit() throws LoginException {
|
||||
if (!succeeded) {
|
||||
return false;
|
||||
} else {
|
||||
// add a Principal (authenticated identity) to the Subject
|
||||
// assume the user we authenticated is the SamplePrincipal
|
||||
userPrincipal = new SamplePrincipal(username);
|
||||
if (!subject.getPrincipals().contains(userPrincipal)) {
|
||||
subject.getPrincipals().add(userPrincipal);
|
||||
}
|
||||
// in any case, clean out state
|
||||
username = null;
|
||||
password = null;
|
||||
commitSucceeded = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(Subject subject, CallbackHandler callbackHandler,
|
||||
Map<String, ?> sharedState, Map<String, ?> options) {
|
||||
this.subject = subject;
|
||||
this.callbackHandler = callbackHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean login() throws LoginException {
|
||||
if (callbackHandler == null) {
|
||||
throw new LoginException("Error: no CallbackHandler available to "
|
||||
+ "garner authentication information from the user");
|
||||
}
|
||||
|
||||
Callback[] callbacks = new Callback[2];
|
||||
callbacks[0] = new NameCallback(header + "user name: ");
|
||||
callbacks[1] = new PasswordCallback(header + "password: ", false);
|
||||
|
||||
try {
|
||||
callbackHandler.handle(callbacks);
|
||||
username = ((NameCallback) callbacks[0]).getName();
|
||||
char[] tmpPassword
|
||||
= ((PasswordCallback) callbacks[1]).getPassword();
|
||||
if (tmpPassword == null) {
|
||||
tmpPassword = new char[0];
|
||||
}
|
||||
password = new char[tmpPassword.length];
|
||||
System.arraycopy(tmpPassword, 0, password, 0, tmpPassword.length);
|
||||
((PasswordCallback) callbacks[1]).clearPassword();
|
||||
} catch (java.io.IOException ioe) {
|
||||
throw (LoginException) new LoginException().initCause(ioe);
|
||||
} catch (UnsupportedCallbackException uce) {
|
||||
throw new LoginException("Error: " + header
|
||||
+ uce.getCallback().toString()
|
||||
+ " not available to garner authentication information "
|
||||
+ "from the user");
|
||||
}
|
||||
|
||||
// verify the username/password
|
||||
if (username.equals(myUsername)
|
||||
&& Arrays.equals(password, myPassword)) {
|
||||
System.out.println("\t\t" + header + " authentication succeeded");
|
||||
succeeded = true;
|
||||
return true;
|
||||
} else {
|
||||
// authentication failed -- clean out state
|
||||
System.out.println("\t\t" + header + " authentication failed");
|
||||
printDebugInfo();
|
||||
succeeded = false;
|
||||
username = null;
|
||||
password = null;
|
||||
throw new FailedLoginException("User Name or Password Incorrect");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean logout() throws LoginException {
|
||||
subject.getPrincipals().remove(userPrincipal);
|
||||
succeeded = false;
|
||||
succeeded = commitSucceeded;
|
||||
username = null;
|
||||
password = null;
|
||||
userPrincipal = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
// print debugging information
|
||||
private void printDebugInfo() {
|
||||
System.out.println("\t\t" + header + " correct user name: "
|
||||
+ myUsername);
|
||||
System.out.println("\t\t" + header + " user entered user name: "
|
||||
+ username);
|
||||
System.out.print("\t\t" + header + " correct password: ");
|
||||
for (char c : myPassword) {
|
||||
System.out.print(c);
|
||||
}
|
||||
System.out.println();
|
||||
System.out.print("\t\t" + header + " user entered password: ");
|
||||
for (char c : password) {
|
||||
System.out.print(c);
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
|
||||
class SamplePrincipal implements Principal, java.io.Serializable {
|
||||
|
||||
/**
|
||||
* @serial
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* Create a SamplePrincipal with a Sample username.
|
||||
*
|
||||
* @param name the Sample username for this user.
|
||||
* @exception NullPointerException if the <code>name</code> is
|
||||
* <code>null</code>.
|
||||
*/
|
||||
public SamplePrincipal(String name) {
|
||||
if (name == null) {
|
||||
throw new NullPointerException("illegal null input");
|
||||
}
|
||||
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SamplePrincipal: " + name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(o instanceof SamplePrincipal)) {
|
||||
return false;
|
||||
}
|
||||
SamplePrincipal that = (SamplePrincipal) o;
|
||||
|
||||
return this.getName().equals(that.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return name.hashCode();
|
||||
}
|
||||
}
|
124
jdk/test/sun/security/TestSignatureOidHelper.java
Normal file
124
jdk/test/sun/security/TestSignatureOidHelper.java
Normal file
@ -0,0 +1,124 @@
|
||||
/*
|
||||
* 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.security.InvalidKeyException;
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.NoSuchProviderException;
|
||||
import java.security.Signature;
|
||||
import java.security.SignatureException;
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
* Utilities for testing the signature algorithm OIDs.
|
||||
*/
|
||||
public class TestSignatureOidHelper {
|
||||
|
||||
private static final byte[] INPUT = "1234567890".getBytes();
|
||||
|
||||
private final String algorithm;
|
||||
|
||||
private final String provider;
|
||||
|
||||
private final int keySize;
|
||||
|
||||
private final List<OidAlgorithmPair> data;
|
||||
|
||||
public TestSignatureOidHelper(String algorithm, String provider,
|
||||
int keySize, List<OidAlgorithmPair> data) {
|
||||
this.algorithm = algorithm;
|
||||
this.provider = provider;
|
||||
this.keySize = keySize;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public void execute() throws Exception {
|
||||
KeyPair keyPair = createKeyPair();
|
||||
for (OidAlgorithmPair oidAlgorithmPair : data) {
|
||||
runTest(oidAlgorithmPair, keyPair);
|
||||
System.out.println("passed");
|
||||
}
|
||||
System.out.println("All tests passed");
|
||||
}
|
||||
|
||||
private KeyPair createKeyPair()
|
||||
throws NoSuchAlgorithmException, NoSuchProviderException {
|
||||
KeyPairGenerator keyGen = KeyPairGenerator.getInstance(algorithm,
|
||||
provider);
|
||||
keyGen.initialize(keySize);
|
||||
return keyGen.generateKeyPair();
|
||||
}
|
||||
|
||||
private void runTest(OidAlgorithmPair oidAlgorithmPair, KeyPair keyPair)
|
||||
throws NoSuchAlgorithmException, NoSuchProviderException,
|
||||
InvalidKeyException, SignatureException {
|
||||
Signature sgAlgorithm =
|
||||
Signature.getInstance(oidAlgorithmPair.algorithm, provider);
|
||||
Signature sgOid = Signature.getInstance(oidAlgorithmPair.oid, provider);
|
||||
|
||||
if (sgAlgorithm == null) {
|
||||
throw new RuntimeException(String.format(
|
||||
"Test failed: algorithm string %s getInstance failed.%n",
|
||||
oidAlgorithmPair.algorithm));
|
||||
}
|
||||
|
||||
if (sgOid == null) {
|
||||
throw new RuntimeException(
|
||||
String.format("Test failed: OID %s getInstance failed.%n",
|
||||
oidAlgorithmPair.oid));
|
||||
}
|
||||
|
||||
if (!sgAlgorithm.getAlgorithm().equals(oidAlgorithmPair.algorithm)) {
|
||||
throw new RuntimeException(String.format(
|
||||
"Test failed: algorithm string %s getInstance "
|
||||
+ "doesn't generate expected algorithm.%n",
|
||||
oidAlgorithmPair.algorithm));
|
||||
}
|
||||
|
||||
sgAlgorithm.initSign(keyPair.getPrivate());
|
||||
sgAlgorithm.update(INPUT);
|
||||
sgOid.initVerify(keyPair.getPublic());
|
||||
sgOid.update(INPUT);
|
||||
if (!sgOid.verify(sgAlgorithm.sign())) {
|
||||
throw new RuntimeException(
|
||||
"Signature verification failed unexpectedly");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class OidAlgorithmPair {
|
||||
|
||||
public final String oid;
|
||||
public final String algorithm;
|
||||
|
||||
public OidAlgorithmPair(String oid, String algorithm) {
|
||||
this.oid = oid;
|
||||
this.algorithm = algorithm;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[oid=" + oid + ", algorithm=" + algorithm + "]";
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* 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.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8075286
|
||||
* @summary Test the SHAwithECDSA signature algorithm OIDs in JDK.
|
||||
* OID and algorithm transformation string should match.
|
||||
* Both could be able to be used to generate the algorithm instance.
|
||||
* @compile ../../TestSignatureOidHelper.java
|
||||
* @run main TestSHAwithECDSASignatureOids
|
||||
*/
|
||||
public class TestSHAwithECDSASignatureOids {
|
||||
|
||||
private static final List<OidAlgorithmPair> DATA = Arrays.asList(
|
||||
new OidAlgorithmPair("1.2.840.10045.4.1", "SHA1withECDSA"),
|
||||
new OidAlgorithmPair("1.2.840.10045.4.3.1", "SHA224withECDSA"),
|
||||
new OidAlgorithmPair("1.2.840.10045.4.3.2", "SHA256withECDSA"),
|
||||
new OidAlgorithmPair("1.2.840.10045.4.3.3", "SHA384withECDSA"),
|
||||
new OidAlgorithmPair("1.2.840.10045.4.3.4", "SHA512withECDSA"));
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
TestSignatureOidHelper helper = new TestSignatureOidHelper("EC",
|
||||
"SunEC", 256, DATA);
|
||||
helper.execute();
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user