This commit is contained in:
Lana Steuck 2010-05-19 12:27:47 -07:00
commit 26f273e24d
76 changed files with 3323 additions and 649 deletions

View File

@ -79,4 +79,5 @@ FILES_c = \
gtk2_interface.c \ gtk2_interface.c \
swing_GTKEngine.c \ swing_GTKEngine.c \
swing_GTKStyle.c \ swing_GTKStyle.c \
rect.c rect.c \
sun_awt_X11_GtkFileDialogPeer.c

View File

@ -33,4 +33,5 @@ FILES_export = \
sun/awt/X11/XDesktopPeer.java \ sun/awt/X11/XDesktopPeer.java \
sun/awt/X11/XToolkit.java \ sun/awt/X11/XToolkit.java \
sun/awt/X11/XComponentPeer.java \ sun/awt/X11/XComponentPeer.java \
sun/awt/X11/XInputMethod.java sun/awt/X11/XInputMethod.java \
sun/awt/X11/GtkFileDialogPeer.java

View File

@ -172,6 +172,7 @@ SUNWprivate_1.1 {
Java_sun_awt_UNIXToolkit_load_1stock_1icon; Java_sun_awt_UNIXToolkit_load_1stock_1icon;
Java_sun_awt_UNIXToolkit_load_1gtk_1icon; Java_sun_awt_UNIXToolkit_load_1gtk_1icon;
Java_sun_awt_UNIXToolkit_nativeSync; Java_sun_awt_UNIXToolkit_nativeSync;
Java_sun_awt_UNIXToolkit_gtkCheckVersionImpl;
Java_java_awt_AWTEvent_initIDs; Java_java_awt_AWTEvent_initIDs;
Java_java_awt_event_InputEvent_initIDs; Java_java_awt_event_InputEvent_initIDs;
Java_java_awt_event_KeyEvent_initIDs; Java_java_awt_event_KeyEvent_initIDs;
@ -396,6 +397,9 @@ SUNWprivate_1.1 {
Java_com_sun_java_swing_plaf_gtk_GTKStyle_nativeGetClassValue; Java_com_sun_java_swing_plaf_gtk_GTKStyle_nativeGetClassValue;
Java_com_sun_java_swing_plaf_gtk_GTKStyle_nativeGetPangoFontName; 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_initIDs;
Java_sun_print_CUPSPrinter_getCupsServer; Java_sun_print_CUPSPrinter_getCupsServer;
Java_sun_print_CUPSPrinter_getCupsPort; Java_sun_print_CUPSPrinter_getCupsPort;

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -26,7 +26,9 @@
package com.sun.jarsigner; package com.sun.jarsigner;
import java.net.URI; import java.net.URI;
import java.security.cert.X509CRL;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import java.util.Set;
import java.util.zip.ZipFile; import java.util.zip.ZipFile;
/** /**
@ -80,6 +82,13 @@ public interface ContentSignerParameters {
*/ */
public X509Certificate[] getSignerCertificateChain(); 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. * Retrieves the content that was signed.
* The content is the JAR file's signature file. * The content is the JAR file's signature file.

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -717,7 +717,7 @@ public class Krb5LoginModule implements LoginModule {
for (int i = 0; i < encKeys.length; i++) { for (int i = 0; i < encKeys.length; i++) {
System.out.println("EncryptionKey: keyType=" + System.out.println("EncryptionKey: keyType=" +
encKeys[i].getEType() + " keyBytes (hex dump)=" + encKeys[i].getEType() + " keyBytes (hex dump)=" +
hd.encode(encKeys[i].getBytes())); hd.encodeBuffer(encKeys[i].getBytes()));
} }
} }

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -63,6 +63,6 @@ final public class AuthorizationDataEntry {
public String toString() { public String toString() {
return "AuthorizationDataEntry: type="+type+", data=" + return "AuthorizationDataEntry: type="+type+", data=" +
data.length + " bytes:\n" + data.length + " bytes:\n" +
new sun.misc.HexDumpEncoder().encode(data); new sun.misc.HexDumpEncoder().encodeBuffer(data);
} }
} }

View File

@ -1163,8 +1163,14 @@ public final class NumericShaper implements java.io.Serializable {
lastkey = newkey; lastkey = newkey;
ctxKey = 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; 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) { } else if ((mask & (1<<ctxKey)) == 0) {
ctxKey = EUROPEAN_KEY; ctxKey = EUROPEAN_KEY;
} }

View File

@ -77,18 +77,51 @@ public class ByteArrayOutputStream extends OutputStream {
buf = new byte[size]; buf = new byte[size];
} }
/**
* 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. * Writes the specified byte to this byte array output stream.
* *
* @param b the byte to be written. * @param b the byte to be written.
*/ */
public synchronized void write(int b) { public synchronized void write(int b) {
int newcount = count + 1; ensureCapacity(count + 1);
if (newcount > buf.length) { buf[count] = (byte) b;
buf = Arrays.copyOf(buf, Math.max(buf.length << 1, newcount)); count += 1;
}
buf[count] = (byte)b;
count = newcount;
} }
/** /**
@ -101,17 +134,12 @@ public class ByteArrayOutputStream extends OutputStream {
*/ */
public synchronized void write(byte b[], int off, int len) { public synchronized void write(byte b[], int off, int len) {
if ((off < 0) || (off > b.length) || (len < 0) || if ((off < 0) || (off > b.length) || (len < 0) ||
((off + len) > b.length) || ((off + len) < 0)) { ((off + len) - b.length > 0)) {
throw new IndexOutOfBoundsException(); 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); System.arraycopy(b, off, buf, count, len);
count = newcount; count += len;
} }
/** /**

View File

@ -36,6 +36,8 @@ import java.util.Arrays;
* sequence can be changed through certain method calls. * sequence can be changed through certain method calls.
* *
* @author Michael McCloskey * @author Michael McCloskey
* @author Martin Buchholz
* @author Ulf Zibis
* @since 1.5 * @since 1.5
*/ */
abstract class AbstractStringBuilder implements Appendable, CharSequence { abstract class AbstractStringBuilder implements Appendable, CharSequence {
@ -98,9 +100,16 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
* @param minimumCapacity the minimum desired capacity. * @param minimumCapacity the minimum desired capacity.
*/ */
public void ensureCapacity(int minimumCapacity) { 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); expandCapacity(minimumCapacity);
}
} }
/** /**
@ -108,11 +117,13 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
* size check or synchronization. * size check or synchronization.
*/ */
void expandCapacity(int minimumCapacity) { void expandCapacity(int minimumCapacity) {
int newCapacity = (value.length + 1) * 2; int newCapacity = value.length * 2;
if (newCapacity < 0) { if (newCapacity - minimumCapacity < 0)
newCapacity = Integer.MAX_VALUE;
} else if (minimumCapacity > newCapacity) {
newCapacity = minimumCapacity; newCapacity = minimumCapacity;
if (newCapacity < 0) {
if (minimumCapacity < 0) // overflow
throw new OutOfMemoryError();
newCapacity = Integer.MAX_VALUE;
} }
value = Arrays.copyOf(value, newCapacity); value = Arrays.copyOf(value, newCapacity);
} }
@ -158,8 +169,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
public void setLength(int newLength) { public void setLength(int newLength) {
if (newLength < 0) if (newLength < 0)
throw new StringIndexOutOfBoundsException(newLength); throw new StringIndexOutOfBoundsException(newLength);
if (newLength > value.length) ensureCapacityInternal(newLength);
expandCapacity(newLength);
if (count < newLength) { if (count < newLength) {
for (; count < newLength; count++) for (; count < newLength; count++)
@ -400,12 +410,9 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
public AbstractStringBuilder append(String str) { public AbstractStringBuilder append(String str) {
if (str == null) str = "null"; if (str == null) str = "null";
int len = str.length(); int len = str.length();
if (len == 0) return this; ensureCapacityInternal(count + len);
int newCount = count + len;
if (newCount > value.length)
expandCapacity(newCount);
str.getChars(0, len, value, count); str.getChars(0, len, value, count);
count = newCount; count += len;
return this; return this;
} }
@ -414,11 +421,9 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
if (sb == null) if (sb == null)
return append("null"); return append("null");
int len = sb.length(); int len = sb.length();
int newCount = count + len; ensureCapacityInternal(count + len);
if (newCount > value.length)
expandCapacity(newCount);
sb.getChars(0, len, value, count); sb.getChars(0, len, value, count);
count = newCount; count += len;
return this; return this;
} }
@ -470,14 +475,10 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
"start " + start + ", end " + end + ", s.length() " "start " + start + ", end " + end + ", s.length() "
+ s.length()); + s.length());
int len = end - start; int len = end - start;
if (len == 0) ensureCapacityInternal(count + len);
return this; for (int i = start, j = count; i < end; i++, j++)
int newCount = count + len; value[j] = s.charAt(i);
if (newCount > value.length) count += len;
expandCapacity(newCount);
for (int i=start; i<end; i++)
value[count++] = s.charAt(i);
count = newCount;
return this; return this;
} }
@ -498,11 +499,10 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
* @return a reference to this object. * @return a reference to this object.
*/ */
public AbstractStringBuilder append(char[] str) { public AbstractStringBuilder append(char[] str) {
int newCount = count + str.length; int len = str.length;
if (newCount > value.length) ensureCapacityInternal(count + len);
expandCapacity(newCount); System.arraycopy(str, 0, value, count, len);
System.arraycopy(str, 0, value, count, str.length); count += len;
count = newCount;
return this; return this;
} }
@ -529,11 +529,9 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
* or {@code offset+len > str.length} * or {@code offset+len > str.length}
*/ */
public AbstractStringBuilder append(char str[], int offset, int len) { public AbstractStringBuilder append(char str[], int offset, int len) {
int newCount = count + len; ensureCapacityInternal(count + len);
if (newCount > value.length)
expandCapacity(newCount);
System.arraycopy(str, offset, value, count, len); System.arraycopy(str, offset, value, count, len);
count = newCount; count += len;
return this; return this;
} }
@ -551,17 +549,13 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
*/ */
public AbstractStringBuilder append(boolean b) { public AbstractStringBuilder append(boolean b) {
if (b) { if (b) {
int newCount = count + 4; ensureCapacityInternal(count + 4);
if (newCount > value.length)
expandCapacity(newCount);
value[count++] = 't'; value[count++] = 't';
value[count++] = 'r'; value[count++] = 'r';
value[count++] = 'u'; value[count++] = 'u';
value[count++] = 'e'; value[count++] = 'e';
} else { } else {
int newCount = count + 5; ensureCapacityInternal(count + 5);
if (newCount > value.length)
expandCapacity(newCount);
value[count++] = 'f'; value[count++] = 'f';
value[count++] = 'a'; value[count++] = 'a';
value[count++] = 'l'; value[count++] = 'l';
@ -587,9 +581,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
* @return a reference to this object. * @return a reference to this object.
*/ */
public AbstractStringBuilder append(char c) { public AbstractStringBuilder append(char c) {
int newCount = count + 1; ensureCapacityInternal(count + 1);
if (newCount > value.length)
expandCapacity(newCount);
value[count++] = c; value[count++] = c;
return this; return this;
} }
@ -614,8 +606,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
int appendedLength = (i < 0) ? Integer.stringSize(-i) + 1 int appendedLength = (i < 0) ? Integer.stringSize(-i) + 1
: Integer.stringSize(i); : Integer.stringSize(i);
int spaceNeeded = count + appendedLength; int spaceNeeded = count + appendedLength;
if (spaceNeeded > value.length) ensureCapacityInternal(spaceNeeded);
expandCapacity(spaceNeeded);
Integer.getChars(i, spaceNeeded, value); Integer.getChars(i, spaceNeeded, value);
count = spaceNeeded; count = spaceNeeded;
return this; return this;
@ -641,8 +632,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
int appendedLength = (l < 0) ? Long.stringSize(-l) + 1 int appendedLength = (l < 0) ? Long.stringSize(-l) + 1
: Long.stringSize(l); : Long.stringSize(l);
int spaceNeeded = count + appendedLength; int spaceNeeded = count + appendedLength;
if (spaceNeeded > value.length) ensureCapacityInternal(spaceNeeded);
expandCapacity(spaceNeeded);
Long.getChars(l, spaceNeeded, value); Long.getChars(l, spaceNeeded, value);
count = spaceNeeded; count = spaceNeeded;
return this; return this;
@ -738,10 +728,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
if (codePoint >= Character.MIN_SUPPLEMENTARY_CODE_POINT) { if (codePoint >= Character.MIN_SUPPLEMENTARY_CODE_POINT) {
n++; n++;
} }
int newCount = count + n; ensureCapacityInternal(count + n);
if (newCount > value.length) {
expandCapacity(newCount);
}
if (n == 1) { if (n == 1) {
value[count++] = (char) codePoint; value[count++] = (char) codePoint;
} else { } else {
@ -807,8 +794,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
end = count; end = count;
int len = str.length(); int len = str.length();
int newCount = count + len - (end - start); int newCount = count + len - (end - start);
if (newCount > value.length) ensureCapacityInternal(newCount);
expandCapacity(newCount);
System.arraycopy(value, end, value, start + len, count - end); System.arraycopy(value, end, value, start + len, count - end);
str.getChars(value, start); str.getChars(value, start);
@ -915,12 +901,10 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
throw new StringIndexOutOfBoundsException( throw new StringIndexOutOfBoundsException(
"offset " + offset + ", len " + len + ", str.length " "offset " + offset + ", len " + len + ", str.length "
+ str.length); + str.length);
int newCount = count + len; ensureCapacityInternal(count + len);
if (newCount > value.length)
expandCapacity(newCount);
System.arraycopy(value, index, value, index + len, count - index); System.arraycopy(value, index, value, index + len, count - index);
System.arraycopy(str, offset, value, index, len); System.arraycopy(str, offset, value, index, len);
count = newCount; count += len;
return this; return this;
} }
@ -984,12 +968,10 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
if (str == null) if (str == null)
str = "null"; str = "null";
int len = str.length(); int len = str.length();
int newCount = count + len; ensureCapacityInternal(count + len);
if (newCount > value.length)
expandCapacity(newCount);
System.arraycopy(value, offset, value, offset + len, count - offset); System.arraycopy(value, offset, value, offset + len, count - offset);
str.getChars(value, offset); str.getChars(value, offset);
count = newCount; count += len;
return this; return this;
} }
@ -1021,12 +1003,10 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
if ((offset < 0) || (offset > length())) if ((offset < 0) || (offset > length()))
throw new StringIndexOutOfBoundsException(offset); throw new StringIndexOutOfBoundsException(offset);
int len = str.length; int len = str.length;
int newCount = count + len; ensureCapacityInternal(count + len);
if (newCount > value.length)
expandCapacity(newCount);
System.arraycopy(value, offset, value, offset + len, count - offset); System.arraycopy(value, offset, value, offset + len, count - offset);
System.arraycopy(str, 0, value, offset, len); System.arraycopy(str, 0, value, offset, len);
count = newCount; count += len;
return this; return this;
} }
@ -1114,16 +1094,12 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
"start " + start + ", end " + end + ", s.length() " "start " + start + ", end " + end + ", s.length() "
+ s.length()); + s.length());
int len = end - start; int len = end - start;
if (len == 0) ensureCapacityInternal(count + len);
return this;
int newCount = count + len;
if (newCount > value.length)
expandCapacity(newCount);
System.arraycopy(value, dstOffset, value, dstOffset + len, System.arraycopy(value, dstOffset, value, dstOffset + len,
count - dstOffset); count - dstOffset);
for (int i=start; i<end; i++) for (int i=start; i<end; i++)
value[dstOffset++] = s.charAt(i); value[dstOffset++] = s.charAt(i);
count = newCount; count += len;
return this; return this;
} }
@ -1170,12 +1146,10 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
* @throws IndexOutOfBoundsException if the offset is invalid. * @throws IndexOutOfBoundsException if the offset is invalid.
*/ */
public AbstractStringBuilder insert(int offset, char c) { public AbstractStringBuilder insert(int offset, char c) {
int newCount = count + 1; ensureCapacityInternal(count + 1);
if (newCount > value.length)
expandCapacity(newCount);
System.arraycopy(value, offset, value, offset + 1, count - offset); System.arraycopy(value, offset, value, offset + 1, count - offset);
value[offset] = c; value[offset] = c;
count = newCount; count += 1;
return this; return this;
} }

View File

@ -2551,8 +2551,8 @@ public final class String
* Examples are programming language identifiers, protocol keys, and HTML * Examples are programming language identifiers, protocol keys, and HTML
* tags. * tags.
* For instance, <code>"TITLE".toLowerCase()</code> in a Turkish locale * For instance, <code>"TITLE".toLowerCase()</code> in a Turkish locale
* returns <code>"t\u0131tle"</code>, where '\u0131' is the LATIN SMALL * returns <code>"t\u005Cu0131tle"</code>, where '\u005Cu0131' is the
* LETTER DOTLESS I character. * LATIN SMALL LETTER DOTLESS I character.
* To obtain correct results for locale insensitive strings, use * To obtain correct results for locale insensitive strings, use
* <code>toLowerCase(Locale.ENGLISH)</code>. * <code>toLowerCase(Locale.ENGLISH)</code>.
* <p> * <p>
@ -2714,8 +2714,8 @@ public final class String
* Examples are programming language identifiers, protocol keys, and HTML * Examples are programming language identifiers, protocol keys, and HTML
* tags. * tags.
* For instance, <code>"title".toUpperCase()</code> in a Turkish locale * For instance, <code>"title".toUpperCase()</code> in a Turkish locale
* returns <code>"T\u0130TLE"</code>, where '\u0130' is the LATIN CAPITAL * returns <code>"T\u005Cu0130TLE"</code>, where '\u005Cu0130' is the
* LETTER I WITH DOT ABOVE character. * LATIN CAPITAL LETTER I WITH DOT ABOVE character.
* To obtain correct results for locale insensitive strings, use * To obtain correct results for locale insensitive strings, use
* <code>toUpperCase(Locale.ENGLISH)</code>. * <code>toUpperCase(Locale.ENGLISH)</code>.
* <p> * <p>

View File

@ -401,29 +401,40 @@ class DatagramSocket implements java.io.Closeable {
* send or receive may throw a PortUnreachableException. Note, there is no * send or receive may throw a PortUnreachableException. Note, there is no
* guarantee that the exception will be thrown. * guarantee that the exception will be thrown.
* *
* <p>A caller's permission to send and receive datagrams to a * <p> If a security manager has been installed then it is invoked to check
* given host and port are checked at connect time. When a socket * access to the remote address. Specifically, if the given {@code address}
* is connected, receive and send <b>will not * is a {@link InetAddress#isMulticastAddress multicast address},
* perform any security checks</b> on incoming and outgoing * the security manager's {@link
* packets, other than matching the packet's and the socket's * java.lang.SecurityManager#checkMulticast(InetAddress)
* address and port. On a send operation, if the packet's address * checkMulticast} method is invoked with the given {@code address}.
* is set and the packet's address and the socket's address do not * Otherwise, the security manager's {@link
* match, an IllegalArgumentException will be thrown. A socket * java.lang.SecurityManager#checkConnect(String,int) checkConnect}
* connected to a multicast address may only be used to send packets. * 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 address the remote address for the socket
* *
* @param port the remote port for the socket. * @param port the remote port for the socket.
* *
* @exception IllegalArgumentException if the address is null, * @throws IllegalArgumentException
* or the port is out of range. * if the address is null, or the port is out of range.
* *
* @exception SecurityException if the caller is not allowed to * @throws SecurityException
* send datagrams to and receive datagrams from the address and port. * if a security manager has been installed and it does
* not permit access to the given remote address
* *
* @see #disconnect * @see #disconnect
* @see #send
* @see #receive
*/ */
public void connect(InetAddress address, int port) { public void connect(InetAddress address, int port) {
try { try {
@ -435,13 +446,25 @@ class DatagramSocket implements java.io.Closeable {
/** /**
* Connects this socket to a remote socket address (IP address + port number). * 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. * @param addr The remote address.
* @throws SocketException if the connect fails *
* @throws IllegalArgumentException if addr is null or addr is a SocketAddress * @throws SocketException
* subclass not supported by this socket * 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 * @since 1.4
* @see #connect
*/ */
public void connect(SocketAddress addr) throws SocketException { public void connect(SocketAddress addr) throws SocketException {
if (addr == null) if (addr == null)

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -26,7 +26,10 @@
package java.security; package java.security;
import java.io.Serializable; import java.io.Serializable;
import java.security.cert.CRL;
import java.security.cert.CertPath; import java.security.cert.CertPath;
import sun.misc.JavaSecurityCodeSignerAccess;
import sun.misc.SharedSecrets;
/** /**
* This class encapsulates information about a code signer. * This class encapsulates information about a code signer.
@ -163,4 +166,43 @@ public final class CodeSigner implements Serializable {
sb.append(")"); sb.append(")");
return sb.toString(); 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();
}
});
}
} }

View File

@ -190,6 +190,14 @@ public abstract class AbstractCollection<E> implements Collection<E> {
return it.hasNext() ? finishToArray(r, it) : r; return it.hasNext() ? finishToArray(r, it) : r;
} }
/**
* 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 * Reallocates the array being used within toArray when the iterator
* returned more elements than expected, and finishes filling it from * returned more elements than expected, and finishes filling it from
@ -205,13 +213,10 @@ public abstract class AbstractCollection<E> implements Collection<E> {
while (it.hasNext()) { while (it.hasNext()) {
int cap = r.length; int cap = r.length;
if (i == cap) { if (i == cap) {
int newCap = ((cap / 2) + 1) * 3; int newCap = cap + (cap >> 1) + 1;
if (newCap <= cap) { // integer overflow // overflow-conscious code
if (cap == Integer.MAX_VALUE) if (newCap - MAX_ARRAY_SIZE > 0)
throw new OutOfMemoryError newCap = hugeCapacity(cap + 1);
("Required array size too large");
newCap = Integer.MAX_VALUE;
}
r = Arrays.copyOf(r, newCap); r = Arrays.copyOf(r, newCap);
} }
r[i++] = (T)it.next(); r[i++] = (T)it.next();
@ -220,6 +225,15 @@ public abstract class AbstractCollection<E> implements Collection<E> {
return (i == r.length) ? r : Arrays.copyOf(r, i); 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 // Modification Operations
/** /**

View File

@ -173,18 +173,47 @@ public class ArrayList<E> extends AbstractList<E>
* necessary, to ensure that it can hold at least the number of elements * necessary, to ensure that it can hold at least the number of elements
* specified by the minimum capacity argument. * specified by the minimum capacity argument.
* *
* @param minCapacity the desired minimum capacity * @param minCapacity the desired minimum capacity
*/ */
public void ensureCapacity(int minCapacity) { public void ensureCapacity(int minCapacity) {
modCount++; 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; int oldCapacity = elementData.length;
if (minCapacity > oldCapacity) { int newCapacity = oldCapacity + (oldCapacity >> 1);
int newCapacity = (oldCapacity * 3)/2 + 1; if (newCapacity - minCapacity < 0)
if (newCapacity < minCapacity) newCapacity = minCapacity;
newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0)
// minCapacity is usually close to size, so this is a win: newCapacity = hugeCapacity(minCapacity);
elementData = Arrays.copyOf(elementData, newCapacity); // 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 class ArrayList<E> extends AbstractList<E>
public void add(int index, E element) { public void add(int index, E element) {
rangeCheckForAdd(index); rangeCheckForAdd(index);
ensureCapacity(size+1); // Increments modCount!! ensureCapacity(size + 1); // Increments modCount!!
System.arraycopy(elementData, index, elementData, index + 1, System.arraycopy(elementData, index, elementData, index + 1,
size - index); size - index);
elementData[index] = element; elementData[index] = element;

View File

@ -364,6 +364,14 @@ public class Hashtable<K,V>
return null; return null;
} }
/**
* 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 * Increases the capacity of and internally reorganizes this
* hashtable, in order to accommodate and access its entries more * hashtable, in order to accommodate and access its entries more
@ -375,7 +383,14 @@ public class Hashtable<K,V>
int oldCapacity = table.length; int oldCapacity = table.length;
Entry[] oldMap = table; 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]; Entry[] newMap = new Entry[newCapacity];
modCount++; modCount++;

View File

@ -170,17 +170,21 @@ public class PriorityQueue<E> extends AbstractQueue<E>
* @throws NullPointerException if the specified collection or any * @throws NullPointerException if the specified collection or any
* of its elements are null * of its elements are null
*/ */
@SuppressWarnings("unchecked")
public PriorityQueue(Collection<? extends E> c) { public PriorityQueue(Collection<? extends E> c) {
initFromCollection(c); if (c instanceof SortedSet<?>) {
if (c instanceof SortedSet) SortedSet<? extends E> ss = (SortedSet<? extends E>) c;
comparator = (Comparator<? super E>) this.comparator = (Comparator<? super E>) ss.comparator();
((SortedSet<? extends E>)c).comparator(); initElementsFromCollection(ss);
else if (c instanceof PriorityQueue) }
comparator = (Comparator<? super E>) else if (c instanceof PriorityQueue<?>) {
((PriorityQueue<? extends E>)c).comparator(); PriorityQueue<? extends E> pq = (PriorityQueue<? extends E>) c;
this.comparator = (Comparator<? super E>) pq.comparator();
initFromPriorityQueue(pq);
}
else { else {
comparator = null; this.comparator = null;
heapify(); initFromCollection(c);
} }
} }
@ -198,9 +202,10 @@ public class PriorityQueue<E> extends AbstractQueue<E>
* @throws NullPointerException if the specified priority queue or any * @throws NullPointerException if the specified priority queue or any
* of its elements are null * of its elements are null
*/ */
@SuppressWarnings("unchecked")
public PriorityQueue(PriorityQueue<? extends E> c) { public PriorityQueue(PriorityQueue<? extends E> c) {
comparator = (Comparator<? super E>)c.comparator(); this.comparator = (Comparator<? super E>) c.comparator();
initFromCollection(c); initFromPriorityQueue(c);
} }
/** /**
@ -216,9 +221,33 @@ public class PriorityQueue<E> extends AbstractQueue<E>
* @throws NullPointerException if the specified sorted set or any * @throws NullPointerException if the specified sorted set or any
* of its elements are null * of its elements are null
*/ */
@SuppressWarnings("unchecked")
public PriorityQueue(SortedSet<? extends E> c) { public PriorityQueue(SortedSet<? extends E> c) {
comparator = (Comparator<? super E>)c.comparator(); this.comparator = (Comparator<? super E>) c.comparator();
initFromCollection(c); 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 @@ public class PriorityQueue<E> extends AbstractQueue<E>
* @param c the collection * @param c the collection
*/ */
private void initFromCollection(Collection<? extends E> c) { private void initFromCollection(Collection<? extends E> c) {
Object[] a = c.toArray(); initElementsFromCollection(c);
// If c.toArray incorrectly doesn't return Object[], copy it. heapify();
if (a.getClass() != Object[].class)
a = Arrays.copyOf(a, a.length, Object[].class);
queue = a;
size = a.length;
} }
/**
* 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. * Increases the capacity of the array.
* *
* @param minCapacity the desired minimum capacity * @param minCapacity the desired minimum capacity
*/ */
private void grow(int minCapacity) { private void grow(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
int oldCapacity = queue.length; int oldCapacity = queue.length;
// Double size if small; else grow by 50% // Double size if small; else grow by 50%
int newCapacity = ((oldCapacity < 64)? int newCapacity = oldCapacity + ((oldCapacity < 64) ?
((oldCapacity + 1) * 2): (oldCapacity + 2) :
((oldCapacity / 2) * 3)); (oldCapacity >> 1));
if (newCapacity < 0) // overflow // overflow-conscious code
newCapacity = Integer.MAX_VALUE; if (newCapacity - MAX_ARRAY_SIZE > 0)
if (newCapacity < minCapacity) newCapacity = hugeCapacity(minCapacity);
newCapacity = minCapacity;
queue = Arrays.copyOf(queue, newCapacity); 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. * Inserts the specified element into this priority queue.
* *

View File

@ -86,8 +86,23 @@ class Random implements java.io.Serializable {
* the seed of the random number generator to a value very likely * the seed of the random number generator to a value very likely
* to be distinct from any other invocation of this constructor. * to be distinct from any other invocation of this constructor.
*/ */
public Random() { this(++seedUniquifier + System.nanoTime()); } public Random() {
private static volatile long seedUniquifier = 8682522807148012L; 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. * Creates a new random number generator using a single {@code long} seed.
@ -103,8 +118,11 @@ class Random implements java.io.Serializable {
* @see #setSeed(long) * @see #setSeed(long)
*/ */
public Random(long seed) { public Random(long seed) {
this.seed = new AtomicLong(0L); this.seed = new AtomicLong(initialScramble(seed));
setSeed(seed); }
private static long initialScramble(long seed) {
return (seed ^ multiplier) & mask;
} }
/** /**
@ -127,8 +145,7 @@ class Random implements java.io.Serializable {
* @param seed the initial seed * @param seed the initial seed
*/ */
synchronized public void setSeed(long seed) { synchronized public void setSeed(long seed) {
seed = (seed ^ multiplier) & mask; this.seed.set(initialScramble(seed));
this.seed.set(seed);
haveNextNextGaussian = false; haveNextNextGaussian = false;
} }

View File

@ -235,16 +235,37 @@ public class Vector<E>
* @see #ensureCapacity(int) * @see #ensureCapacity(int)
*/ */
private void ensureCapacityHelper(int minCapacity) { 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; int oldCapacity = elementData.length;
if (minCapacity > oldCapacity) { int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
Object[] oldData = elementData; capacityIncrement : oldCapacity);
int newCapacity = (capacityIncrement > 0) ? if (newCapacity - minCapacity < 0)
(oldCapacity + capacityIncrement) : (oldCapacity * 2); newCapacity = minCapacity;
if (newCapacity < minCapacity) { if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = minCapacity; newCapacity = hugeCapacity(minCapacity);
} elementData = Arrays.copyOf(elementData, newCapacity);
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;
} }
/** /**

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -27,7 +27,6 @@ package java.util.jar;
import java.io.*; import java.io.*;
import java.util.*; import java.util.*;
import java.util.zip.*;
import java.security.*; import java.security.*;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;

View File

@ -40,7 +40,7 @@ package java.util.zip;
* <blockquote><pre> * <blockquote><pre>
* try { * try {
* // Encode a String into bytes * // Encode a String into bytes
* String inputString = "blahblahblah\u20AC\u20AC"; * String inputString = "blahblahblah";
* byte[] input = inputString.getBytes("UTF-8"); * byte[] input = inputString.getBytes("UTF-8");
* *
* // Compress the bytes * // Compress the bytes

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -205,7 +205,7 @@ class KeyImpl implements SecretKey, Destroyable, Serializable {
+ " keyBytes (hex dump)=" + " keyBytes (hex dump)="
+ (keyBytes == null || keyBytes.length == 0 ? + (keyBytes == null || keyBytes.length == 0 ?
" Empty Key" : " Empty Key" :
'\n' + hd.encode(keyBytes) '\n' + hd.encodeBuffer(keyBytes)
+ '\n'); + '\n');

View File

@ -1330,8 +1330,9 @@ public class JEditorPane extends JTextComponent {
*/ */
public Dimension getPreferredSize() { public Dimension getPreferredSize() {
Dimension d = super.getPreferredSize(); Dimension d = super.getPreferredSize();
JViewport port = SwingUtilities.getParentViewport(this); Container parent = SwingUtilities.getUnwrappedParent(this);
if (port != null) { if (parent instanceof JViewport) {
JViewport port = (JViewport) parent;
TextUI ui = getUI(); TextUI ui = getUI();
int prefWidth = d.width; int prefWidth = d.width;
int prefHeight = d.height; int prefHeight = d.height;
@ -1452,8 +1453,9 @@ public class JEditorPane extends JTextComponent {
* match its own, false otherwise * match its own, false otherwise
*/ */
public boolean getScrollableTracksViewportWidth() { public boolean getScrollableTracksViewportWidth() {
JViewport port = SwingUtilities.getParentViewport(this); Container parent = SwingUtilities.getUnwrappedParent(this);
if (port != null) { if (parent instanceof JViewport) {
JViewport port = (JViewport) parent;
TextUI ui = getUI(); TextUI ui = getUI();
int w = port.getWidth(); int w = port.getWidth();
Dimension min = ui.getMinimumSize(this); Dimension min = ui.getMinimumSize(this);
@ -1474,8 +1476,9 @@ public class JEditorPane extends JTextComponent {
* false otherwise * false otherwise
*/ */
public boolean getScrollableTracksViewportHeight() { public boolean getScrollableTracksViewportHeight() {
JViewport port = SwingUtilities.getParentViewport(this); Container parent = SwingUtilities.getUnwrappedParent(this);
if (port != null) { if (parent instanceof JViewport) {
JViewport port = (JViewport) parent;
TextUI ui = getUI(); TextUI ui = getUI();
int h = port.getHeight(); int h = port.getHeight();
Dimension min = ui.getMinimumSize(this); Dimension min = ui.getMinimumSize(this);

View File

@ -163,18 +163,6 @@ public final class JLayer<V extends Component>
private static final LayerEventController eventController = private static final LayerEventController eventController =
new LayerEventController(); 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 * Creates a new {@code JLayer} object with a {@code null} view component
* and {@code null} {@link javax.swing.plaf.LayerUI}. * and {@code null} {@link javax.swing.plaf.LayerUI}.
@ -396,24 +384,14 @@ public final class JLayer<V extends Component>
} }
/** /**
* Sets the bitmask of event types to receive by this {@code JLayer}. * Enables the events from JLayer and <b>all its descendants</b>
* Here is the list of the supported event types: * defined by the specified event mask parameter
* <ul> * to be delivered to the
* <li>AWTEvent.COMPONENT_EVENT_MASK</li> * {@link LayerUI#eventDispatched(AWTEvent, JLayer)} method.
* <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>
* <p/> * <p/>
* If {@code LayerUI} is installed, * Events are delivered provided that {@code LayerUI} is set
* {@link javax.swing.plaf.LayerUI#eventDispatched(AWTEvent, JLayer)} method * for this {@code JLayer} and the {@code JLayer}
* will only receive events that match the event mask. * is displayable.
* <p/> * <p/>
* The following example shows how to correclty use this method * The following example shows how to correclty use this method
* in the {@code LayerUI} implementations: * in the {@code LayerUI} implementations:
@ -433,19 +411,15 @@ public final class JLayer<V extends Component>
* } * }
* </pre> * </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 * @param layerEventMask the bitmask of event types to receive
* *
* @throws IllegalArgumentException if the {@code layerEventMask} parameter
* contains unsupported event types
* @see #getLayerEventMask() * @see #getLayerEventMask()
* @see LayerUI#eventDispatched(AWTEvent, JLayer)
* @see Component#isDisplayable()
*/ */
public void setLayerEventMask(long layerEventMask) { public void setLayerEventMask(long layerEventMask) {
if (layerEventMask != (layerEventMask & ACCEPTED_EVENTS)) {
throw new IllegalArgumentException(
"The event bitmask contains unsupported event types");
}
long oldEventMask = getLayerEventMask(); long oldEventMask = getLayerEventMask();
this.eventMask = layerEventMask; this.eventMask = layerEventMask;
firePropertyChange("layerEventMask", oldEventMask, layerEventMask); firePropertyChange("layerEventMask", oldEventMask, layerEventMask);
@ -629,6 +603,18 @@ public final class JLayer<V extends Component>
private long currentEventMask; 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") @SuppressWarnings("unchecked")
public void eventDispatched(AWTEvent event) { public void eventDispatched(AWTEvent event) {
Object source = event.getSource(); Object source = event.getSource();
@ -660,6 +646,8 @@ public final class JLayer<V extends Component>
for (Long mask : layerMaskList) { for (Long mask : layerMaskList) {
combinedMask |= mask; combinedMask |= mask;
} }
// filter out all unaccepted events
combinedMask &= ACCEPTED_EVENTS;
if (combinedMask == 0) { if (combinedMask == 0) {
removeAWTEventListener(); removeAWTEventListener();
} else if (getCurrentEventMask() != combinedMask) { } else if (getCurrentEventMask() != combinedMask) {

View File

@ -25,17 +25,7 @@
package javax.swing; package javax.swing;
import java.awt.Color; import java.awt.*;
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.event.*; import java.awt.event.*;
import java.util.Vector; import java.util.Vector;
@ -2779,9 +2769,9 @@ public class JList<E> extends JComponent implements Scrollable, Accessible
getVisibleRowCount() <= 0) { getVisibleRowCount() <= 0) {
return true; return true;
} }
JViewport port = SwingUtilities.getParentViewport(this); Container parent = SwingUtilities.getUnwrappedParent(this);
if (port != null) { if (parent instanceof JViewport) {
return port.getWidth() > getPreferredSize().width; return parent.getWidth() > getPreferredSize().width;
} }
return false; return false;
} }
@ -2805,9 +2795,9 @@ public class JList<E> extends JComponent implements Scrollable, Accessible
getVisibleRowCount() <= 0) { getVisibleRowCount() <= 0) {
return true; return true;
} }
JViewport port = SwingUtilities.getParentViewport(this); Container parent = SwingUtilities.getUnwrappedParent(this);
if (port != null) { if (parent instanceof JViewport) {
return port.getHeight() > getPreferredSize().height; return parent.getHeight() > getPreferredSize().height;
} }
return false; return false;
} }

View File

@ -719,8 +719,9 @@ public class JTable extends JComponent implements TableModelListener, Scrollable
* @see #addNotify * @see #addNotify
*/ */
protected void configureEnclosingScrollPane() { protected void configureEnclosingScrollPane() {
JViewport port = SwingUtilities.getParentViewport(this); Container parent = SwingUtilities.getUnwrappedParent(this);
if (port != null) { if (parent instanceof JViewport) {
JViewport port = (JViewport) parent;
Container gp = port.getParent(); Container gp = port.getParent();
if (gp instanceof JScrollPane) { if (gp instanceof JScrollPane) {
JScrollPane scrollPane = (JScrollPane)gp; JScrollPane scrollPane = (JScrollPane)gp;
@ -752,8 +753,9 @@ public class JTable extends JComponent implements TableModelListener, Scrollable
* from configureEnclosingScrollPane() and updateUI() in a safe manor. * from configureEnclosingScrollPane() and updateUI() in a safe manor.
*/ */
private void configureEnclosingScrollPaneUI() { private void configureEnclosingScrollPaneUI() {
JViewport port = SwingUtilities.getParentViewport(this); Container parent = SwingUtilities.getUnwrappedParent(this);
if (port != null) { if (parent instanceof JViewport) {
JViewport port = (JViewport) parent;
Container gp = port.getParent(); Container gp = port.getParent();
if (gp instanceof JScrollPane) { if (gp instanceof JScrollPane) {
JScrollPane scrollPane = (JScrollPane)gp; JScrollPane scrollPane = (JScrollPane)gp;
@ -822,8 +824,9 @@ public class JTable extends JComponent implements TableModelListener, Scrollable
* @since 1.3 * @since 1.3
*/ */
protected void unconfigureEnclosingScrollPane() { protected void unconfigureEnclosingScrollPane() {
JViewport port = SwingUtilities.getParentViewport(this); Container parent = SwingUtilities.getUnwrappedParent(this);
if (port != null) { if (parent instanceof JViewport) {
JViewport port = (JViewport) parent;
Container gp = port.getParent(); Container gp = port.getParent();
if (gp instanceof JScrollPane) { if (gp instanceof JScrollPane) {
JScrollPane scrollPane = (JScrollPane)gp; JScrollPane scrollPane = (JScrollPane)gp;
@ -5217,10 +5220,10 @@ public class JTable extends JComponent implements TableModelListener, Scrollable
* @see #getFillsViewportHeight * @see #getFillsViewportHeight
*/ */
public boolean getScrollableTracksViewportHeight() { public boolean getScrollableTracksViewportHeight() {
JViewport port = SwingUtilities.getParentViewport(this); Container parent = SwingUtilities.getUnwrappedParent(this);
return getFillsViewportHeight() return getFillsViewportHeight()
&& port != null && parent instanceof JViewport
&& port.getHeight() > getPreferredSize().height; && parent.getHeight() > getPreferredSize().height;
} }
/** /**

View File

@ -292,7 +292,7 @@ public class JTextField extends JTextComponent implements SwingConstants {
*/ */
@Override @Override
public boolean isValidateRoot() { public boolean isValidateRoot() {
return SwingUtilities.getParentViewport(this) == null; return !(SwingUtilities.getUnwrappedParent(this) instanceof JViewport);
} }

View File

@ -3498,9 +3498,9 @@ public class JTree extends JComponent implements Scrollable, Accessible
* @see Scrollable#getScrollableTracksViewportWidth * @see Scrollable#getScrollableTracksViewportWidth
*/ */
public boolean getScrollableTracksViewportWidth() { public boolean getScrollableTracksViewportWidth() {
JViewport port = SwingUtilities.getParentViewport(this); Container parent = SwingUtilities.getUnwrappedParent(this);
if (port != null) { if (parent instanceof JViewport) {
return port.getWidth() > getPreferredSize().width; return parent.getWidth() > getPreferredSize().width;
} }
return false; return false;
} }
@ -3515,9 +3515,9 @@ public class JTree extends JComponent implements Scrollable, Accessible
* @see Scrollable#getScrollableTracksViewportHeight * @see Scrollable#getScrollableTracksViewportHeight
*/ */
public boolean getScrollableTracksViewportHeight() { public boolean getScrollableTracksViewportHeight() {
JViewport port = SwingUtilities.getParentViewport(this); Container parent = SwingUtilities.getUnwrappedParent(this);
if (port != null) { if (parent instanceof JViewport) {
return port.getHeight() > getPreferredSize().height; return parent.getHeight() > getPreferredSize().height;
} }
return false; return false;
} }

View File

@ -1969,58 +1969,53 @@ public class SwingUtilities implements SwingConstants
} }
/** /**
* 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}. * 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}. * @param component {@code Component} to get
* The following way of obtaining the parent {@code JViewport} * the first ancestor of, which is not a {@link JLayer} instance.
* is not recommended any more: *
* <pre> * @return the first ancestor of the {@code component}
* JViewport port = null; * which is not an instance of {@link JLayer}.
* Container parent = component.getParent(); * If such an ancestor can not be found, {@code null} is returned.
* // 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}
* @throws NullPointerException if {@code component} is {@code null} * @throws NullPointerException if {@code component} is {@code null}
* @see JLayer
* *
* @since 1.7 * @since 1.7
*/ */
public static JViewport getParentViewport(Component component) { public static Container getUnwrappedParent(Component component) {
do { Container parent = component.getParent();
component = component.getParent(); while(parent instanceof JLayer) {
if (component instanceof JViewport) { parent = parent.getParent();
return (JViewport) component; }
} return parent;
} while(component instanceof JLayer);
return null;
} }
/** /**
* Returns the first {@code JViewport}'s descendant * 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}, * If the {@code viewport}'s view component is not a {@code JLayer},
* this method is equal to {@link JViewport#getView()} * this method is equivalent to {@link JViewport#getView()}
* otherwise {@link JLayer#getView()} will be recursively tested * 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 * @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} * @throws NullPointerException if {@code viewport} is {@code null}
* @see JViewport#getView() * @see JViewport#getView()
* @see JLayer * @see JLayer
*
* @since 1.7
*/ */
static Component getUnwrappedView(JViewport viewport) { public static Component getUnwrappedView(JViewport viewport) {
Component view = viewport.getView(); Component view = viewport.getView();
while (view instanceof JLayer) { while (view instanceof JLayer) {
view = ((JLayer)view).getView(); view = ((JLayer)view).getView();

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -42,9 +42,10 @@ import sun.awt.AppContext;
import sun.swing.AccumulativeRunnable; import sun.swing.AccumulativeRunnable;
/** /**
* An abstract class to perform lengthy GUI-interacting tasks in a * An abstract class to perform lengthy GUI-interaction tasks in a
* dedicated thread. * 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> * <p>
* When writing a multi-threaded application using Swing, there are * When writing a multi-threaded application using Swing, there are
* two constraints to keep in mind: * two constraints to keep in mind:
@ -772,7 +773,7 @@ public abstract class SwingWorker<T, V> implements RunnableFuture<T> {
}; };
executorService = executorService =
new ThreadPoolExecutor(1, MAX_WORKER_THREADS, new ThreadPoolExecutor(MAX_WORKER_THREADS, MAX_WORKER_THREADS,
10L, TimeUnit.MINUTES, 10L, TimeUnit.MINUTES,
new LinkedBlockingQueue<Runnable>(), new LinkedBlockingQueue<Runnable>(),
threadFactory); threadFactory);

View File

@ -72,58 +72,18 @@ public class LayerUI<V extends Component>
* the specified {@code Graphics} object to * the specified {@code Graphics} object to
* render the content of the component. * render the content of the component.
* <p/> * <p/>
* If {@code g} is not an instance of {@code Graphics2D}, * The default implementation paints the passed component as is.
* this method is no-op.
* *
* @param g the {@code Graphics} context in which to paint; * @param g the {@code Graphics} context in which to paint
* @param c the component being painted; * @param c the component being painted
* it can be safely cast to {@code JLayer<? extends V>}
*
* @see #configureGraphics(Graphics2D, JLayer)
* @see #paintLayer(Graphics2D, JLayer)
*/ */
public void paint(Graphics g, JComponent c) { public void paint(Graphics g, JComponent c) {
if (g instanceof Graphics2D) { c.paint(g);
Graphics2D g2 = (Graphics2D) g.create();
JLayer<? extends V> l = (JLayer<? extends V>) c;
configureGraphics(g2, l);
paintLayer(g2, l);
g2.dispose();
}
} }
/** /**
* This method is called by the {@link #paint} method prior to * Processes {@code AWTEvent}s for {@code JLayer}
* {@link #paintLayer} to configure the {@code Graphics2D} object. * and <b>all its descendants</b> to this {@code LayerUI} instance.
* 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.
* <p/> * <p/>
* To enable the {@code AWTEvent}s of a particular type, * To enable the {@code AWTEvent}s of a particular type,
* you call {@link JLayer#setLayerEventMask} * you call {@link JLayer#setLayerEventMask}
@ -133,13 +93,14 @@ public class LayerUI<V extends Component>
* By default this method calls the appropriate * By default this method calls the appropriate
* {@code process&lt;event&nbsp;type&gt;Event} * {@code process&lt;event&nbsp;type&gt;Event}
* method for the given class of 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 e the event to be dispatched
* @param l the layer this LayerUI is set to * @param l the layer this LayerUI is set to
* *
* @see JLayer#setLayerEventMask(long) * @see JLayer#setLayerEventMask(long)
* @see #installUI(javax.swing.JComponent) * @see Component#isDisplayable()
* @see #uninstallUI(javax.swing.JComponent)
* @see #processComponentEvent * @see #processComponentEvent
* @see #processFocusEvent * @see #processFocusEvent
* @see #processKeyEvent * @see #processKeyEvent
@ -627,17 +588,6 @@ public class LayerUI<V extends Component>
propertyChangeSupport.firePropertyChange(propertyName, oldValue, newValue); propertyChangeSupport.firePropertyChange(propertyName, oldValue, newValue);
} }
/**
* 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 * Notifies the {@code LayerUI} when any of its property are changed
* and enables updating every {@code JLayer} * and enables updating every {@code JLayer}
@ -647,9 +597,6 @@ public class LayerUI<V extends Component>
* @param l the {@code JLayer} this LayerUI is set to * @param l the {@code JLayer} this LayerUI is set to
*/ */
public void applyPropertyChange(PropertyChangeEvent evt, JLayer<? extends V> l) { public void applyPropertyChange(PropertyChangeEvent evt, JLayer<? extends V> l) {
if ("dirty".equals(evt.getPropertyName())) {
l.repaint();
}
} }
/** /**

View File

@ -38,6 +38,7 @@ import javax.swing.plaf.synth.SynthStyle;
import java.awt.Color; import java.awt.Color;
import java.awt.Font; import java.awt.Font;
import java.awt.Insets; import java.awt.Insets;
import java.lang.ref.WeakReference;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
@ -193,7 +194,7 @@ public final class NimbusStyle extends SynthStyle {
* UIDefaults which overrides (or supplements) those defaults found in * UIDefaults which overrides (or supplements) those defaults found in
* UIManager. * UIManager.
*/ */
private JComponent component; private WeakReference<JComponent> component;
/** /**
* Create a new NimbusStyle. Only the prefix must be supplied. At the * Create a new NimbusStyle. Only the prefix must be supplied. At the
@ -209,7 +210,9 @@ public final class NimbusStyle extends SynthStyle {
* should be null otherwise. * should be null otherwise.
*/ */
NimbusStyle(String prefix, JComponent c) { NimbusStyle(String prefix, JComponent c) {
this.component = c; if (c != null) {
this.component = new WeakReference<JComponent>(c);
}
this.prefix = prefix; this.prefix = prefix;
this.painter = new SynthPainterImpl(this); this.painter = new SynthPainterImpl(this);
} }
@ -251,9 +254,11 @@ public final class NimbusStyle extends SynthStyle {
// value is an instance of UIDefaults, then these defaults are used // value is an instance of UIDefaults, then these defaults are used
// in place of, or in addition to, the defaults in UIManager. // in place of, or in addition to, the defaults in UIManager.
if (component != null) { 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) { if (o instanceof UIDefaults) {
Object i = component.getClientProperty( Object i = component.get().getClientProperty(
"Nimbus.Overrides.InheritDefaults"); "Nimbus.Overrides.InheritDefaults");
boolean inherit = i instanceof Boolean ? (Boolean)i : true; boolean inherit = i instanceof Boolean ? (Boolean)i : true;
UIDefaults d = (UIDefaults)o; UIDefaults d = (UIDefaults)o;

View File

@ -2069,9 +2069,9 @@ public abstract class JTextComponent extends JComponent implements Scrollable, A
* width to match its own * width to match its own
*/ */
public boolean getScrollableTracksViewportWidth() { public boolean getScrollableTracksViewportWidth() {
JViewport port = SwingUtilities.getParentViewport(this); Container parent = SwingUtilities.getUnwrappedParent(this);
if (port != null) { if (parent instanceof JViewport) {
return port.getWidth() > getPreferredSize().width; return parent.getWidth() > getPreferredSize().width;
} }
return false; return false;
} }
@ -2090,9 +2090,9 @@ public abstract class JTextComponent extends JComponent implements Scrollable, A
* to match its own * to match its own
*/ */
public boolean getScrollableTracksViewportHeight() { public boolean getScrollableTracksViewportHeight() {
JViewport port = SwingUtilities.getParentViewport(this); Container parent = SwingUtilities.getUnwrappedParent(this);
if (port != null) { if (parent instanceof JViewport) {
return (port.getHeight() > getPreferredSize().height); return parent.getHeight() > getPreferredSize().height;
} }
return false; return false;
} }

View File

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

View File

@ -27,8 +27,8 @@ package sun.misc;
import java.util.jar.JarFile; import java.util.jar.JarFile;
import java.io.Console; import java.io.Console;
import java.io.File;
import java.io.FileDescriptor; import java.io.FileDescriptor;
import java.security.CodeSigner;
import java.security.ProtectionDomain; import java.security.ProtectionDomain;
/** A repository of "shared secrets", which are a mechanism for /** A repository of "shared secrets", which are a mechanism for
@ -49,6 +49,7 @@ public class SharedSecrets {
private static JavaNioAccess javaNioAccess; private static JavaNioAccess javaNioAccess;
private static JavaIOFileDescriptorAccess javaIOFileDescriptorAccess; private static JavaIOFileDescriptorAccess javaIOFileDescriptorAccess;
private static JavaSecurityProtectionDomainAccess javaSecurityProtectionDomainAccess; private static JavaSecurityProtectionDomainAccess javaSecurityProtectionDomainAccess;
private static JavaSecurityCodeSignerAccess javaSecurityCodeSignerAccess;
public static JavaUtilJarAccess javaUtilJarAccess() { public static JavaUtilJarAccess javaUtilJarAccess() {
if (javaUtilJarAccess == null) { if (javaUtilJarAccess == null) {
@ -126,4 +127,16 @@ public class SharedSecrets {
unsafe.ensureClassInitialized(ProtectionDomain.class); unsafe.ensureClassInitialized(ProtectionDomain.class);
return javaSecurityProtectionDomainAccess; return javaSecurityProtectionDomainAccess;
} }
public static void setJavaSecurityCodeSignerAccess
(JavaSecurityCodeSignerAccess jscsa) {
javaSecurityCodeSignerAccess = jscsa;
}
public static JavaSecurityCodeSignerAccess
getJavaSecurityCodeSignerAccess() {
if (javaSecurityCodeSignerAccess == null)
unsafe.ensureClassInitialized(CodeSigner.class);
return javaSecurityCodeSignerAccess;
}
} }

View File

@ -26,16 +26,12 @@
package sun.net.httpserver; package sun.net.httpserver;
import java.io.*; import java.io.*;
import java.nio.*;
import java.nio.channels.*;
import java.net.*; import java.net.*;
import javax.net.ssl.*; import javax.net.ssl.*;
import java.util.*; import java.util.*;
import java.util.logging.Logger; import java.util.logging.Logger;
import java.text.*; import java.text.*;
import sun.net.www.MessageHeader;
import com.sun.net.httpserver.*; import com.sun.net.httpserver.*;
import com.sun.net.httpserver.spi.*;
class ExchangeImpl { class ExchangeImpl {
@ -65,6 +61,8 @@ class ExchangeImpl {
df.setTimeZone (tz); df.setTimeZone (tz);
} }
private static final String HEAD = "HEAD";
/* streams which take care of the HTTP protocol framing /* streams which take care of the HTTP protocol framing
* and are passed up to higher layers * and are passed up to higher layers
*/ */
@ -116,6 +114,10 @@ class ExchangeImpl {
return connection.getHttpContext(); return connection.getHttpContext();
} }
private boolean isHeadRequest() {
return HEAD.equals(getRequestMethod());
}
public void close () { public void close () {
if (closed) { if (closed) {
return; return;
@ -220,24 +222,36 @@ class ExchangeImpl {
} }
contentLen = -1; contentLen = -1;
} }
if (contentLen == 0) {
if (http10) { if (isHeadRequest()) {
o.setWrappedStream (new UndefLengthOutputStream (this, ros)); /* HEAD requests should not set a content length by passing it
close = true; * 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);
}
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 { } else {
rspHdrs.set ("Transfer-encoding", "chunked"); if (contentLen == -1) {
o.setWrappedStream (new ChunkedOutputStream (this, ros)); noContentToSend = true;
contentLen = 0;
}
rspHdrs.set("Content-length", Long.toString(contentLen));
o.setWrappedStream (new FixedLengthOutputStream (this, ros, contentLen));
} }
} else {
if (contentLen == -1) {
noContentToSend = true;
contentLen = 0;
}
/* 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); write (rspHdrs, tmpout);
this.rspContentLen = contentLen; this.rspContentLen = contentLen;

View File

@ -451,6 +451,7 @@ class ServerImpl implements TimeSource {
if (requestLine == null) { if (requestLine == null) {
/* connection closed */ /* connection closed */
connection.close(); connection.close();
allConnections.remove(connection);
return; return;
} }
int space = requestLine.indexOf (' '); int space = requestLine.indexOf (' ');
@ -592,6 +593,8 @@ class ServerImpl implements TimeSource {
sendReply ( sendReply (
code, true, "<h1>"+code+Code.msg(code)+"</h1>"+message code, true, "<h1>"+code+Code.msg(code)+"</h1>"+message
); );
/* connection is already closed by sendReply, now remove it */
allConnections.remove(connection);
} }
void sendReply ( void sendReply (

View File

@ -29,8 +29,10 @@ import java.net.URL;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.net.PasswordAuthentication; import java.net.PasswordAuthentication;
import java.io.IOException;
import java.io.OutputStream;
import sun.net.www.HeaderParser; import sun.net.www.HeaderParser;
import sun.misc.BASE64Encoder;
/** /**
* BasicAuthentication: Encapsulate an http server authentication using * BasicAuthentication: Encapsulate an http server authentication using
@ -74,7 +76,7 @@ class BasicAuthentication extends AuthenticationInfo {
System.arraycopy(nameBytes, 0, concat, 0, nameBytes.length); System.arraycopy(nameBytes, 0, concat, 0, nameBytes.length);
System.arraycopy(passwdBytes, 0, concat, nameBytes.length, System.arraycopy(passwdBytes, 0, concat, nameBytes.length,
passwdBytes.length); passwdBytes.length);
this.auth = "Basic " + (new sun.misc.BASE64Encoder()).encode(concat); this.auth = "Basic " + (new BasicBASE64Encoder()).encode(concat);
this.pw = pw; this.pw = pw;
} }
@ -114,7 +116,7 @@ class BasicAuthentication extends AuthenticationInfo {
System.arraycopy(nameBytes, 0, concat, 0, nameBytes.length); System.arraycopy(nameBytes, 0, concat, 0, nameBytes.length);
System.arraycopy(passwdBytes, 0, concat, nameBytes.length, System.arraycopy(passwdBytes, 0, concat, nameBytes.length,
passwdBytes.length); passwdBytes.length);
this.auth = "Basic " + (new sun.misc.BASE64Encoder()).encode(concat); this.auth = "Basic " + (new BasicBASE64Encoder()).encode(concat);
this.pw = pw; this.pw = pw;
} }
@ -200,4 +202,11 @@ class BasicAuthentication extends AuthenticationInfo {
return npath; 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);
}
}
} }

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -109,7 +109,7 @@ public class Config {
public static synchronized void refresh() throws KrbException { public static synchronized void refresh() throws KrbException {
singleton = new Config(); singleton = new Config();
KeyTab.refresh(); KeyTab.refresh();
KrbKdcReq.KdcAccessibility.reset(); KrbKdcReq.initStatic();
} }

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -499,8 +499,9 @@ public class EncryptionKey
+ " kvno=" + kvno + " kvno=" + kvno
+ " keyValue (hex dump)=" + " keyValue (hex dump)="
+ (keyValue == null || keyValue.length == 0 ? + (keyValue == null || keyValue.length == 0 ?
" Empty Key" : '\n' + Krb5.hexDumper.encode(keyValue) " Empty Key" : '\n'
+ '\n')); + Krb5.hexDumper.encodeBuffer(keyValue)
+ '\n'));
} }
/** /**

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -51,28 +51,31 @@ import java.util.HashSet;
public abstract class KrbKdcReq { public abstract class KrbKdcReq {
// Currently there is no option to specify retries // The following settings can be configured in [libdefaults]
// in the kerberos configuration file // section of krb5.conf, which are global for all realms. Each of
// them can also be defined in a realm, which overrides value here.
private static final int DEFAULT_KDC_RETRY_LIMIT = Krb5.KDC_RETRY_LIMIT;
/** /**
* Default timeout period when requesting a ticket from a KDC. * max retry time for a single KDC, default Krb5.KDC_RETRY_LIMIT (3)
* If not specified in the configuration file,
* a value of 30 seconds is used.
*/ */
public static final int DEFAULT_KDC_TIMEOUT; // milliseconds private static int defaultKdcRetryLimit;
/**
* timeout requesting a ticket from KDC, in millisec, default 30 sec
*/
private static int defaultKdcTimeout;
/**
* max UDP packet size, default unlimited (-1)
*/
private static int defaultUdpPrefLimit;
private static final boolean DEBUG = Krb5.DEBUG; private static final boolean DEBUG = Krb5.DEBUG;
private static int udpPrefLimit = -1;
private static final String BAD_POLICY_KEY = "krb5.kdc.bad.policy"; private static final String BAD_POLICY_KEY = "krb5.kdc.bad.policy";
/** /**
* What to do when a KDC is unavailable, specified in the * What to do when a KDC is unavailable, specified in the
* java.security file with key krb5.kdc.bad.policy. * 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 { private enum BpType {
NONE, TRY_LAST, TRY_LESS NONE, TRY_LAST, TRY_LESS
@ -80,9 +83,16 @@ public abstract class KrbKdcReq {
private static int tryLessMaxRetries = 1; private static int tryLessMaxRetries = 1;
private static int tryLessTimeout = 5000; private static int tryLessTimeout = 5000;
private static final BpType badPolicy; private static BpType badPolicy;
static { static {
initStatic();
}
/**
* Read global settings
*/
public static void initStatic() {
String value = AccessController.doPrivileged( String value = AccessController.doPrivileged(
new PrivilegedAction<String>() { new PrivilegedAction<String>() {
public String run() { public String run() {
@ -95,9 +105,21 @@ public abstract class KrbKdcReq {
if ("tryless".equals(ss[0])) { if ("tryless".equals(ss[0])) {
if (ss.length > 1) { if (ss.length > 1) {
String[] params = ss[1].split(","); String[] params = ss[1].split(",");
tryLessMaxRetries = Integer.parseInt(params[0]); try {
if (params.length > 1) { int tmp0 = Integer.parseInt(params[0]);
tryLessTimeout = Integer.parseInt(params[1]); 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; badPolicy = BpType.TRY_LESS;
@ -110,30 +132,33 @@ public abstract class KrbKdcReq {
badPolicy = BpType.NONE; badPolicy = BpType.NONE;
} }
/*
* Get default timeout.
*/
int timeout = -1; int timeout = -1;
int max_retries = -1;
int udf_pref_limit = -1;
try { try {
Config cfg = Config.getInstance(); Config cfg = Config.getInstance();
String temp = cfg.getDefault("kdc_timeout", "libdefaults"); String temp = cfg.getDefault("kdc_timeout", "libdefaults");
timeout = parsePositiveIntString(temp); timeout = parsePositiveIntString(temp);
temp = cfg.getDefault("max_retries", "libdefaults");
max_retries = parsePositiveIntString(temp);
temp = cfg.getDefault("udp_preference_limit", "libdefaults"); temp = cfg.getDefault("udp_preference_limit", "libdefaults");
udpPrefLimit = parsePositiveIntString(temp); udf_pref_limit = parsePositiveIntString(temp);
} catch (Exception exc) { } catch (Exception exc) {
// ignore any exceptions; use the default time out values // ignore any exceptions; use default values
if (DEBUG) { if (DEBUG) {
System.out.println ("Exception in getting kdc_timeout value, " + System.out.println ("Exception in getting KDC communication " +
"using default value " + "settings, using default value " +
exc.getMessage()); 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) KdcAccessibility.reset();
DEFAULT_KDC_TIMEOUT = timeout;
else
DEFAULT_KDC_TIMEOUT = 30*1000; // 30 seconds
} }
protected byte[] obuf; protected byte[] obuf;
@ -151,6 +176,9 @@ public abstract class KrbKdcReq {
public String send(String realm) public String send(String realm)
throws IOException, KrbException { throws IOException, KrbException {
int udpPrefLimit = getRealmSpecificValue(
realm, "udp_preference_limit", defaultUdpPrefLimit);
boolean useTCP = (udpPrefLimit > 0 && boolean useTCP = (udpPrefLimit > 0 &&
(obuf != null && obuf.length > udpPrefLimit)); (obuf != null && obuf.length > udpPrefLimit));
@ -213,9 +241,10 @@ public abstract class KrbKdcReq {
return; return;
int port = Krb5.KDC_INET_DEFAULT_PORT; int port = Krb5.KDC_INET_DEFAULT_PORT;
int retries = DEFAULT_KDC_RETRY_LIMIT; int retries = getRealmSpecificValue(
int timeout = getKdcTimeout(realm); realm, "max_retries", defaultKdcRetryLimit);
int timeout = getRealmSpecificValue(
realm, "kdc_timeout", defaultKdcTimeout);
if (badPolicy == BpType.TRY_LESS && if (badPolicy == BpType.TRY_LESS &&
KdcAccessibility.isBad(tempKdc)) { KdcAccessibility.isBad(tempKdc)) {
if (retries > tryLessMaxRetries) { if (retries > tryLessMaxRetries) {
@ -322,6 +351,12 @@ public abstract class KrbKdcReq {
if (useTCP) { if (useTCP) {
TCPClient kdcClient = new TCPClient(kdc, port); TCPClient kdcClient = new TCPClient(kdc, port);
if (DEBUG) {
System.out.println(">>> KDCCommunication: kdc=" + kdc
+ " TCP:"
+ port
+ ", #bytes=" + obuf.length);
}
try { try {
/* /*
* Send the data to the kdc. * Send the data to the kdc.
@ -336,7 +371,7 @@ public abstract class KrbKdcReq {
} }
} else { } else {
// For each KDC we try DEFAULT_KDC_RETRY_LIMIT (3) times to // For each KDC we try defaultKdcRetryLimit times to
// get the response // get the response
for (int i=1; i <= retries; i++) { for (int i=1; i <= retries; i++) {
UDPClient kdcClient = new UDPClient(kdc, port, timeout); UDPClient kdcClient = new UDPClient(kdc, port, timeout);
@ -382,37 +417,37 @@ public abstract class KrbKdcReq {
} }
/** /**
* Returns a timeout value for the KDC of the given realm. * Returns krb5.conf setting of {@code key} for a specfic realm,
* A KDC-specific timeout, if specified in the config file, * which can be:
* overrides the default timeout (which may also be specified * 1. defined in the sub-stanza for the given realm inside [realms], or
* in the config file). Default timeout is returned if null * 2. defined in [libdefaults], or
* is specified for realm. * 3. defValue
* @param realm the realm which kdc's timeout is requested * @param realm the given realm in which the setting is requested. Returns
* @return KDC timeout * 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) private int getRealmSpecificValue(String realm, String key, int defValue) {
{ int v = defValue;
int timeout = DEFAULT_KDC_TIMEOUT;
if (realm == null) if (realm == null) return v;
return timeout;
int tempTimeout = -1; int temp = -1;
try { try {
String temp = String value =
Config.getInstance().getDefault("kdc_timeout", realm); Config.getInstance().getDefault(key, realm);
tempTimeout = parsePositiveIntString(temp); temp = parsePositiveIntString(value);
} catch (Exception exc) { } catch (Exception exc) {
// Ignored, defValue will be picked up
} }
if (tempTimeout > 0) if (temp > 0) v = temp;
timeout = tempTimeout;
return timeout; return v;
} }
private static int parsePositiveIntString(String intString) private static int parsePositiveIntString(String intString) {
{
if (intString == null) if (intString == null)
return -1; return -1;
@ -461,7 +496,7 @@ public abstract class KrbKdcReq {
return bads.contains(kdc); return bads.contains(kdc);
} }
public static synchronized void reset() { private static synchronized void reset() {
if (DEBUG) { if (DEBUG) {
System.out.println(">>> KdcAccessibility: reset"); System.out.println(">>> KdcAccessibility: reset");
} }

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -101,7 +101,7 @@ public class PrincipalName
private Realm nameRealm; // optional; a null realm means use default private Realm nameRealm; // optional; a null realm means use default
// Note: the nameRealm is not included in the default ASN.1 encoding // 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; private String salt = null;
protected PrincipalName() { protected PrincipalName() {
@ -123,18 +123,19 @@ public class PrincipalName
} }
public Object clone() { public Object clone() {
PrincipalName pName = new PrincipalName(); try {
pName.nameType = nameType; PrincipalName pName = (PrincipalName) super.clone();
if (nameStrings != null) { // Re-assign mutable fields
pName.nameStrings = if (nameStrings != null) {
new String[nameStrings.length]; pName.nameStrings = nameStrings.clone();
System.arraycopy(nameStrings,0,pName.nameStrings,0, }
nameStrings.length); 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;
} }
/* /*

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -28,7 +28,6 @@ package sun.security.pkcs;
import java.io.*; import java.io.*;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.*; import java.util.*;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
import java.security.cert.X509CRL; import java.security.cert.X509CRL;
@ -173,20 +172,30 @@ public class PKCS7 {
* @param digestAlgorithmIds the message digest algorithm identifiers. * @param digestAlgorithmIds the message digest algorithm identifiers.
* @param contentInfo the content information. * @param contentInfo the content information.
* @param certificates an array of X.509 certificates. * @param certificates an array of X.509 certificates.
* @param crls an array of CRLs
* @param signerInfos an array of signer information. * @param signerInfos an array of signer information.
*/ */
public PKCS7(AlgorithmId[] digestAlgorithmIds, public PKCS7(AlgorithmId[] digestAlgorithmIds,
ContentInfo contentInfo, ContentInfo contentInfo,
X509Certificate[] certificates, X509Certificate[] certificates,
X509CRL[] crls,
SignerInfo[] signerInfos) { SignerInfo[] signerInfos) {
version = BigInteger.ONE; version = BigInteger.ONE;
this.digestAlgorithmIds = digestAlgorithmIds; this.digestAlgorithmIds = digestAlgorithmIds;
this.contentInfo = contentInfo; this.contentInfo = contentInfo;
this.certificates = certificates; this.certificates = certificates;
this.crls = crls;
this.signerInfos = signerInfos; this.signerInfos = signerInfos;
} }
public PKCS7(AlgorithmId[] digestAlgorithmIds,
ContentInfo contentInfo,
X509Certificate[] certificates,
SignerInfo[] signerInfos) {
this(digestAlgorithmIds, contentInfo, certificates, null, signerInfos);
}
private void parseNetscapeCertChain(DerValue val) private void parseNetscapeCertChain(DerValue val)
throws ParsingException, IOException { throws ParsingException, IOException {
DerInputStream dis = new DerInputStream(val.toByteArray()); DerInputStream dis = new DerInputStream(val.toByteArray());
@ -312,7 +321,7 @@ public class PKCS7 {
ByteArrayInputStream bais = null; ByteArrayInputStream bais = null;
try { try {
if (certfac == null) if (certfac == null)
crls[i] = (X509CRL) new X509CRLImpl(crlVals[i]); crls[i] = new X509CRLImpl(crlVals[i]);
else { else {
byte[] encoded = crlVals[i].toByteArray(); byte[] encoded = crlVals[i].toByteArray();
bais = new ByteArrayInputStream(encoded); bais = new ByteArrayInputStream(encoded);
@ -480,7 +489,30 @@ public class PKCS7 {
signedData.putOrderedSetOf((byte)0xA0, implCerts); 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 // signerInfos
signedData.putOrderedSetOf(DerValue.tag_Set, signerInfos); signedData.putOrderedSetOf(DerValue.tag_Set, signerInfos);

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -96,9 +96,9 @@ public class CertId {
HexDumpEncoder encoder = new HexDumpEncoder(); HexDumpEncoder encoder = new HexDumpEncoder();
System.out.println("Issuer Certificate is " + issuerCert); System.out.println("Issuer Certificate is " + issuerCert);
System.out.println("issuerNameHash is " + System.out.println("issuerNameHash is " +
encoder.encode(issuerNameHash)); encoder.encodeBuffer(issuerNameHash));
System.out.println("issuerKeyHash is " + System.out.println("issuerKeyHash is " +
encoder.encode(issuerKeyHash)); encoder.encodeBuffer(issuerKeyHash));
System.out.println("SerialNumber is " + serialNumber.getNumber()); System.out.println("SerialNumber is " + serialNumber.getNumber());
} }
} }

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -26,6 +26,7 @@
package sun.security.tools; package sun.security.tools;
import java.io.*; import java.io.*;
import java.security.cert.X509CRL;
import java.util.*; import java.util.*;
import java.util.zip.*; import java.util.zip.*;
import java.util.jar.*; import java.util.jar.*;
@ -35,6 +36,7 @@ import java.net.URISyntaxException;
import java.text.Collator; import java.text.Collator;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.security.cert.Certificate; import java.security.cert.Certificate;
import java.security.cert.CRL;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
import java.security.*; import java.security.*;
@ -56,6 +58,7 @@ import java.util.Map.Entry;
import sun.security.x509.*; import sun.security.x509.*;
import sun.security.util.*; import sun.security.util.*;
import sun.misc.BASE64Encoder; import sun.misc.BASE64Encoder;
import sun.misc.SharedSecrets;
/** /**
@ -114,14 +117,16 @@ public class JarSigner {
static final int SIGNED_BY_ALIAS = 0x08; // signer is in alias list static final int SIGNED_BY_ALIAS = 0x08; // signer is in alias list
X509Certificate[] certChain; // signer's cert chain (when composing) X509Certificate[] certChain; // signer's cert chain (when composing)
Set<X509CRL> crls; // signer provided CRLs
PrivateKey privateKey; // private key PrivateKey privateKey; // private key
KeyStore store; // the keystore specified by -keystore KeyStore store; // the keystore specified by -keystore
// or the default keystore, never null // or the default keystore, never null
String keystore; // key store file String keystore; // key store file
List<String> crlfiles = new ArrayList<String>(); // CRL files to add
boolean nullStream = false; // null keystore input stream (NONE) boolean nullStream = false; // null keystore input stream (NONE)
boolean token = false; // token-based keystore 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 String alias; // alias to sign jar with
List<String> ckaliases = new ArrayList<String>(); // aliases in -verify List<String> ckaliases = new ArrayList<String>(); // aliases in -verify
char[] storepass; // keystore password char[] storepass; // keystore password
@ -146,6 +151,7 @@ public class JarSigner {
boolean signManifest = true; // "sign" the whole manifest boolean signManifest = true; // "sign" the whole manifest
boolean externalSF = true; // leave the .SF out of the PKCS7 block boolean externalSF = true; // leave the .SF out of the PKCS7 block
boolean strict = false; // treat warnings as error boolean strict = false; // treat warnings as error
boolean autoCRL = false; // Automatcially add CRL defined in cert
// read zip entry raw bytes // read zip entry raw bytes
private ByteArrayOutputStream baos = new ByteArrayOutputStream(2048); private ByteArrayOutputStream baos = new ByteArrayOutputStream(2048);
@ -226,6 +232,29 @@ public class JarSigner {
} else { } else {
loadKeyStore(keystore, true); loadKeyStore(keystore, true);
getAliasInfo(alias); 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 // load the alternative signing mechanism
if (altSignerClass != null) { if (altSignerClass != null) {
@ -367,6 +396,13 @@ public class JarSigner {
} else if (collator.compare(flags, "-digestalg") ==0) { } else if (collator.compare(flags, "-digestalg") ==0) {
if (++n == args.length) usageNoArg(); if (++n == args.length) usageNoArg();
digestalg = args[n]; 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) { } else if (collator.compare(flags, "-certs") ==0) {
showcerts = true; showcerts = true;
} else if (collator.compare(flags, "-strict") ==0) { } else if (collator.compare(flags, "-strict") ==0) {
@ -515,6 +551,9 @@ public class JarSigner {
System.out.println(rb.getString System.out.println(rb.getString
("[-sigalg <algorithm>] name of signature algorithm")); ("[-sigalg <algorithm>] name of signature algorithm"));
System.out.println(); System.out.println();
System.out.println(rb.getString
("[-crl[:auto| <file>] include CRL in signed jar"));
System.out.println();
System.out.println(rb.getString System.out.println(rb.getString
("[-verify] verify a signed JAR file")); ("[-verify] verify a signed JAR file"));
System.out.println(); System.out.println();
@ -654,6 +693,20 @@ public class JarSigner {
if (showcerts) { if (showcerts) {
sb.append(si); sb.append(si);
sb.append('\n'); 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")) { } else if (showcerts && !verbose.equals("all")) {
@ -1123,6 +1176,8 @@ public class JarSigner {
BASE64Encoder encoder = new JarBASE64Encoder(); BASE64Encoder encoder = new JarBASE64Encoder();
Vector<ZipEntry> mfFiles = new Vector<ZipEntry>(); Vector<ZipEntry> mfFiles = new Vector<ZipEntry>();
boolean wasSigned = false;
for (Enumeration<? extends ZipEntry> enum_=zipFile.entries(); for (Enumeration<? extends ZipEntry> enum_=zipFile.entries();
enum_.hasMoreElements();) { enum_.hasMoreElements();) {
ZipEntry ze = enum_.nextElement(); ZipEntry ze = enum_.nextElement();
@ -1132,6 +1187,11 @@ public class JarSigner {
// out first // out first
mfFiles.addElement(ze); mfFiles.addElement(ze);
if (SignatureFileVerifier.isBlockOrSF(
ze.getName().toUpperCase(Locale.ENGLISH))) {
wasSigned = true;
}
if (signatureRelated(ze.getName())) { if (signatureRelated(ze.getName())) {
// ignore signature-related and manifest files // ignore signature-related and manifest files
continue; continue;
@ -1159,37 +1219,41 @@ public class JarSigner {
if (mfModified) { if (mfModified) {
ByteArrayOutputStream baos = new ByteArrayOutputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream();
manifest.write(baos); manifest.write(baos);
byte[] newBytes = baos.toByteArray(); if (wasSigned) {
if (mfRawBytes != null byte[] newBytes = baos.toByteArray();
&& oldAttr.equals(manifest.getMainAttributes())) { if (mfRawBytes != null
&& oldAttr.equals(manifest.getMainAttributes())) {
/* /*
* Note: * Note:
* *
* The Attributes object is based on HashMap and can handle * The Attributes object is based on HashMap and can handle
* continuation columns. Therefore, even if the contents are * continuation columns. Therefore, even if the contents are
* not changed (in a Map view), the bytes that it write() * not changed (in a Map view), the bytes that it write()
* may be different from the original bytes that it read() * may be different from the original bytes that it read()
* from. Since the signature on the main attributes is based * from. Since the signature on the main attributes is based
* on raw bytes, we must retain the exact bytes. * on raw bytes, we must retain the exact bytes.
*/ */
int newPos = findHeaderEnd(newBytes); int newPos = findHeaderEnd(newBytes);
int oldPos = findHeaderEnd(mfRawBytes); int oldPos = findHeaderEnd(mfRawBytes);
if (newPos == oldPos) { if (newPos == oldPos) {
System.arraycopy(mfRawBytes, 0, newBytes, 0, oldPos); System.arraycopy(mfRawBytes, 0, newBytes, 0, oldPos);
} else { } else {
// cat oldHead newTail > newBytes // cat oldHead newTail > newBytes
byte[] lastBytes = new byte[oldPos + byte[] lastBytes = new byte[oldPos +
newBytes.length - newPos]; newBytes.length - newPos];
System.arraycopy(mfRawBytes, 0, lastBytes, 0, oldPos); System.arraycopy(mfRawBytes, 0, lastBytes, 0, oldPos);
System.arraycopy(newBytes, newPos, lastBytes, oldPos, System.arraycopy(newBytes, newPos, lastBytes, oldPos,
newBytes.length - newPos); newBytes.length - newPos);
newBytes = lastBytes; newBytes = lastBytes;
}
} }
mfRawBytes = newBytes;
} else {
mfRawBytes = baos.toByteArray();
} }
mfRawBytes = newBytes;
} }
// Write out the manifest // Write out the manifest
@ -1222,7 +1286,7 @@ public class JarSigner {
try { try {
block = block =
sf.generateBlock(privateKey, sigalg, certChain, sf.generateBlock(privateKey, sigalg, certChain, crls,
externalSF, tsaUrl, tsaCert, signingMechanism, args, externalSF, tsaUrl, tsaCert, signingMechanism, args,
zipFile); zipFile);
} catch (SocketTimeoutException e) { } catch (SocketTimeoutException e) {
@ -1411,23 +1475,31 @@ public class JarSigner {
} }
/** /**
* 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) { private int findHeaderEnd(byte[] bs) {
// An empty line can be at the beginning... // Initial state true to deal with empty header
if (bs.length > 1 && bs[0] == '\r' && bs[1] == '\n') { boolean newline = true; // just met a newline
return 0; int len = bs.length;
} for (int i=0; i<len; i++) {
// ... or after another line switch (bs[i]) {
for (int i=0; i<bs.length-3; i++) { case '\r':
if (bs[i] == '\r' && bs[i+1] == '\n' && if (i < len && bs[i+1] == '\n') i++;
bs[i+2] == '\r' && bs[i+3] == '\n') { // fallthrough
return i; 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, // If header end is not found, it means the MANIFEST.MF has only
// which means no behavior change. // the main attributes section and it does not end with 2 newlines.
return 0; // Returns the whole length so that it can be completely replaced.
return len;
} }
/** /**
@ -2178,6 +2250,7 @@ class SignatureFile {
public Block generateBlock(PrivateKey privateKey, public Block generateBlock(PrivateKey privateKey,
String sigalg, String sigalg,
X509Certificate[] certChain, X509Certificate[] certChain,
Set<X509CRL> crls,
boolean externalSF, String tsaUrl, boolean externalSF, String tsaUrl,
X509Certificate tsaCert, X509Certificate tsaCert,
ContentSigner signingMechanism, ContentSigner signingMechanism,
@ -2185,7 +2258,7 @@ class SignatureFile {
throws NoSuchAlgorithmException, InvalidKeyException, IOException, throws NoSuchAlgorithmException, InvalidKeyException, IOException,
SignatureException, CertificateException SignatureException, CertificateException
{ {
return new Block(this, privateKey, sigalg, certChain, externalSF, return new Block(this, privateKey, sigalg, certChain, crls, externalSF,
tsaUrl, tsaCert, signingMechanism, args, zipFile); tsaUrl, tsaCert, signingMechanism, args, zipFile);
} }
@ -2199,7 +2272,8 @@ class SignatureFile {
* Construct a new signature block. * Construct a new signature block.
*/ */
Block(SignatureFile sfg, PrivateKey privateKey, String sigalg, 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, X509Certificate tsaCert, ContentSigner signingMechanism,
String[] args, ZipFile zipFile) String[] args, ZipFile zipFile)
throws NoSuchAlgorithmException, InvalidKeyException, IOException, throws NoSuchAlgorithmException, InvalidKeyException, IOException,
@ -2286,7 +2360,7 @@ class SignatureFile {
// Assemble parameters for the signing mechanism // Assemble parameters for the signing mechanism
ContentSignerParameters params = ContentSignerParameters params =
new JarSignerParameters(args, tsaUri, tsaCert, signature, new JarSignerParameters(args, tsaUri, tsaCert, signature,
signatureAlgorithm, certChain, content, zipFile); signatureAlgorithm, certChain, crls, content, zipFile);
// Generate the signature block // Generate the signature block
block = signingMechanism.generateSignedData( block = signingMechanism.generateSignedData(
@ -2327,6 +2401,7 @@ class JarSignerParameters implements ContentSignerParameters {
private byte[] signature; private byte[] signature;
private String signatureAlgorithm; private String signatureAlgorithm;
private X509Certificate[] signerCertificateChain; private X509Certificate[] signerCertificateChain;
private Set<X509CRL> crls;
private byte[] content; private byte[] content;
private ZipFile source; private ZipFile source;
@ -2335,7 +2410,8 @@ class JarSignerParameters implements ContentSignerParameters {
*/ */
JarSignerParameters(String[] args, URI tsa, X509Certificate tsaCertificate, JarSignerParameters(String[] args, URI tsa, X509Certificate tsaCertificate,
byte[] signature, String signatureAlgorithm, byte[] signature, String signatureAlgorithm,
X509Certificate[] signerCertificateChain, byte[] content, X509Certificate[] signerCertificateChain, Set<X509CRL> crls,
byte[] content,
ZipFile source) { ZipFile source) {
if (signature == null || signatureAlgorithm == null || if (signature == null || signatureAlgorithm == null ||
@ -2348,6 +2424,7 @@ class JarSignerParameters implements ContentSignerParameters {
this.signature = signature; this.signature = signature;
this.signatureAlgorithm = signatureAlgorithm; this.signatureAlgorithm = signatureAlgorithm;
this.signerCertificateChain = signerCertificateChain; this.signerCertificateChain = signerCertificateChain;
this.crls = crls;
this.content = content; this.content = content;
this.source = source; this.source = source;
} }
@ -2423,4 +2500,13 @@ class JarSignerParameters implements ContentSignerParameters {
public ZipFile getSource() { public ZipFile getSource() {
return source; return source;
} }
@Override
public Set<X509CRL> getCRLs() {
if (crls == null) {
return Collections.emptySet();
} else {
return Collections.unmodifiableSet(crls);
}
}
} }

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -74,6 +74,8 @@ public class JarSignerResources extends java.util.ListResourceBundle {
"[-digestalg <algorithm>] name of digest algorithm"}, "[-digestalg <algorithm>] name of digest algorithm"},
{"[-sigalg <algorithm>] name of signature algorithm", {"[-sigalg <algorithm>] name of signature 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",
"[-verify] verify a signed JAR file"}, "[-verify] verify a signed JAR file"},
{"[-verbose[:suboptions]] verbose output when signing/verifying.", {"[-verbose[:suboptions]] verbose output when signing/verifying.",
@ -191,6 +193,7 @@ public class JarSignerResources extends java.util.ListResourceBundle {
{"using an alternative signing mechanism", {"using an alternative signing mechanism",
"using an alternative signing mechanism"}, "using an alternative signing mechanism"},
{"entry was signed on", "entry was signed on {0}"}, {"entry was signed on", "entry was signed on {0}"},
{"with a CRL including %d entries", "with a CRL including %d entries"},
{"Warning: ", "Warning: "}, {"Warning: ", "Warning: "},
{"This jar contains unsigned entries which have not been integrity-checked. ", {"This jar contains unsigned entries which have not been integrity-checked. ",
"This jar contains unsigned entries which have not been integrity-checked. "}, "This jar contains unsigned entries which have not been integrity-checked. "},

View File

@ -25,6 +25,7 @@
package sun.security.tools; package sun.security.tools;
import sun.misc.SharedSecrets;
import java.io.*; import java.io.*;
import java.security.CodeSigner; import java.security.CodeSigner;
import java.security.KeyStore; import java.security.KeyStore;
@ -42,6 +43,7 @@ import java.security.Principal;
import java.security.Provider; import java.security.Provider;
import java.security.cert.Certificate; import java.security.cert.Certificate;
import java.security.cert.CertificateFactory; import java.security.cert.CertificateFactory;
import java.security.cert.CRL;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
import java.text.Collator; import java.text.Collator;
@ -50,14 +52,20 @@ import java.util.*;
import java.util.jar.JarEntry; import java.util.jar.JarEntry;
import java.util.jar.JarFile; import java.util.jar.JarFile;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.math.BigInteger;
import java.net.URI;
import java.net.URL; import java.net.URL;
import java.net.URLClassLoader; 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.misc.BASE64Encoder;
import sun.security.util.ObjectIdentifier; import sun.security.util.ObjectIdentifier;
import sun.security.pkcs.PKCS10; import sun.security.pkcs.PKCS10;
import sun.security.provider.X509Factory; import sun.security.provider.X509Factory;
import sun.security.util.DerOutputStream;
import sun.security.util.Password; import sun.security.util.Password;
import sun.security.util.PathList; import sun.security.util.PathList;
import javax.crypto.KeyGenerator; import javax.crypto.KeyGenerator;
@ -72,6 +80,7 @@ import javax.net.ssl.X509TrustManager;
import sun.misc.BASE64Decoder; import sun.misc.BASE64Decoder;
import sun.security.pkcs.PKCS10Attribute; import sun.security.pkcs.PKCS10Attribute;
import sun.security.pkcs.PKCS9Attribute; import sun.security.pkcs.PKCS9Attribute;
import sun.security.provider.certpath.ldap.LDAPCertStoreHelper;
import sun.security.util.DerValue; import sun.security.util.DerValue;
import sun.security.x509.*; import sun.security.x509.*;
@ -147,6 +156,7 @@ public final class KeyTool {
private Set<char[]> passwords = new HashSet<char[]> (); private Set<char[]> passwords = new HashSet<char[]> ();
private String startDate = null; private String startDate = null;
private List <String> ids = new ArrayList <String> (); // used in GENCRL
private List <String> v3ext = new ArrayList <String> (); private List <String> v3ext = new ArrayList <String> ();
enum Command { enum Command {
@ -180,9 +190,6 @@ public final class KeyTool {
STARTDATE, EXT, VALIDITY, KEYPASS, KEYSTORE, STARTDATE, EXT, VALIDITY, KEYPASS, KEYSTORE,
STOREPASS, STORETYPE, PROVIDERNAME, PROVIDERCLASS, STOREPASS, STORETYPE, PROVIDERNAME, PROVIDERCLASS,
PROVIDERARG, PROVIDERPATH, V, PROTECTED), 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", IMPORTCERT("Imports a certificate or a certificate chain",
NOPROMPT, TRUSTCACERTS, PROTECTED, ALIAS, FILEIN, NOPROMPT, TRUSTCACERTS, PROTECTED, ALIAS, FILEIN,
KEYPASS, KEYSTORE, STOREPASS, STORETYPE, KEYPASS, KEYSTORE, STOREPASS, STORETYPE,
@ -195,10 +202,6 @@ public final class KeyTool {
SRCALIAS, DESTALIAS, SRCKEYPASS, DESTKEYPASS, SRCALIAS, DESTALIAS, SRCKEYPASS, DESTKEYPASS,
NOPROMPT, PROVIDERCLASS, PROVIDERARG, PROVIDERPATH, NOPROMPT, PROVIDERCLASS, PROVIDERARG, PROVIDERPATH,
V), 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", KEYPASSWD("Changes the key password of an entry",
ALIAS, KEYPASS, NEW, KEYSTORE, STOREPASS, ALIAS, KEYPASS, NEW, KEYSTORE, STOREPASS,
STORETYPE, PROVIDERNAME, PROVIDERCLASS, PROVIDERARG, STORETYPE, PROVIDERNAME, PROVIDERCLASS, PROVIDERARG,
@ -211,12 +214,29 @@ public final class KeyTool {
RFC, FILEIN, SSLSERVER, JARFILE, V), RFC, FILEIN, SSLSERVER, JARFILE, V),
PRINTCERTREQ("Prints the content of a certificate request", PRINTCERTREQ("Prints the content of a certificate request",
FILEIN, V), 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", SELFCERT("Generates a self-signed certificate",
ALIAS, SIGALG, DNAME, STARTDATE, VALIDITY, KEYPASS, ALIAS, SIGALG, DNAME, STARTDATE, VALIDITY, KEYPASS,
STORETYPE, KEYSTORE, STOREPASS, PROVIDERNAME, STORETYPE, KEYSTORE, STOREPASS, PROVIDERNAME,
PROVIDERCLASS, PROVIDERARG, PROVIDERPATH, V), PROVIDERCLASS, PROVIDERARG, PROVIDERPATH, V),
STOREPASSWD("Changes the store password of a keystore", GENCRL("Generates CRL",
NEW, KEYSTORE, STOREPASS, STORETYPE, PROVIDERNAME, 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); PROVIDERCLASS, PROVIDERARG, PROVIDERPATH, V);
final String description; final String description;
@ -244,6 +264,7 @@ public final class KeyTool {
EXT("ext", "<value>", "X.509 extension"), EXT("ext", "<value>", "X.509 extension"),
FILEOUT("file", "<filename>", "output file name"), FILEOUT("file", "<filename>", "output file name"),
FILEIN("file", "<filename>", "input file name"), FILEIN("file", "<filename>", "input file name"),
ID("id", "<id:reason>", "Serial ID of cert to revoke"),
INFILE("infile", "<filename>", "input file name"), INFILE("infile", "<filename>", "input file name"),
KEYALG("keyalg", "<keyalg>", "key algorithm name"), KEYALG("keyalg", "<keyalg>", "key algorithm name"),
KEYPASS("keypass", "<arg>", "key password"), KEYPASS("keypass", "<arg>", "key password"),
@ -458,6 +479,8 @@ public final class KeyTool {
validity = Long.parseLong(args[++i]); validity = Long.parseLong(args[++i]);
} else if (collator.compare(flags, "-ext") == 0) { } else if (collator.compare(flags, "-ext") == 0) {
v3ext.add(args[++i]); v3ext.add(args[++i]);
} else if (collator.compare(flags, "-id") == 0) {
ids.add(args[++i]);
} else if (collator.compare(flags, "-file") == 0) { } else if (collator.compare(flags, "-file") == 0) {
filename = args[++i]; filename = args[++i];
} else if (collator.compare(flags, "-infile") == 0) { } else if (collator.compare(flags, "-infile") == 0) {
@ -720,7 +743,8 @@ public final class KeyTool {
command != GENSECKEY && command != GENSECKEY &&
command != IDENTITYDB && command != IDENTITYDB &&
command != IMPORTCERT && command != IMPORTCERT &&
command != IMPORTKEYSTORE) { command != IMPORTKEYSTORE &&
command != PRINTCRL) {
throw new Exception(rb.getString throw new Exception(rb.getString
("Keystore file does not exist: ") + ksfname); ("Keystore file does not exist: ") + ksfname);
} }
@ -855,10 +879,12 @@ public final class KeyTool {
&& !KeyStoreUtil.isWindowsKeyStore(storetype) && !KeyStoreUtil.isWindowsKeyStore(storetype)
&& isKeyStoreRelated(command)) { && isKeyStoreRelated(command)) {
// here we have EXPORTCERT and LIST (info valid until STOREPASSWD) // here we have EXPORTCERT and LIST (info valid until STOREPASSWD)
System.err.print(rb.getString("Enter keystore password: ")); if (command != PRINTCRL) {
System.err.flush(); System.err.print(rb.getString("Enter keystore password: "));
storePass = Password.readPassword(System.in); System.err.flush();
passwords.add(storePass); storePass = Password.readPassword(System.in);
passwords.add(storePass);
}
} }
// Now load a nullStream-based keystore, // Now load a nullStream-based keystore,
@ -895,7 +921,7 @@ public final class KeyTool {
// Create a certificate factory // Create a certificate factory
if (command == PRINTCERT || command == IMPORTCERT if (command == PRINTCERT || command == IMPORTCERT
|| command == IDENTITYDB) { || command == IDENTITYDB || command == PRINTCRL) {
cf = CertificateFactory.getInstance("X509"); cf = CertificateFactory.getInstance("X509");
} }
@ -1086,6 +1112,22 @@ public final class KeyTool {
ps.close(); 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) { } else if (command == PRINTCERTREQ) {
InputStream inStream = System.in; InputStream inStream = System.in;
if (filename != null) { if (filename != null) {
@ -1098,6 +1140,8 @@ public final class KeyTool {
inStream.close(); inStream.close();
} }
} }
} else if (command == PRINTCRL) {
doPrintCRL(filename, out);
} }
// If we need to save the keystore, do so. // If we need to save the keystore, do so.
@ -1152,7 +1196,8 @@ public final class KeyTool {
CertificateValidity interval = new CertificateValidity(firstDate, CertificateValidity interval = new CertificateValidity(firstDate,
lastDate); lastDate);
PrivateKey privateKey = (PrivateKey)recoverKey(alias, storePass, keyPass).fst; PrivateKey privateKey =
(PrivateKey)recoverKey(alias, storePass, keyPass).fst;
if (sigAlgName == null) { if (sigAlgName == null) {
sigAlgName = getCompatibleSigAlgName(privateKey.getAlgorithm()); sigAlgName = getCompatibleSigAlgName(privateKey.getAlgorithm());
} }
@ -1221,6 +1266,56 @@ public final class KeyTool {
} }
} }
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 * Creates a PKCS#10 cert signing request, corresponding to the
* keys (and name) associated with a given alias. * keys (and name) associated with a given alias.
@ -1925,6 +2020,177 @@ public final class KeyTool {
} }
} }
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) private void doPrintCertReq(InputStream in, PrintStream out)
throws Exception { throws Exception {
@ -2063,6 +2329,16 @@ public final class KeyTool {
out.println(); 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 @@ public final class KeyTool {
if (v.length == 0) { if (v.length == 0) {
out.println(rb.getString("(Empty value)")); out.println(rb.getString("(Empty value)"));
} else { } else {
new sun.misc.HexDumpEncoder().encode(ext.getExtensionValue(), out); new sun.misc.HexDumpEncoder().encodeBuffer(ext.getExtensionValue(), out);
out.println(); out.println();
} }
} }
@ -3330,15 +3606,22 @@ public final class KeyTool {
/** /**
* Match a command (may be abbreviated) with a command set. * Match a command (may be abbreviated) with a command set.
* @param s the command provided * @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 * @return the position of a single match, or -1 if none matched
* @throws Exception if s is ambiguous * @throws Exception if s is ambiguous
*/ */
private static int oneOf(String s, String... list) throws Exception { private static int oneOf(String s, String... list) throws Exception {
int[] match = new int[list.length]; int[] match = new int[list.length];
int nmatch = 0; int nmatch = 0;
int experiment = Integer.MAX_VALUE;
for (int i = 0; i<list.length; i++) { for (int i = 0; i<list.length; i++) {
String one = list[i]; String one = list[i];
if (one == null) {
experiment = i;
continue;
}
if (one.toLowerCase(Locale.ENGLISH) if (one.toLowerCase(Locale.ENGLISH)
.startsWith(s.toLowerCase(Locale.ENGLISH))) { .startsWith(s.toLowerCase(Locale.ENGLISH))) {
match[nmatch++] = i; match[nmatch++] = i;
@ -3360,17 +3643,27 @@ public final class KeyTool {
} }
} }
} }
if (nmatch == 0) return -1; if (nmatch == 0) {
if (nmatch == 1) return match[0]; return -1;
StringBuffer sb = new StringBuffer(); } else if (nmatch == 1) {
MessageFormat form = new MessageFormat(rb.getString return match[0];
("command {0} is ambiguous:")); } else {
Object[] source = {s}; // If multiple matches is in experimental commands, ignore them
sb.append(form.format(source) +"\n "); if (match[1] > experiment) {
for (int i=0; i<nmatch; i++) { return match[0];
sb.append(" " + list[match[i]]); }
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 @@ public final class KeyTool {
"IssuerAlternativeName", "IssuerAlternativeName",
"SubjectInfoAccess", "SubjectInfoAccess",
"AuthorityInfoAccess", "AuthorityInfoAccess",
null,
"CRLDistributionPoints",
}; };
private ObjectIdentifier findOidForExtName(String type) private ObjectIdentifier findOidForExtName(String type)
@ -3417,6 +3712,7 @@ public final class KeyTool {
case 4: return PKIXExtensions.IssuerAlternativeName_Id; case 4: return PKIXExtensions.IssuerAlternativeName_Id;
case 5: return PKIXExtensions.SubjectInfoAccess_Id; case 5: return PKIXExtensions.SubjectInfoAccess_Id;
case 6: return PKIXExtensions.AuthInfoAccess_Id; case 6: return PKIXExtensions.AuthInfoAccess_Id;
case 8: return PKIXExtensions.CRLDistributionPoints_Id;
default: return new ObjectIdentifier(type); default: return new ObjectIdentifier(type);
} }
} }
@ -3712,6 +4008,28 @@ public final class KeyTool {
("Illegal value: ") + extstr); ("Illegal value: ") + extstr);
} }
break; 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: case -1:
ObjectIdentifier oid = new ObjectIdentifier(name); ObjectIdentifier oid = new ObjectIdentifier(name);
byte[] data = null; byte[] data = null;
@ -3748,6 +4066,9 @@ public final class KeyTool {
new DerValue(DerValue.tag_OctetString, data) new DerValue(DerValue.tag_OctetString, data)
.toByteArray())); .toByteArray()));
break; break;
default:
throw new Exception(rb.getString(
"Unknown extension type: ") + extstr);
} }
} }
// always non-critical // always non-critical
@ -3810,11 +4131,8 @@ public final class KeyTool {
System.err.println(rb.getString("Commands:")); System.err.println(rb.getString("Commands:"));
System.err.println(); System.err.println();
for (Command c: Command.values()) { for (Command c: Command.values()) {
if (c != IDENTITYDB if (c == KEYCLONE) break;
&& c != KEYCLONE System.err.printf(" %-20s%s\n", c, rb.getString(c.description));
&& c != SELFCERT) { // Deprecated commands
System.err.printf(" %-20s%s\n", c, rb.getString(c.description));
}
} }
System.err.println(); System.err.println();
System.err.println(rb.getString( System.err.println(rb.getString(

View File

@ -38,6 +38,7 @@ import java.security.cert.X509Certificate;
import java.util.List; import java.util.List;
import com.sun.jarsigner.*; import com.sun.jarsigner.*;
import java.security.cert.X509CRL;
import java.util.Arrays; import java.util.Arrays;
import sun.security.pkcs.*; import sun.security.pkcs.*;
import sun.security.timestamp.*; import sun.security.timestamp.*;
@ -239,7 +240,7 @@ public final class TimestampedSigner extends ContentSigner {
// Create the PKCS #7 signed data message // Create the PKCS #7 signed data message
PKCS7 p7 = PKCS7 p7 =
new PKCS7(algorithms, contentInfo, signerCertificateChain, new PKCS7(algorithms, contentInfo, signerCertificateChain,
signerInfos); parameters.getCRLs().toArray(new X509CRL[parameters.getCRLs().size()]), signerInfos);
ByteArrayOutputStream p7out = new ByteArrayOutputStream(); ByteArrayOutputStream p7out = new ByteArrayOutputStream();
p7.encodeSignedData(p7out); p7.encodeSignedData(p7out);

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -71,6 +71,7 @@ public class Resources extends java.util.ListResourceBundle {
"Generates a secret key"}, //-genseckey "Generates a secret key"}, //-genseckey
{"Generates certificate from a certificate request", {"Generates certificate from a certificate request",
"Generates certificate from a certificate request"}, //-gencert "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",
"Imports entries from a JDK 1.1.x-style identity database"}, //-identitydb "Imports entries from a JDK 1.1.x-style identity database"}, //-identitydb
{"Imports a certificate or a certificate chain", {"Imports a certificate or a certificate chain",
@ -87,6 +88,8 @@ public class Resources extends java.util.ListResourceBundle {
"Prints the content of a certificate"}, //-printcert "Prints the content of a certificate"}, //-printcert
{"Prints the content of a certificate request", {"Prints the content of a certificate request",
"Prints the content of a certificate request"}, //-printcertreq "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",
"Generates a self-signed certificate"}, //-selfcert "Generates a self-signed certificate"}, //-selfcert
{"Changes the store password of a keystore", {"Changes the store password of a keystore",
@ -176,6 +179,8 @@ public class Resources extends java.util.ListResourceBundle {
"verbose output"}, //-v "verbose output"}, //-v
{"validity number of days", {"validity number of days",
"validity number of days"}, //-validity "validity number of days"}, //-validity
{"Serial ID of cert to revoke",
"Serial ID of cert to revoke"}, //-id
// keytool: Running part // keytool: Running part
{"keytool error: ", "keytool error: "}, {"keytool error: ", "keytool error: "},
{"Illegal option: ", "Illegal option: "}, {"Illegal option: ", "Illegal option: "},
@ -375,6 +380,7 @@ public class Resources extends java.util.ListResourceBundle {
{"Signer #%d:", "Signer #%d:"}, {"Signer #%d:", "Signer #%d:"},
{"Timestamp:", "Timestamp:"}, {"Timestamp:", "Timestamp:"},
{"Signature:", "Signature:"}, {"Signature:", "Signature:"},
{"CRLs:", "CRLs:"},
{"Certificate owner: ", "Certificate owner: "}, {"Certificate owner: ", "Certificate owner: "},
{"Not a signed jar file", "Not a signed jar file"}, {"Not a signed jar file", "Not a signed jar file"},
{"No certificate from the SSL server", {"No certificate from the SSL server",
@ -433,6 +439,7 @@ public class Resources extends java.util.ListResourceBundle {
{"This extension cannot be marked as critical. ", {"This extension cannot be marked as critical. ",
"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: "}, {"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:"}, {"command {0} is ambiguous:", "command {0} is ambiguous:"},
// policytool // policytool

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,7 +25,6 @@
package sun.security.util; package sun.security.util;
import java.security.CodeSigner;
import java.security.cert.CertPath; import java.security.cert.CertPath;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
@ -34,11 +33,11 @@ import java.security.*;
import java.io.*; import java.io.*;
import java.util.*; import java.util.*;
import java.util.jar.*; import java.util.jar.*;
import java.io.ByteArrayOutputStream;
import sun.security.pkcs.*; import sun.security.pkcs.*;
import sun.security.timestamp.TimestampToken; import sun.security.timestamp.TimestampToken;
import sun.misc.BASE64Decoder; import sun.misc.BASE64Decoder;
import sun.misc.SharedSecrets;
import sun.security.jca.Providers; import sun.security.jca.Providers;
@ -479,7 +478,12 @@ public class SignatureFileVerifier {
signers = new ArrayList<CodeSigner>(); signers = new ArrayList<CodeSigner>();
} }
// Append the new code signer // 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) { if (debug != null) {
debug.println("Signature Block Certificate: " + debug.println("Signature Block Certificate: " +

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -89,7 +89,7 @@ import sun.misc.HexDumpEncoder;
* @author Hemma Prafullchandra * @author Hemma Prafullchandra
* @see X509CRL * @see X509CRL
*/ */
public class X509CRLImpl extends X509CRL { public class X509CRLImpl extends X509CRL implements DerEncoder {
// CRL data, and its envelope // CRL data, and its envelope
private byte[] signedCRL = null; // DER encoded crl private byte[] signedCRL = null; // DER encoded crl
@ -1189,6 +1189,13 @@ public class X509CRLImpl extends X509CRL {
} }
} }
@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 * Immutable X.509 Certificate Issuer DN and serial number pair
*/ */

View File

@ -314,4 +314,27 @@ public abstract class UNIXToolkit extends SunToolkit
} }
return new RenderingHints(KEY_TEXT_ANTIALIASING, aaHint); 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;
}
} }

View File

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

View File

@ -1054,7 +1054,9 @@ public final class XToolkit extends UNIXToolkit implements Runnable {
} }
public FileDialogPeer createFileDialog(FileDialog target) { 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); targetCreatedPeer(target, peer);
return peer; return peer;
} }

View File

@ -260,3 +260,23 @@ Java_sun_awt_SunToolkit_closeSplashScreen(JNIEnv *env, jclass cls)
} }
dlclose(hSplashLib); 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;
}

View File

@ -32,6 +32,7 @@
#include "java_awt_Transparency.h" #include "java_awt_Transparency.h"
#define GTK2_LIB "libgtk-x11-2.0.so.0" #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_INVALID G_TYPE_MAKE_FUNDAMENTAL (0)
#define G_TYPE_NONE G_TYPE_MAKE_FUNDAMENTAL (1) #define G_TYPE_NONE G_TYPE_MAKE_FUNDAMENTAL (1)
@ -75,6 +76,8 @@ const gint SELECTED = 1 << 9;
const gint DEFAULT = 1 << 10; const gint DEFAULT = 1 << 10;
static void *gtk2_libhandle = NULL; static void *gtk2_libhandle = NULL;
static void *gthread_libhandle = NULL;
static gboolean flag_g_thread_get_initialized = FALSE;
static jmp_buf j; static jmp_buf j;
/* Widgets */ /* Widgets */
@ -150,7 +153,6 @@ static GtkWidget *gtk2_widgets[_GTK_WIDGET_TYPE_SIZE];
/************************* /*************************
* Glib function pointers * Glib function pointers
*************************/ *************************/
static void (*fp_g_free)(gpointer mem);
static gboolean (*fp_g_main_context_iteration)(GMainContext *context, static gboolean (*fp_g_main_context_iteration)(GMainContext *context,
gboolean may_block); gboolean may_block);
@ -204,9 +206,6 @@ static void (*fp_gdk_drawable_get_size)(GdkDrawable *drawable,
/************************ /************************
* Gtk function pointers * 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); static gboolean (*fp_gtk_init_check)(int* argc, char** argv);
/* Painting */ /* Painting */
@ -330,7 +329,6 @@ static void (*fp_gtk_menu_shell_append)(GtkMenuShell *menu_shell,
static void (*fp_gtk_menu_item_set_submenu)(GtkMenuItem *menu_item, static void (*fp_gtk_menu_item_set_submenu)(GtkMenuItem *menu_item,
GtkWidget *submenu); GtkWidget *submenu);
static void (*fp_gtk_widget_realize)(GtkWidget *widget); 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, static GdkPixbuf* (*fp_gtk_widget_render_icon)(GtkWidget *widget,
const gchar *stock_id, GtkIconSize size, const gchar *detail); const gchar *stock_id, GtkIconSize size, const gchar *detail);
static void (*fp_gtk_widget_set_name)(GtkWidget *widget, const gchar *name); static void (*fp_gtk_widget_set_name)(GtkWidget *widget, const gchar *name);
@ -388,6 +386,15 @@ static void* dl_symbol(const char* name)
return result; 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() gboolean gtk2_check_version()
{ {
if (gtk2_libhandle != NULL) { if (gtk2_libhandle != NULL) {
@ -414,6 +421,35 @@ gboolean gtk2_check_version()
} }
} }
/**
* 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 gtk2_load()
{ {
gboolean result; gboolean result;
@ -423,7 +459,9 @@ gboolean gtk2_load()
char *gtk_modules_env; char *gtk_modules_env;
gtk2_libhandle = dlopen(GTK2_LIB, RTLD_LAZY | RTLD_LOCAL); 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; return FALSE;
if (setjmp(j) == 0) if (setjmp(j) == 0)
@ -597,6 +635,28 @@ gboolean gtk2_load()
fp_gtk_range_get_adjustment = fp_gtk_range_get_adjustment =
dl_symbol("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. /* Some functions may be missing in pre-2.4 GTK.
We handle them specially here. We handle them specially here.
*/ */
@ -626,6 +686,10 @@ gboolean gtk2_load()
{ {
dlclose(gtk2_libhandle); dlclose(gtk2_libhandle);
gtk2_libhandle = NULL; gtk2_libhandle = NULL;
dlclose(gthread_libhandle);
gthread_libhandle = NULL;
return FALSE; return FALSE;
} }
@ -678,6 +742,19 @@ gboolean gtk2_load()
*/ */
handler = XSetErrorHandler(NULL); handler = XSetErrorHandler(NULL);
io_handler = XSetIOErrorHandler(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); result = (*fp_gtk_init_check)(NULL, NULL);
XSetErrorHandler(handler); XSetErrorHandler(handler);
@ -722,6 +799,7 @@ int gtk2_unload()
dlerror(); dlerror();
dlclose(gtk2_libhandle); dlclose(gtk2_libhandle);
dlclose(gthread_libhandle);
if ((gtk2_error = dlerror()) != NULL) if ((gtk2_error = dlerror()) != NULL)
{ {
return FALSE; return FALSE;

View File

@ -28,6 +28,21 @@
#include <stdlib.h> #include <stdlib.h>
#include <jni.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 typedef enum _WidgetType
{ {
BUTTON, /* GtkButton */ BUTTON, /* GtkButton */
@ -254,7 +269,13 @@ typedef enum
/* We define all structure pointers to be void* */ /* We define all structure pointers to be void* */
typedef void GError; typedef void GError;
typedef void GMainContext; typedef void GMainContext;
typedef void GSList;
typedef struct _GSList GSList;
struct _GSList
{
gpointer data;
GSList *next;
};
typedef void GdkColormap; typedef void GdkColormap;
typedef void GdkDrawable; typedef void GdkDrawable;
@ -556,6 +577,65 @@ struct _GtkProgressBar
guint ellipsize : 3; 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. * Converts java.lang.String object to UTF-8 character string.
*/ */
@ -569,6 +649,13 @@ const char *getStrFor(JNIEnv *env, jstring value);
*/ */
gboolean gtk2_check_version(); 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 * Load the gtk2 library. If the library is already loaded this method has no
* effect and returns success. * effect and returns success.
@ -651,6 +738,7 @@ jobject gtk2_get_setting(JNIEnv *env, Setting property);
void gtk2_set_range_value(WidgetType widget_type, jdouble value, void gtk2_set_range_value(WidgetType widget_type, jdouble value,
jdouble min, jdouble max, jdouble visible); jdouble min, jdouble max, jdouble visible);
void (*fp_g_free)(gpointer mem);
void (*fp_g_object_unref)(gpointer object); void (*fp_g_object_unref)(gpointer object);
int (*fp_gdk_pixbuf_get_bits_per_sample)(const GdkPixbuf *pixbuf); int (*fp_gdk_pixbuf_get_bits_per_sample)(const GdkPixbuf *pixbuf);
guchar *(*fp_gdk_pixbuf_get_pixels)(const GdkPixbuf *pixbuf); guchar *(*fp_gdk_pixbuf_get_pixels)(const GdkPixbuf *pixbuf);
@ -660,5 +748,47 @@ int (*fp_gdk_pixbuf_get_n_channels)(const GdkPixbuf *pixbuf);
int (*fp_gdk_pixbuf_get_rowstride)(const GdkPixbuf *pixbuf); int (*fp_gdk_pixbuf_get_rowstride)(const GdkPixbuf *pixbuf);
int (*fp_gdk_pixbuf_get_width)(const GdkPixbuf *pixbuf); int (*fp_gdk_pixbuf_get_width)(const GdkPixbuf *pixbuf);
GdkPixbuf *(*fp_gdk_pixbuf_new_from_file)(const char *filename, GError **error); 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 */ #endif /* !_GTK2_INTERFACE_H */

View File

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

View File

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

View File

@ -38,8 +38,10 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1arrow(
jint widget_type, jint state, jint shadow_type, jstring detail, jint widget_type, jint state, jint shadow_type, jstring detail,
jint x, jint y, jint w, jint h, jint arrow_type) 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), gtk2_paint_arrow(widget_type, state, shadow_type, getStrFor(env, detail),
x, y, w, h, arrow_type, TRUE); x, y, w, h, arrow_type, TRUE);
fp_gdk_threads_leave();
} }
/* /*
@ -54,8 +56,10 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1box(
jint x, jint y, jint w, jint h, jint x, jint y, jint w, jint h,
jint synth_state, jint dir) jint synth_state, jint dir)
{ {
fp_gdk_threads_enter();
gtk2_paint_box(widget_type, state, shadow_type, getStrFor(env, detail), gtk2_paint_box(widget_type, state, shadow_type, getStrFor(env, detail),
x, y, w, h, synth_state, dir); x, y, w, h, synth_state, dir);
fp_gdk_threads_leave();
} }
/* /*
@ -70,8 +74,10 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1box_1gap(
jint x, jint y, jint w, jint h, jint x, jint y, jint w, jint h,
jint gap_side, jint gap_x, jint gap_w) 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), gtk2_paint_box_gap(widget_type, state, shadow_type, getStrFor(env, detail),
x, y, w, h, gap_side, gap_x, gap_w); x, y, w, h, gap_side, gap_x, gap_w);
fp_gdk_threads_leave();
} }
/* /*
@ -85,8 +91,10 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1check(
jint widget_type, jint synth_state, jstring detail, jint widget_type, jint synth_state, jstring detail,
jint x, jint y, jint w, jint h) jint x, jint y, jint w, jint h)
{ {
fp_gdk_threads_enter();
gtk2_paint_check(widget_type, synth_state, getStrFor(env, detail), gtk2_paint_check(widget_type, synth_state, getStrFor(env, detail),
x, y, w, h); x, y, w, h);
fp_gdk_threads_leave();
} }
/* /*
@ -100,8 +108,10 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1expander(
jint widget_type, jint state, jstring detail, jint widget_type, jint state, jstring detail,
jint x, jint y, jint w, jint h, jint expander_style) jint x, jint y, jint w, jint h, jint expander_style)
{ {
fp_gdk_threads_enter();
gtk2_paint_expander(widget_type, state, getStrFor(env, detail), gtk2_paint_expander(widget_type, state, getStrFor(env, detail),
x, y, w, h, expander_style); x, y, w, h, expander_style);
fp_gdk_threads_leave();
} }
/* /*
@ -115,8 +125,10 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1extension(
jint widget_type, jint state, jint shadow_type, jstring detail, jint widget_type, jint state, jint shadow_type, jstring detail,
jint x, jint y, jint w, jint h, jint placement) jint x, jint y, jint w, jint h, jint placement)
{ {
fp_gdk_threads_enter();
gtk2_paint_extension(widget_type, state, shadow_type, gtk2_paint_extension(widget_type, state, shadow_type,
getStrFor(env, detail), x, y, w, h, placement); getStrFor(env, detail), x, y, w, h, placement);
fp_gdk_threads_leave();
} }
/* /*
@ -130,8 +142,10 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1flat_1box(
jint widget_type, jint state, jint shadow_type, jstring detail, jint widget_type, jint state, jint shadow_type, jstring detail,
jint x, jint y, jint w, jint h, jboolean has_focus) jint x, jint y, jint w, jint h, jboolean has_focus)
{ {
fp_gdk_threads_enter();
gtk2_paint_flat_box(widget_type, state, shadow_type, gtk2_paint_flat_box(widget_type, state, shadow_type,
getStrFor(env, detail), x, y, w, h, has_focus); getStrFor(env, detail), x, y, w, h, has_focus);
fp_gdk_threads_leave();
} }
/* /*
@ -145,8 +159,10 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1focus(
jint widget_type, jint state, jstring detail, jint widget_type, jint state, jstring detail,
jint x, jint y, jint w, jint h) jint x, jint y, jint w, jint h)
{ {
fp_gdk_threads_enter();
gtk2_paint_focus(widget_type, state, getStrFor(env, detail), gtk2_paint_focus(widget_type, state, getStrFor(env, detail),
x, y, w, h); x, y, w, h);
fp_gdk_threads_leave();
} }
/* /*
@ -160,8 +176,10 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1handle(
jint widget_type, jint state, jint shadow_type, jstring detail, jint widget_type, jint state, jint shadow_type, jstring detail,
jint x, jint y, jint w, jint h, jint orientation) 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), gtk2_paint_handle(widget_type, state, shadow_type, getStrFor(env, detail),
x, y, w, h, orientation); x, y, w, h, orientation);
fp_gdk_threads_leave();
} }
/* /*
@ -175,8 +193,10 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1hline(
jint widget_type, jint state, jstring detail, jint widget_type, jint state, jstring detail,
jint x, jint y, jint w, jint h) jint x, jint y, jint w, jint h)
{ {
fp_gdk_threads_enter();
gtk2_paint_hline(widget_type, state, getStrFor(env, detail), gtk2_paint_hline(widget_type, state, getStrFor(env, detail),
x, y, w, h); x, y, w, h);
fp_gdk_threads_leave();
} }
/* /*
@ -190,8 +210,10 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1option(
jint widget_type, jint synth_state, jstring detail, jint widget_type, jint synth_state, jstring detail,
jint x, jint y, jint w, jint h) jint x, jint y, jint w, jint h)
{ {
fp_gdk_threads_enter();
gtk2_paint_option(widget_type, synth_state, getStrFor(env, detail), gtk2_paint_option(widget_type, synth_state, getStrFor(env, detail),
x, y, w, h); x, y, w, h);
fp_gdk_threads_leave();
} }
/* /*
@ -206,8 +228,10 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1shadow(
jint x, jint y, jint w, jint h, jint x, jint y, jint w, jint h,
jint synth_state, jint dir) jint synth_state, jint dir)
{ {
fp_gdk_threads_enter();
gtk2_paint_shadow(widget_type, state, shadow_type, getStrFor(env, detail), gtk2_paint_shadow(widget_type, state, shadow_type, getStrFor(env, detail),
x, y, w, h, synth_state, dir); x, y, w, h, synth_state, dir);
fp_gdk_threads_leave();
} }
/* /*
@ -221,8 +245,10 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1slider(
jint widget_type, jint state, jint shadow_type, jstring detail, jint widget_type, jint state, jint shadow_type, jstring detail,
jint x, jint y, jint w, jint h, jint orientation) 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), gtk2_paint_slider(widget_type, state, shadow_type, getStrFor(env, detail),
x, y, w, h, orientation); x, y, w, h, orientation);
fp_gdk_threads_leave();
} }
/* /*
@ -236,8 +262,10 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1vline(
jint widget_type, jint state, jstring detail, jint widget_type, jint state, jstring detail,
jint x, jint y, jint w, jint h) jint x, jint y, jint w, jint h)
{ {
fp_gdk_threads_enter();
gtk2_paint_vline(widget_type, state, getStrFor(env, detail), gtk2_paint_vline(widget_type, state, getStrFor(env, detail),
x, y, w, h); x, y, w, h);
fp_gdk_threads_leave();
} }
/* /*
@ -250,7 +278,9 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1background(
JNIEnv *env, jobject this, jint widget_type, jint state, JNIEnv *env, jobject this, jint widget_type, jint state,
jint x, jint y, jint w, jint h) jint x, jint y, jint w, jint h)
{ {
fp_gdk_threads_enter();
gtk_paint_background(widget_type, state, x, y, w, h); gtk_paint_background(widget_type, state, x, y, w, h);
fp_gdk_threads_leave();
} }
/* /*
@ -262,7 +292,9 @@ JNIEXPORT void JNICALL
Java_com_sun_java_swing_plaf_gtk_GTKEngine_nativeStartPainting( Java_com_sun_java_swing_plaf_gtk_GTKEngine_nativeStartPainting(
JNIEnv *env, jobject this, jint w, jint h) JNIEnv *env, jobject this, jint w, jint h)
{ {
fp_gdk_threads_enter();
gtk2_init_painting(w, h); gtk2_init_painting(w, h);
fp_gdk_threads_leave();
} }
/* /*
@ -276,7 +308,9 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_nativeFinishPainting(
{ {
jint transparency; jint transparency;
gint *buffer = (gint*) (*env)->GetPrimitiveArrayCritical(env, dest, 0); gint *buffer = (gint*) (*env)->GetPrimitiveArrayCritical(env, dest, 0);
fp_gdk_threads_enter();
transparency = gtk2_copy_image(buffer, width, height); transparency = gtk2_copy_image(buffer, width, height);
fp_gdk_threads_leave();
(*env)->ReleasePrimitiveArrayCritical(env, dest, buffer, 0); (*env)->ReleasePrimitiveArrayCritical(env, dest, buffer, 0);
return transparency; return transparency;
} }
@ -289,7 +323,9 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_nativeFinishPainting(
JNIEXPORT void JNICALL Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1switch_1theme( JNIEXPORT void JNICALL Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1switch_1theme(
JNIEnv *env, jobject this) JNIEnv *env, jobject this)
{ {
fp_gdk_threads_enter();
flush_gtk_event_loop(); flush_gtk_event_loop();
fp_gdk_threads_leave();
} }
/* /*
@ -300,7 +336,11 @@ JNIEXPORT void JNICALL Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1switch
JNIEXPORT jobject JNICALL Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1get_1gtk_1setting( JNIEXPORT jobject JNICALL Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1get_1gtk_1setting(
JNIEnv *env, jobject this, jint property) 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 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_nativeSetRangeValue(
JNIEnv *env, jobject this, jint widget_type, JNIEnv *env, jobject this, jint widget_type,
jdouble value, jdouble min, jdouble max, jdouble visible) jdouble value, jdouble min, jdouble max, jdouble visible)
{ {
fp_gdk_threads_enter();
gtk2_set_range_value(widget_type, value, min, max, visible); gtk2_set_range_value(widget_type, value, min, max, visible);
fp_gdk_threads_leave();
} }

View File

@ -36,7 +36,11 @@ JNIEXPORT jint JNICALL
Java_com_sun_java_swing_plaf_gtk_GTKStyle_nativeGetXThickness( Java_com_sun_java_swing_plaf_gtk_GTKStyle_nativeGetXThickness(
JNIEnv *env, jclass klass, jint widget_type) 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 @@ JNIEXPORT jint JNICALL
Java_com_sun_java_swing_plaf_gtk_GTKStyle_nativeGetYThickness( Java_com_sun_java_swing_plaf_gtk_GTKStyle_nativeGetYThickness(
JNIEnv *env, jclass klass, jint widget_type) 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 @@ Java_com_sun_java_swing_plaf_gtk_GTKStyle_nativeGetColorForState(
JNIEnv *env, jclass klass, jint widget_type, JNIEnv *env, jclass klass, jint widget_type,
jint state_type, jint type_id) 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 @@ JNIEXPORT jobject JNICALL
Java_com_sun_java_swing_plaf_gtk_GTKStyle_nativeGetClassValue( Java_com_sun_java_swing_plaf_gtk_GTKStyle_nativeGetClassValue(
JNIEnv *env, jclass klass, jint widget_type, jstring key) 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 @@ JNIEXPORT jstring JNICALL
Java_com_sun_java_swing_plaf_gtk_GTKStyle_nativeGetPangoFontName( Java_com_sun_java_swing_plaf_gtk_GTKStyle_nativeGetPangoFontName(
JNIEnv *env, jclass klass, jint widget_type) 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;
} }

View File

@ -403,9 +403,14 @@ public class Win32ShellFolderManager2 extends ShellFolderManager {
} }
} }
String path = dir.getPath(); String path = dir.getPath();
return (path.length() == 3
&& path.charAt(1) == ':' if (path.length() != 3 || path.charAt(1) != ':') {
&& Arrays.asList(drives.listFiles()).contains(dir)); return false;
}
File[] files = drives.listFiles();
return files != null && Arrays.asList(files).contains(dir);
} }
return false; return false;
} }

View File

@ -222,7 +222,8 @@ LPFN_GETNAMEINFO getnameinfo_ptr;
#define IN6_IS_ADDR_ANY(a) \ #define IN6_IS_ADDR_ANY(a) \
(((a)->s6_words[0] == 0) && ((a)->s6_words[1] == 0) && \ (((a)->s6_words[0] == 0) && ((a)->s6_words[1] == 0) && \
((a)->s6_words[2] == 0) && ((a)->s6_words[3] == 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 #endif
#ifndef IPV6_V6ONLY #ifndef IPV6_V6ONLY

View File

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

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -23,7 +23,7 @@
/* /*
* @test * @test
* @bug 6843181 * @bug 6843181 6943963
* @summary Confirm that NumericShaper is thread-safe. * @summary Confirm that NumericShaper is thread-safe.
* @run main/timeout=300/othervm MTTest * @run main/timeout=300/othervm MTTest
*/ */
@ -37,33 +37,34 @@ public class MTTest {
static volatile boolean runrun = true; static volatile boolean runrun = true;
static volatile boolean err = false; static volatile boolean err = false;
final static String text = "-123 (English) 456.00 (Arabic) \u0641\u0642\u0643 -789 (Thai) \u0e01\u0e33 01.23"; final static String text = "-123 (English) 456.00 (Arabic) \u0641\u0642\u0643 -456 (Thai) \u0e01\u0e33 01.23";
static char[] t1, t2; 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; static NumericShaper ns1, ns2, ns3, ns4;
public static void main(String[] args) { public static void main(String[] args) {
System.out.println(" original: " + text); System.out.println("original: " + text);
ns1 = getContextualShaper(EnumSet.of(Range.ARABIC), Range.ARABIC); ns1 = getContextualShaper(EnumSet.of(Range.EASTERN_ARABIC, Range.THAI),
t1 = text.toCharArray(); Range.EUROPEAN);
ns1.shape(t1, 0, t1.length); ns2 = getContextualShaper(EnumSet.of(Range.ARABIC, Range.THAI),
System.out.println("expected t1: " + String.valueOf(t1)); Range.EUROPEAN);
System.out.println("expected for Eastern-Arabic & Thai: " +
String.valueOf(expected1));
System.out.println("expected for Arabic & Thai: " +
String.valueOf(expected2));
ns2 = getContextualShaper(EnumSet.of(Range.THAI), Range.THAI); ns3 = getContextualShaper(EASTERN_ARABIC|THAI, EUROPEAN);
t2 = text.toCharArray(); ns4 = getContextualShaper(ARABIC|THAI, EUROPEAN);
ns2.shape(t2, 0, t2.length);
System.out.println("expected t2: " + String.valueOf(t2));
ns3 = getContextualShaper(ARABIC, ARABIC); Thread th1 = new Thread(new Work(ns1, expected1));
ns4 = getContextualShaper(THAI, THAI); Thread th2 = new Thread(new Work(ns2, expected2));
Thread th3 = new Thread(new Work(ns1, expected1));
Thread th1 = new Thread(new Work(ns1, t1)); Thread th4 = new Thread(new Work(ns2, expected2));
Thread th2 = new Thread(new Work(ns2, t2)); Thread th5 = new Thread(new Work(ns3, expected1));
Thread th3 = new Thread(new Work(ns1, t1)); Thread th6 = new Thread(new Work(ns4, expected2));
Thread th4 = new Thread(new Work(ns2, t2)); Thread th7 = new Thread(new Work(ns3, expected1));
Thread th5 = new Thread(new Work(ns3, t1)); Thread th8 = new Thread(new Work(ns4, expected2));
Thread th6 = new Thread(new Work(ns4, t2));
Thread th7 = new Thread(new Work(ns3, t1));
Thread th8 = new Thread(new Work(ns4, t2));
th1.start(); th1.start();
th2.start(); th2.start();
@ -110,8 +111,8 @@ public class MTTest {
int count = 0; int count = 0;
while (runrun) { while (runrun) {
char[] t = text.toCharArray(); char[] t = text.toCharArray();
count++;
try { try {
count++;
ns.shape(t, 0, t.length); ns.shape(t, 0, t.length);
} catch (Exception e) { } catch (Exception e) {
System.err.println("Error: Unexpected exception: " + e); System.err.println("Error: Unexpected exception: " + e);

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -23,7 +23,7 @@
/* /*
* @test * @test
* @bug 6842557 * @bug 6842557 6943963
* @summary confirm that shaping works as expected. (Mainly for new characters which were added in Unicode 5) * @summary confirm that shaping works as expected. (Mainly for new characters which were added in Unicode 5)
* used where appropriate. * used where appropriate.
*/ */
@ -33,15 +33,25 @@ import java.util.EnumSet;
import static java.awt.font.NumericShaper.*; import static java.awt.font.NumericShaper.*;
public class ShapingTest { public class ShapingTest {
private static boolean err = false;
public static void main(String[] args) { 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, NumericShaper ns_old = getContextualShaper(ARABIC | TAMIL | ETHIOPIC,
EUROPEAN); EUROPEAN);
NumericShaper ns_new = getContextualShaper(EnumSet.of( NumericShaper ns_new = getContextualShaper(EnumSet.of(
Range.ARABIC, Range.TAMIL, Range.ETHIOPIC), Range.ARABIC, Range.TAMIL, Range.ETHIOPIC),
Range.EUROPEAN); Range.EUROPEAN);
boolean err = false;
String[][] data = { String[][] data = {
// Arabic "October 10" // Arabic "October 10"
{"\u0623\u0643\u062a\u0648\u0628\u0631 10", {"\u0623\u0643\u062a\u0648\u0628\u0631 10",
@ -60,45 +70,62 @@ public class ShapingTest {
}; };
for (int i = 0; i < data.length; i++) { 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(); checkResult("Range.ARABIC, Range.TAMIL, Range.ETHIOPIC",
ns_old.shape(text, 0, text.length); ns_new, data[i][0], data[i][1]);
String got = new String(text);
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);
}
text = data[i][0].toCharArray();
ns_new.shape(text, 0, text.length);
got = new String(text);
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);
}
} }
}
if (err) { private static void test6943963() {
throw new RuntimeException("shape() returned unexpected value."); // 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);
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);
}
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 (!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);
} }
} }

View File

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

View File

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

View File

@ -33,18 +33,54 @@
/* /*
* @test * @test
* @bug 4949279 * @bug 4949279 6937857
* @summary Independent instantiations of Random() have distinct seeds. * @summary Independent instantiations of Random() have distinct seeds.
*/ */
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Random; import java.util.Random;
public class DistinctSeeds { public class DistinctSeeds {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
// Strictly speaking, it is possible for these to randomly fail, // 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() || if (new Random().nextLong() == new Random().nextLong() ||
new Random().nextLong() == new Random().nextLong()) new Random().nextLong() == new Random().nextLong())
throw new RuntimeException("Random() seeds not unique."); 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");
} }
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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