--- a/jdk/make/sun/xawt/FILES_c_unix.gmk Thu May 13 13:22:22 2010 -0700
+++ b/jdk/make/sun/xawt/FILES_c_unix.gmk Wed May 19 12:27:47 2010 -0700
@@ -79,4 +79,5 @@
gtk2_interface.c \
swing_GTKEngine.c \
swing_GTKStyle.c \
- rect.c
+ rect.c \
+ sun_awt_X11_GtkFileDialogPeer.c
--- a/jdk/make/sun/xawt/FILES_export_unix.gmk Thu May 13 13:22:22 2010 -0700
+++ b/jdk/make/sun/xawt/FILES_export_unix.gmk Wed May 19 12:27:47 2010 -0700
@@ -33,4 +33,5 @@
sun/awt/X11/XDesktopPeer.java \
sun/awt/X11/XToolkit.java \
sun/awt/X11/XComponentPeer.java \
- sun/awt/X11/XInputMethod.java
+ sun/awt/X11/XInputMethod.java \
+ sun/awt/X11/GtkFileDialogPeer.java
--- a/jdk/make/sun/xawt/mapfile-vers Thu May 13 13:22:22 2010 -0700
+++ b/jdk/make/sun/xawt/mapfile-vers Wed May 19 12:27:47 2010 -0700
@@ -172,6 +172,7 @@
Java_sun_awt_UNIXToolkit_load_1stock_1icon;
Java_sun_awt_UNIXToolkit_load_1gtk_1icon;
Java_sun_awt_UNIXToolkit_nativeSync;
+ Java_sun_awt_UNIXToolkit_gtkCheckVersionImpl;
Java_java_awt_AWTEvent_initIDs;
Java_java_awt_event_InputEvent_initIDs;
Java_java_awt_event_KeyEvent_initIDs;
@@ -396,6 +397,9 @@
Java_com_sun_java_swing_plaf_gtk_GTKStyle_nativeGetClassValue;
Java_com_sun_java_swing_plaf_gtk_GTKStyle_nativeGetPangoFontName;
+ Java_sun_awt_X11_GtkFileDialogPeer_run;
+ Java_sun_awt_X11_GtkFileDialogPeer_quit;
+
Java_sun_print_CUPSPrinter_initIDs;
Java_sun_print_CUPSPrinter_getCupsServer;
Java_sun_print_CUPSPrinter_getCupsPort;
--- a/jdk/src/share/classes/com/sun/jarsigner/ContentSignerParameters.java Thu May 13 13:22:22 2010 -0700
+++ b/jdk/src/share/classes/com/sun/jarsigner/ContentSignerParameters.java Wed May 19 12:27:47 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2003-2010 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,9 @@
package com.sun.jarsigner;
import java.net.URI;
+import java.security.cert.X509CRL;
import java.security.cert.X509Certificate;
+import java.util.Set;
import java.util.zip.ZipFile;
/**
@@ -81,6 +83,13 @@
public X509Certificate[] getSignerCertificateChain();
/**
+ * Retrieves the signer's X.509 CRLs.
+ *
+ * @return An unmodifiable set of X.509 CRLs (never <code>null</code>)
+ */
+ public Set<X509CRL> getCRLs();
+
+ /**
* Retrieves the content that was signed.
* The content is the JAR file's signature file.
*
--- a/jdk/src/share/classes/com/sun/security/auth/module/Krb5LoginModule.java Thu May 13 13:22:22 2010 -0700
+++ b/jdk/src/share/classes/com/sun/security/auth/module/Krb5LoginModule.java Wed May 19 12:27:47 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2000-2010 Sun Microsystems, Inc. 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
@@ -717,7 +717,7 @@
for (int i = 0; i < encKeys.length; i++) {
System.out.println("EncryptionKey: keyType=" +
encKeys[i].getEType() + " keyBytes (hex dump)=" +
- hd.encode(encKeys[i].getBytes()));
+ hd.encodeBuffer(encKeys[i].getBytes()));
}
}
--- a/jdk/src/share/classes/com/sun/security/jgss/AuthorizationDataEntry.java Thu May 13 13:22:22 2010 -0700
+++ b/jdk/src/share/classes/com/sun/security/jgss/AuthorizationDataEntry.java Wed May 19 12:27:47 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2009-2010 Sun Microsystems, Inc. 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
@@ -63,6 +63,6 @@
public String toString() {
return "AuthorizationDataEntry: type="+type+", data=" +
data.length + " bytes:\n" +
- new sun.misc.HexDumpEncoder().encode(data);
+ new sun.misc.HexDumpEncoder().encodeBuffer(data);
}
}
--- a/jdk/src/share/classes/java/awt/font/NumericShaper.java Thu May 13 13:22:22 2010 -0700
+++ b/jdk/src/share/classes/java/awt/font/NumericShaper.java Wed May 19 12:27:47 2010 -0700
@@ -1163,8 +1163,14 @@
lastkey = newkey;
ctxKey = newkey;
- if (((mask & EASTERN_ARABIC) != 0) && (ctxKey == ARABIC_KEY || ctxKey == EASTERN_ARABIC_KEY)) {
+ if (((mask & EASTERN_ARABIC) != 0) &&
+ (ctxKey == ARABIC_KEY ||
+ ctxKey == EASTERN_ARABIC_KEY)) {
ctxKey = EASTERN_ARABIC_KEY;
+ } else if (((mask & ARABIC) != 0) &&
+ (ctxKey == ARABIC_KEY ||
+ ctxKey == EASTERN_ARABIC_KEY)) {
+ ctxKey = ARABIC_KEY;
} else if ((mask & (1<<ctxKey)) == 0) {
ctxKey = EUROPEAN_KEY;
}
--- a/jdk/src/share/classes/java/io/ByteArrayOutputStream.java Thu May 13 13:22:22 2010 -0700
+++ b/jdk/src/share/classes/java/io/ByteArrayOutputStream.java Wed May 19 12:27:47 2010 -0700
@@ -78,17 +78,50 @@
}
/**
+ * Increases the capacity if necessary to ensure that it can hold
+ * at least the number of elements specified by the minimum
+ * capacity argument.
+ *
+ * @param minCapacity the desired minimum capacity
+ * @throws OutOfMemoryError if {@code minCapacity < 0}. This is
+ * interpreted as a request for the unsatisfiably large capacity
+ * {@code (long) Integer.MAX_VALUE + (minCapacity - Integer.MAX_VALUE)}.
+ */
+ private void ensureCapacity(int minCapacity) {
+ // overflow-conscious code
+ if (minCapacity - buf.length > 0)
+ grow(minCapacity);
+ }
+
+ /**
+ * Increases the capacity to ensure that it can hold at least the
+ * number of elements specified by the minimum capacity argument.
+ *
+ * @param minCapacity the desired minimum capacity
+ */
+ private void grow(int minCapacity) {
+ // overflow-conscious code
+ int oldCapacity = buf.length;
+ int newCapacity = oldCapacity << 1;
+ if (newCapacity - minCapacity < 0)
+ newCapacity = minCapacity;
+ if (newCapacity < 0) {
+ if (minCapacity < 0) // overflow
+ throw new OutOfMemoryError();
+ newCapacity = Integer.MAX_VALUE;
+ }
+ buf = Arrays.copyOf(buf, newCapacity);
+ }
+
+ /**
* Writes the specified byte to this byte array output stream.
*
* @param b the byte to be written.
*/
public synchronized void write(int b) {
- int newcount = count + 1;
- if (newcount > buf.length) {
- buf = Arrays.copyOf(buf, Math.max(buf.length << 1, newcount));
- }
- buf[count] = (byte)b;
- count = newcount;
+ ensureCapacity(count + 1);
+ buf[count] = (byte) b;
+ count += 1;
}
/**
@@ -101,17 +134,12 @@
*/
public synchronized void write(byte b[], int off, int len) {
if ((off < 0) || (off > b.length) || (len < 0) ||
- ((off + len) > b.length) || ((off + len) < 0)) {
+ ((off + len) - b.length > 0)) {
throw new IndexOutOfBoundsException();
- } else if (len == 0) {
- return;
}
- int newcount = count + len;
- if (newcount > buf.length) {
- buf = Arrays.copyOf(buf, Math.max(buf.length << 1, newcount));
- }
+ ensureCapacity(count + len);
System.arraycopy(b, off, buf, count, len);
- count = newcount;
+ count += len;
}
/**
--- a/jdk/src/share/classes/java/lang/AbstractStringBuilder.java Thu May 13 13:22:22 2010 -0700
+++ b/jdk/src/share/classes/java/lang/AbstractStringBuilder.java Wed May 19 12:27:47 2010 -0700
@@ -36,6 +36,8 @@
* sequence can be changed through certain method calls.
*
* @author Michael McCloskey
+ * @author Martin Buchholz
+ * @author Ulf Zibis
* @since 1.5
*/
abstract class AbstractStringBuilder implements Appendable, CharSequence {
@@ -98,9 +100,16 @@
* @param minimumCapacity the minimum desired capacity.
*/
public void ensureCapacity(int minimumCapacity) {
- if (minimumCapacity > value.length) {
+ ensureCapacityInternal(minimumCapacity);
+ }
+
+ /**
+ * This method has the same contract as ensureCapacity, but is
+ * never synchronized.
+ */
+ private void ensureCapacityInternal(int minimumCapacity) {
+ if (minimumCapacity - value.length > 0)
expandCapacity(minimumCapacity);
- }
}
/**
@@ -108,11 +117,13 @@
* size check or synchronization.
*/
void expandCapacity(int minimumCapacity) {
- int newCapacity = (value.length + 1) * 2;
+ int newCapacity = value.length * 2;
+ if (newCapacity - minimumCapacity < 0)
+ newCapacity = minimumCapacity;
if (newCapacity < 0) {
+ if (minimumCapacity < 0) // overflow
+ throw new OutOfMemoryError();
newCapacity = Integer.MAX_VALUE;
- } else if (minimumCapacity > newCapacity) {
- newCapacity = minimumCapacity;
}
value = Arrays.copyOf(value, newCapacity);
}
@@ -158,8 +169,7 @@
public void setLength(int newLength) {
if (newLength < 0)
throw new StringIndexOutOfBoundsException(newLength);
- if (newLength > value.length)
- expandCapacity(newLength);
+ ensureCapacityInternal(newLength);
if (count < newLength) {
for (; count < newLength; count++)
@@ -400,12 +410,9 @@
public AbstractStringBuilder append(String str) {
if (str == null) str = "null";
int len = str.length();
- if (len == 0) return this;
- int newCount = count + len;
- if (newCount > value.length)
- expandCapacity(newCount);
+ ensureCapacityInternal(count + len);
str.getChars(0, len, value, count);
- count = newCount;
+ count += len;
return this;
}
@@ -414,11 +421,9 @@
if (sb == null)
return append("null");
int len = sb.length();
- int newCount = count + len;
- if (newCount > value.length)
- expandCapacity(newCount);
+ ensureCapacityInternal(count + len);
sb.getChars(0, len, value, count);
- count = newCount;
+ count += len;
return this;
}
@@ -470,14 +475,10 @@
"start " + start + ", end " + end + ", s.length() "
+ s.length());
int len = end - start;
- if (len == 0)
- return this;
- int newCount = count + len;
- if (newCount > value.length)
- expandCapacity(newCount);
- for (int i=start; i<end; i++)
- value[count++] = s.charAt(i);
- count = newCount;
+ ensureCapacityInternal(count + len);
+ for (int i = start, j = count; i < end; i++, j++)
+ value[j] = s.charAt(i);
+ count += len;
return this;
}
@@ -498,11 +499,10 @@
* @return a reference to this object.
*/
public AbstractStringBuilder append(char[] str) {
- int newCount = count + str.length;
- if (newCount > value.length)
- expandCapacity(newCount);
- System.arraycopy(str, 0, value, count, str.length);
- count = newCount;
+ int len = str.length;
+ ensureCapacityInternal(count + len);
+ System.arraycopy(str, 0, value, count, len);
+ count += len;
return this;
}
@@ -529,11 +529,9 @@
* or {@code offset+len > str.length}
*/
public AbstractStringBuilder append(char str[], int offset, int len) {
- int newCount = count + len;
- if (newCount > value.length)
- expandCapacity(newCount);
+ ensureCapacityInternal(count + len);
System.arraycopy(str, offset, value, count, len);
- count = newCount;
+ count += len;
return this;
}
@@ -551,17 +549,13 @@
*/
public AbstractStringBuilder append(boolean b) {
if (b) {
- int newCount = count + 4;
- if (newCount > value.length)
- expandCapacity(newCount);
+ ensureCapacityInternal(count + 4);
value[count++] = 't';
value[count++] = 'r';
value[count++] = 'u';
value[count++] = 'e';
} else {
- int newCount = count + 5;
- if (newCount > value.length)
- expandCapacity(newCount);
+ ensureCapacityInternal(count + 5);
value[count++] = 'f';
value[count++] = 'a';
value[count++] = 'l';
@@ -587,9 +581,7 @@
* @return a reference to this object.
*/
public AbstractStringBuilder append(char c) {
- int newCount = count + 1;
- if (newCount > value.length)
- expandCapacity(newCount);
+ ensureCapacityInternal(count + 1);
value[count++] = c;
return this;
}
@@ -614,8 +606,7 @@
int appendedLength = (i < 0) ? Integer.stringSize(-i) + 1
: Integer.stringSize(i);
int spaceNeeded = count + appendedLength;
- if (spaceNeeded > value.length)
- expandCapacity(spaceNeeded);
+ ensureCapacityInternal(spaceNeeded);
Integer.getChars(i, spaceNeeded, value);
count = spaceNeeded;
return this;
@@ -641,8 +632,7 @@
int appendedLength = (l < 0) ? Long.stringSize(-l) + 1
: Long.stringSize(l);
int spaceNeeded = count + appendedLength;
- if (spaceNeeded > value.length)
- expandCapacity(spaceNeeded);
+ ensureCapacityInternal(spaceNeeded);
Long.getChars(l, spaceNeeded, value);
count = spaceNeeded;
return this;
@@ -738,10 +728,7 @@
if (codePoint >= Character.MIN_SUPPLEMENTARY_CODE_POINT) {
n++;
}
- int newCount = count + n;
- if (newCount > value.length) {
- expandCapacity(newCount);
- }
+ ensureCapacityInternal(count + n);
if (n == 1) {
value[count++] = (char) codePoint;
} else {
@@ -807,8 +794,7 @@
end = count;
int len = str.length();
int newCount = count + len - (end - start);
- if (newCount > value.length)
- expandCapacity(newCount);
+ ensureCapacityInternal(newCount);
System.arraycopy(value, end, value, start + len, count - end);
str.getChars(value, start);
@@ -915,12 +901,10 @@
throw new StringIndexOutOfBoundsException(
"offset " + offset + ", len " + len + ", str.length "
+ str.length);
- int newCount = count + len;
- if (newCount > value.length)
- expandCapacity(newCount);
+ ensureCapacityInternal(count + len);
System.arraycopy(value, index, value, index + len, count - index);
System.arraycopy(str, offset, value, index, len);
- count = newCount;
+ count += len;
return this;
}
@@ -984,12 +968,10 @@
if (str == null)
str = "null";
int len = str.length();
- int newCount = count + len;
- if (newCount > value.length)
- expandCapacity(newCount);
+ ensureCapacityInternal(count + len);
System.arraycopy(value, offset, value, offset + len, count - offset);
str.getChars(value, offset);
- count = newCount;
+ count += len;
return this;
}
@@ -1021,12 +1003,10 @@
if ((offset < 0) || (offset > length()))
throw new StringIndexOutOfBoundsException(offset);
int len = str.length;
- int newCount = count + len;
- if (newCount > value.length)
- expandCapacity(newCount);
+ ensureCapacityInternal(count + len);
System.arraycopy(value, offset, value, offset + len, count - offset);
System.arraycopy(str, 0, value, offset, len);
- count = newCount;
+ count += len;
return this;
}
@@ -1114,16 +1094,12 @@
"start " + start + ", end " + end + ", s.length() "
+ s.length());
int len = end - start;
- if (len == 0)
- return this;
- int newCount = count + len;
- if (newCount > value.length)
- expandCapacity(newCount);
+ ensureCapacityInternal(count + len);
System.arraycopy(value, dstOffset, value, dstOffset + len,
count - dstOffset);
for (int i=start; i<end; i++)
value[dstOffset++] = s.charAt(i);
- count = newCount;
+ count += len;
return this;
}
@@ -1170,12 +1146,10 @@
* @throws IndexOutOfBoundsException if the offset is invalid.
*/
public AbstractStringBuilder insert(int offset, char c) {
- int newCount = count + 1;
- if (newCount > value.length)
- expandCapacity(newCount);
+ ensureCapacityInternal(count + 1);
System.arraycopy(value, offset, value, offset + 1, count - offset);
value[offset] = c;
- count = newCount;
+ count += 1;
return this;
}
--- a/jdk/src/share/classes/java/lang/String.java Thu May 13 13:22:22 2010 -0700
+++ b/jdk/src/share/classes/java/lang/String.java Wed May 19 12:27:47 2010 -0700
@@ -2551,8 +2551,8 @@
* Examples are programming language identifiers, protocol keys, and HTML
* tags.
* For instance, <code>"TITLE".toLowerCase()</code> in a Turkish locale
- * returns <code>"t\u0131tle"</code>, where '\u0131' is the LATIN SMALL
- * LETTER DOTLESS I character.
+ * returns <code>"t\u005Cu0131tle"</code>, where '\u005Cu0131' is the
+ * LATIN SMALL LETTER DOTLESS I character.
* To obtain correct results for locale insensitive strings, use
* <code>toLowerCase(Locale.ENGLISH)</code>.
* <p>
@@ -2714,8 +2714,8 @@
* Examples are programming language identifiers, protocol keys, and HTML
* tags.
* For instance, <code>"title".toUpperCase()</code> in a Turkish locale
- * returns <code>"T\u0130TLE"</code>, where '\u0130' is the LATIN CAPITAL
- * LETTER I WITH DOT ABOVE character.
+ * returns <code>"T\u005Cu0130TLE"</code>, where '\u005Cu0130' is the
+ * LATIN CAPITAL LETTER I WITH DOT ABOVE character.
* To obtain correct results for locale insensitive strings, use
* <code>toUpperCase(Locale.ENGLISH)</code>.
* <p>
--- a/jdk/src/share/classes/java/net/DatagramSocket.java Thu May 13 13:22:22 2010 -0700
+++ b/jdk/src/share/classes/java/net/DatagramSocket.java Wed May 19 12:27:47 2010 -0700
@@ -401,29 +401,40 @@
* send or receive may throw a PortUnreachableException. Note, there is no
* guarantee that the exception will be thrown.
*
- * <p>A caller's permission to send and receive datagrams to a
- * given host and port are checked at connect time. When a socket
- * is connected, receive and send <b>will not
- * perform any security checks</b> on incoming and outgoing
- * packets, other than matching the packet's and the socket's
- * address and port. On a send operation, if the packet's address
- * is set and the packet's address and the socket's address do not
- * match, an IllegalArgumentException will be thrown. A socket
- * connected to a multicast address may only be used to send packets.
+ * <p> If a security manager has been installed then it is invoked to check
+ * access to the remote address. Specifically, if the given {@code address}
+ * is a {@link InetAddress#isMulticastAddress multicast address},
+ * the security manager's {@link
+ * java.lang.SecurityManager#checkMulticast(InetAddress)
+ * checkMulticast} method is invoked with the given {@code address}.
+ * Otherwise, the security manager's {@link
+ * java.lang.SecurityManager#checkConnect(String,int) checkConnect}
+ * and {@link java.lang.SecurityManager#checkAccept checkAccept} methods
+ * are invoked, with the given {@code address} and {@code port}, to
+ * verify that datagrams are permitted to be sent and received
+ * respectively.
+ *
+ * <p> When a socket is connected, {@link #receive receive} and
+ * {@link #send send} <b>will not perform any security checks</b>
+ * on incoming and outgoing packets, other than matching the packet's
+ * and the socket's address and port. On a send operation, if the
+ * packet's address is set and the packet's address and the socket's
+ * address do not match, an {@code IllegalArgumentException} will be
+ * thrown. A socket connected to a multicast address may only be used
+ * to send packets.
*
* @param address the remote address for the socket
*
* @param port the remote port for the socket.
*
- * @exception IllegalArgumentException if the address is null,
- * or the port is out of range.
+ * @throws IllegalArgumentException
+ * if the address is null, or the port is out of range.
*
- * @exception SecurityException if the caller is not allowed to
- * send datagrams to and receive datagrams from the address and port.
+ * @throws SecurityException
+ * if a security manager has been installed and it does
+ * not permit access to the given remote address
*
* @see #disconnect
- * @see #send
- * @see #receive
*/
public void connect(InetAddress address, int port) {
try {
@@ -435,13 +446,25 @@
/**
* Connects this socket to a remote socket address (IP address + port number).
- * <p>
+ *
+ * <p> If given an {@link InetSocketAddress InetSocketAddress}, this method
+ * behaves as if invoking {@link #connect(InetAddress,int) connect(InetAddress,int)}
+ * with the the given socket addresses IP address and port number.
+ *
* @param addr The remote address.
- * @throws SocketException if the connect fails
- * @throws IllegalArgumentException if addr is null or addr is a SocketAddress
- * subclass not supported by this socket
+ *
+ * @throws SocketException
+ * if the connect fails
+ *
+ * @throws IllegalArgumentException
+ * if {@code addr} is {@code null}, or {@code addr} is a SocketAddress
+ * subclass not supported by this socket
+ *
+ * @throws SecurityException
+ * if a security manager has been installed and it does
+ * not permit access to the given remote address
+ *
* @since 1.4
- * @see #connect
*/
public void connect(SocketAddress addr) throws SocketException {
if (addr == null)
--- a/jdk/src/share/classes/java/security/CodeSigner.java Thu May 13 13:22:22 2010 -0700
+++ b/jdk/src/share/classes/java/security/CodeSigner.java Wed May 19 12:27:47 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2003-2010 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,10 @@
package java.security;
import java.io.Serializable;
+import java.security.cert.CRL;
import java.security.cert.CertPath;
+import sun.misc.JavaSecurityCodeSignerAccess;
+import sun.misc.SharedSecrets;
/**
* This class encapsulates information about a code signer.
@@ -163,4 +166,43 @@
sb.append(")");
return sb.toString();
}
+
+ // A private attribute attached to this CodeSigner object. Can be accessed
+ // through SharedSecrets.getJavaSecurityCodeSignerAccess().[g|s]etCRLs
+ //
+ // Currently called in SignatureFileVerifier.getSigners
+ private transient CRL[] crls;
+
+ /**
+ * Sets the CRLs attached
+ * @param crls, null to clear
+ */
+ void setCRLs(CRL[] crls) {
+ this.crls = crls;
+ }
+
+ /**
+ * Returns the CRLs attached
+ * @return the crls, initially null
+ */
+ CRL[] getCRLs() {
+ return crls;
+ }
+
+ // Set up JavaSecurityCodeSignerAccess in SharedSecrets
+ static {
+ SharedSecrets.setJavaSecurityCodeSignerAccess(
+ new JavaSecurityCodeSignerAccess() {
+ @Override
+ public void setCRLs(CodeSigner signer, CRL[] crls) {
+ signer.setCRLs(crls);
+ }
+
+ @Override
+ public CRL[] getCRLs(CodeSigner signer) {
+ return signer.getCRLs();
+ }
+ });
+ }
+
}
--- a/jdk/src/share/classes/java/util/AbstractCollection.java Thu May 13 13:22:22 2010 -0700
+++ b/jdk/src/share/classes/java/util/AbstractCollection.java Wed May 19 12:27:47 2010 -0700
@@ -191,6 +191,14 @@
}
/**
+ * The maximum size of array to allocate.
+ * Some VMs reserve some header words in an array.
+ * Attempts to allocate larger arrays may result in
+ * OutOfMemoryError: Requested array size exceeds VM limit
+ */
+ private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
+
+ /**
* Reallocates the array being used within toArray when the iterator
* returned more elements than expected, and finishes filling it from
* the iterator.
@@ -205,13 +213,10 @@
while (it.hasNext()) {
int cap = r.length;
if (i == cap) {
- int newCap = ((cap / 2) + 1) * 3;
- if (newCap <= cap) { // integer overflow
- if (cap == Integer.MAX_VALUE)
- throw new OutOfMemoryError
- ("Required array size too large");
- newCap = Integer.MAX_VALUE;
- }
+ int newCap = cap + (cap >> 1) + 1;
+ // overflow-conscious code
+ if (newCap - MAX_ARRAY_SIZE > 0)
+ newCap = hugeCapacity(cap + 1);
r = Arrays.copyOf(r, newCap);
}
r[i++] = (T)it.next();
@@ -220,6 +225,15 @@
return (i == r.length) ? r : Arrays.copyOf(r, i);
}
+ private static int hugeCapacity(int minCapacity) {
+ if (minCapacity < 0) // overflow
+ throw new OutOfMemoryError
+ ("Required array size too large");
+ return (minCapacity > MAX_ARRAY_SIZE) ?
+ Integer.MAX_VALUE :
+ MAX_ARRAY_SIZE;
+ }
+
// Modification Operations
/**
--- a/jdk/src/share/classes/java/util/ArrayList.java Thu May 13 13:22:22 2010 -0700
+++ b/jdk/src/share/classes/java/util/ArrayList.java Wed May 19 12:27:47 2010 -0700
@@ -173,18 +173,47 @@
* necessary, to ensure that it can hold at least the number of elements
* specified by the minimum capacity argument.
*
- * @param minCapacity the desired minimum capacity
+ * @param minCapacity the desired minimum capacity
*/
public void ensureCapacity(int minCapacity) {
modCount++;
+ // overflow-conscious code
+ if (minCapacity - elementData.length > 0)
+ grow(minCapacity);
+ }
+
+ /**
+ * The maximum size of array to allocate.
+ * Some VMs reserve some header words in an array.
+ * Attempts to allocate larger arrays may result in
+ * OutOfMemoryError: Requested array size exceeds VM limit
+ */
+ private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
+
+ /**
+ * Increases the capacity to ensure that it can hold at least the
+ * number of elements specified by the minimum capacity argument.
+ *
+ * @param minCapacity the desired minimum capacity
+ */
+ private void grow(int minCapacity) {
+ // overflow-conscious code
int oldCapacity = elementData.length;
- if (minCapacity > oldCapacity) {
- int newCapacity = (oldCapacity * 3)/2 + 1;
- if (newCapacity < minCapacity)
- newCapacity = minCapacity;
- // minCapacity is usually close to size, so this is a win:
- elementData = Arrays.copyOf(elementData, newCapacity);
- }
+ int newCapacity = oldCapacity + (oldCapacity >> 1);
+ if (newCapacity - minCapacity < 0)
+ newCapacity = minCapacity;
+ if (newCapacity - MAX_ARRAY_SIZE > 0)
+ newCapacity = hugeCapacity(minCapacity);
+ // minCapacity is usually close to size, so this is a win:
+ elementData = Arrays.copyOf(elementData, newCapacity);
+ }
+
+ private static int hugeCapacity(int minCapacity) {
+ if (minCapacity < 0) // overflow
+ throw new OutOfMemoryError();
+ return (minCapacity > MAX_ARRAY_SIZE) ?
+ Integer.MAX_VALUE :
+ MAX_ARRAY_SIZE;
}
/**
@@ -391,7 +420,7 @@
public void add(int index, E element) {
rangeCheckForAdd(index);
- ensureCapacity(size+1); // Increments modCount!!
+ ensureCapacity(size + 1); // Increments modCount!!
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
--- a/jdk/src/share/classes/java/util/Hashtable.java Thu May 13 13:22:22 2010 -0700
+++ b/jdk/src/share/classes/java/util/Hashtable.java Wed May 19 12:27:47 2010 -0700
@@ -365,6 +365,14 @@
}
/**
+ * The maximum size of array to allocate.
+ * Some VMs reserve some header words in an array.
+ * Attempts to allocate larger arrays may result in
+ * OutOfMemoryError: Requested array size exceeds VM limit
+ */
+ private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
+
+ /**
* Increases the capacity of and internally reorganizes this
* hashtable, in order to accommodate and access its entries more
* efficiently. This method is called automatically when the
@@ -375,7 +383,14 @@
int oldCapacity = table.length;
Entry[] oldMap = table;
- int newCapacity = oldCapacity * 2 + 1;
+ // overflow-conscious code
+ int newCapacity = (oldCapacity << 1) + 1;
+ if (newCapacity - MAX_ARRAY_SIZE > 0) {
+ if (oldCapacity == MAX_ARRAY_SIZE)
+ // Keep running with MAX_ARRAY_SIZE buckets
+ return;
+ newCapacity = MAX_ARRAY_SIZE;
+ }
Entry[] newMap = new Entry[newCapacity];
modCount++;
--- a/jdk/src/share/classes/java/util/PriorityQueue.java Thu May 13 13:22:22 2010 -0700
+++ b/jdk/src/share/classes/java/util/PriorityQueue.java Wed May 19 12:27:47 2010 -0700
@@ -170,17 +170,21 @@
* @throws NullPointerException if the specified collection or any
* of its elements are null
*/
+ @SuppressWarnings("unchecked")
public PriorityQueue(Collection<? extends E> c) {
- initFromCollection(c);
- if (c instanceof SortedSet)
- comparator = (Comparator<? super E>)
- ((SortedSet<? extends E>)c).comparator();
- else if (c instanceof PriorityQueue)
- comparator = (Comparator<? super E>)
- ((PriorityQueue<? extends E>)c).comparator();
+ if (c instanceof SortedSet<?>) {
+ SortedSet<? extends E> ss = (SortedSet<? extends E>) c;
+ this.comparator = (Comparator<? super E>) ss.comparator();
+ initElementsFromCollection(ss);
+ }
+ else if (c instanceof PriorityQueue<?>) {
+ PriorityQueue<? extends E> pq = (PriorityQueue<? extends E>) c;
+ this.comparator = (Comparator<? super E>) pq.comparator();
+ initFromPriorityQueue(pq);
+ }
else {
- comparator = null;
- heapify();
+ this.comparator = null;
+ initFromCollection(c);
}
}
@@ -198,9 +202,10 @@
* @throws NullPointerException if the specified priority queue or any
* of its elements are null
*/
+ @SuppressWarnings("unchecked")
public PriorityQueue(PriorityQueue<? extends E> c) {
- comparator = (Comparator<? super E>)c.comparator();
- initFromCollection(c);
+ this.comparator = (Comparator<? super E>) c.comparator();
+ initFromPriorityQueue(c);
}
/**
@@ -216,9 +221,33 @@
* @throws NullPointerException if the specified sorted set or any
* of its elements are null
*/
+ @SuppressWarnings("unchecked")
public PriorityQueue(SortedSet<? extends E> c) {
- comparator = (Comparator<? super E>)c.comparator();
- initFromCollection(c);
+ this.comparator = (Comparator<? super E>) c.comparator();
+ initElementsFromCollection(c);
+ }
+
+ private void initFromPriorityQueue(PriorityQueue<? extends E> c) {
+ if (c.getClass() == PriorityQueue.class) {
+ this.queue = c.toArray();
+ this.size = c.size();
+ } else {
+ initFromCollection(c);
+ }
+ }
+
+ private void initElementsFromCollection(Collection<? extends E> c) {
+ Object[] a = c.toArray();
+ // If c.toArray incorrectly doesn't return Object[], copy it.
+ if (a.getClass() != Object[].class)
+ a = Arrays.copyOf(a, a.length, Object[].class);
+ int len = a.length;
+ if (len == 1 || this.comparator != null)
+ for (int i = 0; i < len; i++)
+ if (a[i] == null)
+ throw new NullPointerException();
+ this.queue = a;
+ this.size = a.length;
}
/**
@@ -227,34 +256,43 @@
* @param c the collection
*/
private void initFromCollection(Collection<? extends E> c) {
- Object[] a = c.toArray();
- // If c.toArray incorrectly doesn't return Object[], copy it.
- if (a.getClass() != Object[].class)
- a = Arrays.copyOf(a, a.length, Object[].class);
- queue = a;
- size = a.length;
+ initElementsFromCollection(c);
+ heapify();
}
/**
+ * The maximum size of array to allocate.
+ * Some VMs reserve some header words in an array.
+ * Attempts to allocate larger arrays may result in
+ * OutOfMemoryError: Requested array size exceeds VM limit
+ */
+ private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
+
+ /**
* Increases the capacity of the array.
*
* @param minCapacity the desired minimum capacity
*/
private void grow(int minCapacity) {
- if (minCapacity < 0) // overflow
- throw new OutOfMemoryError();
int oldCapacity = queue.length;
// Double size if small; else grow by 50%
- int newCapacity = ((oldCapacity < 64)?
- ((oldCapacity + 1) * 2):
- ((oldCapacity / 2) * 3));
- if (newCapacity < 0) // overflow
- newCapacity = Integer.MAX_VALUE;
- if (newCapacity < minCapacity)
- newCapacity = minCapacity;
+ int newCapacity = oldCapacity + ((oldCapacity < 64) ?
+ (oldCapacity + 2) :
+ (oldCapacity >> 1));
+ // overflow-conscious code
+ if (newCapacity - MAX_ARRAY_SIZE > 0)
+ newCapacity = hugeCapacity(minCapacity);
queue = Arrays.copyOf(queue, newCapacity);
}
+ private static int hugeCapacity(int minCapacity) {
+ if (minCapacity < 0) // overflow
+ throw new OutOfMemoryError();
+ return (minCapacity > MAX_ARRAY_SIZE) ?
+ Integer.MAX_VALUE :
+ MAX_ARRAY_SIZE;
+ }
+
/**
* Inserts the specified element into this priority queue.
*
--- a/jdk/src/share/classes/java/util/Random.java Thu May 13 13:22:22 2010 -0700
+++ b/jdk/src/share/classes/java/util/Random.java Wed May 19 12:27:47 2010 -0700
@@ -86,8 +86,23 @@
* the seed of the random number generator to a value very likely
* to be distinct from any other invocation of this constructor.
*/
- public Random() { this(++seedUniquifier + System.nanoTime()); }
- private static volatile long seedUniquifier = 8682522807148012L;
+ public Random() {
+ this(seedUniquifier() ^ System.nanoTime());
+ }
+
+ private static long seedUniquifier() {
+ // L'Ecuyer, "Tables of Linear Congruential Generators of
+ // Different Sizes and Good Lattice Structure", 1999
+ for (;;) {
+ long current = seedUniquifier.get();
+ long next = current * 181783497276652981L;
+ if (seedUniquifier.compareAndSet(current, next))
+ return next;
+ }
+ }
+
+ private static final AtomicLong seedUniquifier
+ = new AtomicLong(8682522807148012L);
/**
* Creates a new random number generator using a single {@code long} seed.
@@ -103,8 +118,11 @@
* @see #setSeed(long)
*/
public Random(long seed) {
- this.seed = new AtomicLong(0L);
- setSeed(seed);
+ this.seed = new AtomicLong(initialScramble(seed));
+ }
+
+ private static long initialScramble(long seed) {
+ return (seed ^ multiplier) & mask;
}
/**
@@ -127,8 +145,7 @@
* @param seed the initial seed
*/
synchronized public void setSeed(long seed) {
- seed = (seed ^ multiplier) & mask;
- this.seed.set(seed);
+ this.seed.set(initialScramble(seed));
haveNextNextGaussian = false;
}
--- a/jdk/src/share/classes/java/util/Vector.java Thu May 13 13:22:22 2010 -0700
+++ b/jdk/src/share/classes/java/util/Vector.java Wed May 19 12:27:47 2010 -0700
@@ -235,16 +235,37 @@
* @see #ensureCapacity(int)
*/
private void ensureCapacityHelper(int minCapacity) {
+ // overflow-conscious code
+ if (minCapacity - elementData.length > 0)
+ grow(minCapacity);
+ }
+
+ /**
+ * The maximum size of array to allocate.
+ * Some VMs reserve some header words in an array.
+ * Attempts to allocate larger arrays may result in
+ * OutOfMemoryError: Requested array size exceeds VM limit
+ */
+ private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
+
+ private void grow(int minCapacity) {
+ // overflow-conscious code
int oldCapacity = elementData.length;
- if (minCapacity > oldCapacity) {
- Object[] oldData = elementData;
- int newCapacity = (capacityIncrement > 0) ?
- (oldCapacity + capacityIncrement) : (oldCapacity * 2);
- if (newCapacity < minCapacity) {
- newCapacity = minCapacity;
- }
- elementData = Arrays.copyOf(elementData, newCapacity);
- }
+ int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
+ capacityIncrement : oldCapacity);
+ if (newCapacity - minCapacity < 0)
+ newCapacity = minCapacity;
+ if (newCapacity - MAX_ARRAY_SIZE > 0)
+ newCapacity = hugeCapacity(minCapacity);
+ elementData = Arrays.copyOf(elementData, newCapacity);
+ }
+
+ private static int hugeCapacity(int minCapacity) {
+ if (minCapacity < 0) // overflow
+ throw new OutOfMemoryError();
+ return (minCapacity > MAX_ARRAY_SIZE) ?
+ Integer.MAX_VALUE :
+ MAX_ARRAY_SIZE;
}
/**
--- a/jdk/src/share/classes/java/util/jar/JarVerifier.java Thu May 13 13:22:22 2010 -0700
+++ b/jdk/src/share/classes/java/util/jar/JarVerifier.java Wed May 19 12:27:47 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1997-2010 Sun Microsystems, Inc. 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
@@ -27,7 +27,6 @@
import java.io.*;
import java.util.*;
-import java.util.zip.*;
import java.security.*;
import java.security.cert.CertificateException;
--- a/jdk/src/share/classes/java/util/zip/Deflater.java Thu May 13 13:22:22 2010 -0700
+++ b/jdk/src/share/classes/java/util/zip/Deflater.java Wed May 19 12:27:47 2010 -0700
@@ -40,7 +40,7 @@
* <blockquote><pre>
* try {
* // Encode a String into bytes
- * String inputString = "blahblahblah\u20AC\u20AC";
+ * String inputString = "blahblahblah";
* byte[] input = inputString.getBytes("UTF-8");
*
* // Compress the bytes
--- a/jdk/src/share/classes/javax/security/auth/kerberos/KeyImpl.java Thu May 13 13:22:22 2010 -0700
+++ b/jdk/src/share/classes/javax/security/auth/kerberos/KeyImpl.java Wed May 19 12:27:47 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2000-2010 Sun Microsystems, Inc. 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
@@ -205,7 +205,7 @@
+ " keyBytes (hex dump)="
+ (keyBytes == null || keyBytes.length == 0 ?
" Empty Key" :
- '\n' + hd.encode(keyBytes)
+ '\n' + hd.encodeBuffer(keyBytes)
+ '\n');
--- a/jdk/src/share/classes/javax/swing/JEditorPane.java Thu May 13 13:22:22 2010 -0700
+++ b/jdk/src/share/classes/javax/swing/JEditorPane.java Wed May 19 12:27:47 2010 -0700
@@ -1330,8 +1330,9 @@
*/
public Dimension getPreferredSize() {
Dimension d = super.getPreferredSize();
- JViewport port = SwingUtilities.getParentViewport(this);
- if (port != null) {
+ Container parent = SwingUtilities.getUnwrappedParent(this);
+ if (parent instanceof JViewport) {
+ JViewport port = (JViewport) parent;
TextUI ui = getUI();
int prefWidth = d.width;
int prefHeight = d.height;
@@ -1452,8 +1453,9 @@
* match its own, false otherwise
*/
public boolean getScrollableTracksViewportWidth() {
- JViewport port = SwingUtilities.getParentViewport(this);
- if (port != null) {
+ Container parent = SwingUtilities.getUnwrappedParent(this);
+ if (parent instanceof JViewport) {
+ JViewport port = (JViewport) parent;
TextUI ui = getUI();
int w = port.getWidth();
Dimension min = ui.getMinimumSize(this);
@@ -1474,8 +1476,9 @@
* false otherwise
*/
public boolean getScrollableTracksViewportHeight() {
- JViewport port = SwingUtilities.getParentViewport(this);
- if (port != null) {
+ Container parent = SwingUtilities.getUnwrappedParent(this);
+ if (parent instanceof JViewport) {
+ JViewport port = (JViewport) parent;
TextUI ui = getUI();
int h = port.getHeight();
Dimension min = ui.getMinimumSize(this);
--- a/jdk/src/share/classes/javax/swing/JLayer.java Thu May 13 13:22:22 2010 -0700
+++ b/jdk/src/share/classes/javax/swing/JLayer.java Wed May 19 12:27:47 2010 -0700
@@ -163,18 +163,6 @@
private static final LayerEventController eventController =
new LayerEventController();
- private static final long ACCEPTED_EVENTS =
- AWTEvent.COMPONENT_EVENT_MASK |
- AWTEvent.CONTAINER_EVENT_MASK |
- AWTEvent.FOCUS_EVENT_MASK |
- AWTEvent.KEY_EVENT_MASK |
- AWTEvent.MOUSE_WHEEL_EVENT_MASK |
- AWTEvent.MOUSE_MOTION_EVENT_MASK |
- AWTEvent.MOUSE_EVENT_MASK |
- AWTEvent.INPUT_METHOD_EVENT_MASK |
- AWTEvent.HIERARCHY_EVENT_MASK |
- AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK;
-
/**
* Creates a new {@code JLayer} object with a {@code null} view component
* and {@code null} {@link javax.swing.plaf.LayerUI}.
@@ -396,24 +384,14 @@
}
/**
- * Sets the bitmask of event types to receive by this {@code JLayer}.
- * Here is the list of the supported event types:
- * <ul>
- * <li>AWTEvent.COMPONENT_EVENT_MASK</li>
- * <li>AWTEvent.CONTAINER_EVENT_MASK</li>
- * <li>AWTEvent.FOCUS_EVENT_MASK</li>
- * <li>AWTEvent.KEY_EVENT_MASK</li>
- * <li>AWTEvent.MOUSE_WHEEL_EVENT_MASK</li>
- * <li>AWTEvent.MOUSE_MOTION_EVENT_MASK</li>
- * <li>AWTEvent.MOUSE_EVENT_MASK</li>
- * <li>AWTEvent.INPUT_METHOD_EVENT_MASK</li>
- * <li>AWTEvent.HIERARCHY_EVENT_MASK</li>
- * <li>AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK</li>
- * </ul>
+ * Enables the events from JLayer and <b>all its descendants</b>
+ * defined by the specified event mask parameter
+ * to be delivered to the
+ * {@link LayerUI#eventDispatched(AWTEvent, JLayer)} method.
* <p/>
- * If {@code LayerUI} is installed,
- * {@link javax.swing.plaf.LayerUI#eventDispatched(AWTEvent, JLayer)} method
- * will only receive events that match the event mask.
+ * Events are delivered provided that {@code LayerUI} is set
+ * for this {@code JLayer} and the {@code JLayer}
+ * is displayable.
* <p/>
* The following example shows how to correclty use this method
* in the {@code LayerUI} implementations:
@@ -433,19 +411,15 @@
* }
* </pre>
*
- * By default {@code JLayer} receives no events.
+ * By default {@code JLayer} receives no events and its event mask is {@code 0}.
*
* @param layerEventMask the bitmask of event types to receive
*
- * @throws IllegalArgumentException if the {@code layerEventMask} parameter
- * contains unsupported event types
* @see #getLayerEventMask()
+ * @see LayerUI#eventDispatched(AWTEvent, JLayer)
+ * @see Component#isDisplayable()
*/
public void setLayerEventMask(long layerEventMask) {
- if (layerEventMask != (layerEventMask & ACCEPTED_EVENTS)) {
- throw new IllegalArgumentException(
- "The event bitmask contains unsupported event types");
- }
long oldEventMask = getLayerEventMask();
this.eventMask = layerEventMask;
firePropertyChange("layerEventMask", oldEventMask, layerEventMask);
@@ -629,6 +603,18 @@
private long currentEventMask;
+ private static final long ACCEPTED_EVENTS =
+ AWTEvent.COMPONENT_EVENT_MASK |
+ AWTEvent.CONTAINER_EVENT_MASK |
+ AWTEvent.FOCUS_EVENT_MASK |
+ AWTEvent.KEY_EVENT_MASK |
+ AWTEvent.MOUSE_WHEEL_EVENT_MASK |
+ AWTEvent.MOUSE_MOTION_EVENT_MASK |
+ AWTEvent.MOUSE_EVENT_MASK |
+ AWTEvent.INPUT_METHOD_EVENT_MASK |
+ AWTEvent.HIERARCHY_EVENT_MASK |
+ AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK;
+
@SuppressWarnings("unchecked")
public void eventDispatched(AWTEvent event) {
Object source = event.getSource();
@@ -660,6 +646,8 @@
for (Long mask : layerMaskList) {
combinedMask |= mask;
}
+ // filter out all unaccepted events
+ combinedMask &= ACCEPTED_EVENTS;
if (combinedMask == 0) {
removeAWTEventListener();
} else if (getCurrentEventMask() != combinedMask) {
--- a/jdk/src/share/classes/javax/swing/JList.java Thu May 13 13:22:22 2010 -0700
+++ b/jdk/src/share/classes/javax/swing/JList.java Wed May 19 12:27:47 2010 -0700
@@ -25,17 +25,7 @@
package javax.swing;
-import java.awt.Color;
-import java.awt.Component;
-import java.awt.Cursor;
-import java.awt.Dimension;
-import java.awt.Font;
-import java.awt.FontMetrics;
-import java.awt.GraphicsEnvironment;
-import java.awt.HeadlessException;
-import java.awt.Insets;
-import java.awt.Point;
-import java.awt.Rectangle;
+import java.awt.*;
import java.awt.event.*;
import java.util.Vector;
@@ -2779,9 +2769,9 @@
getVisibleRowCount() <= 0) {
return true;
}
- JViewport port = SwingUtilities.getParentViewport(this);
- if (port != null) {
- return port.getWidth() > getPreferredSize().width;
+ Container parent = SwingUtilities.getUnwrappedParent(this);
+ if (parent instanceof JViewport) {
+ return parent.getWidth() > getPreferredSize().width;
}
return false;
}
@@ -2805,9 +2795,9 @@
getVisibleRowCount() <= 0) {
return true;
}
- JViewport port = SwingUtilities.getParentViewport(this);
- if (port != null) {
- return port.getHeight() > getPreferredSize().height;
+ Container parent = SwingUtilities.getUnwrappedParent(this);
+ if (parent instanceof JViewport) {
+ return parent.getHeight() > getPreferredSize().height;
}
return false;
}
--- a/jdk/src/share/classes/javax/swing/JTable.java Thu May 13 13:22:22 2010 -0700
+++ b/jdk/src/share/classes/javax/swing/JTable.java Wed May 19 12:27:47 2010 -0700
@@ -719,8 +719,9 @@
* @see #addNotify
*/
protected void configureEnclosingScrollPane() {
- JViewport port = SwingUtilities.getParentViewport(this);
- if (port != null) {
+ Container parent = SwingUtilities.getUnwrappedParent(this);
+ if (parent instanceof JViewport) {
+ JViewport port = (JViewport) parent;
Container gp = port.getParent();
if (gp instanceof JScrollPane) {
JScrollPane scrollPane = (JScrollPane)gp;
@@ -752,8 +753,9 @@
* from configureEnclosingScrollPane() and updateUI() in a safe manor.
*/
private void configureEnclosingScrollPaneUI() {
- JViewport port = SwingUtilities.getParentViewport(this);
- if (port != null) {
+ Container parent = SwingUtilities.getUnwrappedParent(this);
+ if (parent instanceof JViewport) {
+ JViewport port = (JViewport) parent;
Container gp = port.getParent();
if (gp instanceof JScrollPane) {
JScrollPane scrollPane = (JScrollPane)gp;
@@ -822,8 +824,9 @@
* @since 1.3
*/
protected void unconfigureEnclosingScrollPane() {
- JViewport port = SwingUtilities.getParentViewport(this);
- if (port != null) {
+ Container parent = SwingUtilities.getUnwrappedParent(this);
+ if (parent instanceof JViewport) {
+ JViewport port = (JViewport) parent;
Container gp = port.getParent();
if (gp instanceof JScrollPane) {
JScrollPane scrollPane = (JScrollPane)gp;
@@ -5217,10 +5220,10 @@
* @see #getFillsViewportHeight
*/
public boolean getScrollableTracksViewportHeight() {
- JViewport port = SwingUtilities.getParentViewport(this);
+ Container parent = SwingUtilities.getUnwrappedParent(this);
return getFillsViewportHeight()
- && port != null
- && port.getHeight() > getPreferredSize().height;
+ && parent instanceof JViewport
+ && parent.getHeight() > getPreferredSize().height;
}
/**
--- a/jdk/src/share/classes/javax/swing/JTextField.java Thu May 13 13:22:22 2010 -0700
+++ b/jdk/src/share/classes/javax/swing/JTextField.java Wed May 19 12:27:47 2010 -0700
@@ -292,7 +292,7 @@
*/
@Override
public boolean isValidateRoot() {
- return SwingUtilities.getParentViewport(this) == null;
+ return !(SwingUtilities.getUnwrappedParent(this) instanceof JViewport);
}
--- a/jdk/src/share/classes/javax/swing/JTree.java Thu May 13 13:22:22 2010 -0700
+++ b/jdk/src/share/classes/javax/swing/JTree.java Wed May 19 12:27:47 2010 -0700
@@ -3498,9 +3498,9 @@
* @see Scrollable#getScrollableTracksViewportWidth
*/
public boolean getScrollableTracksViewportWidth() {
- JViewport port = SwingUtilities.getParentViewport(this);
- if (port != null) {
- return port.getWidth() > getPreferredSize().width;
+ Container parent = SwingUtilities.getUnwrappedParent(this);
+ if (parent instanceof JViewport) {
+ return parent.getWidth() > getPreferredSize().width;
}
return false;
}
@@ -3515,9 +3515,9 @@
* @see Scrollable#getScrollableTracksViewportHeight
*/
public boolean getScrollableTracksViewportHeight() {
- JViewport port = SwingUtilities.getParentViewport(this);
- if (port != null) {
- return port.getHeight() > getPreferredSize().height;
+ Container parent = SwingUtilities.getUnwrappedParent(this);
+ if (parent instanceof JViewport) {
+ return parent.getHeight() > getPreferredSize().height;
}
return false;
}
--- a/jdk/src/share/classes/javax/swing/SwingUtilities.java Thu May 13 13:22:22 2010 -0700
+++ b/jdk/src/share/classes/javax/swing/SwingUtilities.java Wed May 19 12:27:47 2010 -0700
@@ -1969,58 +1969,53 @@
}
/**
- * Looks for the first ancestor of the {@code component}
+ * Returns the first ancestor of the {@code component}
* which is not an instance of {@link JLayer}.
- * If this ancestor is an instance of {@code JViewport},
- * this {@code JViewport} is returned, otherwise returns {@code null}.
- * The following way of obtaining the parent {@code JViewport}
- * is not recommended any more:
- * <pre>
- * JViewport port = null;
- * Container parent = component.getParent();
- * // not recommended any more
- * if(parent instanceof JViewport) {
- * port = (JViewport) parent;
- * }
- * </pre>
- * Here is the way to go:
- * <pre>
- * // the correct way:
- * JViewport port = SwingUtilities.getParentViewport(component);
- * </pre>
- * @param component {@code Component} to get the parent {@code JViewport} of.
- * @return the {@code JViewport} instance for the {@code component}
- * or {@code null}
+ *
+ * @param component {@code Component} to get
+ * the first ancestor of, which is not a {@link JLayer} instance.
+ *
+ * @return the first ancestor of the {@code component}
+ * which is not an instance of {@link JLayer}.
+ * If such an ancestor can not be found, {@code null} is returned.
+ *
* @throws NullPointerException if {@code component} is {@code null}
+ * @see JLayer
*
* @since 1.7
*/
- public static JViewport getParentViewport(Component component) {
- do {
- component = component.getParent();
- if (component instanceof JViewport) {
- return (JViewport) component;
- }
- } while(component instanceof JLayer);
- return null;
+ public static Container getUnwrappedParent(Component component) {
+ Container parent = component.getParent();
+ while(parent instanceof JLayer) {
+ parent = parent.getParent();
+ }
+ return parent;
}
/**
* Returns the first {@code JViewport}'s descendant
- * which is not an instance of {@code JLayer} or {@code null}.
+ * which is not an instance of {@code JLayer}.
+ * If such a descendant can not be found, {@code null} is returned.
*
* If the {@code viewport}'s view component is not a {@code JLayer},
- * this method is equal to {@link JViewport#getView()}
- * otherwise {@link JLayer#getView()} will be recursively tested
+ * this method is equivalent to {@link JViewport#getView()}
+ * otherwise {@link JLayer#getView()} will be recursively
+ * called on all descending {@code JLayer}s.
+ *
+ * @param viewport {@code JViewport} to get the first descendant of,
+ * which in not a {@code JLayer} instance.
*
* @return the first {@code JViewport}'s descendant
- * which is not an instance of {@code JLayer} or {@code null}.
+ * which is not an instance of {@code JLayer}.
+ * If such a descendant can not be found, {@code null} is returned.
*
* @throws NullPointerException if {@code viewport} is {@code null}
* @see JViewport#getView()
* @see JLayer
+ *
+ * @since 1.7
*/
- static Component getUnwrappedView(JViewport viewport) {
+ public static Component getUnwrappedView(JViewport viewport) {
Component view = viewport.getView();
while (view instanceof JLayer) {
view = ((JLayer)view).getView();
--- a/jdk/src/share/classes/javax/swing/SwingWorker.java Thu May 13 13:22:22 2010 -0700
+++ b/jdk/src/share/classes/javax/swing/SwingWorker.java Wed May 19 12:27:47 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2005-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2005-2010 Sun Microsystems, Inc. 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,10 @@
import sun.swing.AccumulativeRunnable;
/**
- * An abstract class to perform lengthy GUI-interacting tasks in a
- * dedicated thread.
- *
+ * An abstract class to perform lengthy GUI-interaction tasks in a
+ * background thread. Several background threads can be used to execute such
+ * tasks. However, the exact strategy of choosing a thread for any particular
+ * {@code SwingWorker} is unspecified and should not be relied on.
* <p>
* When writing a multi-threaded application using Swing, there are
* two constraints to keep in mind:
@@ -772,7 +773,7 @@
};
executorService =
- new ThreadPoolExecutor(1, MAX_WORKER_THREADS,
+ new ThreadPoolExecutor(MAX_WORKER_THREADS, MAX_WORKER_THREADS,
10L, TimeUnit.MINUTES,
new LinkedBlockingQueue<Runnable>(),
threadFactory);
--- a/jdk/src/share/classes/javax/swing/plaf/LayerUI.java Thu May 13 13:22:22 2010 -0700
+++ b/jdk/src/share/classes/javax/swing/plaf/LayerUI.java Wed May 19 12:27:47 2010 -0700
@@ -72,58 +72,18 @@
* the specified {@code Graphics} object to
* render the content of the component.
* <p/>
- * If {@code g} is not an instance of {@code Graphics2D},
- * this method is no-op.
+ * The default implementation paints the passed component as is.
*
- * @param g the {@code Graphics} context in which to paint;
- * @param c the component being painted;
- * it can be safely cast to {@code JLayer<? extends V>}
- *
- * @see #configureGraphics(Graphics2D, JLayer)
- * @see #paintLayer(Graphics2D, JLayer)
+ * @param g the {@code Graphics} context in which to paint
+ * @param c the component being painted
*/
public void paint(Graphics g, JComponent c) {
- if (g instanceof Graphics2D) {
- Graphics2D g2 = (Graphics2D) g.create();
- JLayer<? extends V> l = (JLayer<? extends V>) c;
- configureGraphics(g2, l);
- paintLayer(g2, l);
- g2.dispose();
- }
+ c.paint(g);
}
/**
- * This method is called by the {@link #paint} method prior to
- * {@link #paintLayer} to configure the {@code Graphics2D} object.
- * The default implementation is empty.
- *
- * @param g2 the {@code Graphics2D} object to configure
- * @param l the {@code JLayer} being painted
- *
- * @see #paintLayer(Graphics2D, JLayer)
- */
- protected void configureGraphics(Graphics2D g2, JLayer<? extends V> l) {
- }
-
- /**
- * Called by the {@link #paint} method,
- * subclasses should override this method
- * to perform any custom painting operations.
- * <p/>
- * The default implementation paints the passed {@code JLayer} as is.
- *
- * @param g2 the {@code Graphics2D} context in which to paint
- * @param l the {@code JLayer} being painted
- *
- * @see #configureGraphics(Graphics2D, JLayer)
- */
- protected void paintLayer(Graphics2D g2, JLayer<? extends V> l) {
- l.paint(g2);
- }
-
- /**
- * Dispatches {@code AWTEvent}s for {@code JLayer}
- * and <b>all its subcomponents</b> to this {@code LayerUI} instance.
+ * Processes {@code AWTEvent}s for {@code JLayer}
+ * and <b>all its descendants</b> to this {@code LayerUI} instance.
* <p/>
* To enable the {@code AWTEvent}s of a particular type,
* you call {@link JLayer#setLayerEventMask}
@@ -133,13 +93,14 @@
* By default this method calls the appropriate
* {@code process<event type>Event}
* method for the given class of event.
+ * <p/>
+ * <b>Note:</b> Events are processed only for displayable {@code JLayer}s.
*
* @param e the event to be dispatched
* @param l the layer this LayerUI is set to
*
* @see JLayer#setLayerEventMask(long)
- * @see #installUI(javax.swing.JComponent)
- * @see #uninstallUI(javax.swing.JComponent)
+ * @see Component#isDisplayable()
* @see #processComponentEvent
* @see #processFocusEvent
* @see #processKeyEvent
@@ -628,17 +589,6 @@
}
/**
- * Repaints all {@code JLayer} instances this {@code LayerUI} is set to.
- * Call this method when the state of this {@code LayerUI} is changed
- * and the visual appearance of its {@code JLayer} objects needs to be updated.
- *
- * @see Component#repaint()
- */
- protected void repaintLayer() {
- firePropertyChange("dirty", null, null);
- }
-
- /**
* Notifies the {@code LayerUI} when any of its property are changed
* and enables updating every {@code JLayer}
* this {@code LayerUI} instance is set to.
@@ -647,9 +597,6 @@
* @param l the {@code JLayer} this LayerUI is set to
*/
public void applyPropertyChange(PropertyChangeEvent evt, JLayer<? extends V> l) {
- if ("dirty".equals(evt.getPropertyName())) {
- l.repaint();
- }
}
/**
--- a/jdk/src/share/classes/javax/swing/plaf/nimbus/NimbusStyle.java Thu May 13 13:22:22 2010 -0700
+++ b/jdk/src/share/classes/javax/swing/plaf/nimbus/NimbusStyle.java Wed May 19 12:27:47 2010 -0700
@@ -38,6 +38,7 @@
import java.awt.Color;
import java.awt.Font;
import java.awt.Insets;
+import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@@ -193,7 +194,7 @@
* UIDefaults which overrides (or supplements) those defaults found in
* UIManager.
*/
- private JComponent component;
+ private WeakReference<JComponent> component;
/**
* Create a new NimbusStyle. Only the prefix must be supplied. At the
@@ -209,7 +210,9 @@
* should be null otherwise.
*/
NimbusStyle(String prefix, JComponent c) {
- this.component = c;
+ if (c != null) {
+ this.component = new WeakReference<JComponent>(c);
+ }
this.prefix = prefix;
this.painter = new SynthPainterImpl(this);
}
@@ -251,9 +254,11 @@
// value is an instance of UIDefaults, then these defaults are used
// in place of, or in addition to, the defaults in UIManager.
if (component != null) {
- Object o = component.getClientProperty("Nimbus.Overrides");
+ // We know component.get() is non-null here, as if the component
+ // were GC'ed, we wouldn't be processing its style.
+ Object o = component.get().getClientProperty("Nimbus.Overrides");
if (o instanceof UIDefaults) {
- Object i = component.getClientProperty(
+ Object i = component.get().getClientProperty(
"Nimbus.Overrides.InheritDefaults");
boolean inherit = i instanceof Boolean ? (Boolean)i : true;
UIDefaults d = (UIDefaults)o;
--- a/jdk/src/share/classes/javax/swing/text/JTextComponent.java Thu May 13 13:22:22 2010 -0700
+++ b/jdk/src/share/classes/javax/swing/text/JTextComponent.java Wed May 19 12:27:47 2010 -0700
@@ -2069,9 +2069,9 @@
* width to match its own
*/
public boolean getScrollableTracksViewportWidth() {
- JViewport port = SwingUtilities.getParentViewport(this);
- if (port != null) {
- return port.getWidth() > getPreferredSize().width;
+ Container parent = SwingUtilities.getUnwrappedParent(this);
+ if (parent instanceof JViewport) {
+ return parent.getWidth() > getPreferredSize().width;
}
return false;
}
@@ -2090,9 +2090,9 @@
* to match its own
*/
public boolean getScrollableTracksViewportHeight() {
- JViewport port = SwingUtilities.getParentViewport(this);
- if (port != null) {
- return (port.getHeight() > getPreferredSize().height);
+ Container parent = SwingUtilities.getUnwrappedParent(this);
+ if (parent instanceof JViewport) {
+ return parent.getHeight() > getPreferredSize().height;
}
return false;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/misc/JavaSecurityCodeSignerAccess.java Wed May 19 12:27:47 2010 -0700
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2010 Sun Microsystems, Inc. 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package sun.misc;
+
+import java.security.CodeSigner;
+import java.security.cert.CRL;
+
+public interface JavaSecurityCodeSignerAccess {
+ void setCRLs(CodeSigner signer, CRL[] crls);
+ CRL[] getCRLs(CodeSigner signer);
+}
--- a/jdk/src/share/classes/sun/misc/SharedSecrets.java Thu May 13 13:22:22 2010 -0700
+++ b/jdk/src/share/classes/sun/misc/SharedSecrets.java Wed May 19 12:27:47 2010 -0700
@@ -27,8 +27,8 @@
import java.util.jar.JarFile;
import java.io.Console;
-import java.io.File;
import java.io.FileDescriptor;
+import java.security.CodeSigner;
import java.security.ProtectionDomain;
/** A repository of "shared secrets", which are a mechanism for
@@ -49,6 +49,7 @@
private static JavaNioAccess javaNioAccess;
private static JavaIOFileDescriptorAccess javaIOFileDescriptorAccess;
private static JavaSecurityProtectionDomainAccess javaSecurityProtectionDomainAccess;
+ private static JavaSecurityCodeSignerAccess javaSecurityCodeSignerAccess;
public static JavaUtilJarAccess javaUtilJarAccess() {
if (javaUtilJarAccess == null) {
@@ -126,4 +127,16 @@
unsafe.ensureClassInitialized(ProtectionDomain.class);
return javaSecurityProtectionDomainAccess;
}
+
+ public static void setJavaSecurityCodeSignerAccess
+ (JavaSecurityCodeSignerAccess jscsa) {
+ javaSecurityCodeSignerAccess = jscsa;
+ }
+
+ public static JavaSecurityCodeSignerAccess
+ getJavaSecurityCodeSignerAccess() {
+ if (javaSecurityCodeSignerAccess == null)
+ unsafe.ensureClassInitialized(CodeSigner.class);
+ return javaSecurityCodeSignerAccess;
+ }
}
--- a/jdk/src/share/classes/sun/net/httpserver/ExchangeImpl.java Thu May 13 13:22:22 2010 -0700
+++ b/jdk/src/share/classes/sun/net/httpserver/ExchangeImpl.java Wed May 19 12:27:47 2010 -0700
@@ -26,16 +26,12 @@
package sun.net.httpserver;
import java.io.*;
-import java.nio.*;
-import java.nio.channels.*;
import java.net.*;
import javax.net.ssl.*;
import java.util.*;
import java.util.logging.Logger;
import java.text.*;
-import sun.net.www.MessageHeader;
import com.sun.net.httpserver.*;
-import com.sun.net.httpserver.spi.*;
class ExchangeImpl {
@@ -65,6 +61,8 @@
df.setTimeZone (tz);
}
+ private static final String HEAD = "HEAD";
+
/* streams which take care of the HTTP protocol framing
* and are passed up to higher layers
*/
@@ -116,6 +114,10 @@
return connection.getHttpContext();
}
+ private boolean isHeadRequest() {
+ return HEAD.equals(getRequestMethod());
+ }
+
public void close () {
if (closed) {
return;
@@ -220,24 +222,36 @@
}
contentLen = -1;
}
- if (contentLen == 0) {
- if (http10) {
- o.setWrappedStream (new UndefLengthOutputStream (this, ros));
- close = true;
- } else {
- rspHdrs.set ("Transfer-encoding", "chunked");
- o.setWrappedStream (new ChunkedOutputStream (this, ros));
+
+ if (isHeadRequest()) {
+ /* HEAD requests should not set a content length by passing it
+ * through this API, but should instead manually set the required
+ * headers.*/
+ if (contentLen >= 0) {
+ final Logger logger = server.getLogger();
+ String msg =
+ "sendResponseHeaders: being invoked with a content length for a HEAD request";
+ logger.warning (msg);
}
- } else {
- if (contentLen == -1) {
- noContentToSend = true;
- contentLen = 0;
+ noContentToSend = true;
+ contentLen = 0;
+ } else { /* not a HEAD request */
+ if (contentLen == 0) {
+ if (http10) {
+ o.setWrappedStream (new UndefLengthOutputStream (this, ros));
+ close = true;
+ } else {
+ rspHdrs.set ("Transfer-encoding", "chunked");
+ o.setWrappedStream (new ChunkedOutputStream (this, ros));
+ }
+ } else {
+ if (contentLen == -1) {
+ noContentToSend = true;
+ contentLen = 0;
+ }
+ rspHdrs.set("Content-length", Long.toString(contentLen));
+ o.setWrappedStream (new FixedLengthOutputStream (this, ros, contentLen));
}
- /* content len might already be set, eg to implement HEAD resp */
- if (rspHdrs.getFirst ("Content-length") == null) {
- rspHdrs.set ("Content-length", Long.toString(contentLen));
- }
- o.setWrappedStream (new FixedLengthOutputStream (this, ros, contentLen));
}
write (rspHdrs, tmpout);
this.rspContentLen = contentLen;
--- a/jdk/src/share/classes/sun/net/httpserver/ServerImpl.java Thu May 13 13:22:22 2010 -0700
+++ b/jdk/src/share/classes/sun/net/httpserver/ServerImpl.java Wed May 19 12:27:47 2010 -0700
@@ -451,6 +451,7 @@
if (requestLine == null) {
/* connection closed */
connection.close();
+ allConnections.remove(connection);
return;
}
int space = requestLine.indexOf (' ');
@@ -592,6 +593,8 @@
sendReply (
code, true, "<h1>"+code+Code.msg(code)+"</h1>"+message
);
+ /* connection is already closed by sendReply, now remove it */
+ allConnections.remove(connection);
}
void sendReply (
--- a/jdk/src/share/classes/sun/net/www/protocol/http/BasicAuthentication.java Thu May 13 13:22:22 2010 -0700
+++ b/jdk/src/share/classes/sun/net/www/protocol/http/BasicAuthentication.java Wed May 19 12:27:47 2010 -0700
@@ -29,8 +29,10 @@
import java.net.URI;
import java.net.URISyntaxException;
import java.net.PasswordAuthentication;
+import java.io.IOException;
+import java.io.OutputStream;
import sun.net.www.HeaderParser;
-
+import sun.misc.BASE64Encoder;
/**
* BasicAuthentication: Encapsulate an http server authentication using
@@ -74,7 +76,7 @@
System.arraycopy(nameBytes, 0, concat, 0, nameBytes.length);
System.arraycopy(passwdBytes, 0, concat, nameBytes.length,
passwdBytes.length);
- this.auth = "Basic " + (new sun.misc.BASE64Encoder()).encode(concat);
+ this.auth = "Basic " + (new BasicBASE64Encoder()).encode(concat);
this.pw = pw;
}
@@ -114,7 +116,7 @@
System.arraycopy(nameBytes, 0, concat, 0, nameBytes.length);
System.arraycopy(passwdBytes, 0, concat, nameBytes.length,
passwdBytes.length);
- this.auth = "Basic " + (new sun.misc.BASE64Encoder()).encode(concat);
+ this.auth = "Basic " + (new BasicBASE64Encoder()).encode(concat);
this.pw = pw;
}
@@ -200,4 +202,11 @@
return npath;
}
+ /* It is never expected that the header value will exceed the bytesPerLine */
+ private class BasicBASE64Encoder extends BASE64Encoder {
+ @Override
+ protected int bytesPerLine() {
+ return (10000);
+ }
+ }
}
--- a/jdk/src/share/classes/sun/security/krb5/Config.java Thu May 13 13:22:22 2010 -0700
+++ b/jdk/src/share/classes/sun/security/krb5/Config.java Wed May 19 12:27:47 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Portions Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Portions Copyright 2000-2010 Sun Microsystems, Inc. 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
@@ -109,7 +109,7 @@
public static synchronized void refresh() throws KrbException {
singleton = new Config();
KeyTab.refresh();
- KrbKdcReq.KdcAccessibility.reset();
+ KrbKdcReq.initStatic();
}
--- a/jdk/src/share/classes/sun/security/krb5/EncryptionKey.java Thu May 13 13:22:22 2010 -0700
+++ b/jdk/src/share/classes/sun/security/krb5/EncryptionKey.java Wed May 19 12:27:47 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Portions Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Portions Copyright 2000-2010 Sun Microsystems, Inc. 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
@@ -499,8 +499,9 @@
+ " kvno=" + kvno
+ " keyValue (hex dump)="
+ (keyValue == null || keyValue.length == 0 ?
- " Empty Key" : '\n' + Krb5.hexDumper.encode(keyValue)
- + '\n'));
+ " Empty Key" : '\n'
+ + Krb5.hexDumper.encodeBuffer(keyValue)
+ + '\n'));
}
/**
--- a/jdk/src/share/classes/sun/security/krb5/KrbKdcReq.java Thu May 13 13:22:22 2010 -0700
+++ b/jdk/src/share/classes/sun/security/krb5/KrbKdcReq.java Wed May 19 12:27:47 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Portions Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Portions Copyright 2000-2010 Sun Microsystems, Inc. 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,28 +51,31 @@
public abstract class KrbKdcReq {
- // Currently there is no option to specify retries
- // in the kerberos configuration file
-
- private static final int DEFAULT_KDC_RETRY_LIMIT = Krb5.KDC_RETRY_LIMIT;
+ // The following settings can be configured in [libdefaults]
+ // section of krb5.conf, which are global for all realms. Each of
+ // them can also be defined in a realm, which overrides value here.
/**
- * Default timeout period when requesting a ticket from a KDC.
- * If not specified in the configuration file,
- * a value of 30 seconds is used.
+ * max retry time for a single KDC, default Krb5.KDC_RETRY_LIMIT (3)
+ */
+ private static int defaultKdcRetryLimit;
+ /**
+ * timeout requesting a ticket from KDC, in millisec, default 30 sec
*/
- public static final int DEFAULT_KDC_TIMEOUT; // milliseconds
+ private static int defaultKdcTimeout;
+ /**
+ * max UDP packet size, default unlimited (-1)
+ */
+ private static int defaultUdpPrefLimit;
private static final boolean DEBUG = Krb5.DEBUG;
- private static int udpPrefLimit = -1;
-
private static final String BAD_POLICY_KEY = "krb5.kdc.bad.policy";
/**
* What to do when a KDC is unavailable, specified in the
* java.security file with key krb5.kdc.bad.policy.
- * Possible values can be TRY_LAST or TRY_LESS
+ * Possible values can be TRY_LAST or TRY_LESS. Reloaded when refreshed.
*/
private enum BpType {
NONE, TRY_LAST, TRY_LESS
@@ -80,9 +83,16 @@
private static int tryLessMaxRetries = 1;
private static int tryLessTimeout = 5000;
- private static final BpType badPolicy;
+ private static BpType badPolicy;
static {
+ initStatic();
+ }
+
+ /**
+ * Read global settings
+ */
+ public static void initStatic() {
String value = AccessController.doPrivileged(
new PrivilegedAction<String>() {
public String run() {
@@ -95,9 +105,21 @@
if ("tryless".equals(ss[0])) {
if (ss.length > 1) {
String[] params = ss[1].split(",");
- tryLessMaxRetries = Integer.parseInt(params[0]);
- if (params.length > 1) {
- tryLessTimeout = Integer.parseInt(params[1]);
+ try {
+ int tmp0 = Integer.parseInt(params[0]);
+ if (params.length > 1) {
+ tryLessTimeout = Integer.parseInt(params[1]);
+ }
+ // Assign here in case of exception at params[1]
+ tryLessMaxRetries = tmp0;
+ } catch (NumberFormatException nfe) {
+ // Ignored. Please note that tryLess is recognized and
+ // used, parameters using default values
+ if (DEBUG) {
+ System.out.println("Invalid " + BAD_POLICY_KEY +
+ " parameter for tryLess: " +
+ value + ", use default");
+ }
}
}
badPolicy = BpType.TRY_LESS;
@@ -110,30 +132,33 @@
badPolicy = BpType.NONE;
}
- /*
- * Get default timeout.
- */
int timeout = -1;
+ int max_retries = -1;
+ int udf_pref_limit = -1;
+
try {
Config cfg = Config.getInstance();
String temp = cfg.getDefault("kdc_timeout", "libdefaults");
timeout = parsePositiveIntString(temp);
+ temp = cfg.getDefault("max_retries", "libdefaults");
+ max_retries = parsePositiveIntString(temp);
temp = cfg.getDefault("udp_preference_limit", "libdefaults");
- udpPrefLimit = parsePositiveIntString(temp);
+ udf_pref_limit = parsePositiveIntString(temp);
} catch (Exception exc) {
- // ignore any exceptions; use the default time out values
+ // ignore any exceptions; use default values
if (DEBUG) {
- System.out.println ("Exception in getting kdc_timeout value, " +
- "using default value " +
+ System.out.println ("Exception in getting KDC communication " +
+ "settings, using default value " +
exc.getMessage());
}
}
+ defaultKdcTimeout = timeout > 0 ? timeout : 30*1000; // 30 seconds
+ defaultKdcRetryLimit =
+ max_retries > 0 ? max_retries : Krb5.KDC_RETRY_LIMIT;
+ defaultUdpPrefLimit = udf_pref_limit;
- if (timeout > 0)
- DEFAULT_KDC_TIMEOUT = timeout;
- else
- DEFAULT_KDC_TIMEOUT = 30*1000; // 30 seconds
+ KdcAccessibility.reset();
}
protected byte[] obuf;
@@ -151,6 +176,9 @@
public String send(String realm)
throws IOException, KrbException {
+ int udpPrefLimit = getRealmSpecificValue(
+ realm, "udp_preference_limit", defaultUdpPrefLimit);
+
boolean useTCP = (udpPrefLimit > 0 &&
(obuf != null && obuf.length > udpPrefLimit));
@@ -213,9 +241,10 @@
return;
int port = Krb5.KDC_INET_DEFAULT_PORT;
- int retries = DEFAULT_KDC_RETRY_LIMIT;
- int timeout = getKdcTimeout(realm);
-
+ int retries = getRealmSpecificValue(
+ realm, "max_retries", defaultKdcRetryLimit);
+ int timeout = getRealmSpecificValue(
+ realm, "kdc_timeout", defaultKdcTimeout);
if (badPolicy == BpType.TRY_LESS &&
KdcAccessibility.isBad(tempKdc)) {
if (retries > tryLessMaxRetries) {
@@ -322,6 +351,12 @@
if (useTCP) {
TCPClient kdcClient = new TCPClient(kdc, port);
+ if (DEBUG) {
+ System.out.println(">>> KDCCommunication: kdc=" + kdc
+ + " TCP:"
+ + port
+ + ", #bytes=" + obuf.length);
+ }
try {
/*
* Send the data to the kdc.
@@ -336,7 +371,7 @@
}
} else {
- // For each KDC we try DEFAULT_KDC_RETRY_LIMIT (3) times to
+ // For each KDC we try defaultKdcRetryLimit times to
// get the response
for (int i=1; i <= retries; i++) {
UDPClient kdcClient = new UDPClient(kdc, port, timeout);
@@ -382,37 +417,37 @@
}
/**
- * Returns a timeout value for the KDC of the given realm.
- * A KDC-specific timeout, if specified in the config file,
- * overrides the default timeout (which may also be specified
- * in the config file). Default timeout is returned if null
- * is specified for realm.
- * @param realm the realm which kdc's timeout is requested
- * @return KDC timeout
+ * Returns krb5.conf setting of {@code key} for a specfic realm,
+ * which can be:
+ * 1. defined in the sub-stanza for the given realm inside [realms], or
+ * 2. defined in [libdefaults], or
+ * 3. defValue
+ * @param realm the given realm in which the setting is requested. Returns
+ * the global setting if null
+ * @param key the key for the setting
+ * @param defValue default value
+ * @return a value for the key
*/
- private int getKdcTimeout(String realm)
- {
- int timeout = DEFAULT_KDC_TIMEOUT;
+ private int getRealmSpecificValue(String realm, String key, int defValue) {
+ int v = defValue;
- if (realm == null)
- return timeout;
+ if (realm == null) return v;
- int tempTimeout = -1;
+ int temp = -1;
try {
- String temp =
- Config.getInstance().getDefault("kdc_timeout", realm);
- tempTimeout = parsePositiveIntString(temp);
+ String value =
+ Config.getInstance().getDefault(key, realm);
+ temp = parsePositiveIntString(value);
} catch (Exception exc) {
+ // Ignored, defValue will be picked up
}
- if (tempTimeout > 0)
- timeout = tempTimeout;
+ if (temp > 0) v = temp;
- return timeout;
+ return v;
}
- private static int parsePositiveIntString(String intString)
- {
+ private static int parsePositiveIntString(String intString) {
if (intString == null)
return -1;
@@ -461,7 +496,7 @@
return bads.contains(kdc);
}
- public static synchronized void reset() {
+ private static synchronized void reset() {
if (DEBUG) {
System.out.println(">>> KdcAccessibility: reset");
}
--- a/jdk/src/share/classes/sun/security/krb5/PrincipalName.java Thu May 13 13:22:22 2010 -0700
+++ b/jdk/src/share/classes/sun/security/krb5/PrincipalName.java Wed May 19 12:27:47 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Portions Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Portions Copyright 2000-2010 Sun Microsystems, Inc. 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
@@ -101,7 +101,7 @@
private Realm nameRealm; // optional; a null realm means use default
// Note: the nameRealm is not included in the default ASN.1 encoding
- // salt for principal
+ // cached salt, might be changed by KDC info, not used in clone
private String salt = null;
protected PrincipalName() {
@@ -123,18 +123,19 @@
}
public Object clone() {
- PrincipalName pName = new PrincipalName();
- pName.nameType = nameType;
- if (nameStrings != null) {
- pName.nameStrings =
- new String[nameStrings.length];
- System.arraycopy(nameStrings,0,pName.nameStrings,0,
- nameStrings.length);
+ try {
+ PrincipalName pName = (PrincipalName) super.clone();
+ // Re-assign mutable fields
+ if (nameStrings != null) {
+ pName.nameStrings = nameStrings.clone();
+ }
+ if (nameRealm != null) {
+ pName.nameRealm = (Realm)nameRealm.clone();
+ }
+ return pName;
+ } catch (CloneNotSupportedException ex) {
+ throw new AssertionError("Should never happen");
}
- if (nameRealm != null) {
- pName.nameRealm = (Realm)nameRealm.clone();
- }
- return pName;
}
/*
--- a/jdk/src/share/classes/sun/security/pkcs/PKCS7.java Thu May 13 13:22:22 2010 -0700
+++ b/jdk/src/share/classes/sun/security/pkcs/PKCS7.java Wed May 19 12:27:47 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1996-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1996-2010 Sun Microsystems, Inc. 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
@@ -28,7 +28,6 @@
import java.io.*;
import java.math.BigInteger;
import java.util.*;
-import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.security.cert.CertificateException;
import java.security.cert.X509CRL;
@@ -173,20 +172,30 @@
* @param digestAlgorithmIds the message digest algorithm identifiers.
* @param contentInfo the content information.
* @param certificates an array of X.509 certificates.
+ * @param crls an array of CRLs
* @param signerInfos an array of signer information.
*/
public PKCS7(AlgorithmId[] digestAlgorithmIds,
ContentInfo contentInfo,
X509Certificate[] certificates,
+ X509CRL[] crls,
SignerInfo[] signerInfos) {
version = BigInteger.ONE;
this.digestAlgorithmIds = digestAlgorithmIds;
this.contentInfo = contentInfo;
this.certificates = certificates;
+ this.crls = crls;
this.signerInfos = signerInfos;
}
+ public PKCS7(AlgorithmId[] digestAlgorithmIds,
+ ContentInfo contentInfo,
+ X509Certificate[] certificates,
+ SignerInfo[] signerInfos) {
+ this(digestAlgorithmIds, contentInfo, certificates, null, signerInfos);
+ }
+
private void parseNetscapeCertChain(DerValue val)
throws ParsingException, IOException {
DerInputStream dis = new DerInputStream(val.toByteArray());
@@ -312,7 +321,7 @@
ByteArrayInputStream bais = null;
try {
if (certfac == null)
- crls[i] = (X509CRL) new X509CRLImpl(crlVals[i]);
+ crls[i] = new X509CRLImpl(crlVals[i]);
else {
byte[] encoded = crlVals[i].toByteArray();
bais = new ByteArrayInputStream(encoded);
@@ -480,7 +489,30 @@
signedData.putOrderedSetOf((byte)0xA0, implCerts);
}
- // no crls (OPTIONAL field)
+ // CRLs (optional)
+ if (crls != null && crls.length != 0) {
+ // cast to X509CRLImpl[] since X509CRLImpl implements DerEncoder
+ Set<X509CRLImpl> implCRLs = new HashSet<X509CRLImpl>(crls.length);
+ for (X509CRL crl: crls) {
+ if (crl instanceof X509CRLImpl)
+ implCRLs.add((X509CRLImpl) crl);
+ else {
+ try {
+ byte[] encoded = crl.getEncoded();
+ implCRLs.add(new X509CRLImpl(encoded));
+ } catch (CRLException ce) {
+ IOException ie = new IOException(ce.getMessage());
+ ie.initCause(ce);
+ throw ie;
+ }
+ }
+ }
+
+ // Add the CRL set (tagged with [1] IMPLICIT)
+ // to the signed data
+ signedData.putOrderedSetOf((byte)0xA1,
+ implCRLs.toArray(new X509CRLImpl[implCRLs.size()]));
+ }
// signerInfos
signedData.putOrderedSetOf(DerValue.tag_Set, signerInfos);
--- a/jdk/src/share/classes/sun/security/provider/certpath/CertId.java Thu May 13 13:22:22 2010 -0700
+++ b/jdk/src/share/classes/sun/security/provider/certpath/CertId.java Wed May 19 12:27:47 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2003-2010 Sun Microsystems, Inc. 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
@@ -96,9 +96,9 @@
HexDumpEncoder encoder = new HexDumpEncoder();
System.out.println("Issuer Certificate is " + issuerCert);
System.out.println("issuerNameHash is " +
- encoder.encode(issuerNameHash));
+ encoder.encodeBuffer(issuerNameHash));
System.out.println("issuerKeyHash is " +
- encoder.encode(issuerKeyHash));
+ encoder.encodeBuffer(issuerKeyHash));
System.out.println("SerialNumber is " + serialNumber.getNumber());
}
}
--- a/jdk/src/share/classes/sun/security/tools/JarSigner.java Thu May 13 13:22:22 2010 -0700
+++ b/jdk/src/share/classes/sun/security/tools/JarSigner.java Wed May 19 12:27:47 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1997-2010 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
package sun.security.tools;
import java.io.*;
+import java.security.cert.X509CRL;
import java.util.*;
import java.util.zip.*;
import java.util.jar.*;
@@ -35,6 +36,7 @@
import java.text.Collator;
import java.text.MessageFormat;
import java.security.cert.Certificate;
+import java.security.cert.CRL;
import java.security.cert.X509Certificate;
import java.security.cert.CertificateException;
import java.security.*;
@@ -56,6 +58,7 @@
import sun.security.x509.*;
import sun.security.util.*;
import sun.misc.BASE64Encoder;
+import sun.misc.SharedSecrets;
/**
@@ -114,14 +117,16 @@
static final int SIGNED_BY_ALIAS = 0x08; // signer is in alias list
X509Certificate[] certChain; // signer's cert chain (when composing)
+ Set<X509CRL> crls; // signer provided CRLs
PrivateKey privateKey; // private key
KeyStore store; // the keystore specified by -keystore
// or the default keystore, never null
String keystore; // key store file
+ List<String> crlfiles = new ArrayList<String>(); // CRL files to add
boolean nullStream = false; // null keystore input stream (NONE)
boolean token = false; // token-based keystore
- String jarfile; // jar file to sign or verify
+ String jarfile; // jar files to sign or verify
String alias; // alias to sign jar with
List<String> ckaliases = new ArrayList<String>(); // aliases in -verify
char[] storepass; // keystore password
@@ -146,6 +151,7 @@
boolean signManifest = true; // "sign" the whole manifest
boolean externalSF = true; // leave the .SF out of the PKCS7 block
boolean strict = false; // treat warnings as error
+ boolean autoCRL = false; // Automatcially add CRL defined in cert
// read zip entry raw bytes
private ByteArrayOutputStream baos = new ByteArrayOutputStream(2048);
@@ -226,6 +232,29 @@
} else {
loadKeyStore(keystore, true);
getAliasInfo(alias);
+ crls = new HashSet<X509CRL>();
+ if (crlfiles.size() > 0 || autoCRL) {
+ CertificateFactory fac =
+ CertificateFactory.getInstance("X509");
+ List<CRL> list = new ArrayList<CRL>();
+ for (String file: crlfiles) {
+ Collection<? extends CRL> tmp = KeyTool.loadCRLs(file);
+ for (CRL crl: tmp) {
+ if (crl instanceof X509CRL) {
+ crls.add((X509CRL)crl);
+ }
+ }
+ }
+ if (autoCRL) {
+ List<CRL> crlsFromCert =
+ KeyTool.readCRLsFromCert(certChain[0]);
+ for (CRL crl: crlsFromCert) {
+ if (crl instanceof X509CRL) {
+ crls.add((X509CRL)crl);
+ }
+ }
+ }
+ }
// load the alternative signing mechanism
if (altSignerClass != null) {
@@ -367,6 +396,13 @@
} else if (collator.compare(flags, "-digestalg") ==0) {
if (++n == args.length) usageNoArg();
digestalg = args[n];
+ } else if (collator.compare(flags, "-crl") ==0) {
+ if ("auto".equals(modifier)) {
+ autoCRL = true;
+ } else {
+ if (++n == args.length) usageNoArg();
+ crlfiles.add(args[n]);
+ }
} else if (collator.compare(flags, "-certs") ==0) {
showcerts = true;
} else if (collator.compare(flags, "-strict") ==0) {
@@ -516,6 +552,9 @@
("[-sigalg <algorithm>] name of signature algorithm"));
System.out.println();
System.out.println(rb.getString
+ ("[-crl[:auto| <file>] include CRL in signed jar"));
+ System.out.println();
+ System.out.println(rb.getString
("[-verify] verify a signed JAR file"));
System.out.println();
System.out.println(rb.getString
@@ -654,6 +693,20 @@
if (showcerts) {
sb.append(si);
sb.append('\n');
+ CRL[] crls = SharedSecrets
+ .getJavaSecurityCodeSignerAccess()
+ .getCRLs(signer);
+ if (crls != null) {
+ for (CRL crl: crls) {
+ if (crl instanceof X509CRLImpl) {
+ sb.append(tab).append("[");
+ sb.append(String.format(
+ rb.getString("with a CRL including %d entries"),
+ ((X509CRLImpl)crl).getRevokedCertificates().size()))
+ .append("]\n");
+ }
+ }
+ }
}
}
} else if (showcerts && !verbose.equals("all")) {
@@ -1123,6 +1176,8 @@
BASE64Encoder encoder = new JarBASE64Encoder();
Vector<ZipEntry> mfFiles = new Vector<ZipEntry>();
+ boolean wasSigned = false;
+
for (Enumeration<? extends ZipEntry> enum_=zipFile.entries();
enum_.hasMoreElements();) {
ZipEntry ze = enum_.nextElement();
@@ -1132,6 +1187,11 @@
// out first
mfFiles.addElement(ze);
+ if (SignatureFileVerifier.isBlockOrSF(
+ ze.getName().toUpperCase(Locale.ENGLISH))) {
+ wasSigned = true;
+ }
+
if (signatureRelated(ze.getName())) {
// ignore signature-related and manifest files
continue;
@@ -1159,37 +1219,41 @@
if (mfModified) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
manifest.write(baos);
- byte[] newBytes = baos.toByteArray();
- if (mfRawBytes != null
- && oldAttr.equals(manifest.getMainAttributes())) {
+ if (wasSigned) {
+ byte[] newBytes = baos.toByteArray();
+ if (mfRawBytes != null
+ && oldAttr.equals(manifest.getMainAttributes())) {
- /*
- * Note:
- *
- * The Attributes object is based on HashMap and can handle
- * continuation columns. Therefore, even if the contents are
- * not changed (in a Map view), the bytes that it write()
- * may be different from the original bytes that it read()
- * from. Since the signature on the main attributes is based
- * on raw bytes, we must retain the exact bytes.
- */
+ /*
+ * Note:
+ *
+ * The Attributes object is based on HashMap and can handle
+ * continuation columns. Therefore, even if the contents are
+ * not changed (in a Map view), the bytes that it write()
+ * may be different from the original bytes that it read()
+ * from. Since the signature on the main attributes is based
+ * on raw bytes, we must retain the exact bytes.
+ */
- int newPos = findHeaderEnd(newBytes);
- int oldPos = findHeaderEnd(mfRawBytes);
+ int newPos = findHeaderEnd(newBytes);
+ int oldPos = findHeaderEnd(mfRawBytes);
- if (newPos == oldPos) {
- System.arraycopy(mfRawBytes, 0, newBytes, 0, oldPos);
- } else {
- // cat oldHead newTail > newBytes
- byte[] lastBytes = new byte[oldPos +
- newBytes.length - newPos];
- System.arraycopy(mfRawBytes, 0, lastBytes, 0, oldPos);
- System.arraycopy(newBytes, newPos, lastBytes, oldPos,
- newBytes.length - newPos);
- newBytes = lastBytes;
+ if (newPos == oldPos) {
+ System.arraycopy(mfRawBytes, 0, newBytes, 0, oldPos);
+ } else {
+ // cat oldHead newTail > newBytes
+ byte[] lastBytes = new byte[oldPos +
+ newBytes.length - newPos];
+ System.arraycopy(mfRawBytes, 0, lastBytes, 0, oldPos);
+ System.arraycopy(newBytes, newPos, lastBytes, oldPos,
+ newBytes.length - newPos);
+ newBytes = lastBytes;
+ }
}
+ mfRawBytes = newBytes;
+ } else {
+ mfRawBytes = baos.toByteArray();
}
- mfRawBytes = newBytes;
}
// Write out the manifest
@@ -1222,7 +1286,7 @@
try {
block =
- sf.generateBlock(privateKey, sigalg, certChain,
+ sf.generateBlock(privateKey, sigalg, certChain, crls,
externalSF, tsaUrl, tsaCert, signingMechanism, args,
zipFile);
} catch (SocketTimeoutException e) {
@@ -1411,23 +1475,31 @@
}
/**
- * Find the position of an empty line inside bs
+ * Find the length of header inside bs. The header is a multiple (>=0)
+ * lines of attributes plus an empty line. The empty line is included
+ * in the header.
*/
private int findHeaderEnd(byte[] bs) {
- // An empty line can be at the beginning...
- if (bs.length > 1 && bs[0] == '\r' && bs[1] == '\n') {
- return 0;
- }
- // ... or after another line
- for (int i=0; i<bs.length-3; i++) {
- if (bs[i] == '\r' && bs[i+1] == '\n' &&
- bs[i+2] == '\r' && bs[i+3] == '\n') {
- return i;
+ // Initial state true to deal with empty header
+ boolean newline = true; // just met a newline
+ int len = bs.length;
+ for (int i=0; i<len; i++) {
+ switch (bs[i]) {
+ case '\r':
+ if (i < len && bs[i+1] == '\n') i++;
+ // fallthrough
+ case '\n':
+ if (newline) return i+1; //+1 to get length
+ newline = true;
+ break;
+ default:
+ newline = false;
}
}
- // If header end is not found, return 0,
- // which means no behavior change.
- return 0;
+ // If header end is not found, it means the MANIFEST.MF has only
+ // the main attributes section and it does not end with 2 newlines.
+ // Returns the whole length so that it can be completely replaced.
+ return len;
}
/**
@@ -2178,6 +2250,7 @@
public Block generateBlock(PrivateKey privateKey,
String sigalg,
X509Certificate[] certChain,
+ Set<X509CRL> crls,
boolean externalSF, String tsaUrl,
X509Certificate tsaCert,
ContentSigner signingMechanism,
@@ -2185,7 +2258,7 @@
throws NoSuchAlgorithmException, InvalidKeyException, IOException,
SignatureException, CertificateException
{
- return new Block(this, privateKey, sigalg, certChain, externalSF,
+ return new Block(this, privateKey, sigalg, certChain, crls, externalSF,
tsaUrl, tsaCert, signingMechanism, args, zipFile);
}
@@ -2199,7 +2272,8 @@
* Construct a new signature block.
*/
Block(SignatureFile sfg, PrivateKey privateKey, String sigalg,
- X509Certificate[] certChain, boolean externalSF, String tsaUrl,
+ X509Certificate[] certChain, Set<X509CRL> crls,
+ boolean externalSF, String tsaUrl,
X509Certificate tsaCert, ContentSigner signingMechanism,
String[] args, ZipFile zipFile)
throws NoSuchAlgorithmException, InvalidKeyException, IOException,
@@ -2286,7 +2360,7 @@
// Assemble parameters for the signing mechanism
ContentSignerParameters params =
new JarSignerParameters(args, tsaUri, tsaCert, signature,
- signatureAlgorithm, certChain, content, zipFile);
+ signatureAlgorithm, certChain, crls, content, zipFile);
// Generate the signature block
block = signingMechanism.generateSignedData(
@@ -2327,6 +2401,7 @@
private byte[] signature;
private String signatureAlgorithm;
private X509Certificate[] signerCertificateChain;
+ private Set<X509CRL> crls;
private byte[] content;
private ZipFile source;
@@ -2335,7 +2410,8 @@
*/
JarSignerParameters(String[] args, URI tsa, X509Certificate tsaCertificate,
byte[] signature, String signatureAlgorithm,
- X509Certificate[] signerCertificateChain, byte[] content,
+ X509Certificate[] signerCertificateChain, Set<X509CRL> crls,
+ byte[] content,
ZipFile source) {
if (signature == null || signatureAlgorithm == null ||
@@ -2348,6 +2424,7 @@
this.signature = signature;
this.signatureAlgorithm = signatureAlgorithm;
this.signerCertificateChain = signerCertificateChain;
+ this.crls = crls;
this.content = content;
this.source = source;
}
@@ -2423,4 +2500,13 @@
public ZipFile getSource() {
return source;
}
+
+ @Override
+ public Set<X509CRL> getCRLs() {
+ if (crls == null) {
+ return Collections.emptySet();
+ } else {
+ return Collections.unmodifiableSet(crls);
+ }
+ }
}
--- a/jdk/src/share/classes/sun/security/tools/JarSignerResources.java Thu May 13 13:22:22 2010 -0700
+++ b/jdk/src/share/classes/sun/security/tools/JarSignerResources.java Wed May 19 12:27:47 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2000-2010 Sun Microsystems, Inc. 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
@@ -74,6 +74,8 @@
"[-digestalg <algorithm>] name of digest algorithm"},
{"[-sigalg <algorithm>] name of signature algorithm",
"[-sigalg <algorithm>] name of signature algorithm"},
+ {"[-crl[:auto| <file>] include CRL in signed jar",
+ "[-crl[:auto| <file>] include CRL in signed jar"},
{"[-verify] verify a signed JAR file",
"[-verify] verify a signed JAR file"},
{"[-verbose[:suboptions]] verbose output when signing/verifying.",
@@ -191,6 +193,7 @@
{"using an alternative signing mechanism",
"using an alternative signing mechanism"},
{"entry was signed on", "entry was signed on {0}"},
+ {"with a CRL including %d entries", "with a CRL including %d entries"},
{"Warning: ", "Warning: "},
{"This jar contains unsigned entries which have not been integrity-checked. ",
"This jar contains unsigned entries which have not been integrity-checked. "},
--- a/jdk/src/share/classes/sun/security/tools/KeyTool.java Thu May 13 13:22:22 2010 -0700
+++ b/jdk/src/share/classes/sun/security/tools/KeyTool.java Wed May 19 12:27:47 2010 -0700
@@ -25,6 +25,7 @@
package sun.security.tools;
+import sun.misc.SharedSecrets;
import java.io.*;
import java.security.CodeSigner;
import java.security.KeyStore;
@@ -42,6 +43,7 @@
import java.security.Provider;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
+import java.security.cert.CRL;
import java.security.cert.X509Certificate;
import java.security.cert.CertificateException;
import java.text.Collator;
@@ -50,14 +52,20 @@
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.lang.reflect.Constructor;
+import java.math.BigInteger;
+import java.net.URI;
import java.net.URL;
import java.net.URLClassLoader;
-
+import java.security.cert.CertStore;
+
+import java.security.cert.X509CRL;
+import java.security.cert.X509CRLEntry;
+import java.security.cert.X509CRLSelector;
+import javax.security.auth.x500.X500Principal;
import sun.misc.BASE64Encoder;
import sun.security.util.ObjectIdentifier;
import sun.security.pkcs.PKCS10;
import sun.security.provider.X509Factory;
-import sun.security.util.DerOutputStream;
import sun.security.util.Password;
import sun.security.util.PathList;
import javax.crypto.KeyGenerator;
@@ -72,6 +80,7 @@
import sun.misc.BASE64Decoder;
import sun.security.pkcs.PKCS10Attribute;
import sun.security.pkcs.PKCS9Attribute;
+import sun.security.provider.certpath.ldap.LDAPCertStoreHelper;
import sun.security.util.DerValue;
import sun.security.x509.*;
@@ -147,6 +156,7 @@
private Set<char[]> passwords = new HashSet<char[]> ();
private String startDate = null;
+ private List <String> ids = new ArrayList <String> (); // used in GENCRL
private List <String> v3ext = new ArrayList <String> ();
enum Command {
@@ -180,9 +190,6 @@
STARTDATE, EXT, VALIDITY, KEYPASS, KEYSTORE,
STOREPASS, STORETYPE, PROVIDERNAME, PROVIDERCLASS,
PROVIDERARG, PROVIDERPATH, V, PROTECTED),
- IDENTITYDB("Imports entries from a JDK 1.1.x-style identity database",
- FILEIN, STORETYPE, KEYSTORE, STOREPASS, PROVIDERNAME,
- PROVIDERCLASS, PROVIDERARG, PROVIDERPATH, V),
IMPORTCERT("Imports a certificate or a certificate chain",
NOPROMPT, TRUSTCACERTS, PROTECTED, ALIAS, FILEIN,
KEYPASS, KEYSTORE, STOREPASS, STORETYPE,
@@ -195,10 +202,6 @@
SRCALIAS, DESTALIAS, SRCKEYPASS, DESTKEYPASS,
NOPROMPT, PROVIDERCLASS, PROVIDERARG, PROVIDERPATH,
V),
- KEYCLONE("Clones a key entry",
- ALIAS, DESTALIAS, KEYPASS, NEW, STORETYPE,
- KEYSTORE, STOREPASS, PROVIDERNAME, PROVIDERCLASS,
- PROVIDERARG, PROVIDERPATH, V),
KEYPASSWD("Changes the key password of an entry",
ALIAS, KEYPASS, NEW, KEYSTORE, STOREPASS,
STORETYPE, PROVIDERNAME, PROVIDERCLASS, PROVIDERARG,
@@ -211,12 +214,29 @@
RFC, FILEIN, SSLSERVER, JARFILE, V),
PRINTCERTREQ("Prints the content of a certificate request",
FILEIN, V),
+ PRINTCRL("Prints the content of a CRL file",
+ FILEIN, V),
+ STOREPASSWD("Changes the store password of a keystore",
+ NEW, KEYSTORE, STOREPASS, STORETYPE, PROVIDERNAME,
+ PROVIDERCLASS, PROVIDERARG, PROVIDERPATH, V),
+
+ // Undocumented start here, KEYCLONE is used a marker in -help;
+
+ KEYCLONE("Clones a key entry",
+ ALIAS, DESTALIAS, KEYPASS, NEW, STORETYPE,
+ KEYSTORE, STOREPASS, PROVIDERNAME, PROVIDERCLASS,
+ PROVIDERARG, PROVIDERPATH, V),
SELFCERT("Generates a self-signed certificate",
ALIAS, SIGALG, DNAME, STARTDATE, VALIDITY, KEYPASS,
STORETYPE, KEYSTORE, STOREPASS, PROVIDERNAME,
PROVIDERCLASS, PROVIDERARG, PROVIDERPATH, V),
- STOREPASSWD("Changes the store password of a keystore",
- NEW, KEYSTORE, STOREPASS, STORETYPE, PROVIDERNAME,
+ GENCRL("Generates CRL",
+ RFC, FILEOUT, ID,
+ ALIAS, SIGALG, EXT, KEYPASS, KEYSTORE,
+ STOREPASS, STORETYPE, PROVIDERNAME, PROVIDERCLASS,
+ PROVIDERARG, PROVIDERPATH, V, PROTECTED),
+ IDENTITYDB("Imports entries from a JDK 1.1.x-style identity database",
+ FILEIN, STORETYPE, KEYSTORE, STOREPASS, PROVIDERNAME,
PROVIDERCLASS, PROVIDERARG, PROVIDERPATH, V);
final String description;
@@ -244,6 +264,7 @@
EXT("ext", "<value>", "X.509 extension"),
FILEOUT("file", "<filename>", "output file name"),
FILEIN("file", "<filename>", "input file name"),
+ ID("id", "<id:reason>", "Serial ID of cert to revoke"),
INFILE("infile", "<filename>", "input file name"),
KEYALG("keyalg", "<keyalg>", "key algorithm name"),
KEYPASS("keypass", "<arg>", "key password"),
@@ -458,6 +479,8 @@
validity = Long.parseLong(args[++i]);
} else if (collator.compare(flags, "-ext") == 0) {
v3ext.add(args[++i]);
+ } else if (collator.compare(flags, "-id") == 0) {
+ ids.add(args[++i]);
} else if (collator.compare(flags, "-file") == 0) {
filename = args[++i];
} else if (collator.compare(flags, "-infile") == 0) {
@@ -720,7 +743,8 @@
command != GENSECKEY &&
command != IDENTITYDB &&
command != IMPORTCERT &&
- command != IMPORTKEYSTORE) {
+ command != IMPORTKEYSTORE &&
+ command != PRINTCRL) {
throw new Exception(rb.getString
("Keystore file does not exist: ") + ksfname);
}
@@ -855,10 +879,12 @@
&& !KeyStoreUtil.isWindowsKeyStore(storetype)
&& isKeyStoreRelated(command)) {
// here we have EXPORTCERT and LIST (info valid until STOREPASSWD)
- System.err.print(rb.getString("Enter keystore password: "));
- System.err.flush();
- storePass = Password.readPassword(System.in);
- passwords.add(storePass);
+ if (command != PRINTCRL) {
+ System.err.print(rb.getString("Enter keystore password: "));
+ System.err.flush();
+ storePass = Password.readPassword(System.in);
+ passwords.add(storePass);
+ }
}
// Now load a nullStream-based keystore,
@@ -895,7 +921,7 @@
// Create a certificate factory
if (command == PRINTCERT || command == IMPORTCERT
- || command == IDENTITYDB) {
+ || command == IDENTITYDB || command == PRINTCRL) {
cf = CertificateFactory.getInstance("X509");
}
@@ -1086,6 +1112,22 @@
ps.close();
}
}
+ } else if (command == GENCRL) {
+ if (alias == null) {
+ alias = keyAlias;
+ }
+ PrintStream ps = null;
+ if (filename != null) {
+ ps = new PrintStream(new FileOutputStream(filename));
+ out = ps;
+ }
+ try {
+ doGenCRL(out);
+ } finally {
+ if (ps != null) {
+ ps.close();
+ }
+ }
} else if (command == PRINTCERTREQ) {
InputStream inStream = System.in;
if (filename != null) {
@@ -1098,6 +1140,8 @@
inStream.close();
}
}
+ } else if (command == PRINTCRL) {
+ doPrintCRL(filename, out);
}
// If we need to save the keystore, do so.
@@ -1152,7 +1196,8 @@
CertificateValidity interval = new CertificateValidity(firstDate,
lastDate);
- PrivateKey privateKey = (PrivateKey)recoverKey(alias, storePass, keyPass).fst;
+ PrivateKey privateKey =
+ (PrivateKey)recoverKey(alias, storePass, keyPass).fst;
if (sigAlgName == null) {
sigAlgName = getCompatibleSigAlgName(privateKey.getAlgorithm());
}
@@ -1221,6 +1266,56 @@
}
}
+ private void doGenCRL(PrintStream out)
+ throws Exception {
+ if (ids == null) {
+ throw new Exception("Must provide -id when -gencrl");
+ }
+ Certificate signerCert = keyStore.getCertificate(alias);
+ byte[] encoded = signerCert.getEncoded();
+ X509CertImpl signerCertImpl = new X509CertImpl(encoded);
+ X509CertInfo signerCertInfo = (X509CertInfo)signerCertImpl.get(
+ X509CertImpl.NAME + "." + X509CertImpl.INFO);
+ X500Name owner = (X500Name)signerCertInfo.get(X509CertInfo.SUBJECT + "." +
+ CertificateSubjectName.DN_NAME);
+
+ Date firstDate = getStartDate(startDate);
+ Date lastDate = (Date) firstDate.clone();
+ lastDate.setTime(lastDate.getTime() + (long)validity*1000*24*60*60);
+ CertificateValidity interval = new CertificateValidity(firstDate,
+ lastDate);
+
+
+ PrivateKey privateKey =
+ (PrivateKey)recoverKey(alias, storePass, keyPass).fst;
+ if (sigAlgName == null) {
+ sigAlgName = getCompatibleSigAlgName(privateKey.getAlgorithm());
+ }
+
+ X509CRLEntry[] badCerts = new X509CRLEntry[ids.size()];
+ for (int i=0; i<ids.size(); i++) {
+ String id = ids.get(i);
+ int d = id.indexOf(':');
+ if (d >= 0) {
+ CRLExtensions ext = new CRLExtensions();
+ ext.set("Reason", new CRLReasonCodeExtension(Integer.parseInt(id.substring(d+1))));
+ badCerts[i] = new X509CRLEntryImpl(new BigInteger(id.substring(0, d)),
+ firstDate, ext);
+ } else {
+ badCerts[i] = new X509CRLEntryImpl(new BigInteger(ids.get(i)), firstDate);
+ }
+ }
+ X509CRLImpl crl = new X509CRLImpl(owner, firstDate, lastDate, badCerts);
+ crl.sign(privateKey, sigAlgName);
+ if (rfc) {
+ out.println("-----BEGIN X509 CRL-----");
+ new BASE64Encoder().encodeBuffer(crl.getEncodedInternal(), out);
+ out.println("-----END X509 CRL-----");
+ } else {
+ out.write(crl.getEncodedInternal());
+ }
+ }
+
/**
* Creates a PKCS#10 cert signing request, corresponding to the
* keys (and name) associated with a given alias.
@@ -1925,6 +2020,177 @@
}
}
+ private static <T> Iterable<T> e2i(final Enumeration<T> e) {
+ return new Iterable<T>() {
+ @Override
+ public Iterator<T> iterator() {
+ return new Iterator<T>() {
+ @Override
+ public boolean hasNext() {
+ return e.hasMoreElements();
+ }
+ @Override
+ public T next() {
+ return e.nextElement();
+ }
+ public void remove() {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+ };
+ }
+ };
+ }
+
+ /**
+ * Loads CRLs from a source. This method is also called in JarSigner.
+ * @param src the source, which means System.in if null, or a URI,
+ * or a bare file path name
+ */
+ public static Collection<? extends CRL> loadCRLs(String src) throws Exception {
+ InputStream in = null;
+ URI uri = null;
+ if (src == null) {
+ in = System.in;
+ } else {
+ try {
+ uri = new URI(src);
+ if (uri.getScheme().equals("ldap")) {
+ // No input stream for LDAP
+ } else {
+ in = uri.toURL().openStream();
+ }
+ } catch (Exception e) {
+ try {
+ in = new FileInputStream(src);
+ } catch (Exception e2) {
+ if (uri == null || uri.getScheme() == null) {
+ throw e2; // More likely a bare file path
+ } else {
+ throw e; // More likely a protocol or network problem
+ }
+ }
+ }
+ }
+ if (in != null) {
+ try {
+ // Read the full stream before feeding to X509Factory,
+ // otherwise, keytool -gencrl | keytool -printcrl
+ // might not work properly, since -gencrl is slow
+ // and there's no data in the pipe at the beginning.
+ ByteArrayOutputStream bout = new ByteArrayOutputStream();
+ byte[] b = new byte[4096];
+ while (true) {
+ int len = in.read(b);
+ if (len < 0) break;
+ bout.write(b, 0, len);
+ }
+ return CertificateFactory.getInstance("X509").generateCRLs(
+ new ByteArrayInputStream(bout.toByteArray()));
+ } finally {
+ if (in != System.in) {
+ in.close();
+ }
+ }
+ } else { // must be LDAP, and uri is not null
+ String path = uri.getPath();
+ if (path.charAt(0) == '/') path = path.substring(1);
+ LDAPCertStoreHelper h = new LDAPCertStoreHelper();
+ CertStore s = h.getCertStore(uri);
+ X509CRLSelector sel =
+ h.wrap(new X509CRLSelector(), null, path);
+ return s.getCRLs(sel);
+ }
+ }
+
+ /**
+ * Returns CRLs described in a X509Certificate's CRLDistributionPoints
+ * Extension. Only those containing a general name of type URI are read.
+ */
+ public static List<CRL> readCRLsFromCert(X509Certificate cert)
+ throws Exception {
+ List<CRL> crls = new ArrayList<CRL>();
+ CRLDistributionPointsExtension ext =
+ X509CertImpl.toImpl(cert).getCRLDistributionPointsExtension();
+ if (ext == null) return crls;
+ for (DistributionPoint o: (List<DistributionPoint>)
+ ext.get(CRLDistributionPointsExtension.POINTS)) {
+ GeneralNames names = o.getFullName();
+ if (names != null) {
+ for (GeneralName name: names.names()) {
+ if (name.getType() == GeneralNameInterface.NAME_URI) {
+ URIName uriName = (URIName)name.getName();
+ for (CRL crl: KeyTool.loadCRLs(uriName.getName())) {
+ if (crl instanceof X509CRL) {
+ crls.add((X509CRL)crl);
+ }
+ }
+ break; // Different name should point to same CRL
+ }
+ }
+ }
+ }
+ return crls;
+ }
+
+ private static String verifyCRL(KeyStore ks, CRL crl)
+ throws Exception {
+ X509CRLImpl xcrl = (X509CRLImpl)crl;
+ X500Principal issuer = xcrl.getIssuerX500Principal();
+ for (String s: e2i(ks.aliases())) {
+ Certificate cert = ks.getCertificate(s);
+ if (cert instanceof X509Certificate) {
+ X509Certificate xcert = (X509Certificate)cert;
+ if (xcert.getSubjectX500Principal().equals(issuer)) {
+ try {
+ ((X509CRLImpl)crl).verify(cert.getPublicKey());
+ return s;
+ } catch (Exception e) {
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ private void doPrintCRL(String src, PrintStream out)
+ throws Exception {
+ for (CRL crl: loadCRLs(src)) {
+ printCRL(crl, out);
+ String issuer = null;
+ if (caks != null) {
+ issuer = verifyCRL(caks, crl);
+ if (issuer != null) {
+ System.out.println("Verified by " + issuer + " in cacerts");
+ }
+ }
+ if (issuer == null && keyStore != null) {
+ issuer = verifyCRL(keyStore, crl);
+ if (issuer != null) {
+ System.out.println("Verified by " + issuer + " in keystore");
+ }
+ }
+ if (issuer == null) {
+ out.println(rb.getString
+ ("*******************************************"));
+ out.println("WARNING: not verified. Make sure -keystore and -alias are correct.");
+ out.println(rb.getString
+ ("*******************************************\n\n"));
+ }
+ }
+ }
+
+ private void printCRL(CRL crl, PrintStream out)
+ throws Exception {
+ if (rfc) {
+ X509CRL xcrl = (X509CRL)crl;
+ out.println("-----BEGIN X509 CRL-----");
+ new BASE64Encoder().encodeBuffer(xcrl.getEncoded(), out);
+ out.println("-----END X509 CRL-----");
+ } else {
+ out.println(crl.toString());
+ }
+ }
+
private void doPrintCertReq(InputStream in, PrintStream out)
throws Exception {
@@ -2063,6 +2329,16 @@
out.println();
}
}
+ CRL[] crls = SharedSecrets
+ .getJavaSecurityCodeSignerAccess()
+ .getCRLs(signer);
+ if (crls != null) {
+ out.println(rb.getString("CRLs:"));
+ out.println();
+ for (CRL crl: crls) {
+ printCRL(crl, out);
+ }
+ }
}
}
}
@@ -2620,7 +2896,7 @@
if (v.length == 0) {
out.println(rb.getString("(Empty value)"));
} else {
- new sun.misc.HexDumpEncoder().encode(ext.getExtensionValue(), out);
+ new sun.misc.HexDumpEncoder().encodeBuffer(ext.getExtensionValue(), out);
out.println();
}
}
@@ -3330,15 +3606,22 @@
/**
* Match a command (may be abbreviated) with a command set.
* @param s the command provided
- * @param list the legal command set
+ * @param list the legal command set. If there is a null, commands after it
+ * are regarded experimental, which means they are supported but their
+ * existence should not be revealed to user.
* @return the position of a single match, or -1 if none matched
* @throws Exception if s is ambiguous
*/
private static int oneOf(String s, String... list) throws Exception {
int[] match = new int[list.length];
int nmatch = 0;
+ int experiment = Integer.MAX_VALUE;
for (int i = 0; i<list.length; i++) {
String one = list[i];
+ if (one == null) {
+ experiment = i;
+ continue;
+ }
if (one.toLowerCase(Locale.ENGLISH)
.startsWith(s.toLowerCase(Locale.ENGLISH))) {
match[nmatch++] = i;
@@ -3360,17 +3643,27 @@
}
}
}
- if (nmatch == 0) return -1;
- if (nmatch == 1) return match[0];
- StringBuffer sb = new StringBuffer();
- MessageFormat form = new MessageFormat(rb.getString
- ("command {0} is ambiguous:"));
- Object[] source = {s};
- sb.append(form.format(source) +"\n ");
- for (int i=0; i<nmatch; i++) {
- sb.append(" " + list[match[i]]);
+ if (nmatch == 0) {
+ return -1;
+ } else if (nmatch == 1) {
+ return match[0];
+ } else {
+ // If multiple matches is in experimental commands, ignore them
+ if (match[1] > experiment) {
+ return match[0];
+ }
+ StringBuffer sb = new StringBuffer();
+ MessageFormat form = new MessageFormat(rb.getString
+ ("command {0} is ambiguous:"));
+ Object[] source = {s};
+ sb.append(form.format(source));
+ sb.append("\n ");
+ for (int i=0; i<nmatch && match[i]<experiment; i++) {
+ sb.append(' ');
+ sb.append(list[match[i]]);
+ }
+ throw new Exception(sb.toString());
}
- throw new Exception(sb.toString());
}
/**
@@ -3405,6 +3698,8 @@
"IssuerAlternativeName",
"SubjectInfoAccess",
"AuthorityInfoAccess",
+ null,
+ "CRLDistributionPoints",
};
private ObjectIdentifier findOidForExtName(String type)
@@ -3417,6 +3712,7 @@
case 4: return PKIXExtensions.IssuerAlternativeName_Id;
case 5: return PKIXExtensions.SubjectInfoAccess_Id;
case 6: return PKIXExtensions.AuthInfoAccess_Id;
+ case 8: return PKIXExtensions.CRLDistributionPoints_Id;
default: return new ObjectIdentifier(type);
}
}
@@ -3712,6 +4008,28 @@
("Illegal value: ") + extstr);
}
break;
+ case 8: // CRL, experimental, only support 1 distributionpoint
+ if(value != null) {
+ String[] ps = value.split(",");
+ GeneralNames gnames = new GeneralNames();
+ for(String item: ps) {
+ colonpos = item.indexOf(':');
+ if (colonpos < 0) {
+ throw new Exception("Illegal item " + item + " in " + extstr);
+ }
+ String t = item.substring(0, colonpos);
+ String v = item.substring(colonpos+1);
+ gnames.add(createGeneralName(t, v));
+ }
+ ext.set(CRLDistributionPointsExtension.NAME,
+ new CRLDistributionPointsExtension(
+ isCritical, Collections.singletonList(
+ new DistributionPoint(gnames, null, null))));
+ } else {
+ throw new Exception(rb.getString
+ ("Illegal value: ") + extstr);
+ }
+ break;
case -1:
ObjectIdentifier oid = new ObjectIdentifier(name);
byte[] data = null;
@@ -3748,6 +4066,9 @@
new DerValue(DerValue.tag_OctetString, data)
.toByteArray()));
break;
+ default:
+ throw new Exception(rb.getString(
+ "Unknown extension type: ") + extstr);
}
}
// always non-critical
@@ -3810,11 +4131,8 @@
System.err.println(rb.getString("Commands:"));
System.err.println();
for (Command c: Command.values()) {
- if (c != IDENTITYDB
- && c != KEYCLONE
- && c != SELFCERT) { // Deprecated commands
- System.err.printf(" %-20s%s\n", c, rb.getString(c.description));
- }
+ if (c == KEYCLONE) break;
+ System.err.printf(" %-20s%s\n", c, rb.getString(c.description));
}
System.err.println();
System.err.println(rb.getString(
--- a/jdk/src/share/classes/sun/security/tools/TimestampedSigner.java Thu May 13 13:22:22 2010 -0700
+++ b/jdk/src/share/classes/sun/security/tools/TimestampedSigner.java Wed May 19 12:27:47 2010 -0700
@@ -38,6 +38,7 @@
import java.util.List;
import com.sun.jarsigner.*;
+import java.security.cert.X509CRL;
import java.util.Arrays;
import sun.security.pkcs.*;
import sun.security.timestamp.*;
@@ -239,7 +240,7 @@
// Create the PKCS #7 signed data message
PKCS7 p7 =
new PKCS7(algorithms, contentInfo, signerCertificateChain,
- signerInfos);
+ parameters.getCRLs().toArray(new X509CRL[parameters.getCRLs().size()]), signerInfos);
ByteArrayOutputStream p7out = new ByteArrayOutputStream();
p7.encodeSignedData(p7out);
--- a/jdk/src/share/classes/sun/security/util/Resources.java Thu May 13 13:22:22 2010 -0700
+++ b/jdk/src/share/classes/sun/security/util/Resources.java Wed May 19 12:27:47 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2000-2010 Sun Microsystems, Inc. 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
@@ -71,6 +71,7 @@
"Generates a secret key"}, //-genseckey
{"Generates certificate from a certificate request",
"Generates certificate from a certificate request"}, //-gencert
+ {"Generates CRL", "Generates CRL"}, //-gencrl
{"Imports entries from a JDK 1.1.x-style identity database",
"Imports entries from a JDK 1.1.x-style identity database"}, //-identitydb
{"Imports a certificate or a certificate chain",
@@ -87,6 +88,8 @@
"Prints the content of a certificate"}, //-printcert
{"Prints the content of a certificate request",
"Prints the content of a certificate request"}, //-printcertreq
+ {"Prints the content of a CRL file",
+ "Prints the content of a CRL file"}, //-printcrl
{"Generates a self-signed certificate",
"Generates a self-signed certificate"}, //-selfcert
{"Changes the store password of a keystore",
@@ -176,6 +179,8 @@
"verbose output"}, //-v
{"validity number of days",
"validity number of days"}, //-validity
+ {"Serial ID of cert to revoke",
+ "Serial ID of cert to revoke"}, //-id
// keytool: Running part
{"keytool error: ", "keytool error: "},
{"Illegal option: ", "Illegal option: "},
@@ -375,6 +380,7 @@
{"Signer #%d:", "Signer #%d:"},
{"Timestamp:", "Timestamp:"},
{"Signature:", "Signature:"},
+ {"CRLs:", "CRLs:"},
{"Certificate owner: ", "Certificate owner: "},
{"Not a signed jar file", "Not a signed jar file"},
{"No certificate from the SSL server",
@@ -433,6 +439,7 @@
{"This extension cannot be marked as critical. ",
"This extension cannot be marked as critical. "},
{"Odd number of hex digits found: ", "Odd number of hex digits found: "},
+ {"Unknown extension type: ", "Unknown extension type: "},
{"command {0} is ambiguous:", "command {0} is ambiguous:"},
// policytool
--- a/jdk/src/share/classes/sun/security/util/SignatureFileVerifier.java Thu May 13 13:22:22 2010 -0700
+++ b/jdk/src/share/classes/sun/security/util/SignatureFileVerifier.java Wed May 19 12:27:47 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1997-2010 Sun Microsystems, Inc. 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
@@ -25,7 +25,6 @@
package sun.security.util;
-import java.security.CodeSigner;
import java.security.cert.CertPath;
import java.security.cert.X509Certificate;
import java.security.cert.CertificateException;
@@ -34,11 +33,11 @@
import java.io.*;
import java.util.*;
import java.util.jar.*;
-import java.io.ByteArrayOutputStream;
import sun.security.pkcs.*;
import sun.security.timestamp.TimestampToken;
import sun.misc.BASE64Decoder;
+import sun.misc.SharedSecrets;
import sun.security.jca.Providers;
@@ -479,7 +478,12 @@
signers = new ArrayList<CodeSigner>();
}
// Append the new code signer
- signers.add(new CodeSigner(certChain, getTimestamp(info)));
+ CodeSigner signer = new CodeSigner(certChain, getTimestamp(info));
+ if (block.getCRLs() != null) {
+ SharedSecrets.getJavaSecurityCodeSignerAccess().setCRLs(
+ signer, block.getCRLs());
+ }
+ signers.add(signer);
if (debug != null) {
debug.println("Signature Block Certificate: " +
--- a/jdk/src/share/classes/sun/security/x509/X509CRLImpl.java Thu May 13 13:22:22 2010 -0700
+++ b/jdk/src/share/classes/sun/security/x509/X509CRLImpl.java Wed May 19 12:27:47 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1997-2010 Sun Microsystems, Inc. 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
@@ -89,7 +89,7 @@
* @author Hemma Prafullchandra
* @see X509CRL
*/
-public class X509CRLImpl extends X509CRL {
+public class X509CRLImpl extends X509CRL implements DerEncoder {
// CRL data, and its envelope
private byte[] signedCRL = null; // DER encoded crl
@@ -1189,6 +1189,13 @@
}
}
+ @Override
+ public void derEncode(OutputStream out) throws IOException {
+ if (signedCRL == null)
+ throw new IOException("Null CRL to encode");
+ out.write(signedCRL.clone());
+ }
+
/**
* Immutable X.509 Certificate Issuer DN and serial number pair
*/
--- a/jdk/src/solaris/classes/sun/awt/UNIXToolkit.java Thu May 13 13:22:22 2010 -0700
+++ b/jdk/src/solaris/classes/sun/awt/UNIXToolkit.java Wed May 19 12:27:47 2010 -0700
@@ -314,4 +314,27 @@
}
return new RenderingHints(KEY_TEXT_ANTIALIASING, aaHint);
}
+
+ private native boolean gtkCheckVersionImpl(int major, int minor,
+ int micro);
+
+ /**
+ * Returns {@code true} if the GTK+ library is compatible with the given
+ * version.
+ *
+ * @param major
+ * The required major version.
+ * @param minor
+ * The required minor version.
+ * @param micro
+ * The required micro version.
+ * @return {@code true} if the GTK+ library is compatible with the given
+ * version.
+ */
+ public boolean checkGtkVersion(int major, int minor, int micro) {
+ if (loadGTK()) {
+ return gtkCheckVersionImpl(major, minor, micro);
+ }
+ return false;
+ }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/solaris/classes/sun/awt/X11/GtkFileDialogPeer.java Wed May 19 12:27:47 2010 -0700
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2010 Sun Microsystems, Inc. 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package sun.awt.X11;
+
+import java.awt.Dialog;
+import java.awt.FileDialog;
+import java.awt.peer.FileDialogPeer;
+import java.io.File;
+import java.io.FilenameFilter;
+import javax.swing.SwingUtilities;
+import javax.swing.SwingWorker;
+import sun.awt.AWTAccessor;
+
+/**
+ * FileDialogPeer for the GtkFileChooser.
+ *
+ * @author Costantino Cerbo (c.cerbo@gmail.com)
+ */
+class GtkFileDialogPeer extends XDialogPeer implements FileDialogPeer {
+
+ private FileDialog fd;
+
+ public GtkFileDialogPeer(FileDialog fd) {
+ super((Dialog) fd);
+ this.fd = fd;
+ }
+
+ private native void run(String title, int mode, String dir, String file,
+ FilenameFilter filter, boolean isMultipleMode);
+
+ private native void quit();
+
+ /**
+ * Called exclusively by the native C code.
+ */
+ private void setFileInternal(String directory, String[] filenames) {
+ AWTAccessor.FileDialogAccessor accessor = AWTAccessor
+ .getFileDialogAccessor();
+
+ if (filenames == null) {
+ accessor.setDirectory(fd, null);
+ accessor.setFile(fd, null);
+ accessor.setFiles(fd, null, null);
+ } else {
+ accessor.setDirectory(fd, directory);
+ accessor.setFile(fd, filenames[0]);
+ accessor.setFiles(fd, directory, filenames);
+ }
+ }
+
+ /**
+ * Called exclusively by the native C code.
+ */
+ private boolean filenameFilterCallback(String fullname) {
+ if (fd.getFilenameFilter() == null) {
+ // no filter, accept all.
+ return true;
+ }
+
+ File filen = new File(fullname);
+ return fd.getFilenameFilter().accept(new File(filen.getParent()),
+ filen.getName());
+ }
+
+ @Override
+ public void setVisible(boolean b) {
+ XToolkit.awtLock();
+ try {
+ if (b) {
+ Thread t = new Thread() {
+ public void run() {
+ GtkFileDialogPeer.this.run(fd.getTitle(), fd.getMode(),
+ fd.getDirectory(), fd.getFile(), fd
+ .getFilenameFilter(), fd
+ .isMultipleMode());
+ fd.setVisible(false);
+ }
+ };
+ t.start();
+ } else {
+ quit();
+ fd.setVisible(false);
+ }
+ } finally {
+ XToolkit.awtUnlock();
+ }
+ }
+
+ @Override
+ public void dispose() {
+ quit();
+ super.dispose();
+ }
+
+ @Override
+ public void setDirectory(String dir) {
+ // We do not implement this method because we
+ // have delegated to FileDialog#setDirectory
+ }
+
+ @Override
+ public void setFile(String file) {
+ // We do not implement this method because we
+ // have delegated to FileDialog#setFile
+ }
+
+ @Override
+ public void setFilenameFilter(FilenameFilter filter) {
+ // We do not implement this method because we
+ // have delegated to FileDialog#setFilenameFilter
+ }
+}
--- a/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java Thu May 13 13:22:22 2010 -0700
+++ b/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java Wed May 19 12:27:47 2010 -0700
@@ -1054,7 +1054,9 @@
}
public FileDialogPeer createFileDialog(FileDialog target) {
- FileDialogPeer peer = new XFileDialogPeer(target);
+ // The current GtkFileChooser is available from GTK+ 2.4
+ FileDialogPeer peer = checkGtkVersion(2, 4, 0) ? new GtkFileDialogPeer(
+ target) : new XFileDialogPeer(target);
targetCreatedPeer(target, peer);
return peer;
}
--- a/jdk/src/solaris/native/sun/awt/awt_UNIXToolkit.c Thu May 13 13:22:22 2010 -0700
+++ b/jdk/src/solaris/native/sun/awt/awt_UNIXToolkit.c Wed May 19 12:27:47 2010 -0700
@@ -260,3 +260,23 @@
}
dlclose(hSplashLib);
}
+
+/*
+ * Class: sun_awt_UNIXToolkit
+ * Method: gtkCheckVersionImpl
+ * Signature: (III)Ljava/lang/String;
+ */
+JNIEXPORT jboolean JNICALL
+Java_sun_awt_UNIXToolkit_gtkCheckVersionImpl(JNIEnv *env, jobject this,
+ jint major, jint minor, jint micro)
+{
+ char *ret;
+
+ ret = fp_gtk_check_version(major, minor, micro);
+ if (ret == NULL) {
+ return TRUE;
+ }
+
+ free(ret);
+ return FALSE;
+}
--- a/jdk/src/solaris/native/sun/awt/gtk2_interface.c Thu May 13 13:22:22 2010 -0700
+++ b/jdk/src/solaris/native/sun/awt/gtk2_interface.c Wed May 19 12:27:47 2010 -0700
@@ -32,6 +32,7 @@
#include "java_awt_Transparency.h"
#define GTK2_LIB "libgtk-x11-2.0.so.0"
+#define GTHREAD_LIB "libgthread-2.0.so.0"
#define G_TYPE_INVALID G_TYPE_MAKE_FUNDAMENTAL (0)
#define G_TYPE_NONE G_TYPE_MAKE_FUNDAMENTAL (1)
@@ -75,6 +76,8 @@
const gint DEFAULT = 1 << 10;
static void *gtk2_libhandle = NULL;
+static void *gthread_libhandle = NULL;
+static gboolean flag_g_thread_get_initialized = FALSE;
static jmp_buf j;
/* Widgets */
@@ -150,7 +153,6 @@
/*************************
* Glib function pointers
*************************/
-static void (*fp_g_free)(gpointer mem);
static gboolean (*fp_g_main_context_iteration)(GMainContext *context,
gboolean may_block);
@@ -204,9 +206,6 @@
/************************
* Gtk function pointers
************************/
-static gchar* (*fp_gtk_check_version)(guint required_major,
- guint required_minor,
- guint required_micro);
static gboolean (*fp_gtk_init_check)(int* argc, char** argv);
/* Painting */
@@ -330,7 +329,6 @@
static void (*fp_gtk_menu_item_set_submenu)(GtkMenuItem *menu_item,
GtkWidget *submenu);
static void (*fp_gtk_widget_realize)(GtkWidget *widget);
-static void (*fp_gtk_widget_destroy)(GtkWidget *widget);
static GdkPixbuf* (*fp_gtk_widget_render_icon)(GtkWidget *widget,
const gchar *stock_id, GtkIconSize size, const gchar *detail);
static void (*fp_gtk_widget_set_name)(GtkWidget *widget, const gchar *name);
@@ -388,6 +386,15 @@
return result;
}
+static void* dl_symbol_gthread(const char* name)
+{
+ void* result = dlsym(gthread_libhandle, name);
+ if (!result)
+ longjmp(j, NO_SYMBOL_EXCEPTION);
+
+ return result;
+}
+
gboolean gtk2_check_version()
{
if (gtk2_libhandle != NULL) {
@@ -414,6 +421,35 @@
}
}
+/**
+ * Functions for sun_awt_X11_GtkFileDialogPeer.c
+ */
+void gtk2_file_chooser_load()
+{
+ fp_gtk_file_chooser_get_filename = dl_symbol(
+ "gtk_file_chooser_get_filename");
+ fp_gtk_file_chooser_dialog_new = dl_symbol("gtk_file_chooser_dialog_new");
+ fp_gtk_file_chooser_set_current_folder = dl_symbol(
+ "gtk_file_chooser_set_current_folder");
+ fp_gtk_file_chooser_set_filename = dl_symbol(
+ "gtk_file_chooser_set_filename");
+ fp_gtk_file_filter_add_custom = dl_symbol("gtk_file_filter_add_custom");
+ fp_gtk_file_chooser_set_filter = dl_symbol("gtk_file_chooser_set_filter");
+ fp_gtk_file_chooser_get_type = dl_symbol("gtk_file_chooser_get_type");
+ fp_gtk_file_filter_new = dl_symbol("gtk_file_filter_new");
+ if (fp_gtk_check_version(2, 8, 0) == NULL) {
+ fp_gtk_file_chooser_set_do_overwrite_confirmation = dl_symbol(
+ "gtk_file_chooser_set_do_overwrite_confirmation");
+ }
+ fp_gtk_file_chooser_set_select_multiple = dl_symbol(
+ "gtk_file_chooser_set_select_multiple");
+ fp_gtk_file_chooser_get_current_folder = dl_symbol(
+ "gtk_file_chooser_get_current_folder");
+ fp_gtk_file_chooser_get_filenames = dl_symbol(
+ "gtk_file_chooser_get_filenames");
+ fp_gtk_g_slist_length = dl_symbol("g_slist_length");
+}
+
gboolean gtk2_load()
{
gboolean result;
@@ -423,7 +459,9 @@
char *gtk_modules_env;
gtk2_libhandle = dlopen(GTK2_LIB, RTLD_LAZY | RTLD_LOCAL);
- if (gtk2_libhandle == NULL)
+ gthread_libhandle = dlopen(GTHREAD_LIB, RTLD_LAZY | RTLD_LOCAL);
+
+ if (gtk2_libhandle == NULL || gthread_libhandle == NULL)
return FALSE;
if (setjmp(j) == 0)
@@ -597,6 +635,28 @@
fp_gtk_range_get_adjustment =
dl_symbol("gtk_range_get_adjustment");
+ fp_gtk_widget_hide = dl_symbol("gtk_widget_hide");
+ fp_gtk_main_quit = dl_symbol("gtk_main_quit");
+ fp_g_signal_connect_data = dl_symbol("g_signal_connect_data");
+ fp_gtk_widget_show = dl_symbol("gtk_widget_show");
+ fp_gtk_main = dl_symbol("gtk_main");
+
+ /**
+ * GLib thread system
+ */
+ fp_g_thread_init = dl_symbol_gthread("g_thread_init");
+ fp_gdk_threads_init = dl_symbol("gdk_threads_init");
+ fp_gdk_threads_enter = dl_symbol("gdk_threads_enter");
+ fp_gdk_threads_leave = dl_symbol("gdk_threads_leave");
+
+ /**
+ * Functions for sun_awt_X11_GtkFileDialogPeer.c
+ */
+ if (fp_gtk_check_version(2, 4, 0) == NULL) {
+ // The current GtkFileChooser is available from GTK+ 2.4
+ gtk2_file_chooser_load();
+ }
+
/* Some functions may be missing in pre-2.4 GTK.
We handle them specially here.
*/
@@ -626,6 +686,10 @@
{
dlclose(gtk2_libhandle);
gtk2_libhandle = NULL;
+
+ dlclose(gthread_libhandle);
+ gthread_libhandle = NULL;
+
return FALSE;
}
@@ -678,6 +742,19 @@
*/
handler = XSetErrorHandler(NULL);
io_handler = XSetIOErrorHandler(NULL);
+
+ if (fp_gtk_check_version(2, 2, 0) == NULL) {
+ // Init the thread system to use GLib in a thread-safe mode
+ if (!flag_g_thread_get_initialized) {
+ flag_g_thread_get_initialized = TRUE;
+
+ fp_g_thread_init(NULL);
+
+ //According the GTK documentation, gdk_threads_init() should be
+ //called before gtk_init() or gtk_init_check()
+ fp_gdk_threads_init();
+ }
+ }
result = (*fp_gtk_init_check)(NULL, NULL);
XSetErrorHandler(handler);
@@ -722,6 +799,7 @@
dlerror();
dlclose(gtk2_libhandle);
+ dlclose(gthread_libhandle);
if ((gtk2_error = dlerror()) != NULL)
{
return FALSE;
--- a/jdk/src/solaris/native/sun/awt/gtk2_interface.h Thu May 13 13:22:22 2010 -0700
+++ b/jdk/src/solaris/native/sun/awt/gtk2_interface.h Wed May 19 12:27:47 2010 -0700
@@ -28,6 +28,21 @@
#include <stdlib.h>
#include <jni.h>
+#define _G_TYPE_CIC(ip, gt, ct) ((ct*) ip)
+#define G_TYPE_CHECK_INSTANCE_CAST(instance, g_type, c_type) (_G_TYPE_CIC ((instance), (g_type), c_type))
+#define GTK_TYPE_FILE_CHOOSER (fp_gtk_file_chooser_get_type ())
+#define GTK_FILE_CHOOSER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_FILE_CHOOSER, GtkFileChooser))
+#define fp_g_signal_connect(instance, detailed_signal, c_handler, data) \
+ fp_g_signal_connect_data ((instance), (detailed_signal), (c_handler), (data), NULL, (GConnectFlags) 0)
+#define G_CALLBACK(f) ((GCallback) (f))
+#define G_TYPE_FUNDAMENTAL_SHIFT (2)
+#define G_TYPE_MAKE_FUNDAMENTAL(x) ((GType) ((x) << G_TYPE_FUNDAMENTAL_SHIFT))
+#define G_TYPE_OBJECT G_TYPE_MAKE_FUNDAMENTAL (20)
+#define G_OBJECT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), G_TYPE_OBJECT, GObject))
+#define GTK_STOCK_CANCEL "gtk-cancel"
+#define GTK_STOCK_SAVE "gtk-save"
+#define GTK_STOCK_OPEN "gtk-open"
+
typedef enum _WidgetType
{
BUTTON, /* GtkButton */
@@ -254,7 +269,13 @@
/* We define all structure pointers to be void* */
typedef void GError;
typedef void GMainContext;
-typedef void GSList;
+
+typedef struct _GSList GSList;
+struct _GSList
+{
+ gpointer data;
+ GSList *next;
+};
typedef void GdkColormap;
typedef void GdkDrawable;
@@ -556,6 +577,65 @@
guint ellipsize : 3;
};
+typedef enum {
+ GTK_RESPONSE_NONE = -1,
+ GTK_RESPONSE_REJECT = -2,
+ GTK_RESPONSE_ACCEPT = -3,
+ GTK_RESPONSE_DELETE_EVENT = -4,
+ GTK_RESPONSE_OK = -5,
+ GTK_RESPONSE_CANCEL = -6,
+ GTK_RESPONSE_CLOSE = -7,
+ GTK_RESPONSE_YES = -8,
+ GTK_RESPONSE_NO = -9,
+ GTK_RESPONSE_APPLY = -10,
+ GTK_RESPONSE_HELP = -11
+} GtkResponseType;
+
+typedef struct _GtkWindow GtkWindow;
+
+typedef struct _GtkFileChooser GtkFileChooser;
+
+typedef enum {
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ GTK_FILE_CHOOSER_ACTION_SAVE,
+ GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+ GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER
+} GtkFileChooserAction;
+
+typedef struct _GtkFileFilter GtkFileFilter;
+
+typedef enum {
+ GTK_FILE_FILTER_FILENAME = 1 << 0,
+ GTK_FILE_FILTER_URI = 1 << 1,
+ GTK_FILE_FILTER_DISPLAY_NAME = 1 << 2,
+ GTK_FILE_FILTER_MIME_TYPE = 1 << 3
+} GtkFileFilterFlags;
+
+typedef struct {
+ GtkFileFilterFlags contains;
+ const gchar *filename;
+ const gchar *uri;
+ const gchar *display_name;
+ const gchar *mime_type;
+} GtkFileFilterInfo;
+
+typedef gboolean (*GtkFileFilterFunc)(const GtkFileFilterInfo *filter_info,
+ gpointer data);
+
+typedef void (*GDestroyNotify)(gpointer data);
+
+typedef void (*GCallback)(void);
+
+typedef struct _GClosure GClosure;
+
+typedef void (*GClosureNotify)(gpointer data, GClosure *closure);
+
+typedef enum {
+ G_CONNECT_AFTER = 1 << 0, G_CONNECT_SWAPPED = 1 << 1
+} GConnectFlags;
+
+typedef struct _GThreadFunctions GThreadFunctions;
+
/*
* Converts java.lang.String object to UTF-8 character string.
*/
@@ -569,6 +649,13 @@
*/
gboolean gtk2_check_version();
+/**
+ * Returns :
+ * NULL if the GTK+ library is compatible with the given version, or a string
+ * describing the version mismatch.
+ */
+gchar* (*fp_gtk_check_version)(guint required_major, guint required_minor,
+ guint required_micro);
/*
* Load the gtk2 library. If the library is already loaded this method has no
* effect and returns success.
@@ -651,6 +738,7 @@
void gtk2_set_range_value(WidgetType widget_type, jdouble value,
jdouble min, jdouble max, jdouble visible);
+void (*fp_g_free)(gpointer mem);
void (*fp_g_object_unref)(gpointer object);
int (*fp_gdk_pixbuf_get_bits_per_sample)(const GdkPixbuf *pixbuf);
guchar *(*fp_gdk_pixbuf_get_pixels)(const GdkPixbuf *pixbuf);
@@ -660,5 +748,47 @@
int (*fp_gdk_pixbuf_get_rowstride)(const GdkPixbuf *pixbuf);
int (*fp_gdk_pixbuf_get_width)(const GdkPixbuf *pixbuf);
GdkPixbuf *(*fp_gdk_pixbuf_new_from_file)(const char *filename, GError **error);
+void (*fp_gtk_widget_destroy)(GtkWidget *widget);
+
+
+/**
+ * Function Pointers for GtkFileChooser
+ */
+gchar* (*fp_gtk_file_chooser_get_filename)(GtkFileChooser *chooser);
+void (*fp_gtk_widget_hide)(GtkWidget *widget);
+void (*fp_gtk_main_quit)(void);
+GtkWidget* (*fp_gtk_file_chooser_dialog_new)(const gchar *title,
+ GtkWindow *parent, GtkFileChooserAction action,
+ const gchar *first_button_text, ...);
+gboolean (*fp_gtk_file_chooser_set_current_folder)(GtkFileChooser *chooser,
+ const gchar *filename);
+gboolean (*fp_gtk_file_chooser_set_filename)(GtkFileChooser *chooser,
+ const char *filename);
+void (*fp_gtk_file_filter_add_custom)(GtkFileFilter *filter,
+ GtkFileFilterFlags needed, GtkFileFilterFunc func, gpointer data,
+ GDestroyNotify notify);
+void (*fp_gtk_file_chooser_set_filter)(GtkFileChooser *chooser,
+ GtkFileFilter *filter);
+GType (*fp_gtk_file_chooser_get_type)(void);
+GtkFileFilter* (*fp_gtk_file_filter_new)(void);
+void (*fp_gtk_file_chooser_set_do_overwrite_confirmation)(
+ GtkFileChooser *chooser, gboolean do_overwrite_confirmation);
+void (*fp_gtk_file_chooser_set_select_multiple)(
+ GtkFileChooser *chooser, gboolean select_multiple);
+gchar* (*fp_gtk_file_chooser_get_current_folder)(GtkFileChooser *chooser);
+GSList* (*fp_gtk_file_chooser_get_filenames)(GtkFileChooser *chooser);
+guint (*fp_gtk_g_slist_length)(GSList *list);
+gulong (*fp_g_signal_connect_data)(gpointer instance,
+ const gchar *detailed_signal, GCallback c_handler, gpointer data,
+ GClosureNotify destroy_data, GConnectFlags connect_flags);
+void (*fp_gtk_widget_show)(GtkWidget *widget);
+void (*fp_gtk_main)(void);
+guint (*fp_gtk_main_level)(void);
+
+
+void (*fp_g_thread_init)(GThreadFunctions *vtable);
+void (*fp_gdk_threads_init)(void);
+void (*fp_gdk_threads_enter)(void);
+void (*fp_gdk_threads_leave)(void);
#endif /* !_GTK2_INTERFACE_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/solaris/native/sun/awt/sun_awt_X11_GtkFileDialogPeer.c Wed May 19 12:27:47 2010 -0700
@@ -0,0 +1,225 @@
+#include <jni.h>
+#include <stdio.h>
+#include <jni_util.h>
+#include <string.h>
+#include "gtk2_interface.h"
+#include "sun_awt_X11_GtkFileDialogPeer.h"
+
+static JavaVM *jvm;
+static GtkWidget *dialog = NULL;
+
+/* To cache some method IDs */
+static jmethodID filenameFilterCallbackMethodID = NULL;
+static jmethodID setFileInternalMethodID = NULL;
+
+static gboolean filenameFilterCallback(const GtkFileFilterInfo * filter_info, gpointer obj)
+{
+ JNIEnv *env;
+ jclass cx;
+ jstring filename;
+
+ env = (JNIEnv *) JNU_GetEnv(jvm, JNI_VERSION_1_2);
+
+ if (filenameFilterCallbackMethodID == NULL) {
+ cx = (*env)->GetObjectClass(env, (jobject) obj);
+ if (cx == NULL) {
+ JNU_ThrowInternalError(env, "Could not get file filter class");
+ return 0;
+ }
+
+ filenameFilterCallbackMethodID = (*env)->GetMethodID(env, cx,
+ "filenameFilterCallback", "(Ljava/lang/String;)Z");
+ if (filenameFilterCallbackMethodID == NULL) {
+ JNU_ThrowInternalError(env,
+ "Could not get filenameFilterCallback method id");
+ return 0;
+ }
+ }
+
+ filename = (*env)->NewStringUTF(env, filter_info->filename);
+
+ return (*env)->CallBooleanMethod(env, obj, filenameFilterCallbackMethodID,
+ filename);
+}
+
+/*
+ * Class: sun_awt_X11_GtkFileDialogPeer
+ * Method: quit
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_sun_awt_X11_GtkFileDialogPeer_quit
+(JNIEnv * env, jobject jpeer)
+{
+ if (dialog != NULL)
+ {
+ fp_gtk_widget_hide (dialog);
+ fp_gtk_widget_destroy (dialog);
+
+ fp_gtk_main_quit ();
+ dialog = NULL;
+ }
+}
+
+/**
+ * Convert a GSList to an array of filenames (without the parent folder)
+ */
+static jobjectArray toFilenamesArray(JNIEnv *env, GSList* list)
+{
+ jstring str;
+ jclass stringCls;
+ GSList *iterator;
+ jobjectArray array;
+ int i;
+ char* entry;
+
+ if (NULL == list) {
+ return NULL;
+ }
+
+ stringCls = (*env)->FindClass(env, "java/lang/String");
+ if (stringCls == NULL) {
+ JNU_ThrowInternalError(env, "Could not get java.lang.String class");
+ return NULL;
+ }
+
+ array = (*env)->NewObjectArray(env, fp_gtk_g_slist_length(list), stringCls,
+ NULL);
+ if (array == NULL) {
+ JNU_ThrowInternalError(env, "Could not instantiate array files array");
+ return NULL;
+ }
+
+ i = 0;
+ for (iterator = list; iterator; iterator = iterator->next) {
+ entry = (char*) iterator->data;
+ entry = strrchr(entry, '/') + 1;
+ str = (*env)->NewStringUTF(env, entry);
+ (*env)->SetObjectArrayElement(env, array, i, str);
+ i++;
+ }
+
+ return array;
+}
+
+static void handle_response(GtkWidget* aDialog, gint responseId, gpointer obj)
+{
+ JNIEnv *env;
+ char *current_folder;
+ GSList *filenames;
+ jclass cx;
+ jstring jcurrent_folder;
+ jobjectArray jfilenames;
+
+ env = (JNIEnv *) JNU_GetEnv(jvm, JNI_VERSION_1_2);
+ current_folder = NULL;
+ filenames = NULL;
+
+ if (responseId == GTK_RESPONSE_ACCEPT) {
+ current_folder = fp_gtk_file_chooser_get_current_folder(
+ GTK_FILE_CHOOSER(dialog));
+ filenames = fp_gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(dialog));
+ }
+
+ if (setFileInternalMethodID == NULL) {
+ cx = (*env)->GetObjectClass(env, (jobject) obj);
+ if (cx == NULL) {
+ JNU_ThrowInternalError(env, "Could not get GTK peer class");
+ return;
+ }
+
+ setFileInternalMethodID = (*env)->GetMethodID(env, cx,
+ "setFileInternal", "(Ljava/lang/String;[Ljava/lang/String;)V");
+ if (setFileInternalMethodID == NULL) {
+ JNU_ThrowInternalError(env,
+ "Could not get setFileInternalMethodID method id");
+ return;
+ }
+ }
+
+ jcurrent_folder = (*env)->NewStringUTF(env, current_folder);
+ jfilenames = toFilenamesArray(env, filenames);
+
+ (*env)->CallVoidMethod(env, obj, setFileInternalMethodID, jcurrent_folder,
+ jfilenames);
+ fp_g_free(current_folder);
+
+ Java_sun_awt_X11_GtkFileDialogPeer_quit(NULL, NULL);
+}
+
+/*
+ * Class: sun_awt_X11_GtkFileDialogPeer
+ * Method: run
+ * Signature: (Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/io/FilenameFilter;Z;)V
+ */
+JNIEXPORT void JNICALL
+Java_sun_awt_X11_GtkFileDialogPeer_run(JNIEnv * env, jobject jpeer,
+ jstring jtitle, jint mode, jstring jdir, jstring jfile,
+ jobject jfilter, jboolean multiple)
+{
+ GtkFileFilter *filter;
+
+ if (jvm == NULL) {
+ (*env)->GetJavaVM(env, &jvm);
+ }
+
+ fp_gdk_threads_init();
+ fp_gdk_threads_enter();
+
+ const char *title = (*env)->GetStringUTFChars(env, jtitle, 0);
+
+ if (mode == 1) {
+ /* Save action */
+ dialog = fp_gtk_file_chooser_dialog_new(title, NULL,
+ GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL,
+ GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL);
+ }
+ else {
+ /* Default action OPEN */
+ dialog = fp_gtk_file_chooser_dialog_new(title, NULL,
+ GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL,
+ GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);
+
+ /* Set multiple selection mode, that is allowed only in OPEN action */
+ if (multiple) {
+ fp_gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog),
+ multiple);
+ }
+ }
+
+ (*env)->ReleaseStringUTFChars(env, jtitle, title);
+
+ /* Set the directory */
+ if (jdir != NULL) {
+ const char *dir = (*env)->GetStringUTFChars(env, jdir, 0);
+ fp_gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), dir);
+ (*env)->ReleaseStringUTFChars(env, jdir, dir);
+ }
+
+ /* Set the filename */
+ if (jfile != NULL) {
+ const char *filename = (*env)->GetStringUTFChars(env, jfile, 0);
+ fp_gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), filename);
+ (*env)->ReleaseStringUTFChars(env, jfile, filename);
+ }
+
+ /* Set the file filter */
+ if (jfilter != NULL) {
+ filter = fp_gtk_file_filter_new();
+ fp_gtk_file_filter_add_custom(filter, GTK_FILE_FILTER_FILENAME,
+ filenameFilterCallback, jpeer, NULL);
+ fp_gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog), filter);
+ }
+
+ /* Other Properties */
+ if (fp_gtk_check_version(2, 8, 0) == NULL) {
+ fp_gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(
+ dialog), TRUE);
+ }
+
+ fp_g_signal_connect(G_OBJECT(dialog), "response", G_CALLBACK(
+ handle_response), jpeer);
+ fp_gtk_widget_show(dialog);
+
+ fp_gtk_main();
+ fp_gdk_threads_leave();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/solaris/native/sun/awt/sun_awt_X11_GtkFileDialogPeer.h Wed May 19 12:27:47 2010 -0700
@@ -0,0 +1,31 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class sun_awt_X11_GtkFileDialogPeer */
+
+#ifndef _Included_sun_awt_X11_GtkFileDialogPeer
+#define _Included_sun_awt_X11_GtkFileDialogPeer
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*
+ * Class: sun_awt_X11_GtkFileDialogPeer
+ * Method: run
+ * Signature: (Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/io/FilenameFilter;Z;)V
+ */
+JNIEXPORT void JNICALL Java_sun_awt_X11_GtkFileDialogPeer_run
+(JNIEnv *, jobject, jstring, jint, jstring, jstring, jobject, jboolean);
+
+/*
+ * Class: sun_awt_X11_GtkFileDialogPeer
+ * Method: quit
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_sun_awt_X11_GtkFileDialogPeer_quit
+(JNIEnv *, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
--- a/jdk/src/solaris/native/sun/awt/swing_GTKEngine.c Thu May 13 13:22:22 2010 -0700
+++ b/jdk/src/solaris/native/sun/awt/swing_GTKEngine.c Wed May 19 12:27:47 2010 -0700
@@ -38,8 +38,10 @@
jint widget_type, jint state, jint shadow_type, jstring detail,
jint x, jint y, jint w, jint h, jint arrow_type)
{
+ fp_gdk_threads_enter();
gtk2_paint_arrow(widget_type, state, shadow_type, getStrFor(env, detail),
x, y, w, h, arrow_type, TRUE);
+ fp_gdk_threads_leave();
}
/*
@@ -54,8 +56,10 @@
jint x, jint y, jint w, jint h,
jint synth_state, jint dir)
{
+ fp_gdk_threads_enter();
gtk2_paint_box(widget_type, state, shadow_type, getStrFor(env, detail),
x, y, w, h, synth_state, dir);
+ fp_gdk_threads_leave();
}
/*
@@ -70,8 +74,10 @@
jint x, jint y, jint w, jint h,
jint gap_side, jint gap_x, jint gap_w)
{
+ fp_gdk_threads_enter();
gtk2_paint_box_gap(widget_type, state, shadow_type, getStrFor(env, detail),
x, y, w, h, gap_side, gap_x, gap_w);
+ fp_gdk_threads_leave();
}
/*
@@ -85,8 +91,10 @@
jint widget_type, jint synth_state, jstring detail,
jint x, jint y, jint w, jint h)
{
+ fp_gdk_threads_enter();
gtk2_paint_check(widget_type, synth_state, getStrFor(env, detail),
x, y, w, h);
+ fp_gdk_threads_leave();
}
/*
@@ -100,8 +108,10 @@
jint widget_type, jint state, jstring detail,
jint x, jint y, jint w, jint h, jint expander_style)
{
+ fp_gdk_threads_enter();
gtk2_paint_expander(widget_type, state, getStrFor(env, detail),
x, y, w, h, expander_style);
+ fp_gdk_threads_leave();
}
/*
@@ -115,8 +125,10 @@
jint widget_type, jint state, jint shadow_type, jstring detail,
jint x, jint y, jint w, jint h, jint placement)
{
+ fp_gdk_threads_enter();
gtk2_paint_extension(widget_type, state, shadow_type,
getStrFor(env, detail), x, y, w, h, placement);
+ fp_gdk_threads_leave();
}
/*
@@ -130,8 +142,10 @@
jint widget_type, jint state, jint shadow_type, jstring detail,
jint x, jint y, jint w, jint h, jboolean has_focus)
{
+ fp_gdk_threads_enter();
gtk2_paint_flat_box(widget_type, state, shadow_type,
getStrFor(env, detail), x, y, w, h, has_focus);
+ fp_gdk_threads_leave();
}
/*
@@ -145,8 +159,10 @@
jint widget_type, jint state, jstring detail,
jint x, jint y, jint w, jint h)
{
+ fp_gdk_threads_enter();
gtk2_paint_focus(widget_type, state, getStrFor(env, detail),
x, y, w, h);
+ fp_gdk_threads_leave();
}
/*
@@ -160,8 +176,10 @@
jint widget_type, jint state, jint shadow_type, jstring detail,
jint x, jint y, jint w, jint h, jint orientation)
{
+ fp_gdk_threads_enter();
gtk2_paint_handle(widget_type, state, shadow_type, getStrFor(env, detail),
x, y, w, h, orientation);
+ fp_gdk_threads_leave();
}
/*
@@ -175,8 +193,10 @@
jint widget_type, jint state, jstring detail,
jint x, jint y, jint w, jint h)
{
+ fp_gdk_threads_enter();
gtk2_paint_hline(widget_type, state, getStrFor(env, detail),
x, y, w, h);
+ fp_gdk_threads_leave();
}
/*
@@ -190,8 +210,10 @@
jint widget_type, jint synth_state, jstring detail,
jint x, jint y, jint w, jint h)
{
+ fp_gdk_threads_enter();
gtk2_paint_option(widget_type, synth_state, getStrFor(env, detail),
x, y, w, h);
+ fp_gdk_threads_leave();
}
/*
@@ -206,8 +228,10 @@
jint x, jint y, jint w, jint h,
jint synth_state, jint dir)
{
+ fp_gdk_threads_enter();
gtk2_paint_shadow(widget_type, state, shadow_type, getStrFor(env, detail),
x, y, w, h, synth_state, dir);
+ fp_gdk_threads_leave();
}
/*
@@ -221,8 +245,10 @@
jint widget_type, jint state, jint shadow_type, jstring detail,
jint x, jint y, jint w, jint h, jint orientation)
{
+ fp_gdk_threads_enter();
gtk2_paint_slider(widget_type, state, shadow_type, getStrFor(env, detail),
x, y, w, h, orientation);
+ fp_gdk_threads_leave();
}
/*
@@ -236,8 +262,10 @@
jint widget_type, jint state, jstring detail,
jint x, jint y, jint w, jint h)
{
+ fp_gdk_threads_enter();
gtk2_paint_vline(widget_type, state, getStrFor(env, detail),
x, y, w, h);
+ fp_gdk_threads_leave();
}
/*
@@ -250,7 +278,9 @@
JNIEnv *env, jobject this, jint widget_type, jint state,
jint x, jint y, jint w, jint h)
{
+ fp_gdk_threads_enter();
gtk_paint_background(widget_type, state, x, y, w, h);
+ fp_gdk_threads_leave();
}
/*
@@ -262,7 +292,9 @@
Java_com_sun_java_swing_plaf_gtk_GTKEngine_nativeStartPainting(
JNIEnv *env, jobject this, jint w, jint h)
{
+ fp_gdk_threads_enter();
gtk2_init_painting(w, h);
+ fp_gdk_threads_leave();
}
/*
@@ -276,7 +308,9 @@
{
jint transparency;
gint *buffer = (gint*) (*env)->GetPrimitiveArrayCritical(env, dest, 0);
+ fp_gdk_threads_enter();
transparency = gtk2_copy_image(buffer, width, height);
+ fp_gdk_threads_leave();
(*env)->ReleasePrimitiveArrayCritical(env, dest, buffer, 0);
return transparency;
}
@@ -289,7 +323,9 @@
JNIEXPORT void JNICALL Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1switch_1theme(
JNIEnv *env, jobject this)
{
+ fp_gdk_threads_enter();
flush_gtk_event_loop();
+ fp_gdk_threads_leave();
}
/*
@@ -300,7 +336,11 @@
JNIEXPORT jobject JNICALL Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1get_1gtk_1setting(
JNIEnv *env, jobject this, jint property)
{
- return gtk2_get_setting(env, property);
+ jobject obj;
+ fp_gdk_threads_enter();
+ obj = gtk2_get_setting(env, property);
+ fp_gdk_threads_leave();
+ return obj;
}
/*
@@ -313,5 +353,7 @@
JNIEnv *env, jobject this, jint widget_type,
jdouble value, jdouble min, jdouble max, jdouble visible)
{
+ fp_gdk_threads_enter();
gtk2_set_range_value(widget_type, value, min, max, visible);
+ fp_gdk_threads_leave();
}
--- a/jdk/src/solaris/native/sun/awt/swing_GTKStyle.c Thu May 13 13:22:22 2010 -0700
+++ b/jdk/src/solaris/native/sun/awt/swing_GTKStyle.c Wed May 19 12:27:47 2010 -0700
@@ -36,7 +36,11 @@
Java_com_sun_java_swing_plaf_gtk_GTKStyle_nativeGetXThickness(
JNIEnv *env, jclass klass, jint widget_type)
{
- return gtk2_get_xthickness(env, widget_type);
+ jint ret;
+ fp_gdk_threads_enter();
+ ret = gtk2_get_xthickness(env, widget_type);
+ fp_gdk_threads_leave();
+ return ret;
}
/*
@@ -48,7 +52,11 @@
Java_com_sun_java_swing_plaf_gtk_GTKStyle_nativeGetYThickness(
JNIEnv *env, jclass klass, jint widget_type)
{
- return gtk2_get_ythickness(env, widget_type);
+ jint ret;
+ fp_gdk_threads_enter();
+ ret = gtk2_get_ythickness(env, widget_type);
+ fp_gdk_threads_leave();
+ return ret;
}
/*
@@ -61,7 +69,11 @@
JNIEnv *env, jclass klass, jint widget_type,
jint state_type, jint type_id)
{
- return gtk2_get_color_for_state(env, widget_type, state_type, type_id);
+ jint ret;
+ fp_gdk_threads_enter();
+ ret = gtk2_get_color_for_state(env, widget_type, state_type, type_id);
+ fp_gdk_threads_leave();
+ return ret;
}
/*
@@ -73,7 +85,11 @@
Java_com_sun_java_swing_plaf_gtk_GTKStyle_nativeGetClassValue(
JNIEnv *env, jclass klass, jint widget_type, jstring key)
{
- return gtk2_get_class_value(env, widget_type, key);
+ jobject ret;
+ fp_gdk_threads_enter();
+ ret = gtk2_get_class_value(env, widget_type, key);
+ fp_gdk_threads_leave();
+ return ret;
}
/*
@@ -85,5 +101,9 @@
Java_com_sun_java_swing_plaf_gtk_GTKStyle_nativeGetPangoFontName(
JNIEnv *env, jclass klass, jint widget_type)
{
- return gtk2_get_pango_font_name(env, widget_type);
+ jstring ret;
+ fp_gdk_threads_enter();
+ ret = gtk2_get_pango_font_name(env, widget_type);
+ fp_gdk_threads_leave();
+ return ret;
}
--- a/jdk/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java Thu May 13 13:22:22 2010 -0700
+++ b/jdk/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java Wed May 19 12:27:47 2010 -0700
@@ -403,9 +403,14 @@
}
}
String path = dir.getPath();
- return (path.length() == 3
- && path.charAt(1) == ':'
- && Arrays.asList(drives.listFiles()).contains(dir));
+
+ if (path.length() != 3 || path.charAt(1) != ':') {
+ return false;
+ }
+
+ File[] files = drives.listFiles();
+
+ return files != null && Arrays.asList(files).contains(dir);
}
return false;
}
--- a/jdk/src/windows/native/java/net/net_util_md.h Thu May 13 13:22:22 2010 -0700
+++ b/jdk/src/windows/native/java/net/net_util_md.h Wed May 19 12:27:47 2010 -0700
@@ -222,7 +222,8 @@
#define IN6_IS_ADDR_ANY(a) \
(((a)->s6_words[0] == 0) && ((a)->s6_words[1] == 0) && \
((a)->s6_words[2] == 0) && ((a)->s6_words[3] == 0) && \
- ((a)->s6_words[4] == 0) && ((a)->s6_words[5] == 0))
+ ((a)->s6_words[4] == 0) && ((a)->s6_words[5] == 0) && \
+ ((a)->s6_words[6] == 0) && ((a)->s6_words[7] == 0))
#endif
#ifndef IPV6_V6ONLY
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/net/httpserver/bugs/HeadTest.java Wed May 19 12:27:47 2010 -0700
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2010 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * @test
+ * @bug 6886723
+ * @summary light weight http server doesn't return correct status code for HEAD requests
+ */
+
+import java.net.InetSocketAddress;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.io.IOException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import com.sun.net.httpserver.HttpContext;
+import com.sun.net.httpserver.HttpExchange;
+import com.sun.net.httpserver.HttpHandler;
+import com.sun.net.httpserver.HttpServer;
+
+public class HeadTest {
+
+ public static void main(String[] args) throws Exception {
+ server();
+ }
+
+ static void server() throws Exception {
+ InetSocketAddress inetAddress = new InetSocketAddress(0);
+ HttpServer server = HttpServer.create(inetAddress, 5);
+ try {
+ server.setExecutor(Executors.newFixedThreadPool(5));
+ HttpContext chunkedContext = server.createContext("/chunked");
+ chunkedContext.setHandler(new HttpHandler() {
+ @Override
+ public void handle(HttpExchange msg) {
+ try {
+ try {
+ if (msg.getRequestMethod().equals("HEAD")) {
+ msg.getRequestBody().close();
+ msg.getResponseHeaders().add("Transfer-encoding", "chunked");
+ msg.sendResponseHeaders(200, -1);
+ }
+ } catch(IOException ioe) {
+ ioe.printStackTrace();
+ }
+ } finally {
+ msg.close();
+ }
+ }
+ });
+ HttpContext clContext = server.createContext("/content");
+ clContext.setHandler(new HttpHandler() {
+ @Override
+ public void handle(HttpExchange msg) {
+ try {
+ try {
+ if (msg.getRequestMethod().equals("HEAD")) {
+ msg.getRequestBody().close();
+ msg.getResponseHeaders().add("Content-length", "1024");
+ msg.sendResponseHeaders(200, -1);
+ }
+ } catch(IOException ioe) {
+ ioe.printStackTrace();
+ }
+ } finally {
+ msg.close();
+ }
+ }
+ });
+ server.start();
+ String urlStr = "http://localhost:" + server.getAddress().getPort() + "/";
+ System.out.println("Server is at " + urlStr);
+
+ // Run the chunked client
+ for(int i=0; i < 10; i++) {
+ runClient(urlStr + "chunked/");
+ }
+ // Run the content length client
+ for(int i=0; i < 10; i++) {
+ runClient(urlStr + "content/");
+ }
+ } finally {
+ // Stop the server
+ ((ExecutorService)server.getExecutor()).shutdown();
+ server.stop(0);
+ }
+ }
+
+ static void runClient(String urlStr) throws Exception {
+ HttpURLConnection conn = (HttpURLConnection) new URL(urlStr).openConnection();
+ conn.setRequestMethod("HEAD");
+ int status = conn.getResponseCode();
+ if (status != 200) {
+ throw new RuntimeException("HEAD request doesn't return 200, but returns " + status);
+ }
+ }
+}
--- a/jdk/test/java/awt/font/NumericShaper/MTTest.java Thu May 13 13:22:22 2010 -0700
+++ b/jdk/test/java/awt/font/NumericShaper/MTTest.java Wed May 19 12:27:47 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2010 Sun Microsystems, Inc. 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
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 6843181
+ * @bug 6843181 6943963
* @summary Confirm that NumericShaper is thread-safe.
* @run main/timeout=300/othervm MTTest
*/
@@ -37,33 +37,34 @@
static volatile boolean runrun = true;
static volatile boolean err = false;
- final static String text = "-123 (English) 456.00 (Arabic) \u0641\u0642\u0643 -789 (Thai) \u0e01\u0e33 01.23";
- static char[] t1, t2;
+ final static String text = "-123 (English) 456.00 (Arabic) \u0641\u0642\u0643 -456 (Thai) \u0e01\u0e33 01.23";
+ final static char[] expected1 = "-123 (English) 456.00 (Arabic) \u0641\u0642\u0643 -\u06f4\u06f5\u06f6 (Thai) \u0e01\u0e33 \u0e50\u0e51.\u0e52\u0e53".toCharArray(); // for EASTERN_ARABIC
+ final static char[] expected2 = "-123 (English) 456.00 (Arabic) \u0641\u0642\u0643 -\u0664\u0665\u0666 (Thai) \u0e01\u0e33 \u0e50\u0e51.\u0e52\u0e53".toCharArray(); // for ARABIC
+
static NumericShaper ns1, ns2, ns3, ns4;
public static void main(String[] args) {
- System.out.println(" original: " + text);
- ns1 = getContextualShaper(EnumSet.of(Range.ARABIC), Range.ARABIC);
- t1 = text.toCharArray();
- ns1.shape(t1, 0, t1.length);
- System.out.println("expected t1: " + String.valueOf(t1));
-
- ns2 = getContextualShaper(EnumSet.of(Range.THAI), Range.THAI);
- t2 = text.toCharArray();
- ns2.shape(t2, 0, t2.length);
- System.out.println("expected t2: " + String.valueOf(t2));
+ System.out.println("original: " + text);
+ ns1 = getContextualShaper(EnumSet.of(Range.EASTERN_ARABIC, Range.THAI),
+ Range.EUROPEAN);
+ ns2 = getContextualShaper(EnumSet.of(Range.ARABIC, Range.THAI),
+ Range.EUROPEAN);
+ System.out.println("expected for Eastern-Arabic & Thai: " +
+ String.valueOf(expected1));
+ System.out.println("expected for Arabic & Thai: " +
+ String.valueOf(expected2));
- ns3 = getContextualShaper(ARABIC, ARABIC);
- ns4 = getContextualShaper(THAI, THAI);
+ ns3 = getContextualShaper(EASTERN_ARABIC|THAI, EUROPEAN);
+ ns4 = getContextualShaper(ARABIC|THAI, EUROPEAN);
- Thread th1 = new Thread(new Work(ns1, t1));
- Thread th2 = new Thread(new Work(ns2, t2));
- Thread th3 = new Thread(new Work(ns1, t1));
- Thread th4 = new Thread(new Work(ns2, t2));
- Thread th5 = new Thread(new Work(ns3, t1));
- Thread th6 = new Thread(new Work(ns4, t2));
- Thread th7 = new Thread(new Work(ns3, t1));
- Thread th8 = new Thread(new Work(ns4, t2));
+ Thread th1 = new Thread(new Work(ns1, expected1));
+ Thread th2 = new Thread(new Work(ns2, expected2));
+ Thread th3 = new Thread(new Work(ns1, expected1));
+ Thread th4 = new Thread(new Work(ns2, expected2));
+ Thread th5 = new Thread(new Work(ns3, expected1));
+ Thread th6 = new Thread(new Work(ns4, expected2));
+ Thread th7 = new Thread(new Work(ns3, expected1));
+ Thread th8 = new Thread(new Work(ns4, expected2));
th1.start();
th2.start();
@@ -110,8 +111,8 @@
int count = 0;
while (runrun) {
char[] t = text.toCharArray();
+ count++;
try {
- count++;
ns.shape(t, 0, t.length);
} catch (Exception e) {
System.err.println("Error: Unexpected exception: " + e);
--- a/jdk/test/java/awt/font/NumericShaper/ShapingTest.java Thu May 13 13:22:22 2010 -0700
+++ b/jdk/test/java/awt/font/NumericShaper/ShapingTest.java Wed May 19 12:27:47 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2010 Sun Microsystems, Inc. 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
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 6842557
+ * @bug 6842557 6943963
* @summary confirm that shaping works as expected. (Mainly for new characters which were added in Unicode 5)
* used where appropriate.
*/
@@ -33,15 +33,25 @@
import static java.awt.font.NumericShaper.*;
public class ShapingTest {
+
+ private static boolean err = false;
+
public static void main(String[] args) {
+ test6842557();
+ test6943963();
+
+ if (err) {
+ throw new RuntimeException("shape() returned unexpected value.");
+ }
+ }
+
+ private static void test6842557() {
NumericShaper ns_old = getContextualShaper(ARABIC | TAMIL | ETHIOPIC,
EUROPEAN);
NumericShaper ns_new = getContextualShaper(EnumSet.of(
Range.ARABIC, Range.TAMIL, Range.ETHIOPIC),
Range.EUROPEAN);
- boolean err = false;
-
String[][] data = {
// Arabic "October 10"
{"\u0623\u0643\u062a\u0648\u0628\u0631 10",
@@ -60,45 +70,62 @@
};
for (int i = 0; i < data.length; i++) {
- String expected = data[i][1];
+ checkResult("ARABIC | TAMIL | ETHIOPIC",
+ ns_old, data[i][0], data[i][1]);
- char[] text = data[i][0].toCharArray();
- ns_old.shape(text, 0, text.length);
- String got = new String(text);
+ checkResult("Range.ARABIC, Range.TAMIL, Range.ETHIOPIC",
+ ns_new, data[i][0], data[i][1]);
+ }
+ }
- if (!expected.equals(got)) {
- err = true;
- System.err.println("Error with traditional range.");
- System.err.println(" text = " + data[i][0]);
- System.err.println(" got = " + got);
- System.err.println(" expected = " + expected);
- } else {
- System.err.println("OK with traditional range.");
- System.err.println(" text = " + data[i][0]);
- System.err.println(" got = " + got);
- System.err.println(" expected = " + expected);
- }
+ private static void test6943963() {
+ // Needed to reproduce this bug.
+ NumericShaper ns_dummy = getContextualShaper(ARABIC | TAMIL | ETHIOPIC,
+ EUROPEAN);
+ char[] c = "\u1200 1".toCharArray();
+ ns_dummy.shape(c, 0, c.length);
+
+
+ String given = "\u0627\u0628 456";
+ String expected_ARABIC = "\u0627\u0628 \u0664\u0665\u0666";
+ String expected_EASTERN_ARABIC = "\u0627\u0628 \u06f4\u06f5\u06f6";
+
+ NumericShaper ns = getContextualShaper(ARABIC);
+ checkResult("ARABIC", ns, given, expected_ARABIC);
+
+ ns = getContextualShaper(EnumSet.of(Range.ARABIC));
+ checkResult("Range.ARABIC", ns, given, expected_ARABIC);
- text = data[i][0].toCharArray();
- ns_new.shape(text, 0, text.length);
- got = new String(text);
+ ns = getContextualShaper(EASTERN_ARABIC);
+ checkResult("EASTERN_ARABIC", ns, given, expected_EASTERN_ARABIC);
+
+ ns = getContextualShaper(EnumSet.of(Range.EASTERN_ARABIC));
+ checkResult("Range.EASTERN_ARABIC", ns, given, expected_EASTERN_ARABIC);
+
+ ns = getContextualShaper(ARABIC | EASTERN_ARABIC);
+ checkResult("ARABIC | EASTERN_ARABIC", ns, given, expected_EASTERN_ARABIC);
+
+ ns = getContextualShaper(EnumSet.of(Range.ARABIC, Range.EASTERN_ARABIC));
+ checkResult("Range.ARABIC, Range.EASTERN_ARABIC", ns, given, expected_EASTERN_ARABIC);
+ }
- if (!expected.equals(got)) {
- err = true;
- System.err.println("Error with new Enum range.");
- System.err.println(" text = " + data[i][0]);
- System.err.println(" got = " + got);
- System.err.println(" expected = " + expected);
- } else {
- System.err.println("OK with new Enum range.");
- System.err.println(" text = " + data[i][0]);
- System.err.println(" got = " + got);
- System.err.println(" expected = " + expected);
- }
- }
+ private static void checkResult(String ranges, NumericShaper ns,
+ String given, String expected) {
+ char[] text = given.toCharArray();
+ ns.shape(text, 0, text.length);
+ String got = new String(text);
- if (err) {
- throw new RuntimeException("shape() returned unexpected value.");
+ if (!expected.equals(got)) {
+ err = true;
+ System.err.println("Error with range(s) <" + ranges + ">.");
+ System.err.println(" text = " + given);
+ System.err.println(" got = " + got);
+ System.err.println(" expected = " + expected);
+ } else {
+ System.out.println("OK with range(s) <" + ranges + ">.");
+ System.out.println(" text = " + given);
+ System.out.println(" got = " + got);
+ System.out.println(" expected = " + expected);
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/DatagramSocket/LocalSocketAddress.java Wed May 19 12:27:47 2010 -0700
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2010 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ * @bug 6718504
+ * @summary IN6_IS_ADDR_ANY tests only 12 bytes of 16-byte address
+ */
+
+import java.net.DatagramSocket;
+import java.net.InetAddress;
+import java.net.Inet6Address;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.util.*;
+
+public class LocalSocketAddress {
+ public static void main(String[] args) throws SocketException {
+ InetAddress IPv6LoopbackAddr = null;
+ DatagramSocket soc = null;
+
+ try {
+ List<NetworkInterface> nics = Collections.list(NetworkInterface.getNetworkInterfaces());
+ for (NetworkInterface nic : nics) {
+ if (!nic.isLoopback())
+ continue;
+
+ List<InetAddress> addrs = Collections.list(nic.getInetAddresses());
+ for (InetAddress addr : addrs) {
+ if (addr instanceof Inet6Address) {
+ IPv6LoopbackAddr = addr;
+ break;
+ }
+ }
+ }
+
+ if (IPv6LoopbackAddr == null) {
+ System.out.println("IPv6 is not available, exiting test.");
+ return;
+ }
+
+ soc = new DatagramSocket(0, IPv6LoopbackAddr);
+
+ if (!IPv6LoopbackAddr.equals(soc.getLocalAddress())) {
+ throw new RuntimeException("Bound address is " + soc.getLocalAddress() +
+ ", but should be " + IPv6LoopbackAddr);
+ }
+ } finally {
+ if (soc != null) { soc.close(); }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/PriorityQueue/NoNulls.java Wed May 19 12:27:47 2010 -0700
@@ -0,0 +1,204 @@
+/*
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * Written by Martin Buchholz with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+/*
+ * @test
+ * @bug 6950540
+ * @summary Attempt to add a null throws NullPointerException
+ */
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.PriorityQueue;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.LinkedBlockingDeque;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.PriorityBlockingQueue;
+
+public class NoNulls {
+ void test(String[] args) throws Throwable {
+ final Comparator<String> nullTolerantComparator
+ = new Comparator<>() {
+ public int compare(String x, String y) {
+ return (x == null ? -1 :
+ y == null ? 1 :
+ x.compareTo(y));
+ }};
+
+ final SortedSet<String> nullSortedSet
+ = new TreeSet<>(nullTolerantComparator);
+ nullSortedSet.add(null);
+
+ final PriorityQueue<String> nullPriorityQueue
+ = new PriorityQueue<>() {
+ public Object[] toArray() { return new Object[] { null };}};
+
+ final Collection<String> nullCollection = new ArrayList<>();
+ nullCollection.add(null);
+
+ THROWS(NullPointerException.class,
+ new F() { void f() {
+ new PriorityQueue<String>(nullCollection);
+ }},
+ new F() { void f() {
+ new PriorityBlockingQueue<String>(nullCollection);
+ }},
+ new F() { void f() {
+ new ArrayBlockingQueue<String>(10, false, nullCollection);
+ }},
+ new F() { void f() {
+ new ArrayBlockingQueue<String>(10, true, nullCollection);
+ }},
+ new F() { void f() {
+ new LinkedBlockingQueue<String>(nullCollection);
+ }},
+ new F() { void f() {
+ new LinkedBlockingDeque<String>(nullCollection);
+ }},
+
+ new F() { void f() {
+ new PriorityQueue<String>((Collection<String>) nullPriorityQueue);
+ }},
+ new F() { void f() {
+ new PriorityBlockingQueue<String>((Collection<String>) nullPriorityQueue);
+ }},
+
+ new F() { void f() {
+ new PriorityQueue<String>(nullSortedSet);
+ }},
+ new F() { void f() {
+ new PriorityBlockingQueue<String>(nullSortedSet);
+ }},
+
+ new F() { void f() {
+ new PriorityQueue<String>((Collection<String>) nullSortedSet);
+ }},
+ new F() { void f() {
+ new PriorityBlockingQueue<String>((Collection<String>) nullSortedSet);
+ }},
+
+ new F() { void f() {
+ new PriorityQueue<String>(nullPriorityQueue);
+ }},
+ new F() { void f() {
+ new PriorityBlockingQueue<String>(nullPriorityQueue);
+ }},
+
+ new F() { void f() {
+ new PriorityQueue<String>().add(null);
+ }},
+ new F() { void f() {
+ new PriorityBlockingQueue<String>().add(null);
+ }},
+ new F() { void f() {
+ new ArrayBlockingQueue<String>(10, false).add(null);
+ }},
+ new F() { void f() {
+ new ArrayBlockingQueue<String>(10, true).add(null);
+ }},
+ new F() { void f() {
+ new LinkedBlockingQueue<String>().add(null);
+ }},
+ new F() { void f() {
+ new LinkedBlockingDeque<String>().add(null);
+ }},
+
+ new F() { void f() {
+ new PriorityQueue<String>().offer(null);
+ }},
+ new F() { void f() {
+ new PriorityBlockingQueue<String>().offer(null);
+ }});
+
+ nullSortedSet.add("foo");
+ nullCollection.add("foo");
+ THROWS(NullPointerException.class,
+ new F() { void f() {
+ new PriorityQueue<String>(nullCollection);
+ }},
+ new F() { void f() {
+ new PriorityBlockingQueue<String>(nullCollection);
+ }},
+
+ new F() { void f() {
+ new PriorityQueue<String>((Collection<String>) nullPriorityQueue);
+ }},
+ new F() { void f() {
+ new PriorityBlockingQueue<String>((Collection<String>) nullPriorityQueue);
+ }},
+
+ new F() { void f() {
+ new PriorityQueue<String>(nullSortedSet);
+ }},
+ new F() { void f() {
+ new PriorityBlockingQueue<String>(nullSortedSet);
+ }},
+
+ new F() { void f() {
+ new PriorityQueue<String>((Collection<String>) nullSortedSet);
+ }},
+ new F() { void f() {
+ new PriorityBlockingQueue<String>((Collection<String>) nullSortedSet);
+ }});
+
+ }
+
+ //--------------------- Infrastructure ---------------------------
+ volatile int passed = 0, failed = 0;
+ void pass() {passed++;}
+ void fail() {failed++; Thread.dumpStack();}
+ void fail(String msg) {System.err.println(msg); fail();}
+ void unexpected(Throwable t) {failed++; t.printStackTrace();}
+ void check(boolean cond) {if (cond) pass(); else fail();}
+ void equal(Object x, Object y) {
+ if (x == null ? y == null : x.equals(y)) pass();
+ else fail(x + " not equal to " + y);}
+ public static void main(String[] args) throws Throwable {
+ new NoNulls().instanceMain(args);}
+ public void instanceMain(String[] args) throws Throwable {
+ try {test(args);} catch (Throwable t) {unexpected(t);}
+ System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
+ if (failed > 0) throw new AssertionError("Some tests failed");}
+ abstract class F {abstract void f() throws Throwable;}
+ void THROWS(Class<? extends Throwable> k, F... fs) {
+ for (F f : fs)
+ try {f.f(); fail("Expected " + k.getName() + " not thrown");}
+ catch (Throwable t) {
+ if (k.isAssignableFrom(t.getClass())) pass();
+ else unexpected(t);}}
+}
--- a/jdk/test/java/util/Random/DistinctSeeds.java Thu May 13 13:22:22 2010 -0700
+++ b/jdk/test/java/util/Random/DistinctSeeds.java Wed May 19 12:27:47 2010 -0700
@@ -33,18 +33,54 @@
/*
* @test
- * @bug 4949279
+ * @bug 4949279 6937857
* @summary Independent instantiations of Random() have distinct seeds.
*/
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
import java.util.Random;
public class DistinctSeeds {
public static void main(String[] args) throws Exception {
// Strictly speaking, it is possible for these to randomly fail,
- // but the probability should be *extremely* small (< 2**-63).
+ // but the probability should be small (approximately 2**-48).
if (new Random().nextLong() == new Random().nextLong() ||
new Random().nextLong() == new Random().nextLong())
throw new RuntimeException("Random() seeds not unique.");
+
+ // Now try generating seeds concurrently
+ class RandomCollector implements Runnable {
+ long[] randoms = new long[1<<17];
+ public void run() {
+ for (int i = 0; i < randoms.length; i++)
+ randoms[i] = new Random().nextLong();
+ }
+ }
+ final int threadCount = 2;
+ List<RandomCollector> collectors = new ArrayList<RandomCollector>();
+ List<Thread> threads = new ArrayList<Thread>();
+ for (int i = 0; i < threadCount; i++) {
+ RandomCollector r = new RandomCollector();
+ collectors.add(r);
+ threads.add(new Thread(r));
+ }
+ for (Thread thread : threads)
+ thread.start();
+ for (Thread thread : threads)
+ thread.join();
+ int collisions = 0;
+ HashSet<Long> s = new HashSet<Long>();
+ for (RandomCollector r : collectors) {
+ for (long x : r.randoms) {
+ if (s.contains(x))
+ collisions++;
+ s.add(x);
+ }
+ }
+ System.out.printf("collisions=%d%n", collisions);
+ if (collisions > 10)
+ throw new Error("too many collisions");
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JFileChooser/6945316/bug6945316.java Wed May 19 12:27:47 2010 -0700
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2010 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ @bug 6945316
+ @summary The Win32ShellFolderManager2.isFileSystemRoot can throw NPE
+ @author Pavel Porvatov
+ @run main bug6945316
+*/
+
+import sun.awt.OSInfo;
+import sun.awt.shell.ShellFolder;
+
+import java.awt.*;
+import java.io.File;
+import java.util.concurrent.CountDownLatch;
+
+public class bug6945316 {
+ public static void main(String[] args) throws Exception {
+ if (OSInfo.getOSType() != OSInfo.OSType.WINDOWS) {
+ System.out.println("The test is suitable only for Windows OS. Skipped.");
+
+ return;
+ }
+
+ // Init toolkit because it shouldn't be interrupted while initialization
+ Toolkit.getDefaultToolkit();
+
+ // Init the sun.awt.shell.Win32ShellFolderManager2.drives field
+ ShellFolder.get("fileChooserComboBoxFolders");
+
+ // To get NPE the path must obey the following rules:
+ // path.length() == 3 && path.charAt(1) == ':'
+ final File tempFile = new File("c:\\");
+
+ for (int i = 0; i < 10000; i++) {
+ final CountDownLatch countDownLatch = new CountDownLatch(1);
+
+ final Thread thread = new Thread() {
+ public void run() {
+ countDownLatch.countDown();
+
+ ShellFolder.isFileSystemRoot(tempFile);
+ }
+ };
+
+ thread.start();
+
+ countDownLatch.await();
+
+ thread.interrupt();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/SwingWorker/6880336/NestedWorkers.java Wed May 19 12:27:47 2010 -0700
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2010 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ * @bug 6880336
+ * @summary Test for nested SwingWorkers, i.e. when the second worker is
+started from the first's doInBackground() method. A timeout when running
+* this test is an indication of failure.
+ * @author Artem Ananiev
+ * @run main/timeout=32 NestedWorkers
+ */
+
+import javax.swing.*;
+
+public class NestedWorkers extends SwingWorker<String, Void> {
+
+ private final static int MAX_LEVEL = 2;
+
+ private int level;
+
+ public NestedWorkers(int level) {
+ super();
+ this.level = level;
+ }
+
+ @Override
+ public String doInBackground() throws Exception {
+ if (level < MAX_LEVEL) {
+ SwingWorker<String, Void> nested = new NestedWorkers(level + 1);
+ nested.execute();
+ nested.get();
+ }
+ System.out.println("doInBackground " + level + " is complete");
+ return String.valueOf(level);
+ }
+
+ public static void main(String[] args) throws Exception {
+ SwingUtilities.invokeAndWait(new Runnable() {
+ @Override
+ public void run() {
+ SwingWorker<String, Void> sw = new NestedWorkers(0);
+ sw.execute();
+ try {
+ System.err.println(sw.get());
+ } catch (Exception z) {
+ throw new RuntimeException(z);
+ }
+ }
+ });
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/plaf/nimbus/Test6919629.java Wed May 19 12:27:47 2010 -0700
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ @bug 6919629
+ @summary Tests that components with Nimbus.Overrides are GC'ed properly
+ @author Peter Zhelezniakov
+ @run main Test6919629
+*/
+
+import java.awt.Color;
+import java.lang.ref.WeakReference;
+import javax.swing.*;
+import javax.swing.plaf.nimbus.NimbusLookAndFeel;
+
+public class Test6919629
+{
+ JFrame f;
+ WeakReference<JLabel> ref;
+
+ public static void main(String[] args) throws Exception {
+ UIManager.setLookAndFeel(new NimbusLookAndFeel());
+ Test6919629 t = new Test6919629();
+ t.test();
+ System.gc();
+ t.check();
+ }
+
+ void test() throws Exception {
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ UIDefaults d = new UIDefaults();
+ d.put("Label.textForeground", Color.MAGENTA);
+
+ JLabel l = new JLabel();
+ ref = new WeakReference<JLabel>(l);
+ l.putClientProperty("Nimbus.Overrides", d);
+
+ f = new JFrame();
+ f.getContentPane().add(l);
+ f.pack();
+ f.setVisible(true);
+ }
+ });
+ Thread.sleep(2000);
+
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ f.getContentPane().removeAll();
+ f.setVisible(false);
+ f.dispose();
+ }
+ });
+ Thread.sleep(2000);
+ }
+
+ void check() {
+ if (ref.get() != null) {
+ throw new RuntimeException("Failed: an unused component wasn't collected");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/net/www/protocol/http/BasicLongCredentials.java Wed May 19 12:27:47 2010 -0700
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2010 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * @test
+ * @bug 6947917
+ * @summary Error in basic authentication when user name and password are long
+ */
+
+import com.sun.net.httpserver.BasicAuthenticator;
+import com.sun.net.httpserver.HttpContext;
+import com.sun.net.httpserver.HttpExchange;
+import com.sun.net.httpserver.HttpHandler;
+import com.sun.net.httpserver.HttpPrincipal;
+import com.sun.net.httpserver.HttpServer;
+import java.io.InputStream;
+import java.io.IOException;
+import java.net.Authenticator;
+import java.net.InetSocketAddress;
+import java.net.PasswordAuthentication;
+import java.net.HttpURLConnection;
+import java.net.URL;
+
+public class BasicLongCredentials {
+
+ static final String USERNAME = "ThisIsMyReallyReallyReallyReallyReallyReally" +
+ "LongFirstNameDotLastNameAtCompanyEmailAddress";
+ static final String PASSWORD = "AndThisIsALongLongLongLongLongLongLongLongLong" +
+ "LongLongLongLongLongLongLongLongLongPassword";
+ static final String REALM = "foobar@test.realm";
+
+ public static void main (String[] args) throws Exception {
+ HttpServer server = HttpServer.create(new InetSocketAddress(0), 0);
+ try {
+ Handler handler = new Handler();
+ HttpContext ctx = server.createContext("/test", handler);
+
+ BasicAuthenticator a = new BasicAuthenticator(REALM) {
+ public boolean checkCredentials (String username, String pw) {
+ return USERNAME.equals(username) && PASSWORD.equals(pw);
+ }
+ };
+ ctx.setAuthenticator(a);
+ server.start();
+
+ Authenticator.setDefault(new MyAuthenticator());
+
+ URL url = new URL("http://localhost:"+server.getAddress().getPort()+"/test/");
+ HttpURLConnection urlc = (HttpURLConnection)url.openConnection();
+ InputStream is = urlc.getInputStream();
+ int c = 0;
+ while (is.read()!= -1) { c ++; }
+
+ if (c != 0) { throw new RuntimeException("Test failed c = " + c); }
+ if (error) { throw new RuntimeException("Test failed: error"); }
+
+ System.out.println ("OK");
+ } finally {
+ server.stop(0);
+ }
+ }
+
+ public static boolean error = false;
+
+ static class MyAuthenticator extends java.net.Authenticator {
+ @Override
+ public PasswordAuthentication getPasswordAuthentication () {
+ if (!getRequestingPrompt().equals(REALM)) {
+ BasicLongCredentials.error = true;
+ }
+ return new PasswordAuthentication (USERNAME, PASSWORD.toCharArray());
+ }
+ }
+
+ static class Handler implements HttpHandler {
+ public void handle (HttpExchange t) throws IOException {
+ InputStream is = t.getRequestBody();
+ while (is.read () != -1) ;
+ is.close();
+ t.sendResponseHeaders(200, -1);
+ HttpPrincipal p = t.getPrincipal();
+ if (!p.getUsername().equals(USERNAME)) {
+ error = true;
+ }
+ if (!p.getRealm().equals(REALM)) {
+ error = true;
+ }
+ t.close();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/krb5/ServiceNameClone.java Wed May 19 12:27:47 2010 -0700
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2010 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+/*
+ * @test
+ * @bug 6856069
+ * @summary PrincipalName.clone() does not invoke super.clone()
+ */
+
+import sun.security.krb5.ServiceName;
+
+public class ServiceNameClone {
+ public static void main(String[] args) throws Exception {
+ ServiceName sn = new ServiceName("me@HERE");
+ if (sn.clone().getClass() != ServiceName.class) {
+ throw new Exception("ServiceName's clone is not a ServiceName");
+ }
+ if (!sn.clone().equals(sn)) {
+ throw new Exception("ServiceName's clone changed");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/krb5/auto/MaxRetries.java Wed May 19 12:27:47 2010 -0700
@@ -0,0 +1,203 @@
+/*
+ * Copyright 2010 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6844193
+ * @run main/timeout=300 MaxRetries
+ * @summary support max_retries in krb5.conf
+ */
+
+import java.io.*;
+import java.security.Security;
+
+public class MaxRetries {
+ public static void main(String[] args)
+ throws Exception {
+
+ System.setProperty("sun.security.krb5.debug", "true");
+ new OneKDC(null).writeJAASConf();
+ System.setProperty("java.security.krb5.conf", "alternative-krb5.conf");
+
+ // For tryLast
+ Security.setProperty("krb5.kdc.bad.policy", "trylast");
+ rewriteMaxRetries(4);
+ test1(4000, 6); // 1 1 1 1 2 2
+ test1(4000, 2); // 2 2
+
+ rewriteMaxRetries(1);
+ test1(1000, 3); // 1 2 2
+ test1(1000, 2); // 2 2
+
+ rewriteMaxRetries(-1);
+ test1(5000, 4); // 1 1 2 2
+ test1(5000, 2); // 2 2
+
+ // For tryLess
+ Security.setProperty("krb5.kdc.bad.policy", "tryless");
+ rewriteMaxRetries(4);
+ test1(4000, 7); // 1 1 1 1 2 1 2
+ test1(4000, 4); // 1 2 1 2
+
+ rewriteMaxRetries(1);
+ test1(1000, 4); // 1 2 1 2
+ test1(1000, 4); // 1 2 1 2
+
+ rewriteMaxRetries(-1);
+ test1(5000, 5); // 1 1 2 1 2
+ test1(5000, 4); // 1 2 1 2
+
+ rewriteUdpPrefLimit(-1, -1); // default, no limit
+ test2("UDP");
+
+ rewriteUdpPrefLimit(10, -1); // global rules
+ test2("TCP");
+
+ rewriteUdpPrefLimit(10, 10000); // realm rules
+ test2("UDP");
+
+ rewriteUdpPrefLimit(10000, 10); // realm rules
+ test2("TCP");
+ }
+
+ /**
+ * One round of test for max_retries and timeout.
+ * @param timeout the expected timeout
+ * @param count the expected total try
+ */
+ private static void test1(int timeout, int count) throws Exception {
+ String timeoutTag = "timeout=" + timeout;
+ ByteArrayOutputStream bo = new ByteArrayOutputStream();
+ PrintStream oldout = System.out;
+ System.setOut(new PrintStream(bo));
+ Context c = Context.fromJAAS("client");
+ System.setOut(oldout);
+
+ String[] lines = new String(bo.toByteArray()).split("\n");
+ System.out.println("----------------- TEST (" + timeout + "," +
+ count + ") -----------------");
+ for (String line: lines) {
+ if (line.startsWith(">>> KDCCommunication")) {
+ System.out.println(line);
+ if (line.indexOf(timeoutTag) < 0) {
+ throw new Exception("Wrong timeout value");
+ }
+ count--;
+ }
+ }
+ if (count != 0) {
+ throw new Exception("Retry count is " + count + " less");
+ }
+ }
+
+ /**
+ * One round of test for udp_preference_limit.
+ * @param proto the expected protocol used
+ */
+ private static void test2(String proto) throws Exception {
+ ByteArrayOutputStream bo = new ByteArrayOutputStream();
+ PrintStream oldout = System.out;
+ System.setOut(new PrintStream(bo));
+ Context c = Context.fromJAAS("client");
+ System.setOut(oldout);
+
+ int count = 2;
+ String[] lines = new String(bo.toByteArray()).split("\n");
+ System.out.println("----------------- TEST -----------------");
+ for (String line: lines) {
+ if (line.startsWith(">>> KDCCommunication")) {
+ System.out.println(line);
+ count--;
+ if (line.indexOf(proto) < 0) {
+ throw new Exception("Wrong timeout value");
+ }
+ }
+ }
+ if (count != 0) {
+ throw new Exception("Retry count is " + count + " less");
+ }
+ }
+
+ /**
+ * Set udp_preference_limit for global and realm
+ */
+ private static void rewriteUdpPrefLimit(int global, int realm)
+ throws Exception {
+ BufferedReader fr = new BufferedReader(new FileReader(OneKDC.KRB5_CONF));
+ FileWriter fw = new FileWriter("alternative-krb5.conf");
+ while (true) {
+ String s = fr.readLine();
+ if (s == null) {
+ break;
+ }
+ if (s.startsWith("[realms]")) {
+ // Reconfig global setting
+ if (global != -1) {
+ fw.write("udp_preference_limit = " + global + "\n");
+ }
+ } else if (s.trim().startsWith("kdc = ")) {
+ if (realm != -1) {
+ // Reconfig for realm
+ fw.write(" udp_preference_limit = " + realm + "\n");
+ }
+ }
+ fw.write(s + "\n");
+ }
+ fr.close();
+ fw.close();
+ sun.security.krb5.Config.refresh();
+ }
+
+ /**
+ * Set max_retries and timeout value for realm. The global value is always
+ * 2 and 5000.
+ * @param value max_retries and timeout/1000 for a realm, -1 means none.
+ */
+ private static void rewriteMaxRetries(int value) throws Exception {
+ BufferedReader fr = new BufferedReader(new FileReader(OneKDC.KRB5_CONF));
+ FileWriter fw = new FileWriter("alternative-krb5.conf");
+ while (true) {
+ String s = fr.readLine();
+ if (s == null) {
+ break;
+ }
+ if (s.startsWith("[realms]")) {
+ // Reconfig global setting
+ fw.write("max_retries = 2\n");
+ fw.write("kdc_timeout = 5000\n");
+ } else if (s.trim().startsWith("kdc = ")) {
+ if (value != -1) {
+ // Reconfig for realm
+ fw.write(" max_retries = " + value + "\n");
+ fw.write(" kdc_timeout = " + (value*1000) + "\n");
+ }
+ // Add a bad KDC as the first candidate
+ fw.write(" kdc = localhost:33333\n");
+ }
+ fw.write(s + "\n");
+ }
+ fr.close();
+ fw.close();
+ sun.security.krb5.Config.refresh();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/tools/jarsigner/crl.sh Wed May 19 12:27:47 2010 -0700
@@ -0,0 +1,91 @@
+#
+# Copyright 2010 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+
+# @test
+# @bug 6890876
+# @summary jarsigner can add CRL info into signed jar
+#
+
+if [ "${TESTJAVA}" = "" ] ; then
+ JAVAC_CMD=`which javac`
+ TESTJAVA=`dirname $JAVAC_CMD`/..
+fi
+
+# set platform-dependent variables
+# PF: platform name, say, solaris-sparc
+
+PF=""
+
+OS=`uname -s`
+case "$OS" in
+ Windows* )
+ FS="\\"
+ ;;
+ * )
+ FS="/"
+ ;;
+esac
+
+KS=crl.jks
+JFILE=crl.jar
+
+KT="$TESTJAVA${FS}bin${FS}keytool -storepass changeit -keypass changeit -keystore $KS"
+JAR=$TESTJAVA${FS}bin${FS}jar
+JARSIGNER=$TESTJAVA${FS}bin${FS}jarsigner
+
+rm $KS $JFILE
+
+# Generates some crl files, each containing two entries
+
+$KT -alias a -dname CN=a -keyalg rsa -genkey -validity 300
+$KT -alias a -gencrl -id 1:1 -id 2:2 -file crl1
+$KT -alias a -gencrl -id 3:3 -id 4:4 -file crl2
+$KT -alias b -dname CN=b -keyalg rsa -genkey -validity 300
+$KT -alias b -gencrl -id 5:1 -id 6:2 -file crl3
+
+$KT -alias c -dname CN=c -keyalg rsa -genkey -validity 300 \
+ -ext crl=uri:file://`pwd`/crl1
+
+echo A > A
+
+# Test -crl:auto, cRLDistributionPoints is a local file
+
+$JAR cvf $JFILE A
+$JARSIGNER -keystore $KS -storepass changeit $JFILE c \
+ -crl:auto || exit 1
+$JARSIGNER -keystore $KS -verify -debug -strict $JFILE || exit 6
+$KT -printcert -jarfile $JFILE | grep CRLs || exit 7
+
+# Test -crl <file>
+
+$JAR cvf $JFILE A
+$JARSIGNER -keystore $KS -storepass changeit $JFILE a \
+ -crl crl1 -crl crl2 || exit 1
+$JARSIGNER -keystore $KS -storepass changeit $JFILE b \
+ -crl crl3 -crl crl2 || exit 1
+$JARSIGNER -keystore $KS -verify -debug -strict $JFILE || exit 3
+$KT -printcert -jarfile $JFILE | grep CRLs || exit 4
+CRLCOUNT=`$KT -printcert -jarfile $JFILE | grep SerialNumber | wc -l`
+if [ $CRLCOUNT != 8 ]; then exit 5; fi
+
+exit 0
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/tools/jarsigner/diffend.sh Wed May 19 12:27:47 2010 -0700
@@ -0,0 +1,113 @@
+#
+# Copyright 2010 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+
+# @test
+# @bug 6948909
+# @summary Jarsigner removes MANIFEST.MF info for badly packages jar's
+#
+
+if [ "${TESTSRC}" = "" ] ; then
+ TESTSRC="."
+fi
+if [ "${TESTCLASSES}" = "" ] ; then
+ TESTCLASSES="."
+fi
+if [ "${TESTJAVA}" = "" ] ; then
+ echo "TESTJAVA not set. Test cannot execute."
+ echo "FAILED!!!"
+ exit 1
+fi
+
+# set platform-dependent variables
+OS=`uname -s`
+case "$OS" in
+ SunOS | Linux )
+ NULL=/dev/null
+ PS=":"
+ FS="/"
+ CP="${FS}bin${FS}cp -f"
+ TMP=/tmp
+ ;;
+ CYGWIN* )
+ NULL=/dev/null
+ PS=";"
+ FS="/"
+ CP="cp -f"
+ TMP=/tmp
+ ;;
+ Windows_* )
+ NULL=NUL
+ PS=";"
+ FS="\\"
+ CP="cp -f"
+ TMP="c:/temp"
+ ;;
+ * )
+ echo "Unrecognized operating system!"
+ exit 1;
+ ;;
+esac
+
+echo 1 > 1
+mkdir META-INF
+
+# Create a fake .RSA file so that jarsigner believes it's signed
+
+touch META-INF/x.RSA
+
+# A MANIFEST.MF using \n as newlines and no double newlines at the end
+
+cat > META-INF/MANIFEST.MF <<EOF
+Manifest-Version: 1.0
+Created-By: 1.7.0-internal (Sun Microsystems Inc.)
+Today: Monday
+EOF
+
+# With the fake .RSA file, to trigger the if (wasSigned) block
+
+rm diffend.jar
+zip diffend.jar META-INF/MANIFEST.MF META-INF/x.RSA 1
+
+${TESTJAVA}${FS}bin${FS}jarsigner \
+ -keystore ${TESTSRC}${FS}JarSigning.keystore \
+ -storepass bbbbbb \
+ -digestalg SHA1 \
+ -signedjar diffend.new.jar \
+ diffend.jar c
+
+unzip -p diffend.new.jar META-INF/MANIFEST.MF | grep Today || exit 1
+
+# Without the fake .RSA file, to trigger the else block
+
+rm diffend.jar
+zip diffend.jar META-INF/MANIFEST.MF 1
+
+${TESTJAVA}${FS}bin${FS}jarsigner \
+ -keystore ${TESTSRC}${FS}JarSigning.keystore \
+ -storepass bbbbbb \
+ -digestalg SHA1 \
+ -signedjar diffend.new.jar \
+ diffend.jar c
+
+unzip -p diffend.new.jar META-INF/MANIFEST.MF | grep Today || exit 2
+