This commit is contained in:
Lana Steuck 2015-09-26 09:21:45 -07:00
commit 02eb542660
103 changed files with 5857 additions and 1628 deletions
jdk
make/mapfiles/libjava
src
test

@ -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>&nbsp;-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 &lt;plugin-path&gt; </pre></blockquote>
*
* <p> where <tt>&lt;plugin-path&gt;</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
*/

@ -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);
}
}

@ -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);
}
}
}
}

@ -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();
}
}

@ -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;
}
}

@ -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;
}

@ -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");
}
}
}

@ -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;
}
}
}

@ -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;
}
}
}

@ -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;

@ -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);
}
}
}
}

@ -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 ;
};

@ -0,0 +1,5 @@
JAASConfigSyntaxTest{
;
;
;
};

@ -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();
}
}

@ -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