--- a/jdk/make/lib/Lib-java.management.gmk Thu Apr 09 06:40:17 2015 -0700
+++ b/jdk/make/lib/Lib-java.management.gmk Thu Apr 09 17:36:47 2015 -0700
@@ -38,6 +38,11 @@
$(LIBJAVA_HEADER_FLAGS) \
#
+# In (at least) VS2013 and later, -DPSAPI_VERSION=1 is needed to generate
+# a binary that is compatible with windows versions older than 7/2008R2.
+# See MSDN documentation for GetProcessMemoryInfo for more information.
+BUILD_LIBMANAGEMENT_CFLAGS += -DPSAPI_VERSION=1
+
BUILD_LIBMANAGEMENT_EXCLUDES :=
ifneq ($(OPENJDK_TARGET_OS), solaris)
--- a/jdk/src/java.base/share/classes/java/util/BitSet.java Thu Apr 09 06:40:17 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/util/BitSet.java Thu Apr 09 17:36:47 2015 -0700
@@ -1229,7 +1229,7 @@
public int nextInt() {
if (next != -1) {
int ret = next;
- next = nextSetBit(next+1);
+ next = (next == Integer.MAX_VALUE) ? -1 : nextSetBit(next+1);
return ret;
} else {
throw new NoSuchElementException();
--- a/jdk/src/java.base/share/classes/java/util/zip/ZipEntry.java Thu Apr 09 06:40:17 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/util/zip/ZipEntry.java Thu Apr 09 17:36:47 2015 -0700
@@ -481,6 +481,8 @@
}
break;
case EXTID_NTFS:
+ if (sz < 32) // reserved 4 bytes + tag 2 bytes + size 2 bytes
+ break; // m[a|c]time 24 bytes
int pos = off + 4; // reserved 4 bytes
if (get16(extra, pos) != 0x0001 || get16(extra, pos + 2) != 24)
break;
--- a/jdk/src/java.base/share/classes/javax/crypto/CipherInputStream.java Thu Apr 09 06:40:17 2015 -0700
+++ b/jdk/src/java.base/share/classes/javax/crypto/CipherInputStream.java Thu Apr 09 17:36:47 2015 -0700
@@ -25,7 +25,11 @@
package javax.crypto;
-import java.io.*;
+import java.io.InputStream;
+import java.io.FilterInputStream;
+import java.io.IOException;
+import javax.crypto.BadPaddingException;
+import javax.crypto.IllegalBlockSizeException;
/**
* A CipherInputStream is composed of an InputStream and a Cipher so
@@ -88,8 +92,6 @@
private int ofinish = 0;
// stream status
private boolean closed = false;
- // The stream has been read from. False if the stream has never been read.
- private boolean read = false;
/**
* private convenience function.
@@ -101,11 +103,15 @@
* return (ofinish-ostart) (we have this many bytes for you)
* return 0 (no data now, but could have more later)
* return -1 (absolutely no more data)
+ *
+ * Note: Exceptions are only thrown after the stream is completely read.
+ * For AEAD ciphers a read() of any length will internally cause the
+ * whole stream to be read fully and verify the authentication tag before
+ * returning decrypted data or exceptions.
*/
private int getMoreData() throws IOException {
if (done) return -1;
int readin = input.read(ibuffer);
- read = true;
if (readin == -1) {
done = true;
try {
@@ -301,17 +307,16 @@
closed = true;
input.close();
- try {
- // throw away the unprocessed data
- if (!done) {
+
+ // Throw away the unprocessed data and throw no crypto exceptions.
+ // AEAD ciphers are fully readed before closing. Any authentication
+ // exceptions would occur while reading.
+ if (!done) {
+ try {
cipher.doFinal();
}
- }
- catch (BadPaddingException | IllegalBlockSizeException ex) {
- /* If no data has been read from the stream to be en/decrypted,
- we supress any exceptions, and close quietly. */
- if (read) {
- throw new IOException(ex);
+ catch (BadPaddingException | IllegalBlockSizeException ex) {
+ // Catch exceptions as the rest of the stream is unused.
}
}
ostart = 0;
--- a/jdk/src/java.base/share/classes/javax/security/auth/Policy.java Thu Apr 09 06:40:17 2015 -0700
+++ b/jdk/src/java.base/share/classes/javax/security/auth/Policy.java Thu Apr 09 17:36:47 2015 -0700
@@ -322,7 +322,7 @@
* in conjunction with the provided
* {@code CodeSource}, determines the Permissions
* returned by this method. This parameter
- * may be {@code null}. <p>
+ * may be {@code null}.
*
* @param cs the code specified by its {@code CodeSource}
* that determines, in conjunction with the provided
--- a/jdk/src/java.security.jgss/share/classes/org/ietf/jgss/GSSContext.java Thu Apr 09 06:40:17 2015 -0700
+++ b/jdk/src/java.security.jgss/share/classes/org/ietf/jgss/GSSContext.java Thu Apr 09 17:36:47 2015 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -104,7 +104,7 @@
* operations on the <code>GSSContext</code> object are presented,
* including: object instantiation, setting of desired flags, context
* establishment, query of actual context flags, per-message operations on
- * application data, and finally context deletion.<p>
+ * application data, and finally context deletion.
*
* <pre>
* // Create a context using default credentials
@@ -209,7 +209,7 @@
* Some mechanism providers might require that the caller be granted
* permission to initiate a security context. A failed permission check
* might cause a {@link java.lang.SecurityException SecurityException}
- * to be thrown from this method.<p>
+ * to be thrown from this method.
*
* @return a byte[] containing the token to be sent to the
* peer. <code>null</code> indicates that no token is generated.
@@ -276,7 +276,7 @@
* to be thrown from this method.<p>
*
* The following example code demonstrates how this method might be
- * used:<p>
+ * used:
* <pre>
* InputStream is ...
* OutputStream os ...
@@ -346,7 +346,7 @@
* to be thrown from this method.<p>
*
* The following example code demonstrates how this method might be
- * used:<p>
+ * used:
* <pre>
* byte[] inToken;
* byte[] outToken;
@@ -423,7 +423,7 @@
* to be thrown from this method.<p>
*
* The following example code demonstrates how this method might be
- * used:<p>
+ * used:
* <pre>
* InputStream is ...
* OutputStream os ...
@@ -510,7 +510,7 @@
* GSS-API implementations are recommended but not required to detect
* invalid QOP values when <code>getWrapSizeLimit</code> is called.
* This routine guarantees only a maximum message size, not the
- * availability of specific QOP values for message protection.<p>
+ * availability of specific QOP values for message protection.
*
* @param qop the level of protection wrap will be asked to provide.
* @param confReq <code>true</code> if wrap will be asked to provide
@@ -595,7 +595,7 @@
*
* Since some application-level protocols may wish to use tokens
* emitted by wrap to provide "secure framing", implementations should
- * support the wrapping of zero-length messages.<p>
+ * support the wrapping of zero-length messages.
*
* @param inStream an InputStream containing the application data to be
* protected. All of the data that is available in
@@ -630,7 +630,7 @@
*
* Since some application-level protocols may wish to use tokens
* emitted by wrap to provide "secure framing", implementations should
- * support the wrapping and unwrapping of zero-length messages.<p>
+ * support the wrapping and unwrapping of zero-length messages.
*
* @param inBuf a byte array containing the wrap token received from
* peer.
@@ -679,7 +679,7 @@
*
* Other than the possible blocking behavior described above, this
* method is equivalent to the byte array based {@link #unwrap(byte[],
- * int, int, MessageProp) unwrap} method.<p>
+ * int, int, MessageProp) unwrap} method.
*
* @param inStream an InputStream that contains the wrap token generated
* by the peer.
@@ -827,7 +827,7 @@
*
* Other than the possible blocking behavior described above, this
* method is equivalent to the byte array based {@link #verifyMIC(byte[],
- * int, int, byte[], int, int, MessageProp) verifyMIC} method.<p>
+ * int, int, byte[], int, int, MessageProp) verifyMIC} method.
*
* @param tokStream an InputStream containing the token generated by the
* peer's getMIC method.
@@ -913,7 +913,7 @@
* might require mutual authentication even if the application
* doesn't. Therefore, the application should check to see if the
* request was honored with the {@link #getMutualAuthState()
- * getMutualAuthState} method.<p>
+ * getMutualAuthState} method.
*
* @param state a boolean value indicating whether mutual
* authentication should be used or not.
@@ -943,7 +943,7 @@
* MessageProp#isOldToken() MessageProp.isOldToken} methods will return
* valid results for the <code>MessageProp</code> object that is passed
* in to the <code>unwrap</code> method or the <code>verifyMIC</code>
- * method.<p>
+ * method.
*
* @param state a boolean value indicating whether replay detection
* should be enabled over the established context or not.
@@ -975,7 +975,7 @@
* {@link MessageProp#isGapToken() MessageProp.isGapToken} methods will return
* valid results for the <code>MessageProp</code> object that is passed
* in to the <code>unwrap</code> method or the <code>verifyMIC</code>
- * method.<p>
+ * method.
*
* @param state a boolean value indicating whether sequence checking
* should be enabled over the established context or not.
@@ -1001,7 +1001,7 @@
* delegation must not be used, then the mechanism will honor the
* request and delegation will not occur. This is an exception
* to the general rule that a mechanism may enable a service even if it
- * is not requested.<p>
+ * is not requested.
*
* @param state a boolean value indicating whether the credentials
* should be delegated or not.
@@ -1021,7 +1021,7 @@
*
* Not all mechanisms support anonymity for the initiator. Therefore, the
* application should check to see if the request was honored with the
- * {@link #getAnonymityState() getAnonymityState} method.<p>
+ * {@link #getAnonymityState() getAnonymityState} method.
*
* @param state a boolean value indicating if the initiator should
* be authenticated to the acceptor as an anonymous principal.
@@ -1048,7 +1048,7 @@
* object that is passed in to the <code>wrap</code> method.<p>
*
* Enabling confidentiality will also automatically enable
- * integrity.<p>
+ * integrity.
*
* @param state a boolean value indicating whether confidentiality
* should be enabled or not.
@@ -1075,7 +1075,7 @@
* the {@link #getIntegState() getIntegState} method.<p>
*
* Disabling integrity will also automatically disable
- * confidentiality.<p>
+ * confidentiality.
*
* @param state a boolean value indicating whether integrity
* should be enabled or not.
@@ -1095,7 +1095,7 @@
*
* The actual lifetime of the context will depend on the capabilities of
* the underlying mechanism and the application should call the {@link
- * #getLifetime() getLifetime} method to determine this.<p>
+ * #getLifetime() getLifetime} method to determine this.
*
* @param lifetime the desired context lifetime in seconds. Use
* <code>INDEFINITE_LIFETIME</code> to request an indefinite lifetime
@@ -1133,7 +1133,7 @@
* initiator requests that delegation not be allowed the {@link
* #requestCredDeleg(boolean) requestCredDeleg} method will honor that
* request and this method will return <code>false</code> on the
- * initiator's side from that point onwards. <p>
+ * initiator's side from that point onwards.
*
* @return true if delegation is enabled, false otherwise.
* @see #requestCredDeleg(boolean)
@@ -1147,7 +1147,7 @@
* called only after context establishment is complete. An initiator
* that requests mutual authentication can call this method after
* context completion and dispose the context if its request was not
- * honored.<p>
+ * honored.
*
* @return true if mutual authentication is enabled, false otherwise.
* @see #requestMutualAuth(boolean)
@@ -1161,7 +1161,7 @@
* definitive answer this method must be called only after context
* establishment is complete. An initiator that requests replay
* detection can call this method after context completion and
- * dispose the context if its request was not honored.<p>
+ * dispose the context if its request was not honored.
*
* @return true if replay detection is enabled, false otherwise.
* @see #requestReplayDet(boolean)
@@ -1175,7 +1175,7 @@
* definitive answer this method must be called only after context
* establishment is complete. An initiator that requests sequence
* checking can call this method after context completion and
- * dispose the context if its request was not honored.<p>
+ * dispose the context if its request was not honored.
*
* @return true if sequence checking is enabled, false otherwise.
* @see #requestSequenceDet(boolean)
@@ -1195,7 +1195,7 @@
* should be sent to the peer or the context aborted.</strong> On the
* acceptor side, a call to this method determines if any of the tokens
* processed by <code>acceptSecContext</code> thus far have divulged
- * the identity of the initiator.<p>
+ * the identity of the initiator.
*
* @return true if the context initiator is still anonymous, false
* otherwise.
@@ -1235,7 +1235,7 @@
* #isProtReady() isProtReady} or {@link #isEstablished()
* isEstablished} return <code>true</code>. If this method returns
* <code>true</code>, so will {@link #getIntegState()
- * getIntegState}<p>
+ * getIntegState}
*
* @return true if confidentiality services are available, false
* otherwise.
@@ -1250,7 +1250,7 @@
* #isProtReady() isProtReady} or {@link #isEstablished()
* isEstablished} return <code>true</code>. This method will always
* return <code>true</code> if {@link #getConfState() getConfState}
- * returns true.<p>
+ * returns true.
*
* @return true if integrity services are available, false otherwise.
* @see #requestInteg(boolean)
@@ -1262,7 +1262,7 @@
* context is. It can be called by both the context initiator and the
* context acceptor, but for a definitive answer it should be called
* only after {@link #isEstablished() isEstablished} returns
- * true.<p>
+ * true.
*
* @return the remaining lifetime in seconds
* @see #requestLifetime(int)
--- a/jdk/src/java.security.jgss/share/classes/org/ietf/jgss/GSSCredential.java Thu Apr 09 06:40:17 2015 -0700
+++ b/jdk/src/java.security.jgss/share/classes/org/ietf/jgss/GSSCredential.java Thu Apr 09 17:36:47 2015 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -57,7 +57,7 @@
*
* This example code demonstrates the creation of a GSSCredential
* implementation for a specific entity, querying of its fields, and its
- * release when it is no longer needed:<p>
+ * release when it is no longer needed:
* <pre>
* GSSManager manager = GSSManager.getInstance();
*
--- a/jdk/src/java.security.jgss/share/classes/org/ietf/jgss/GSSException.java Thu Apr 09 06:40:17 2015 -0700
+++ b/jdk/src/java.security.jgss/share/classes/org/ietf/jgss/GSSException.java Thu Apr 09 17:36:47 2015 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -34,7 +34,7 @@
* mechanism implementation is responsible for setting appropriate minor
* status codes when throwing this exception. Aside from delivering the
* numeric error codes to the caller, this class performs the mapping from
- * their numeric values to textual representations. <p>
+ * their numeric values to textual representations.
*
* @author Mayank Upadhyay
* @since 1.4
--- a/jdk/src/java.security.jgss/share/classes/org/ietf/jgss/GSSManager.java Thu Apr 09 06:40:17 2015 -0700
+++ b/jdk/src/java.security.jgss/share/classes/org/ietf/jgss/GSSManager.java Thu Apr 09 17:36:47 2015 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -55,7 +55,7 @@
* of this and recover cleanly by catching the exception.<p>
*
* It is envisioned that there will be three most common ways in which
- * providers will be used:<p>
+ * providers will be used:
* <ol>
* <li> The application does not care about what provider is used (the
* default case).
@@ -87,7 +87,7 @@
* the <code>addProviderAtFront</code> method on a GSSManager that has
* already created an object.<p>
*
- * Here is some sample code showing how the GSSManager might be used: <p>
+ * Here is some sample code showing how the GSSManager might be used:
* <pre>
* GSSManager manager = GSSManager.getInstance();
*
@@ -116,7 +116,7 @@
* GSSContext.DEFAULT_LIFETIME);
* </pre><p>
*
- * The server side might use the following variation of this source:<p>
+ * The server side might use the following variation of this source:
*
* <pre>
* // Acquire credentials for the server
@@ -387,7 +387,7 @@
* Non-default values for lifetime cannot always be honored by the
* underlying mechanisms, thus applications should be prepared to call
* {@link GSSCredential#getRemainingLifetime() getRemainingLifetime}
- * on the returned credential.<p>
+ * on the returned credential.
*
* @param name the name of the principal for whom this credential is to be
* acquired. Use <code>null</code> to specify the default principal.
@@ -442,7 +442,7 @@
* Non-default values for lifetime cannot always be honored by the
* underlying mechanisms, thus applications should be prepared to call
* {@link GSSCredential#getRemainingLifetime() getRemainingLifetime}
- * on the returned credential.<p>
+ * on the returned credential.
*
* @param name the name of the principal for whom this credential is to
* be acquired. Use <code>null</code> to specify the default
@@ -492,7 +492,7 @@
* Non-default values for lifetime cannot always be honored by the
* underlying mechanism, thus applications should be prepared to call
* {@link GSSContext#getLifetime() getLifetime} on the returned
- * context.<p>
+ * context.
*
* @param peer the name of the target peer.
* @param mech the Oid of the desired mechanism. Use <code>null</code>
@@ -610,7 +610,7 @@
* operation is unavailable.<p>
*
* Suppose an application desired that the provider A always be checked
- * first when any mechanism is needed, it would call:<p>
+ * first when any mechanism is needed, it would call:
* <pre>
* GSSManager mgr = GSSManager.getInstance();
* // mgr may at this point have its own pre-configured list
@@ -621,7 +621,7 @@
* </pre>
* Now if it also desired that the mechanism of Oid m1 always be
* obtained from the provider B before the previously set A was checked,
- * it would call:<p>
+ * it would call:
* <pre>
* mgr.addProviderAtFront(B, m1);
* </pre>
@@ -632,7 +632,7 @@
* directly.<p>
*
* Suppose at a later time the following call is made to the same
- * GSSManager instance:<p>
+ * GSSManager instance:
* <pre>
* mgr.addProviderAtFront(B, null)
* </pre>
@@ -684,14 +684,14 @@
* Suppose an application desired that when a mechanism of Oid m1 is
* needed the system default providers always be checked first, and only
* when they do not support m1 should a provider A be checked. It would
- * then make the call:<p>
+ * then make the call:
* <pre>
* GSSManager mgr = GSSManager.getInstance();
* mgr.addProviderAtEnd(A, m1);
* </pre>
* Now, if it also desired that for all mechanisms the provider B be
* checked after all configured providers have been checked, it would
- * then call:<p>
+ * then call:
* <pre>
* mgr.addProviderAtEnd(B, null);
* </pre>
@@ -699,7 +699,7 @@
* null)}.<p>
*
* Suppose at a later time the following call is made to the same
- * GSSManager instance:<p>
+ * GSSManager instance:
* <pre>
* mgr.addProviderAtEnd(B, m2)
* </pre>
@@ -708,7 +708,7 @@
* request is made for the already existing pairs of (A, m1) or (B,
* null).<p>
*
- * Please note, however, that the following call:<p>
+ * Please note, however, that the following call:
* <pre>
* mgr.addProviderAtEnd(A, null)
* </pre>
--- a/jdk/src/java.security.jgss/share/classes/org/ietf/jgss/GSSName.java Thu Apr 09 06:40:17 2015 -0700
+++ b/jdk/src/java.security.jgss/share/classes/org/ietf/jgss/GSSName.java Thu Apr 09 17:36:47 2015 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -48,7 +48,7 @@
* The code below creates a <code>GSSName</code>, converts it to an MN, performs a
* comparison, obtains a printable representation of the name, exports it
* to a byte array and then re-imports to obtain a
- * new <code>GSSName</code>.<p>
+ * new <code>GSSName</code>.
* <pre>
* GSSManager manager = GSSManager.getInstance();
*
@@ -236,7 +236,8 @@
* method {@link GSSManager#createName(byte[], Oid)
* GSSManager.createName} and specifying the NT_EXPORT_NAME as the name
* type object identifier. The resulting <code>GSSName</code> name will
- * also be a MN.<p>
+ * also be a MN.
+ *
* @return a byte[] containing the exported name. RFC 2743 defines the
* "Mechanism-Independent Exported Name Object Format" for these bytes.
*
--- a/jdk/src/java.security.jgss/share/classes/org/ietf/jgss/MessageProp.java Thu Apr 09 06:40:17 2015 -0700
+++ b/jdk/src/java.security.jgss/share/classes/org/ietf/jgss/MessageProp.java Thu Apr 09 17:36:47 2015 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2001, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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,7 +42,7 @@
* <code>false</code>. Upon return from these methods, this object will also
* contain any supplementary status values applicable to the processed
* token. The supplementary status values can indicate old tokens, out
- * of sequence tokens, gap tokens or duplicate tokens.<p>
+ * of sequence tokens, gap tokens or duplicate tokens.
*
* @see GSSContext#wrap
* @see GSSContext#unwrap
--- a/jdk/src/java.security.jgss/share/classes/org/ietf/jgss/package.html Thu Apr 09 06:40:17 2015 -0700
+++ b/jdk/src/java.security.jgss/share/classes/org/ietf/jgss/package.html Thu Apr 09 17:36:47 2015 -0700
@@ -2,7 +2,7 @@
<html>
<head>
<!--
-Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+Copyright (c) 2000, 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
@@ -55,10 +55,10 @@
The GSS-API does not perform any communication with the peer. It merely
produces tokens that the application must somehow transport to the
- other end.<p>
+ other end.
<h3>Credential Acquisition</h3>
-<a name=useSubjectCredsOnly>
+<a name=useSubjectCredsOnly></a>
The GSS-API itself does not dictate how an underlying mechanism
obtains the credentials that are needed for authentication. It is
assumed that prior to calling the GSS-API, these credentials are
@@ -97,7 +97,6 @@
the provider is free to use any credentials cache of its choice. Such
a credential cache might be a disk cache, an in-memory cache, or even
just the current Subject itself.
-</a>
<h2>Related Documentation</h2>
<p>
--- a/jdk/src/jdk.dev/share/classes/jdk/tools/jimage/JImageTask.java Thu Apr 09 06:40:17 2015 -0700
+++ b/jdk/src/jdk.dev/share/classes/jdk/tools/jimage/JImageTask.java Thu Apr 09 17:36:47 2015 -0700
@@ -269,11 +269,11 @@
return 0L;
}
- String name = pathString.substring(chop).replace('\\','/');
-
File file = path.toFile();
if (file.isFile()) {
+ String name = pathString.substring(chop).replace(File.separatorChar, '/');
+
if (options.verbose) {
log.println(name);
}
@@ -310,7 +310,7 @@
for (File file : files) {
try {
Path path = file.toPath();
- String name = path.toString();
+ String name = path.toString().replace(File.separatorChar, '/');
if (name.endsWith(MODULES_ENTRY) || name.endsWith(PACKAGES_ENTRY)) {
for (String line: Files.readAllLines(path)) {
--- a/jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java Thu Apr 09 06:40:17 2015 -0700
+++ b/jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java Thu Apr 09 17:36:47 2015 -0700
@@ -2271,6 +2271,8 @@
}
break;
case EXTID_NTFS:
+ if (sz < 32)
+ break;
pos += 4; // reserved 4 bytes
if (SH(extra, pos) != 0x0001)
break;
--- a/jdk/test/ProblemList.txt Thu Apr 09 06:40:17 2015 -0700
+++ b/jdk/test/ProblemList.txt Thu Apr 09 17:36:47 2015 -0700
@@ -251,6 +251,64 @@
# 8026393
sun/security/tools/jarsigner/warnings/BadKeyUsageTest.java generic-all
+# 8077138: Some PKCS11 tests fail because NSS library is not initialized
+sun/security/pkcs11/Cipher/ReinitCipher.java windows-all
+sun/security/pkcs11/Cipher/TestPKCS5PaddingError.java windows-all
+sun/security/pkcs11/Cipher/TestRSACipher.java windows-all
+sun/security/pkcs11/Cipher/TestRSACipherWrap.java windows-all
+sun/security/pkcs11/Cipher/TestRawRSACipher.java windows-all
+sun/security/pkcs11/Cipher/TestSymmCiphers.java windows-all
+sun/security/pkcs11/Cipher/TestSymmCiphersNoPad.java windows-all
+sun/security/pkcs11/KeyAgreement/TestDH.java windows-all
+sun/security/pkcs11/KeyAgreement/TestInterop.java windows-all
+sun/security/pkcs11/KeyAgreement/TestShort.java windows-all
+sun/security/pkcs11/KeyGenerator/DESParity.java windows-all
+sun/security/pkcs11/KeyGenerator/TestKeyGenerator.java windows-all
+sun/security/pkcs11/KeyPairGenerator/TestDH2048.java windows-all
+sun/security/pkcs11/KeyStore/SecretKeysBasic.sh windows-all
+sun/security/pkcs11/Mac/MacKAT.java windows-all
+sun/security/pkcs11/Mac/MacSameTest.java windows-all
+sun/security/pkcs11/Mac/ReinitMac.java windows-all
+sun/security/pkcs11/MessageDigest/ByteBuffers.java windows-all
+sun/security/pkcs11/MessageDigest/DigestKAT.java windows-all
+sun/security/pkcs11/MessageDigest/ReinitDigest.java windows-all
+sun/security/pkcs11/MessageDigest/TestCloning.java windows-all
+sun/security/pkcs11/Provider/ConfigQuotedString.sh windows-all
+sun/security/pkcs11/Provider/Login.sh windows-all
+sun/security/pkcs11/SampleTest.java windows-all
+sun/security/pkcs11/Secmod/AddPrivateKey.java windows-all
+sun/security/pkcs11/Secmod/AddTrustedCert.java windows-all
+sun/security/pkcs11/Secmod/Crypto.java windows-all
+sun/security/pkcs11/Secmod/GetPrivateKey.java windows-all
+sun/security/pkcs11/Secmod/JksSetPrivateKey.java windows-all
+sun/security/pkcs11/SecureRandom/Basic.java windows-all
+sun/security/pkcs11/SecureRandom/TestDeserialization.java windows-all
+sun/security/pkcs11/Serialize/SerializeProvider.java windows-all
+sun/security/pkcs11/Signature/ByteBuffers.java windows-all
+sun/security/pkcs11/Signature/ReinitSignature.java windows-all
+sun/security/pkcs11/Signature/TestDSA.java windows-all
+sun/security/pkcs11/Signature/TestDSAKeyLength.java windows-all
+sun/security/pkcs11/Signature/TestRSAKeyLength.java windows-all
+sun/security/pkcs11/ec/ReadCertificates.java windows-all
+sun/security/pkcs11/ec/ReadPKCS12.java windows-all
+sun/security/pkcs11/ec/TestCurves.java windows-all
+sun/security/pkcs11/ec/TestECDH.java windows-all
+sun/security/pkcs11/ec/TestECDH2.java windows-all
+sun/security/pkcs11/ec/TestECDSA.java windows-all
+sun/security/pkcs11/ec/TestECDSA2.java windows-all
+sun/security/pkcs11/ec/TestECGenSpec.java windows-all
+sun/security/pkcs11/rsa/KeyWrap.java windows-all
+sun/security/pkcs11/rsa/TestCACerts.java windows-all
+sun/security/pkcs11/rsa/TestKeyFactory.java windows-all
+sun/security/pkcs11/rsa/TestKeyPairGenerator.java windows-all
+sun/security/pkcs11/rsa/TestSignatures.java windows-all
+sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java windows-all
+sun/security/pkcs11/tls/TestKeyMaterial.java windows-all
+sun/security/pkcs11/tls/TestLeadingZeroesP11.java windows-all
+sun/security/pkcs11/tls/TestMasterSecret.java windows-all
+sun/security/pkcs11/tls/TestPRF.java windows-all
+sun/security/pkcs11/tls/TestPremaster.java windows-all
+
############################################################################
# jdk_sound
--- a/jdk/test/java/util/BitSet/BitSetStreamTest.java Thu Apr 09 06:40:17 2015 -0700
+++ b/jdk/test/java/util/BitSet/BitSetStreamTest.java Thu Apr 09 17:36:47 2015 -0700
@@ -43,7 +43,7 @@
/**
* @test
* @summary test BitSet stream
- * @bug 8012645
+ * @bug 8012645 8076442
* @run testng BitSetStreamTest
*/
public class BitSetStreamTest {
@@ -70,6 +70,7 @@
{ "step 5", IntStream.range(0, 255).map(f -> f * 5) },
{ "step 7", IntStream.range(0, 255).map(f -> f * 7) },
{ "1, 10, 100, 1000", IntStream.of(1, 10, 100, 1000) },
+ { "max int", IntStream.of(Integer.MAX_VALUE) },
{ "25 fibs", IntStream.generate(new Fibs()).limit(25) }
};
@@ -106,6 +107,8 @@
for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i+1)) {
assertTrue(it.hasNext());
assertEquals(it.nextInt(), i);
+ if (i == Integer.MAX_VALUE)
+ break; // or (i+1) would overflow
}
assertFalse(it.hasNext());
}
--- a/jdk/test/java/util/zip/TestExtraTime.java Thu Apr 09 06:40:17 2015 -0700
+++ b/jdk/test/java/util/zip/TestExtraTime.java Thu Apr 09 17:36:47 2015 -0700
@@ -23,7 +23,7 @@
/**
* @test
- * @bug 4759491 6303183 7012868 8015666 8023713 8068790
+ * @bug 4759491 6303183 7012868 8015666 8023713 8068790 8076641
* @summary Test ZOS and ZIS timestamp in extra field correctly
*/
@@ -40,7 +40,6 @@
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
-
public class TestExtraTime {
public static void main(String[] args) throws Throwable{
@@ -71,6 +70,7 @@
}
testNullHandling();
+ testTagOnlyHandling();
testTimeConversions();
}
@@ -208,4 +208,42 @@
}
}
}
+
+ static void check(ZipEntry ze, byte[] extra) {
+ if (extra != null) {
+ byte[] extra1 = ze.getExtra();
+ if (extra1 == null || extra1.length < extra.length ||
+ !Arrays.equals(Arrays.copyOfRange(extra1,
+ extra1.length - extra.length,
+ extra1.length),
+ extra)) {
+ throw new RuntimeException("Timestamp: storing extra field failed!");
+ }
+ }
+ }
+
+ static void testTagOnlyHandling() throws Throwable {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ byte[] extra = new byte[] { 0x0a, 0, 4, 0, 0, 0, 0, 0 };
+ try (ZipOutputStream zos = new ZipOutputStream(baos)) {
+ ZipEntry ze = new ZipEntry("TestExtraTime.java");
+ ze.setExtra(extra);
+ zos.putNextEntry(ze);
+ zos.write(new byte[] { 1,2 ,3, 4});
+ }
+ try (ZipInputStream zis = new ZipInputStream(
+ new ByteArrayInputStream(baos.toByteArray()))) {
+ ZipEntry ze = zis.getNextEntry();
+ check(ze, extra);
+ }
+ Path zpath = Paths.get(System.getProperty("test.dir", "."),
+ "TestExtraTime.zip");
+ Files.copy(new ByteArrayInputStream(baos.toByteArray()), zpath);
+ try (ZipFile zf = new ZipFile(zpath.toFile())) {
+ ZipEntry ze = zf.getEntry("TestExtraTime.java");
+ check(ze, extra);
+ } finally {
+ Files.delete(zpath);
+ }
+ }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/crypto/Cipher/CipherInputStreamExceptions.java Thu Apr 09 17:36:47 2015 -0700
@@ -0,0 +1,415 @@
+/*
+ * 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 8064546
+ * @summary Throw exceptions during reading but not closing of a
+ * CipherInputStream:
+ * - Make sure authenticated algorithms continue to throwing exceptions
+ * when the authentication tag fails verification.
+ * - Make sure other algorithms do not throw exceptions when the stream
+ * calls close() and only throw when read() errors.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.lang.Exception;
+import java.lang.RuntimeException;
+import java.lang.Throwable;
+import java.security.AlgorithmParameters;
+import javax.crypto.AEADBadTagException;
+import javax.crypto.Cipher;
+import javax.crypto.CipherInputStream;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+import javax.crypto.spec.GCMParameterSpec;
+
+public class CipherInputStreamExceptions {
+
+ static SecretKeySpec key = new SecretKeySpec(new byte[16], "AES");
+ static GCMParameterSpec gcmspec = new GCMParameterSpec(128, new byte[16]);
+ static IvParameterSpec iv = new IvParameterSpec(new byte[16]);
+ static boolean failure = false;
+
+ /* Full read stream, check that getMoreData() is throwing an exception
+ * This test
+ * 1) Encrypt 100 bytes with AES/GCM/PKCS5Padding
+ * 2) Changes the last byte to invalidate the authetication tag.
+ * 3) Fully reads CipherInputStream to decrypt the message and closes
+ */
+
+ static void gcm_AEADBadTag() throws Exception {
+ Cipher c;
+ byte[] read = new byte[200];
+
+ System.out.println("Running gcm_AEADBadTag");
+
+ // Encrypt 100 bytes with AES/GCM/PKCS5Padding
+ byte[] ct = encryptedText("GCM", 100);
+ // Corrupt the encrypted message
+ ct = corruptGCM(ct);
+ // Create stream for decryption
+ CipherInputStream in = getStream("GCM", ct);
+
+ try {
+ int size = in.read(read);
+ throw new RuntimeException("Fail: CipherInputStream.read() " +
+ "returned " + size + " and didn't throw an exception.");
+ } catch (IOException e) {
+ Throwable ec = e.getCause();
+ if (ec instanceof AEADBadTagException) {
+ System.out.println(" Pass.");
+ } else {
+ System.out.println(" Fail: " + ec.getMessage());
+ throw new RuntimeException(ec);
+ }
+ } finally {
+ in.close();
+ }
+ }
+
+ /* Short read stream,
+ * This test
+ * 1) Encrypt 100 bytes with AES/GCM/PKCS5Padding
+ * 2) Reads 100 bytes from stream to decrypt the message and closes
+ * 3) Make sure no value is returned by read()
+ * 4) Make sure no exception is thrown
+ */
+
+ static void gcm_shortReadAEAD() throws Exception {
+ Cipher c;
+ byte[] read = new byte[100];
+
+ System.out.println("Running gcm_shortReadAEAD");
+
+ byte[] pt = new byte[600];
+ pt[0] = 1;
+ // Encrypt provided 600 bytes with AES/GCM/PKCS5Padding
+ byte[] ct = encryptedText("GCM", pt);
+ // Create stream for decryption
+ CipherInputStream in = getStream("GCM", ct);
+
+ int size = 0;
+ try {
+ size = in.read(read);
+ in.close();
+ if (read.length != 100) {
+ throw new RuntimeException("Fail: read size = " + read.length +
+ "should be 100.");
+ }
+ if (read[0] != 1) {
+ throw new RuntimeException("Fail: The decrypted text does " +
+ "not match the plaintext: '" + read[0] +"'");
+ }
+ } catch (IOException e) {
+ System.out.println(" Fail: " + e.getMessage());
+ throw new RuntimeException(e.getCause());
+ }
+ System.out.println(" Pass.");
+ }
+
+ /*
+ * Verify doFinal() exception is suppressed when input stream is not
+ * read before it is closed.
+ * This test:
+ * 1) Encrypt 100 bytes with AES/GCM/PKCS5Padding
+ * 2) Changes the last byte to invalidate the authetication tag.
+ * 3) Opens a CipherInputStream and the closes it. Never reads from it.
+ *
+ * There should be no exception thrown.
+ */
+ static void gcm_suppressUnreadCorrupt() throws Exception {
+ Cipher c;
+ byte[] read = new byte[200];
+
+ System.out.println("Running supressUnreadCorrupt test");
+
+ // Encrypt 100 bytes with AES/GCM/PKCS5Padding
+ byte[] ct = encryptedText("GCM", 100);
+ // Corrupt the encrypted message
+ ct = corruptGCM(ct);
+ // Create stream for decryption
+ CipherInputStream in = getStream("GCM", ct);
+
+ try {
+ in.close();
+ System.out.println(" Pass.");
+ } catch (IOException e) {
+ System.out.println(" Fail: " + e.getMessage());
+ throw new RuntimeException(e.getCause());
+ }
+ }
+
+ /*
+ * Verify noexception thrown when 1 byte is read from a GCM stream
+ * and then closed
+ * This test:
+ * 1) Encrypt 100 bytes with AES/GCM/PKCS5Padding
+ * 2) Read one byte from the stream, expect no exception thrown.
+ * 4) Close stream,expect no exception thrown.
+ */
+ static void gcm_oneReadByte() throws Exception {
+
+ System.out.println("Running gcm_oneReadByte test");
+
+ // Encrypt 100 bytes with AES/GCM/PKCS5Padding
+ byte[] ct = encryptedText("GCM", 100);
+ // Create stream for decryption
+ CipherInputStream in = getStream("GCM", ct);
+
+ try {
+ in.read();
+ System.out.println(" Pass.");
+ } catch (Exception e) {
+ System.out.println(" Fail: " + e.getMessage());
+ throw new RuntimeException(e.getCause());
+ }
+ }
+
+ /*
+ * Verify exception thrown when 1 byte is read from a corrupted GCM stream
+ * and then closed
+ * This test:
+ * 1) Encrypt 100 bytes with AES/GCM/PKCS5Padding
+ * 2) Changes the last byte to invalidate the authetication tag.
+ * 3) Read one byte from the stream, expect exception thrown.
+ * 4) Close stream,expect no exception thrown.
+ */
+ static void gcm_oneReadByteCorrupt() throws Exception {
+
+ System.out.println("Running gcm_oneReadByteCorrupt test");
+
+ // Encrypt 100 bytes with AES/GCM/PKCS5Padding
+ byte[] ct = encryptedText("GCM", 100);
+ // Corrupt the encrypted message
+ ct = corruptGCM(ct);
+ // Create stream for decryption
+ CipherInputStream in = getStream("GCM", ct);
+
+ try {
+ in.read();
+ System.out.println(" Fail. No exception thrown.");
+ } catch (IOException e) {
+ Throwable ec = e.getCause();
+ if (ec instanceof AEADBadTagException) {
+ System.out.println(" Pass.");
+ } else {
+ System.out.println(" Fail: " + ec.getMessage());
+ throw new RuntimeException(ec);
+ }
+ }
+ }
+
+ /* Check that close() does not throw an exception with full message in
+ * CipherInputStream's ibuffer.
+ * This test:
+ * 1) Encrypts a 97 byte message with AES/CBC/PKCS5Padding
+ * 2) Create a stream that sends 96 bytes.
+ * 3) Read stream once,
+ * 4) Close and expect no exception
+ */
+
+ static void cbc_shortStream() throws Exception {
+ Cipher c;
+ AlgorithmParameters params;
+ byte[] read = new byte[200];
+
+ System.out.println("Running cbc_shortStream");
+
+ // Encrypt 97 byte with AES/CBC/PKCS5Padding
+ byte[] ct = encryptedText("CBC", 97);
+ // Create stream with only 96 bytes of encrypted data
+ CipherInputStream in = getStream("CBC", ct, 96);
+
+ try {
+ int size = in.read(read);
+ in.close();
+ if (size != 80) {
+ throw new RuntimeException("Fail: CipherInputStream.read() " +
+ "returned " + size + ". Should have been 80");
+ }
+ System.out.println(" Pass.");
+ } catch (IOException e) {
+ System.out.println(" Fail: " + e.getMessage());
+ throw new RuntimeException(e.getCause());
+ }
+ }
+
+ /* Check that close() does not throw an exception when the whole message is
+ * inside the internal buffer (ibuffer) in CipherInputStream and we read
+ * one byte and close the stream.
+ * This test:
+ * 1) Encrypts a 400 byte message with AES/CBC/PKCS5Padding
+ * 2) Read one byte from the stream
+ * 3) Close and expect no exception
+ */
+
+ static void cbc_shortRead400() throws Exception {
+ System.out.println("Running cbc_shortRead400");
+
+ // Encrypt 400 byte with AES/CBC/PKCS5Padding
+ byte[] ct = encryptedText("CBC", 400);
+ // Create stream with encrypted data
+ CipherInputStream in = getStream("CBC", ct);
+
+ try {
+ in.read();
+ in.close();
+ System.out.println(" Pass.");
+ } catch (IOException e) {
+ System.out.println(" Fail: " + e.getMessage());
+ throw new RuntimeException(e.getCause());
+ }
+ }
+
+ /* Check that close() does not throw an exception when the inside the
+ * internal buffer (ibuffer) in CipherInputStream does not contain the
+ * whole message.
+ * This test:
+ * 1) Encrypts a 600 byte message with AES/CBC/PKCS5Padding
+ * 2) Read one byte from the stream
+ * 3) Close and expect no exception
+ */
+
+ static void cbc_shortRead600() throws Exception {
+ System.out.println("Running cbc_shortRead600");
+
+ // Encrypt 600 byte with AES/CBC/PKCS5Padding
+ byte[] ct = encryptedText("CBC", 600);
+ // Create stream with encrypted data
+ CipherInputStream in = getStream("CBC", ct);
+
+ try {
+ in.read();
+ in.close();
+ System.out.println(" Pass.");
+ } catch (IOException e) {
+ System.out.println(" Fail: " + e.getMessage());
+ throw new RuntimeException(e.getCause());
+ }
+ }
+
+ /* Check that exception is thrown when message is fully read
+ * This test:
+ * 1) Encrypts a 96 byte message with AES/CBC/PKCS5Padding
+ * 2) Create a stream that sends 95 bytes.
+ * 3) Read stream to the end
+ * 4) Expect IllegalBlockSizeException thrown
+ */
+
+ static void cbc_readAllIllegalBlockSize() throws Exception {
+ byte[] read = new byte[200];
+
+ System.out.println("Running cbc_readAllIllegalBlockSize test");
+
+ // Encrypt 96 byte with AES/CBC/PKCS5Padding
+ byte[] ct = encryptedText("CBC", 96);
+ // Create a stream with only 95 bytes of encrypted data
+ CipherInputStream in = getStream("CBC", ct, 95);
+
+ try {
+ int s, size = 0;
+ while ((s = in.read(read)) != -1) {
+ size += s;
+ }
+ throw new RuntimeException("Fail: No IllegalBlockSizeException. " +
+ "CipherInputStream.read() returned " + size);
+
+ } catch (IOException e) {
+ Throwable ec = e.getCause();
+ if (ec instanceof IllegalBlockSizeException) {
+ System.out.println(" Pass.");
+ } else {
+ System.out.println(" Fail: " + ec.getMessage());
+ throw new RuntimeException(ec);
+ }
+ }
+ }
+
+ /* Generic method to create encrypted text */
+ static byte[] encryptedText(String mode, int length) throws Exception{
+ return encryptedText(mode, new byte[length]);
+ }
+
+ /* Generic method to create encrypted text */
+ static byte[] encryptedText(String mode, byte[] pt) throws Exception{
+ Cipher c;
+ if (mode.compareTo("GCM") == 0) {
+ c = Cipher.getInstance("AES/GCM/PKCS5Padding", "SunJCE");
+ c.init(Cipher.ENCRYPT_MODE, key, gcmspec);
+ } else if (mode.compareTo("CBC") == 0) {
+ c = Cipher.getInstance("AES/CBC/PKCS5Padding", "SunJCE");
+ c.init(Cipher.ENCRYPT_MODE, key, iv);
+ } else {
+ return null;
+ }
+
+ return c.doFinal(pt);
+ }
+
+ /* Generic method to get a properly setup CipherInputStream */
+ static CipherInputStream getStream(String mode, byte[] ct) throws Exception {
+ return getStream(mode, ct, ct.length);
+ }
+
+ /* Generic method to get a properly setup CipherInputStream */
+ static CipherInputStream getStream(String mode, byte[] ct, int length)
+ throws Exception {
+ Cipher c;
+
+ if (mode.compareTo("GCM") == 0) {
+ c = Cipher.getInstance("AES/GCM/PKCS5Padding", "SunJCE");
+ c.init(Cipher.DECRYPT_MODE, key, gcmspec);
+ } else if (mode.compareTo("CBC") == 0) {
+ c = Cipher.getInstance("AES/CBC/PKCS5Padding", "SunJCE");
+ c.init(Cipher.DECRYPT_MODE, key, iv);
+ } else {
+ return null;
+ }
+
+ return new CipherInputStream(new ByteArrayInputStream(ct, 0, length), c);
+
+ }
+
+ /* Generic method for corrupting a GCM message. Change the last
+ * byte on of the authentication tag
+ */
+ static byte[] corruptGCM(byte[] ct) {
+ ct[ct.length - 1] = (byte) (ct[ct.length - 1] + 1);
+ return ct;
+ }
+
+ public static void main(String[] args) throws Exception {
+ gcm_AEADBadTag();
+ gcm_shortReadAEAD();
+ gcm_suppressUnreadCorrupt();
+ gcm_oneReadByte();
+ gcm_oneReadByteCorrupt();
+ cbc_shortStream();
+ cbc_shortRead400();
+ cbc_shortRead600();
+ cbc_readAllIllegalBlockSize();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/jdk/internal/jimage/JImageTest.java Thu Apr 09 17:36:47 2015 -0700
@@ -0,0 +1,158 @@
+/*
+ * 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
+ * @summary Test to see if jimage tool extracts and recreates correctly.
+ * @run main/timeout=360 JImageTest
+ */
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+/**
+ * Basic test for jimage tool.
+ */
+public class JImageTest {
+ private static Runtime runtime = Runtime.getRuntime();
+ private static int errors = 0;
+
+ static class Tool {
+ private int exit = 0;
+ private String out = "";
+ private String err = "";
+
+ private void feedInputStream(String in, OutputStream out) {
+ try (OutputStreamWriter outputStream = new OutputStreamWriter(out)) {
+ if (in != null) {
+ outputStream.write(in, 0, in.length());
+ }
+ } catch (final IOException ex) {
+ // Process was not expecting input. May be normal state of affairs.
+ }
+ }
+
+ private Thread getOutputStreamThread(InputStream in, StringBuilder out) {
+ return new Thread(() -> {
+ final char buffer[] = new char[1024];
+
+ try (final InputStreamReader inputStream = new InputStreamReader(in)) {
+ for (int length; (length = inputStream.read(buffer, 0, buffer.length)) != -1; ) {
+ out.append(buffer, 0, length);
+ }
+ } catch (final IOException ex) {
+ out.append(ex.toString());
+ }
+ });
+ }
+
+ Tool(String[] args) {
+ this(null, args);
+ }
+
+ Tool(String in, String[] args) {
+ ProcessBuilder processBuilder = new ProcessBuilder(args);
+ exec(processBuilder, in);
+ }
+
+ private void exec(ProcessBuilder processBuilder, String in) {
+ StringBuilder outBuilder = new StringBuilder();
+ StringBuilder errBuilder = new StringBuilder();
+
+ try {
+ Process process = processBuilder.start();
+
+ Thread outThread = getOutputStreamThread(process.getInputStream(), outBuilder);
+ Thread errThread = getOutputStreamThread(process.getErrorStream(), errBuilder);
+
+ outThread.start();
+ errThread.start();
+
+ feedInputStream(in, process.getOutputStream());
+
+ exit = process.waitFor();
+ outThread.join();
+ errThread.join();
+ } catch (IOException | InterruptedException ex) {
+ ex.printStackTrace();
+ exit = -1;
+ }
+
+ out = outBuilder.toString();
+ err = errBuilder.toString();
+ }
+
+ int getExit() {
+ return exit;
+ }
+
+ String getOut() {
+ return out;
+ }
+
+ String getErr() {
+ return err;
+ }
+ }
+
+ private static void exec(String... args) {
+ Tool tool = new Tool(args);
+ int exit = tool.getExit();
+
+ if (exit != 0) {
+ errors++;
+ System.err.println("----------Tool.out----------");
+ System.err.append(tool.getOut());
+ System.err.println("----------Tool.err----------");
+ System.err.append(tool.getErr());
+ System.err.println("----------Tool.exit----------");
+ System.err.println("Error code = " + exit);
+ throw new RuntimeException("JImageTest FAIL");
+ }
+ }
+
+ public static void main(String[] args) {
+ final String JAVA_HOME = System.getProperty("java.home");
+ Path jimagePath = Paths.get(JAVA_HOME, "bin", "jimage");
+ Path bootimagePath = Paths.get(JAVA_HOME, "lib", "modules", "bootmodules.jimage");
+
+ if (Files.exists(jimagePath) && Files.exists(bootimagePath)) {
+ String jimage = jimagePath.toAbsolutePath().toString();
+ String bootimage = bootimagePath.toAbsolutePath().toString();
+ String extractDir = Paths.get(".", "extract").toAbsolutePath().toString();
+ String recreateImage = Paths.get(".", "recreate.jimage").toAbsolutePath().toString();
+
+ exec(new String[] {jimage, "extract", "--dir", extractDir, bootimage});
+ exec(new String[] {jimage, "recreate", "--dir", extractDir, recreateImage});
+
+ System.out.println("Test successful");
+ } else {
+ System.out.println("Test skipped, no module image");
+ }
+ }
+}