diff --git a/make/java/nio/FILES_java.gmk b/make/java/nio/FILES_java.gmk index 41397cacdc0dd408144108ab0ca7f9c8c7d905ee..b394b89e483df4f16e245d127f49f46e7ebf8095 100644 --- a/make/java/nio/FILES_java.gmk +++ b/make/java/nio/FILES_java.gmk @@ -232,6 +232,7 @@ FILES_src = \ sun/nio/cs/UTF_16BE.java \ sun/nio/cs/UTF_16LE.java \ sun/nio/cs/UTF_8.java \ + sun/nio/cs/CESU_8.java \ sun/nio/cs/Unicode.java \ sun/nio/cs/UnicodeDecoder.java \ sun/nio/cs/UnicodeEncoder.java \ diff --git a/make/sun/net/Makefile b/make/sun/net/Makefile index 3e56798e2ee1b018dbd74a76ff701ec94eee5b90..b36fa664f8e07534b11479080df52224796b5d90 100644 --- a/make/sun/net/Makefile +++ b/make/sun/net/Makefile @@ -28,6 +28,7 @@ PACKAGE = sun.net PRODUCT = sun SUBDIRS_MAKEFLAGS += JAVAC_MAX_WARNINGS=true SUBDIRS_MAKEFLAGS += JAVAC_WARNINGS_FATAL=true +SUBDIRS_MAKEFLAGS += JAVAC_LINT_OPTIONS=-Xlint:all,-deprecation,-path include $(BUILDDIR)/common/Defs.gmk SUBDIRS = others spi diff --git a/src/share/classes/com/sun/org/apache/xml/internal/security/utils/IdResolver.java b/src/share/classes/com/sun/org/apache/xml/internal/security/utils/IdResolver.java index 61baa1595ad87c473e280a985f7c670c8bdd4d20..2fba84559687d56f3a5078b1af070a95157a2378 100644 --- a/src/share/classes/com/sun/org/apache/xml/internal/security/utils/IdResolver.java +++ b/src/share/classes/com/sun/org/apache/xml/internal/security/utils/IdResolver.java @@ -250,6 +250,8 @@ public class IdResolver { int index=s==null ? elementIndex : names.indexOf(n.getNamespaceURI()); index=(index<0) ? namesLength : index; String name=n.getLocalName(); + if (name == null) + name = n.getName(); if (name.length()>2) continue; String value=n.getNodeValue(); diff --git a/src/share/classes/java/lang/ref/Reference.java b/src/share/classes/java/lang/ref/Reference.java index f483edf58d2565b5572e2417c0742fb5c9fd30ba..6d3d9c3bd1a15aee1c7b394df77de9b98f29fd5d 100644 --- a/src/share/classes/java/lang/ref/Reference.java +++ b/src/share/classes/java/lang/ref/Reference.java @@ -27,7 +27,6 @@ package java.lang.ref; import sun.misc.Cleaner; - /** * Abstract base class for reference objects. This class defines the * operations common to all reference objects. Because reference objects are @@ -69,7 +68,7 @@ public abstract class Reference { * null. * * Pending: queue = ReferenceQueue with which instance is registered; - * next = Following instance in queue, or this if at end of list. + * next = this * * Enqueued: queue = ReferenceQueue.ENQUEUED; next = Following instance * in queue, or this if at end of list. @@ -81,17 +80,28 @@ public abstract class Reference { * the next field is null then the instance is active; if it is non-null, * then the collector should treat the instance normally. * - * To ensure that concurrent collector can discover active Reference + * To ensure that a concurrent collector can discover active Reference * objects without interfering with application threads that may apply * the enqueue() method to those objects, collectors should link - * discovered objects through the discovered field. + * discovered objects through the discovered field. The discovered + * field is also used for linking Reference objects in the pending list. */ private T referent; /* Treated specially by GC */ ReferenceQueue queue; + /* When active: NULL + * pending: this + * Enqueued: next reference in queue (or this if last) + * Inactive: this + */ Reference next; + + /* When active: next element in a discovered reference list maintained by GC (or this if last) + * pending: next element in the pending list (or null if last) + * otherwise: NULL + */ transient private Reference discovered; /* used by VM */ @@ -106,7 +116,8 @@ public abstract class Reference { /* List of References waiting to be enqueued. The collector adds * References to this list, while the Reference-handler thread removes - * them. This list is protected by the above lock object. + * them. This list is protected by the above lock object. The + * list uses the discovered field to link its elements. */ private static Reference pending = null; @@ -120,14 +131,12 @@ public abstract class Reference { public void run() { for (;;) { - Reference r; synchronized (lock) { if (pending != null) { r = pending; - Reference rn = r.next; - pending = (rn == r) ? null : rn; - r.next = r; + pending = r.discovered; + r.discovered = null; } else { try { lock.wait(); @@ -201,10 +210,8 @@ public abstract class Reference { * been enqueued */ public boolean isEnqueued() { - /* In terms of the internal states, this predicate actually tests - whether the instance is either Pending or Enqueued */ synchronized (this) { - return (this.queue != ReferenceQueue.NULL) && (this.next != null); + return (this.next != null && this.queue == ReferenceQueue.ENQUEUED); } } diff --git a/src/share/classes/java/net/InetAddress.java b/src/share/classes/java/net/InetAddress.java index a64011f09145a398aa6702fd4ef08374bcc7e530..8758cab7af3b0d7581efdf7b9d6593f1066cabf3 100644 --- a/src/share/classes/java/net/InetAddress.java +++ b/src/share/classes/java/net/InetAddress.java @@ -876,10 +876,12 @@ class InetAddress implements java.io.Serializable { nameService = java.security.AccessController.doPrivileged( new java.security.PrivilegedExceptionAction() { public NameService run() { - Iterator itr = Service.providers(NameServiceDescriptor.class); + // sun.misc.Service.providers returns a raw Iterator + @SuppressWarnings("unchecked") + Iterator itr = + Service.providers(NameServiceDescriptor.class); while (itr.hasNext()) { - NameServiceDescriptor nsd - = (NameServiceDescriptor)itr.next(); + NameServiceDescriptor nsd = itr.next(); if (providerName. equalsIgnoreCase(nsd.getType()+"," +nsd.getProviderName())) { diff --git a/src/share/classes/java/net/ServerSocket.java b/src/share/classes/java/net/ServerSocket.java index 86bc174b88f3239706235897a46ee4c22ce78ce0..b4ab7b6b8a432a21945511d9359de33a443c4acd 100644 --- a/src/share/classes/java/net/ServerSocket.java +++ b/src/share/classes/java/net/ServerSocket.java @@ -267,10 +267,9 @@ class ServerSocket implements java.io.Closeable { AccessController.doPrivileged( new PrivilegedExceptionAction() { public Void run() throws NoSuchMethodException { - Class[] cl = new Class[2]; - cl[0] = SocketAddress.class; - cl[1] = Integer.TYPE; - impl.getClass().getDeclaredMethod("connect", cl); + impl.getClass().getDeclaredMethod("connect", + SocketAddress.class, + int.class); return null; } }); diff --git a/src/share/classes/java/nio/charset/Charset.java b/src/share/classes/java/nio/charset/Charset.java index 53b0d2be957d359f90eb872244d3eb062c0fec78..2d3f020bcf6e6ac5588bb9f4791eca70310f9324 100644 --- a/src/share/classes/java/nio/charset/Charset.java +++ b/src/share/classes/java/nio/charset/Charset.java @@ -435,7 +435,7 @@ public abstract class Charset AccessController.doPrivileged(new PrivilegedAction() { public Object run() { try { - Class epc + Class epc = Class.forName("sun.nio.cs.ext.ExtendedCharsets"); extendedProvider = (CharsetProvider)epc.newInstance(); } catch (ClassNotFoundException x) { diff --git a/src/share/classes/java/nio/file/Files.java b/src/share/classes/java/nio/file/Files.java index 27778294000135d4d593879e6fbb93419a1b3dab..2683b7efe090666b4df6292c80308ac506a0e276 100644 --- a/src/share/classes/java/nio/file/Files.java +++ b/src/share/classes/java/nio/file/Files.java @@ -363,6 +363,17 @@ public final class Files { // -- Directories -- + private static class AcceptAllFilter + implements DirectoryStream.Filter + { + private AcceptAllFilter() { } + + @Override + public boolean accept(Path entry) { return true; } + + static final AcceptAllFilter FILTER = new AcceptAllFilter(); + } + /** * Opens a directory, returning a {@link DirectoryStream} to iterate over * all entries in the directory. The elements returned by the directory @@ -397,12 +408,7 @@ public final class Files { public static DirectoryStream newDirectoryStream(Path dir) throws IOException { - return provider(dir).newDirectoryStream(dir, new DirectoryStream.Filter() { - @Override - public boolean accept(Path entry) { - return true; - } - }); + return provider(dir).newDirectoryStream(dir, AcceptAllFilter.FILTER); } /** diff --git a/src/share/classes/java/security/Security.java b/src/share/classes/java/security/Security.java index b9dd1441d6366e30d6916055e26d3175e7d8abb3..f8890e62fec8c55f515a3ba3657702dd06af398a 100644 --- a/src/share/classes/java/security/Security.java +++ b/src/share/classes/java/security/Security.java @@ -814,7 +814,7 @@ public final class Security { public Void run() { try { /* Get the class via the bootstrap class loader. */ - Class cl = Class.forName( + Class cl = Class.forName( "java.lang.SecurityManager", false, null); Field f = null; boolean accessible = false; diff --git a/src/share/classes/java/text/BreakIterator.java b/src/share/classes/java/text/BreakIterator.java index e00e09adc3173a8cfac1c2cc9cbe2648c0282dae..6010784dbafcae5209540a26500110e583cbef3b 100644 --- a/src/share/classes/java/text/BreakIterator.java +++ b/src/share/classes/java/text/BreakIterator.java @@ -443,7 +443,7 @@ public abstract class BreakIterator implements Cloneable /** * Returns a new BreakIterator instance - * for word breaks + * for word breaks * for the {@linkplain Locale#getDefault() default locale}. * @return A break iterator for word breaks */ @@ -454,7 +454,7 @@ public abstract class BreakIterator implements Cloneable /** * Returns a new BreakIterator instance - * for word breaks + * for word breaks * for the given locale. * @param locale the desired locale * @return A break iterator for word breaks @@ -470,7 +470,7 @@ public abstract class BreakIterator implements Cloneable /** * Returns a new BreakIterator instance - * for line breaks + * for line breaks * for the {@linkplain Locale#getDefault() default locale}. * @return A break iterator for line breaks */ @@ -481,7 +481,7 @@ public abstract class BreakIterator implements Cloneable /** * Returns a new BreakIterator instance - * for line breaks + * for line breaks * for the given locale. * @param locale the desired locale * @return A break iterator for line breaks @@ -497,7 +497,7 @@ public abstract class BreakIterator implements Cloneable /** * Returns a new BreakIterator instance - * for character breaks + * for character breaks * for the {@linkplain Locale#getDefault() default locale}. * @return A break iterator for character breaks */ @@ -508,7 +508,7 @@ public abstract class BreakIterator implements Cloneable /** * Returns a new BreakIterator instance - * for character breaks + * for character breaks * for the given locale. * @param locale the desired locale * @return A break iterator for character breaks @@ -524,7 +524,7 @@ public abstract class BreakIterator implements Cloneable /** * Returns a new BreakIterator instance - * for sentence breaks + * for sentence breaks * for the {@linkplain Locale#getDefault() default locale}. * @return A break iterator for sentence breaks */ @@ -535,7 +535,7 @@ public abstract class BreakIterator implements Cloneable /** * Returns a new BreakIterator instance - * for sentence breaks + * for sentence breaks * for the given locale. * @param locale the desired locale * @return A break iterator for sentence breaks diff --git a/src/share/classes/java/util/Collections.java b/src/share/classes/java/util/Collections.java index e55eb59296e264a49cfa86a460e7b1304145e374..04e642e1c002064d9194ea85cf8d7c3608e97e9e 100644 --- a/src/share/classes/java/util/Collections.java +++ b/src/share/classes/java/util/Collections.java @@ -3201,6 +3201,102 @@ public class Collections { } } + /** + * Returns the empty sorted set (immutable). This set is serializable. + * + *

This example illustrates the type-safe way to obtain an empty sorted + * set: + *

+     *     SortedSet<String> s = Collections.emptySortedSet();
+     * 
+ * Implementation note: Implementations of this method need not + * create a separate SortedSet object for each call. + * + * @since 1.8 + */ + @SuppressWarnings("unchecked") + public static final SortedSet emptySortedSet() { + return (SortedSet) new EmptySortedSet<>(); + } + + /** + * @serial include + */ + private static class EmptySortedSet + extends AbstractSet + implements SortedSet, Serializable + { + private static final long serialVersionUID = 6316515401502265487L; + public Iterator iterator() { return emptyIterator(); } + public int size() {return 0;} + public boolean isEmpty() {return true;} + public boolean contains(Object obj) {return false;} + public boolean containsAll(Collection c) { return c.isEmpty(); } + public Object[] toArray() { return new Object[0]; } + + public E[] toArray(E[] a) { + if (a.length > 0) + a[0] = null; + return a; + } + + // Preserves singleton property + private Object readResolve() { + return new EmptySortedSet<>(); + } + + public Comparator comparator() { + return null; + } + + public SortedSet subSet(Object fromElement, Object toElement) { + Objects.requireNonNull(fromElement); + Objects.requireNonNull(toElement); + + if (!(fromElement instanceof Comparable) || + !(toElement instanceof Comparable)) + { + throw new ClassCastException(); + } + + if ((((Comparable)fromElement).compareTo(toElement) >= 0) || + (((Comparable)toElement).compareTo(fromElement) < 0)) + { + throw new IllegalArgumentException(); + } + + return emptySortedSet(); + } + + public SortedSet headSet(Object toElement) { + Objects.requireNonNull(toElement); + + if (!(toElement instanceof Comparable)) { + throw new ClassCastException(); + } + + return emptySortedSet(); + } + + public SortedSet tailSet(Object fromElement) { + Objects.requireNonNull(fromElement); + + if (!(fromElement instanceof Comparable)) { + throw new ClassCastException(); + } + + return emptySortedSet(); + } + + public E first() { + throw new NoSuchElementException(); + } + + public E last() { + throw new NoSuchElementException(); + } + } + /** * The empty list (immutable). This list is serializable. * diff --git a/src/share/classes/sun/nio/ch/Util.java b/src/share/classes/sun/nio/ch/Util.java index 9aa7c1628540da7d19aad70f2cd08742a9bacb2c..fafc48f3552a2707c0b4b56517457f8bfb1a6fc4 100644 --- a/src/share/classes/sun/nio/ch/Util.java +++ b/src/share/classes/sun/nio/ch/Util.java @@ -363,10 +363,10 @@ class Util { try { Class cl = Class.forName("java.nio.DirectByteBuffer"); Constructor ctor = cl.getDeclaredConstructor( - new Class[] { int.class, - long.class, - FileDescriptor.class, - Runnable.class }); + new Class[] { int.class, + long.class, + FileDescriptor.class, + Runnable.class }); ctor.setAccessible(true); directByteBufferConstructor = ctor; } catch (ClassNotFoundException | @@ -408,10 +408,10 @@ class Util { try { Class cl = Class.forName("java.nio.DirectByteBufferR"); Constructor ctor = cl.getDeclaredConstructor( - new Class[] { int.class, - long.class, - FileDescriptor.class, - Runnable.class }); + new Class[] { int.class, + long.class, + FileDescriptor.class, + Runnable.class }); ctor.setAccessible(true); directByteBufferRConstructor = ctor; } catch (ClassNotFoundException | diff --git a/src/share/classes/sun/nio/cs/CESU_8.java b/src/share/classes/sun/nio/cs/CESU_8.java new file mode 100644 index 0000000000000000000000000000000000000000..40711f83d86c01db9ab4e9a908a0ceabd26d1b3f --- /dev/null +++ b/src/share/classes/sun/nio/cs/CESU_8.java @@ -0,0 +1,604 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package sun.nio.cs; + +import java.nio.Buffer; +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.charset.Charset; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CharsetEncoder; +import java.nio.charset.CoderResult; +import java.nio.charset.CodingErrorAction; + +/* Legal CESU-8 Byte Sequences + * + * # Code Points Bits Bit/Byte pattern + * 1 7 0xxxxxxx + * U+0000..U+007F 00..7F + * + * 2 11 110xxxxx 10xxxxxx + * U+0080..U+07FF C2..DF 80..BF + * + * 3 16 1110xxxx 10xxxxxx 10xxxxxx + * U+0800..U+0FFF E0 A0..BF 80..BF + * U+1000..U+FFFF E1..EF 80..BF 80..BF + * + */ + +class CESU_8 extends Unicode +{ + public CESU_8() { + super("CESU-8", StandardCharsets.aliases_CESU_8); + } + + public String historicalName() { + return "CESU8"; + } + + public CharsetDecoder newDecoder() { + return new Decoder(this); + } + + public CharsetEncoder newEncoder() { + return new Encoder(this); + } + + private static final void updatePositions(Buffer src, int sp, + Buffer dst, int dp) { + src.position(sp - src.arrayOffset()); + dst.position(dp - dst.arrayOffset()); + } + + private static class Decoder extends CharsetDecoder + implements ArrayDecoder { + private Decoder(Charset cs) { + super(cs, 1.0f, 1.0f); + } + + private static boolean isNotContinuation(int b) { + return (b & 0xc0) != 0x80; + } + + // [E0] [A0..BF] [80..BF] + // [E1..EF] [80..BF] [80..BF] + private static boolean isMalformed3(int b1, int b2, int b3) { + return (b1 == (byte)0xe0 && (b2 & 0xe0) == 0x80) || + (b2 & 0xc0) != 0x80 || (b3 & 0xc0) != 0x80; + } + + // only used when there is only one byte left in src buffer + private static boolean isMalformed3_2(int b1, int b2) { + return (b1 == (byte)0xe0 && (b2 & 0xe0) == 0x80) || + (b2 & 0xc0) != 0x80; + } + + + // [F0] [90..BF] [80..BF] [80..BF] + // [F1..F3] [80..BF] [80..BF] [80..BF] + // [F4] [80..8F] [80..BF] [80..BF] + // only check 80-be range here, the [0xf0,0x80...] and [0xf4,0x90-...] + // will be checked by Character.isSupplementaryCodePoint(uc) + private static boolean isMalformed4(int b2, int b3, int b4) { + return (b2 & 0xc0) != 0x80 || (b3 & 0xc0) != 0x80 || + (b4 & 0xc0) != 0x80; + } + + // only used when there is less than 4 bytes left in src buffer + private static boolean isMalformed4_2(int b1, int b2) { + return (b1 == 0xf0 && b2 == 0x90) || + (b2 & 0xc0) != 0x80; + } + + private static boolean isMalformed4_3(int b3) { + return (b3 & 0xc0) != 0x80; + } + + private static CoderResult malformedN(ByteBuffer src, int nb) { + switch (nb) { + case 1: + case 2: // always 1 + return CoderResult.malformedForLength(1); + case 3: + int b1 = src.get(); + int b2 = src.get(); // no need to lookup b3 + return CoderResult.malformedForLength( + ((b1 == (byte)0xe0 && (b2 & 0xe0) == 0x80) || + isNotContinuation(b2)) ? 1 : 2); + case 4: // we don't care the speed here + b1 = src.get() & 0xff; + b2 = src.get() & 0xff; + if (b1 > 0xf4 || + (b1 == 0xf0 && (b2 < 0x90 || b2 > 0xbf)) || + (b1 == 0xf4 && (b2 & 0xf0) != 0x80) || + isNotContinuation(b2)) + return CoderResult.malformedForLength(1); + if (isNotContinuation(src.get())) + return CoderResult.malformedForLength(2); + return CoderResult.malformedForLength(3); + default: + assert false; + return null; + } + } + + private static CoderResult malformed(ByteBuffer src, int sp, + CharBuffer dst, int dp, + int nb) + { + src.position(sp - src.arrayOffset()); + CoderResult cr = malformedN(src, nb); + updatePositions(src, sp, dst, dp); + return cr; + } + + + private static CoderResult malformed(ByteBuffer src, + int mark, int nb) + { + src.position(mark); + CoderResult cr = malformedN(src, nb); + src.position(mark); + return cr; + } + + private static CoderResult malformedForLength(ByteBuffer src, + int sp, + CharBuffer dst, + int dp, + int malformedNB) + { + updatePositions(src, sp, dst, dp); + return CoderResult.malformedForLength(malformedNB); + } + + private static CoderResult malformedForLength(ByteBuffer src, + int mark, + int malformedNB) + { + src.position(mark); + return CoderResult.malformedForLength(malformedNB); + } + + + private static CoderResult xflow(Buffer src, int sp, int sl, + Buffer dst, int dp, int nb) { + updatePositions(src, sp, dst, dp); + return (nb == 0 || sl - sp < nb) + ? CoderResult.UNDERFLOW : CoderResult.OVERFLOW; + } + + private static CoderResult xflow(Buffer src, int mark, int nb) { + src.position(mark); + return (nb == 0 || src.remaining() < nb) + ? CoderResult.UNDERFLOW : CoderResult.OVERFLOW; + } + + private CoderResult decodeArrayLoop(ByteBuffer src, + CharBuffer dst) + { + // This method is optimized for ASCII input. + byte[] sa = src.array(); + int sp = src.arrayOffset() + src.position(); + int sl = src.arrayOffset() + src.limit(); + + char[] da = dst.array(); + int dp = dst.arrayOffset() + dst.position(); + int dl = dst.arrayOffset() + dst.limit(); + int dlASCII = dp + Math.min(sl - sp, dl - dp); + + // ASCII only loop + while (dp < dlASCII && sa[sp] >= 0) + da[dp++] = (char) sa[sp++]; + while (sp < sl) { + int b1 = sa[sp]; + if (b1 >= 0) { + // 1 byte, 7 bits: 0xxxxxxx + if (dp >= dl) + return xflow(src, sp, sl, dst, dp, 1); + da[dp++] = (char) b1; + sp++; + } else if ((b1 >> 5) == -2 && (b1 & 0x1e) != 0) { + // 2 bytes, 11 bits: 110xxxxx 10xxxxxx + if (sl - sp < 2 || dp >= dl) + return xflow(src, sp, sl, dst, dp, 2); + int b2 = sa[sp + 1]; + if (isNotContinuation(b2)) + return malformedForLength(src, sp, dst, dp, 1); + da[dp++] = (char) (((b1 << 6) ^ b2) + ^ + (((byte) 0xC0 << 6) ^ + ((byte) 0x80 << 0))); + sp += 2; + } else if ((b1 >> 4) == -2) { + // 3 bytes, 16 bits: 1110xxxx 10xxxxxx 10xxxxxx + int srcRemaining = sl - sp; + if (srcRemaining < 3 || dp >= dl) { + if (srcRemaining > 1 && isMalformed3_2(b1, sa[sp + 1])) + return malformedForLength(src, sp, dst, dp, 1); + return xflow(src, sp, sl, dst, dp, 3); + } + int b2 = sa[sp + 1]; + int b3 = sa[sp + 2]; + if (isMalformed3(b1, b2, b3)) + return malformed(src, sp, dst, dp, 3); + da[dp++] = (char) + ((b1 << 12) ^ + (b2 << 6) ^ + (b3 ^ + (((byte) 0xE0 << 12) ^ + ((byte) 0x80 << 6) ^ + ((byte) 0x80 << 0)))); + sp += 3; + } else { + return malformed(src, sp, dst, dp, 1); + } + } + return xflow(src, sp, sl, dst, dp, 0); + } + + private CoderResult decodeBufferLoop(ByteBuffer src, + CharBuffer dst) + { + int mark = src.position(); + int limit = src.limit(); + while (mark < limit) { + int b1 = src.get(); + if (b1 >= 0) { + // 1 byte, 7 bits: 0xxxxxxx + if (dst.remaining() < 1) + return xflow(src, mark, 1); // overflow + dst.put((char) b1); + mark++; + } else if ((b1 >> 5) == -2 && (b1 & 0x1e) != 0) { + // 2 bytes, 11 bits: 110xxxxx 10xxxxxx + if (limit - mark < 2|| dst.remaining() < 1) + return xflow(src, mark, 2); + int b2 = src.get(); + if (isNotContinuation(b2)) + return malformedForLength(src, mark, 1); + dst.put((char) (((b1 << 6) ^ b2) + ^ + (((byte) 0xC0 << 6) ^ + ((byte) 0x80 << 0)))); + mark += 2; + } else if ((b1 >> 4) == -2) { + // 3 bytes, 16 bits: 1110xxxx 10xxxxxx 10xxxxxx + int srcRemaining = limit - mark; + if (srcRemaining < 3 || dst.remaining() < 1) { + if (srcRemaining > 1 && isMalformed3_2(b1, src.get())) + return malformedForLength(src, mark, 1); + return xflow(src, mark, 3); + } + int b2 = src.get(); + int b3 = src.get(); + if (isMalformed3(b1, b2, b3)) + return malformed(src, mark, 3); + dst.put((char) + ((b1 << 12) ^ + (b2 << 6) ^ + (b3 ^ + (((byte) 0xE0 << 12) ^ + ((byte) 0x80 << 6) ^ + ((byte) 0x80 << 0))))); + mark += 3; + } else { + return malformed(src, mark, 1); + } + } + return xflow(src, mark, 0); + } + + protected CoderResult decodeLoop(ByteBuffer src, + CharBuffer dst) + { + if (src.hasArray() && dst.hasArray()) + return decodeArrayLoop(src, dst); + else + return decodeBufferLoop(src, dst); + } + + private static ByteBuffer getByteBuffer(ByteBuffer bb, byte[] ba, int sp) + { + if (bb == null) + bb = ByteBuffer.wrap(ba); + bb.position(sp); + return bb; + } + + // returns -1 if there is/are malformed byte(s) and the + // "action" for malformed input is not REPLACE. + public int decode(byte[] sa, int sp, int len, char[] da) { + final int sl = sp + len; + int dp = 0; + int dlASCII = Math.min(len, da.length); + ByteBuffer bb = null; // only necessary if malformed + + // ASCII only optimized loop + while (dp < dlASCII && sa[sp] >= 0) + da[dp++] = (char) sa[sp++]; + + while (sp < sl) { + int b1 = sa[sp++]; + if (b1 >= 0) { + // 1 byte, 7 bits: 0xxxxxxx + da[dp++] = (char) b1; + } else if ((b1 >> 5) == -2 && (b1 & 0x1e) != 0) { + // 2 bytes, 11 bits: 110xxxxx 10xxxxxx + if (sp < sl) { + int b2 = sa[sp++]; + if (isNotContinuation(b2)) { + if (malformedInputAction() != CodingErrorAction.REPLACE) + return -1; + da[dp++] = replacement().charAt(0); + sp--; // malformedN(bb, 2) always returns 1 + } else { + da[dp++] = (char) (((b1 << 6) ^ b2)^ + (((byte) 0xC0 << 6) ^ + ((byte) 0x80 << 0))); + } + continue; + } + if (malformedInputAction() != CodingErrorAction.REPLACE) + return -1; + da[dp++] = replacement().charAt(0); + return dp; + } else if ((b1 >> 4) == -2) { + // 3 bytes, 16 bits: 1110xxxx 10xxxxxx 10xxxxxx + if (sp + 1 < sl) { + int b2 = sa[sp++]; + int b3 = sa[sp++]; + if (isMalformed3(b1, b2, b3)) { + if (malformedInputAction() != CodingErrorAction.REPLACE) + return -1; + da[dp++] = replacement().charAt(0); + sp -=3; + bb = getByteBuffer(bb, sa, sp); + sp += malformedN(bb, 3).length(); + } else { + da[dp++] = (char)((b1 << 12) ^ + (b2 << 6) ^ + (b3 ^ + (((byte) 0xE0 << 12) ^ + ((byte) 0x80 << 6) ^ + ((byte) 0x80 << 0)))); + } + continue; + } + if (malformedInputAction() != CodingErrorAction.REPLACE) + return -1; + if (sp < sl && isMalformed3_2(b1, sa[sp])) { + da[dp++] = replacement().charAt(0); + continue; + + } + da[dp++] = replacement().charAt(0); + return dp; + } else { + if (malformedInputAction() != CodingErrorAction.REPLACE) + return -1; + da[dp++] = replacement().charAt(0); + } + } + return dp; + } + } + + private static class Encoder extends CharsetEncoder + implements ArrayEncoder { + + private Encoder(Charset cs) { + super(cs, 1.1f, 3.0f); + } + + public boolean canEncode(char c) { + return !Character.isSurrogate(c); + } + + public boolean isLegalReplacement(byte[] repl) { + return ((repl.length == 1 && repl[0] >= 0) || + super.isLegalReplacement(repl)); + } + + private static CoderResult overflow(CharBuffer src, int sp, + ByteBuffer dst, int dp) { + updatePositions(src, sp, dst, dp); + return CoderResult.OVERFLOW; + } + + private static CoderResult overflow(CharBuffer src, int mark) { + src.position(mark); + return CoderResult.OVERFLOW; + } + + private static void to3Bytes(byte[] da, int dp, char c) { + da[dp] = (byte)(0xe0 | ((c >> 12))); + da[dp + 1] = (byte)(0x80 | ((c >> 6) & 0x3f)); + da[dp + 2] = (byte)(0x80 | (c & 0x3f)); + } + + private static void to3Bytes(ByteBuffer dst, char c) { + dst.put((byte)(0xe0 | ((c >> 12)))); + dst.put((byte)(0x80 | ((c >> 6) & 0x3f))); + dst.put((byte)(0x80 | (c & 0x3f))); + } + + private Surrogate.Parser sgp; + private char[] c2; + private CoderResult encodeArrayLoop(CharBuffer src, + ByteBuffer dst) + { + char[] sa = src.array(); + int sp = src.arrayOffset() + src.position(); + int sl = src.arrayOffset() + src.limit(); + + byte[] da = dst.array(); + int dp = dst.arrayOffset() + dst.position(); + int dl = dst.arrayOffset() + dst.limit(); + int dlASCII = dp + Math.min(sl - sp, dl - dp); + + // ASCII only loop + while (dp < dlASCII && sa[sp] < '\u0080') + da[dp++] = (byte) sa[sp++]; + while (sp < sl) { + char c = sa[sp]; + if (c < 0x80) { + // Have at most seven bits + if (dp >= dl) + return overflow(src, sp, dst, dp); + da[dp++] = (byte)c; + } else if (c < 0x800) { + // 2 bytes, 11 bits + if (dl - dp < 2) + return overflow(src, sp, dst, dp); + da[dp++] = (byte)(0xc0 | (c >> 6)); + da[dp++] = (byte)(0x80 | (c & 0x3f)); + } else if (Character.isSurrogate(c)) { + // Have a surrogate pair + if (sgp == null) + sgp = new Surrogate.Parser(); + int uc = sgp.parse(c, sa, sp, sl); + if (uc < 0) { + updatePositions(src, sp, dst, dp); + return sgp.error(); + } + if (dl - dp < 6) + return overflow(src, sp, dst, dp); + to3Bytes(da, dp, Character.highSurrogate(uc)); + dp += 3; + to3Bytes(da, dp, Character.lowSurrogate(uc)); + dp += 3; + sp++; // 2 chars + } else { + // 3 bytes, 16 bits + if (dl - dp < 3) + return overflow(src, sp, dst, dp); + to3Bytes(da, dp, c); + dp += 3; + } + sp++; + } + updatePositions(src, sp, dst, dp); + return CoderResult.UNDERFLOW; + } + + private CoderResult encodeBufferLoop(CharBuffer src, + ByteBuffer dst) + { + int mark = src.position(); + while (src.hasRemaining()) { + char c = src.get(); + if (c < 0x80) { + // Have at most seven bits + if (!dst.hasRemaining()) + return overflow(src, mark); + dst.put((byte)c); + } else if (c < 0x800) { + // 2 bytes, 11 bits + if (dst.remaining() < 2) + return overflow(src, mark); + dst.put((byte)(0xc0 | (c >> 6))); + dst.put((byte)(0x80 | (c & 0x3f))); + } else if (Character.isSurrogate(c)) { + // Have a surrogate pair + if (sgp == null) + sgp = new Surrogate.Parser(); + int uc = sgp.parse(c, src); + if (uc < 0) { + src.position(mark); + return sgp.error(); + } + if (dst.remaining() < 6) + return overflow(src, mark); + to3Bytes(dst, Character.highSurrogate(uc)); + to3Bytes(dst, Character.lowSurrogate(uc)); + mark++; // 2 chars + } else { + // 3 bytes, 16 bits + if (dst.remaining() < 3) + return overflow(src, mark); + to3Bytes(dst, c); + } + mark++; + } + src.position(mark); + return CoderResult.UNDERFLOW; + } + + protected final CoderResult encodeLoop(CharBuffer src, + ByteBuffer dst) + { + if (src.hasArray() && dst.hasArray()) + return encodeArrayLoop(src, dst); + else + return encodeBufferLoop(src, dst); + } + + // returns -1 if there is malformed char(s) and the + // "action" for malformed input is not REPLACE. + public int encode(char[] sa, int sp, int len, byte[] da) { + int sl = sp + len; + int dp = 0; + int dlASCII = dp + Math.min(len, da.length); + + // ASCII only optimized loop + while (dp < dlASCII && sa[sp] < '\u0080') + da[dp++] = (byte) sa[sp++]; + + while (sp < sl) { + char c = sa[sp++]; + if (c < 0x80) { + // Have at most seven bits + da[dp++] = (byte)c; + } else if (c < 0x800) { + // 2 bytes, 11 bits + da[dp++] = (byte)(0xc0 | (c >> 6)); + da[dp++] = (byte)(0x80 | (c & 0x3f)); + } else if (Character.isSurrogate(c)) { + if (sgp == null) + sgp = new Surrogate.Parser(); + int uc = sgp.parse(c, sa, sp - 1, sl); + if (uc < 0) { + if (malformedInputAction() != CodingErrorAction.REPLACE) + return -1; + da[dp++] = replacement()[0]; + } else { + to3Bytes(da, dp, Character.highSurrogate(uc)); + dp += 3; + to3Bytes(da, dp, Character.lowSurrogate(uc)); + dp += 3; + sp++; // 2 chars + } + } else { + // 3 bytes, 16 bits + to3Bytes(da, dp, c); + dp += 3; + } + } + return dp; + } + } +} diff --git a/src/share/classes/sun/nio/cs/UTF_8.java b/src/share/classes/sun/nio/cs/UTF_8.java index 56d6bcc7b6d3a098f196b7ab115ddccdf728b979..1f7edaad2d86dddb07aaed1e618dcf25be8f9991 100644 --- a/src/share/classes/sun/nio/cs/UTF_8.java +++ b/src/share/classes/sun/nio/cs/UTF_8.java @@ -72,8 +72,8 @@ class UTF_8 extends Unicode return new Encoder(this); } - static final void updatePositions(Buffer src, int sp, - Buffer dst, int dp) { + private static final void updatePositions(Buffer src, int sp, + Buffer dst, int dp) { src.position(sp - src.arrayOffset()); dst.position(dp - dst.arrayOffset()); } @@ -88,11 +88,6 @@ class UTF_8 extends Unicode return (b & 0xc0) != 0x80; } - // [C2..DF] [80..BF] - private static boolean isMalformed2(int b1, int b2) { - return (b1 & 0x1e) == 0x0 || (b2 & 0xc0) != 0x80; - } - // [E0] [A0..BF] [80..BF] // [E1..EF] [80..BF] [80..BF] private static boolean isMalformed3(int b1, int b2, int b3) { @@ -100,6 +95,12 @@ class UTF_8 extends Unicode (b2 & 0xc0) != 0x80 || (b3 & 0xc0) != 0x80; } + // only used when there is only one byte left in src buffer + private static boolean isMalformed3_2(int b1, int b2) { + return (b1 == (byte)0xe0 && (b2 & 0xe0) == 0x80) || + (b2 & 0xc0) != 0x80; + } + // [F0] [90..BF] [80..BF] [80..BF] // [F1..F3] [80..BF] [80..BF] [80..BF] // [F4] [80..8F] [80..BF] [80..BF] @@ -110,6 +111,16 @@ class UTF_8 extends Unicode (b4 & 0xc0) != 0x80; } + // only used when there is less than 4 bytes left in src buffer + private static boolean isMalformed4_2(int b1, int b2) { + return (b1 == 0xf0 && b2 == 0x90) || + (b2 & 0xc0) != 0x80; + } + + private static boolean isMalformed4_3(int b3) { + return (b3 & 0xc0) != 0x80; + } + private static CoderResult lookupN(ByteBuffer src, int n) { for (int i = 1; i < n; i++) { @@ -122,28 +133,14 @@ class UTF_8 extends Unicode private static CoderResult malformedN(ByteBuffer src, int nb) { switch (nb) { case 1: - int b1 = src.get(); - if ((b1 >> 2) == -2) { - // 5 bytes 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx - if (src.remaining() < 4) - return CoderResult.UNDERFLOW; - return lookupN(src, 5); - } - if ((b1 >> 1) == -2) { - // 6 bytes 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx - if (src.remaining() < 5) - return CoderResult.UNDERFLOW; - return lookupN(src, 6); - } - return CoderResult.malformedForLength(1); case 2: // always 1 return CoderResult.malformedForLength(1); case 3: - b1 = src.get(); + int b1 = src.get(); int b2 = src.get(); // no need to lookup b3 return CoderResult.malformedForLength( ((b1 == (byte)0xe0 && (b2 & 0xe0) == 0x80) || - isNotContinuation(b2))?1:2); + isNotContinuation(b2)) ? 1 : 2); case 4: // we don't care the speed here b1 = src.get() & 0xff; b2 = src.get() & 0xff; @@ -171,6 +168,7 @@ class UTF_8 extends Unicode return cr; } + private static CoderResult malformed(ByteBuffer src, int mark, int nb) { @@ -180,18 +178,36 @@ class UTF_8 extends Unicode return cr; } + private static CoderResult malformedForLength(ByteBuffer src, + int sp, + CharBuffer dst, + int dp, + int malformedNB) + { + updatePositions(src, sp, dst, dp); + return CoderResult.malformedForLength(malformedNB); + } + + private static CoderResult malformedForLength(ByteBuffer src, + int mark, + int malformedNB) + { + src.position(mark); + return CoderResult.malformedForLength(malformedNB); + } + + private static CoderResult xflow(Buffer src, int sp, int sl, Buffer dst, int dp, int nb) { updatePositions(src, sp, dst, dp); return (nb == 0 || sl - sp < nb) - ?CoderResult.UNDERFLOW:CoderResult.OVERFLOW; + ? CoderResult.UNDERFLOW : CoderResult.OVERFLOW; } private static CoderResult xflow(Buffer src, int mark, int nb) { - CoderResult cr = (nb == 0 || src.remaining() < (nb - 1)) - ?CoderResult.UNDERFLOW:CoderResult.OVERFLOW; src.position(mark); - return cr; + return (nb == 0 || src.remaining() < nb) + ? CoderResult.UNDERFLOW : CoderResult.OVERFLOW; } private CoderResult decodeArrayLoop(ByteBuffer src, @@ -210,7 +226,6 @@ class UTF_8 extends Unicode // ASCII only loop while (dp < dlASCII && sa[sp] >= 0) da[dp++] = (char) sa[sp++]; - while (sp < sl) { int b1 = sa[sp]; if (b1 >= 0) { @@ -219,13 +234,20 @@ class UTF_8 extends Unicode return xflow(src, sp, sl, dst, dp, 1); da[dp++] = (char) b1; sp++; - } else if ((b1 >> 5) == -2) { + } else if ((b1 >> 5) == -2 && (b1 & 0x1e) != 0) { // 2 bytes, 11 bits: 110xxxxx 10xxxxxx + // [C2..DF] [80..BF] if (sl - sp < 2 || dp >= dl) return xflow(src, sp, sl, dst, dp, 2); int b2 = sa[sp + 1]; - if (isMalformed2(b1, b2)) - return malformed(src, sp, dst, dp, 2); + // Now we check the first byte of 2-byte sequence as + // if ((b1 >> 5) == -2 && (b1 & 0x1e) != 0) + // no longer need to check b1 against c1 & c0 for + // malformed as we did in previous version + // (b1 & 0x1e) == 0x0 || (b2 & 0xc0) != 0x80; + // only need to check the second byte b2. + if (isNotContinuation(b2)) + return malformedForLength(src, sp, dst, dp, 1); da[dp++] = (char) (((b1 << 6) ^ b2) ^ (((byte) 0xC0 << 6) ^ @@ -233,24 +255,37 @@ class UTF_8 extends Unicode sp += 2; } else if ((b1 >> 4) == -2) { // 3 bytes, 16 bits: 1110xxxx 10xxxxxx 10xxxxxx - if (sl - sp < 3 || dp >= dl) + int srcRemaining = sl - sp; + if (srcRemaining < 3 || dp >= dl) { + if (srcRemaining > 1 && isMalformed3_2(b1, sa[sp + 1])) + return malformedForLength(src, sp, dst, dp, 1); return xflow(src, sp, sl, dst, dp, 3); + } int b2 = sa[sp + 1]; int b3 = sa[sp + 2]; if (isMalformed3(b1, b2, b3)) return malformed(src, sp, dst, dp, 3); - da[dp++] = (char) + char c = (char) ((b1 << 12) ^ (b2 << 6) ^ (b3 ^ (((byte) 0xE0 << 12) ^ ((byte) 0x80 << 6) ^ ((byte) 0x80 << 0)))); + if (Character.isSurrogate(c)) + return malformedForLength(src, sp, dst, dp, 3); + da[dp++] = c; sp += 3; } else if ((b1 >> 3) == -2) { // 4 bytes, 21 bits: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx - if (sl - sp < 4 || dl - dp < 2) + int srcRemaining = sl - sp; + if (srcRemaining < 4 || dl - dp < 2) { + if (srcRemaining > 1 && isMalformed4_2(b1, sa[sp + 1])) + return malformedForLength(src, sp, dst, dp, 1); + if (srcRemaining > 2 && isMalformed4_3(sa[sp + 2])) + return malformedForLength(src, sp, dst, dp, 2); return xflow(src, sp, sl, dst, dp, 4); + } int b2 = sa[sp + 1]; int b3 = sa[sp + 2]; int b4 = sa[sp + 3]; @@ -289,38 +324,51 @@ class UTF_8 extends Unicode return xflow(src, mark, 1); // overflow dst.put((char) b1); mark++; - } else if ((b1 >> 5) == -2) { + } else if ((b1 >> 5) == -2 && (b1 & 0x1e) != 0) { // 2 bytes, 11 bits: 110xxxxx 10xxxxxx if (limit - mark < 2|| dst.remaining() < 1) return xflow(src, mark, 2); int b2 = src.get(); - if (isMalformed2(b1, b2)) - return malformed(src, mark, 2); - dst.put((char) (((b1 << 6) ^ b2) + if (isNotContinuation(b2)) + return malformedForLength(src, mark, 1); + dst.put((char) (((b1 << 6) ^ b2) ^ (((byte) 0xC0 << 6) ^ ((byte) 0x80 << 0)))); mark += 2; } else if ((b1 >> 4) == -2) { // 3 bytes, 16 bits: 1110xxxx 10xxxxxx 10xxxxxx - if (limit - mark < 3 || dst.remaining() < 1) + int srcRemaining = limit - mark; + if (srcRemaining < 3 || dst.remaining() < 1) { + if (srcRemaining > 1 && isMalformed3_2(b1, src.get())) + return malformedForLength(src, mark, 1); return xflow(src, mark, 3); + } int b2 = src.get(); int b3 = src.get(); if (isMalformed3(b1, b2, b3)) return malformed(src, mark, 3); - dst.put((char) - ((b1 << 12) ^ - (b2 << 6) ^ - (b3 ^ - (((byte) 0xE0 << 12) ^ - ((byte) 0x80 << 6) ^ - ((byte) 0x80 << 0))))); + char c = (char) + ((b1 << 12) ^ + (b2 << 6) ^ + (b3 ^ + (((byte) 0xE0 << 12) ^ + ((byte) 0x80 << 6) ^ + ((byte) 0x80 << 0)))); + if (Character.isSurrogate(c)) + return malformedForLength(src, mark, 3); + dst.put(c); mark += 3; } else if ((b1 >> 3) == -2) { // 4 bytes, 21 bits: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx - if (limit - mark < 4 || dst.remaining() < 2) + int srcRemaining = limit - mark; + if (srcRemaining < 4 || dst.remaining() < 2) { + if (srcRemaining > 1 && isMalformed4_2(b1, src.get())) + return malformedForLength(src, mark, 1); + if (srcRemaining > 2 && isMalformed4_3(src.get())) + return malformedForLength(src, mark, 2); return xflow(src, mark, 4); + } int b2 = src.get(); int b3 = src.get(); int b4 = src.get(); @@ -364,7 +412,7 @@ class UTF_8 extends Unicode return bb; } - // returns -1 if there is malformed byte(s) and the + // returns -1 if there is/are malformed byte(s) and the // "action" for malformed input is not REPLACE. public int decode(byte[] sa, int sp, int len, char[] da) { final int sl = sp + len; @@ -381,11 +429,11 @@ class UTF_8 extends Unicode if (b1 >= 0) { // 1 byte, 7 bits: 0xxxxxxx da[dp++] = (char) b1; - } else if ((b1 >> 5) == -2) { + } else if ((b1 >> 5) == -2 && (b1 & 0x1e) != 0) { // 2 bytes, 11 bits: 110xxxxx 10xxxxxx if (sp < sl) { int b2 = sa[sp++]; - if (isMalformed2(b1, b2)) { + if (isNotContinuation(b2)) { if (malformedInputAction() != CodingErrorAction.REPLACE) return -1; da[dp++] = replacement().charAt(0); @@ -410,21 +458,33 @@ class UTF_8 extends Unicode if (malformedInputAction() != CodingErrorAction.REPLACE) return -1; da[dp++] = replacement().charAt(0); - sp -=3; + sp -= 3; bb = getByteBuffer(bb, sa, sp); sp += malformedN(bb, 3).length(); } else { - da[dp++] = (char)((b1 << 12) ^ + char c = (char)((b1 << 12) ^ (b2 << 6) ^ (b3 ^ (((byte) 0xE0 << 12) ^ ((byte) 0x80 << 6) ^ ((byte) 0x80 << 0)))); + if (Character.isSurrogate(c)) { + if (malformedInputAction() != CodingErrorAction.REPLACE) + return -1; + da[dp++] = replacement().charAt(0); + } else { + da[dp++] = c; + } } continue; } if (malformedInputAction() != CodingErrorAction.REPLACE) return -1; + if (sp < sl && isMalformed3_2(b1, sa[sp])) { + da[dp++] = replacement().charAt(0); + continue; + + } da[dp++] = replacement().charAt(0); return dp; } else if ((b1 >> 3) == -2) { @@ -458,28 +518,29 @@ class UTF_8 extends Unicode } if (malformedInputAction() != CodingErrorAction.REPLACE) return -1; + + if (sp < sl && isMalformed4_2(b1, sa[sp])) { + da[dp++] = replacement().charAt(0); + continue; + } + sp++; + if (sp < sl && isMalformed4_3(sa[sp])) { + da[dp++] = replacement().charAt(0); + continue; + } da[dp++] = replacement().charAt(0); return dp; } else { if (malformedInputAction() != CodingErrorAction.REPLACE) return -1; da[dp++] = replacement().charAt(0); - sp--; - bb = getByteBuffer(bb, sa, sp); - CoderResult cr = malformedN(bb, 1); - if (!cr.isError()) { - // leading byte for 5 or 6-byte, but don't have enough - // bytes in buffer to check. Consumed rest as malformed. - return dp; - } - sp += cr.length(); } } return dp; } } - private static class Encoder extends CharsetEncoder + private static final class Encoder extends CharsetEncoder implements ArrayEncoder { private Encoder(Charset cs) { diff --git a/src/share/classes/sun/nio/cs/standard-charsets b/src/share/classes/sun/nio/cs/standard-charsets index 06120fee8f30c5623d40531c7ecfabc00fc33bba..245713500a6cd50e1c79f60411ec84dde31ec5c0 100644 --- a/src/share/classes/sun/nio/cs/standard-charsets +++ b/src/share/classes/sun/nio/cs/standard-charsets @@ -63,6 +63,10 @@ charset UTF-8 UTF_8 alias UTF8 # JDK historical alias unicode-1-1-utf-8 +charset CESU-8 CESU_8 + alias CESU8 + alias csCESU-8 + charset UTF-16 UTF_16 alias UTF_16 # JDK historical alias utf16 diff --git a/src/share/classes/sun/security/ssl/MAC.java b/src/share/classes/sun/security/ssl/MAC.java index 8002148a9948a7075ec247c97304f8014b98f63d..ae5c9d43bc0e9e0bc0bba40cd8203b21e6d9a6e8 100644 --- a/src/share/classes/sun/security/ssl/MAC.java +++ b/src/share/classes/sun/security/ssl/MAC.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -172,10 +172,10 @@ final class MAC { * when there are only 2^8 sequence numbers left. */ return (block != null && mac != null && - block[0] == 0xFF && block[1] == 0xFF && - block[2] == 0xFF && block[3] == 0xFF && - block[4] == 0xFF && block[5] == 0xFF && - block[6] == 0xFF); + block[0] == (byte)0xFF && block[1] == (byte)0xFF && + block[2] == (byte)0xFF && block[3] == (byte)0xFF && + block[4] == (byte)0xFF && block[5] == (byte)0xFF && + block[6] == (byte)0xFF); } /* @@ -192,7 +192,7 @@ final class MAC { * only 2^48 sequence numbers left. */ return (block != null && mac != null && - block[0] == 0xFF && block[1] == 0xFF); + block[0] == (byte)0xFF && block[1] == (byte)0xFF); } // increment the sequence number in the block array diff --git a/src/share/classes/sun/util/xml/XMLUtils.java b/src/share/classes/sun/util/xml/XMLUtils.java index ab7ca8513961dc5604e4b5d1f5858b3dd8142528..07677334db8bc475ec8c406818dae009e7ebecdb 100644 --- a/src/share/classes/sun/util/xml/XMLUtils.java +++ b/src/share/classes/sun/util/xml/XMLUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -76,7 +76,7 @@ public class XMLUtils { } catch (SAXException saxe) { throw new InvalidPropertiesFormatException(saxe); } - Element propertiesElement = (Element)doc.getChildNodes().item(1); + Element propertiesElement = doc.getDocumentElement(); String xmlVersion = propertiesElement.getAttribute("version"); if (xmlVersion.compareTo(EXTERNAL_XML_VERSION) > 0) throw new InvalidPropertiesFormatException( diff --git a/src/share/javavm/export/jvm.h b/src/share/javavm/export/jvm.h index d1dfefca47f881e6d658185fa1f82b53c691d51f..8d833ebeeac13d47ac33a6b229d700a87f188ced 100644 --- a/src/share/javavm/export/jvm.h +++ b/src/share/javavm/export/jvm.h @@ -1424,7 +1424,8 @@ typedef struct { */ unsigned int thread_park_blocker : 1; unsigned int post_vm_init_hook_enabled : 1; - unsigned int : 30; + unsigned int pending_list_uses_discovered_field : 1; + unsigned int : 29; unsigned int : 32; unsigned int : 32; } jdk_version_info; diff --git a/src/share/native/common/jdk_util.c b/src/share/native/common/jdk_util.c index e737982893ecd7a47de869fa940ff32ddf45807c..8fe32bfcfaf341bfd629b601ded18490418417cb 100644 --- a/src/share/native/common/jdk_util.c +++ b/src/share/native/common/jdk_util.c @@ -101,5 +101,5 @@ JDK_GetVersionInfo0(jdk_version_info* info, size_t info_size) { // Advertise presence of sun.misc.PostVMInitHook: // future optimization: detect if this is enabled. info->post_vm_init_hook_enabled = 1; - + info->pending_list_uses_discovered_field = 1; } diff --git a/src/windows/classes/sun/nio/fs/WindowsDirectoryStream.java b/src/windows/classes/sun/nio/fs/WindowsDirectoryStream.java index 9a461f92c824f536035084cb5c606730c7b1d439..02309ff01b20083b7d114ccadb9e85de7bc40ee6 100644 --- a/src/windows/classes/sun/nio/fs/WindowsDirectoryStream.java +++ b/src/windows/classes/sun/nio/fs/WindowsDirectoryStream.java @@ -124,26 +124,27 @@ class WindowsDirectoryStream private boolean atEof; private String first; private Path nextEntry; + private String prefix; WindowsDirectoryIterator(String first) { atEof = false; this.first = first; + if (dir.needsSlashWhenResolving()) { + prefix = dir.toString() + "\\"; + } else { + prefix = dir.toString(); + } + } + + // links to self and parent directories are ignored + private boolean isSelfOrParent(String name) { + return name.equals(".") || name.equals(".."); } // applies filter and also ignores "." and ".." private Path acceptEntry(String s, BasicFileAttributes attrs) { - if (s.equals(".") || s.equals("..")) - return null; - if (dir.needsSlashWhenResolving()) { - StringBuilder sb = new StringBuilder(dir.toString()); - sb.append('\\'); - sb.append(s); - s = sb.toString(); - } else { - s = dir + s; - } Path entry = WindowsPath - .createFromNormalizedPath(dir.getFileSystem(), s, attrs); + .createFromNormalizedPath(dir.getFileSystem(), prefix + s, attrs); try { if (filter.accept(entry)) return entry; @@ -157,7 +158,7 @@ class WindowsDirectoryStream private Path readNextEntry() { // handle first element returned by search if (first != null) { - nextEntry = acceptEntry(first, null); + nextEntry = isSelfOrParent(first) ? null : acceptEntry(first, null); first = null; if (nextEntry != null) return nextEntry; @@ -184,6 +185,10 @@ class WindowsDirectoryStream return null; } + // ignore link to self and parent directories + if (isSelfOrParent(name)) + continue; + // grab the attributes from the WIN32_FIND_DATA structure // (needs to be done while holding closeLock because close // will release the buffer) diff --git a/src/windows/classes/sun/nio/fs/WindowsPathParser.java b/src/windows/classes/sun/nio/fs/WindowsPathParser.java index f1158e5f7de714f941f81d49b660b05741f656bc..c45858b4ae9d80fe1b0e4a3e0acca674f15587d3 100644 --- a/src/windows/classes/sun/nio/fs/WindowsPathParser.java +++ b/src/windows/classes/sun/nio/fs/WindowsPathParser.java @@ -120,12 +120,18 @@ class WindowsPathParser { off = next; } else { if (isLetter(c0) && c1 == ':') { - root = input.substring(0, 2); - if (len > 2 && isSlash(input.charAt(2))) { + char c2; + if (len > 2 && isSlash(c2 = input.charAt(2))) { + // avoid concatenation when root is "D:\" + if (c2 == '\\') { + root = input.substring(0, 3); + } else { + root = input.substring(0, 2) + '\\'; + } off = 3; - root += "\\"; type = WindowsPathType.ABSOLUTE; } else { + root = input.substring(0, 2); off = 2; type = WindowsPathType.DRIVE_RELATIVE; } diff --git a/test/ProblemList.txt b/test/ProblemList.txt index 9f91b1879b205616039259ab8a6765c778f8884e..5b483f97cb4095df4d72ce1cbb3eee111a7f72e5 100644 --- a/test/ProblemList.txt +++ b/test/ProblemList.txt @@ -490,9 +490,6 @@ sun/security/pkcs11/ec/TestECDSA.java solaris-i586 #sun/security/pkcs11/ec/TestKeyFactory.java solaris-i586 sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java solaris-i586 -# Directly references PKCS11 class -sun/security/pkcs11/Provider/Absolute.java windows-x64 - # Fails on Fedora 9/Ubuntu 10.04 64bit, PKCS11Exception: CKR_DEVICE_ERROR sun/security/pkcs11/KeyAgreement/TestDH.java generic-all diff --git a/test/java/lang/ref/ReferenceEnqueue.java b/test/java/lang/ref/ReferenceEnqueue.java new file mode 100644 index 0000000000000000000000000000000000000000..25907a034cca9ebeb18a24db3f2b9d0e79a2f979 --- /dev/null +++ b/test/java/lang/ref/ReferenceEnqueue.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + * @bug 4268317 + * @summary Test if Reference.enqueue() works properly with GC + */ + +import java.lang.ref.*; + +public class ReferenceEnqueue { + + public static void main(String args[]) throws Exception { + for (int i=0; i < 5; i++) + new WeakRef().run(); + System.out.println("Test passed."); + } + + static class WeakRef { + final ReferenceQueue queue = new ReferenceQueue(); + final Reference ref; + final int iterations = 1000; + + WeakRef() { + this.ref = new WeakReference(new Object(), queue); + } + + void run() throws InterruptedException { + System.gc(); + for (int i = 0; i < iterations; i++) { + System.gc(); + if (ref.isEnqueued()) { + break; + } + + Thread.sleep(100); + } + + if (ref.isEnqueued() == false) { + // GC have not enqueued refWeak for the timeout period + System.out.println("Reference not enqueued yet"); + return; + } + + if (ref.enqueue() == true) { + // enqueue() should return false since + // ref is already enqueued by the GC + throw new RuntimeException("Error: enqueue() returned true;" + + " expected false"); + } + + if (queue.poll() == null) { + // poll() should return ref enqueued by the GC + throw new RuntimeException("Error: poll() returned null;" + + " expected ref object"); + } + } + } +} diff --git a/test/java/lang/ref/ReferenceEnqueuePending.java b/test/java/lang/ref/ReferenceEnqueuePending.java new file mode 100644 index 0000000000000000000000000000000000000000..0e8868fa9fd67b4244c8c3266fa4a3606fe698d4 --- /dev/null +++ b/test/java/lang/ref/ReferenceEnqueuePending.java @@ -0,0 +1,201 @@ +/* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + * @bug 4243978 + * @summary Test if Reference.enqueue() works properly with pending references + */ +import java.lang.ref.*; + +public class ReferenceEnqueuePending { + static class NumberedWeakReference extends WeakReference { + // Add an integer to identify the weak reference object. + int number; + + NumberedWeakReference(Integer referent, ReferenceQueue q, int i) { + super(referent, q); + number = i; + } + } + + final static boolean debug = System.getProperty("test.debug") != null; + final static int iterations = 1000; + final static int gc_trigger = 99; + static int[] a = new int[2 * iterations]; + // Keep all weak references alive with the following array. + static NumberedWeakReference[] b = new NumberedWeakReference[iterations]; + + public static void main(String[] argv) throws Exception { + if (debug) { + System.out.println("Starting the test."); + } + // Raise thread priority to match the referenceHandler + // priority, so that they can race also on a uniprocessor. + raisePriority(); + + ReferenceQueue refQueue = new ReferenceQueue<>(); + + // Our objective is to let the mutator enqueue + // a Reference object that may already be in the + // pending state because of having been identified + // as weakly reachable at a previous garbage collection. + // To this end, we create many Reference objects, each with a + // a unique integer object as its referant. + // We let the referents become eligible for collection, + // while racing with the garbage collector which may + // have pended some of these Reference objects. + // Finally we check that all of the Reference objects + // end up on the their queue. The test was originally + // submitted to show that such races could break the + // pending list and/or the reference queue, because of sharing + // the same link ("next") for maintaining both lists, thus + // losing some of the Reference objects on either queue. + + Integer obj = new Integer(0); + NumberedWeakReference weaky = new NumberedWeakReference(obj, refQueue, 0); + for (int i = 1; i < iterations; i++) { + // Create a new object, dropping the onlY strong reference to + // the previous Integer object. + obj = new Integer(i); + // Trigger gc each gc_trigger iterations. + if ((i % gc_trigger) == 0) { + forceGc(0); + } + // Enqueue every other weaky. + if ((i % 2) == 0) { + weaky.enqueue(); + } + // Remember the Reference objects, for testing later. + b[i - 1] = weaky; + // Get a new weaky for the Integer object just + // created, which may be explicitly enqueued in + // our next trip around the loop. + weaky = new NumberedWeakReference(obj, refQueue, i); + } + + // Do a final collection to discover and process all + // Reference objects created above, allowing enough time + // for the ReferenceHandler thread to queue the References. + forceGc(100); + forceGc(100); + + // Verify that all WeakReference objects ended up queued. + checkResult(refQueue, obj, iterations-1); + System.out.println("Test passed."); + } + + private static void checkResult(ReferenceQueue queue, + Integer obj, + int expected) { + if (debug) { + System.out.println("Reading the queue"); + } + + // Empty the queue and record numbers into a[]; + NumberedWeakReference weakRead = (NumberedWeakReference) queue.poll(); + int length = 0; + while (weakRead != null) { + a[length++] = weakRead.number; + weakRead = (NumberedWeakReference) queue.poll(); + } + if (debug) { + System.out.println("Reference Queue had " + length + " elements"); + } + // Use the last Reference object of those created above, so as to keep it "alive". + System.out.println("I must write " + obj + " to prevent compiler optimizations."); + + + // verify the queued references: all but the last Reference object + // should have been in the queue. + if (debug) { + System.out.println("Start of final check"); + } + + // Sort the first "length" elements in array "a[]". + sort(length); + + boolean fail = (length != expected); + for (int i = 0; i < length; i++) { + if (a[i] != i) { + if (debug) { + System.out.println("a[" + i + "] is not " + i + " but " + a[i]); + } + fail = true; + } + } + if (fail) { + printMissingElements(length, expected); + throw new RuntimeException("TEST FAILED: only " + length + + " reference objects have been queued out of " + + expected); + } + } + + private static void printMissingElements(int length, int expected) { + System.out.println("The following numbers were not found in the reference queue: "); + int missing = 0; + int element = 0; + for (int i = 0; i < length; i++) { + while ((a[i] != element) & (element < expected)) { + System.out.print(element + " "); + if (missing % 20 == 19) { + System.out.println(" "); + } + missing++; + element++; + } + element++; + } + System.out.print("\n"); + } + + private static void forceGc(long millis) throws InterruptedException { + Runtime.getRuntime().gc(); + Thread.sleep(millis); + } + + // Bubble sort the first "length" elements in array "a". + private static void sort(int length) { + int hold; + if (debug) { + System.out.println("Sorting. Length=" + length); + } + for (int pass = 1; pass < length; pass++) { // passes over the array + for (int i = 0; i < length - pass; i++) { // a single pass + if (a[i] > a[i + 1]) { // then swap + hold = a[i]; + a[i] = a[i + 1]; + a[i + 1] = hold; + } + } // End of i loop + } // End of pass loop + } + + // Raise thread priority so as to increase the + // probability of the mutator succeeding in enqueueing + // an object that is still in the pending state. + // This is (probably) only required for a uniprocessor. + static void raisePriority() { + Thread tr = Thread.currentThread(); + tr.setPriority(Thread.MAX_PRIORITY); + } +} // End of class ReferenceEnqueuePending diff --git a/test/java/nio/charset/coders/Errors.java b/test/java/nio/charset/coders/Errors.java index be19c0b403d04f7f7ebb441af09d74b4abdfa114..0b74001dd6e1da9eb2c9365baeff6e985682989a 100644 --- a/test/java/nio/charset/coders/Errors.java +++ b/test/java/nio/charset/coders/Errors.java @@ -23,7 +23,7 @@ /* @test * @summary Check that error cases are replaced correctly in String/ISR/OSW - * @bug 4457851 + * @bug 4457851 7096080 * * @build Errors Util * @run main Errors @@ -193,11 +193,9 @@ public class Errors { t.test("\uFFFF", new byte[] { (byte)0xEF, (byte)0xBF, (byte)0xBF }); t.test(new byte[] { X, (byte)0x7f, Y }, "x\u007Fy"); t.test(new byte[] { X, (byte)0x80, Y }, "x\uFFFDy"); - t.test(new byte[] { (byte)0xf0, (byte)0xf0 }, "\uFFFD"); } public static void main(String[] args) throws Exception { - test_US_ASCII(new TestString("US-ASCII")); test_US_ASCII(new TestStream("US-ASCII")); diff --git a/test/java/util/Collections/EmptySortedSet.java b/test/java/util/Collections/EmptySortedSet.java new file mode 100644 index 0000000000000000000000000000000000000000..224400ec7a8d8e5e86f76c6a58143b96bd38a77d --- /dev/null +++ b/test/java/util/Collections/EmptySortedSet.java @@ -0,0 +1,351 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 4533691 + * @summary Unit test for Collections.emptySortedSet + */ + +import java.lang.reflect.Method; +import java.math.BigInteger; +import java.util.Collections; +import java.util.Comparator; +import java.util.Iterator; +import java.util.NoSuchElementException; +import java.util.SortedSet; +import java.util.TreeSet; + +public class EmptySortedSet { + static int status = 0; + private static final String FAILED = " failed. "; + private static final String PERIOD = "."; + private final String thisClassName = this.getClass().getName(); + + public static void main(String[] args) throws Exception { + new EmptySortedSet(); + } + + public EmptySortedSet() throws Exception { + run(); + } + + /** + * Returns {@code true} if the {@link Object} passed in is an empty + * {@link SortedSet}. + * + * @param obj the object to test + * @return {@code true} if the {@link Object} is an empty {@link SortedSet} + * otherwise {@code false}. + */ + private boolean isEmptySortedSet(Object obj) { + boolean isEmptySortedSet = false; + + // We determine if the object is an empty sorted set by testing if it's + // an instance of SortedSet, and if so, if it's empty. Currently the + // testing doesn't include checks of the other methods. + if (obj instanceof SortedSet) { + SortedSet ss = (SortedSet) obj; + + if ((ss.isEmpty()) && (ss.size() == 0)) { + isEmptySortedSet = true; + } + } + + return isEmptySortedSet; + } + + private void run() throws Exception { + Method[] methods = this.getClass().getDeclaredMethods(); + + for (int i = 0; i < methods.length; i++) { + Method method = methods[i]; + String methodName = method.getName(); + + if (methodName.startsWith("test")) { + try { + Object obj = method.invoke(this, new Object[0]); + } catch(Exception e) { + throw new Exception(this.getClass().getName() + "." + + methodName + " test failed, test exception " + + "follows\n" + e.getCause()); + } + } + } + } + + private void throwException(String methodName, String reason) + throws Exception + { + StringBuilder sb = new StringBuilder(thisClassName); + sb.append(PERIOD); + sb.append(methodName); + sb.append(FAILED); + sb.append(reason); + throw new Exception(sb.toString()); + } + + /** + * + */ + private void test00() throws Exception { + //throwException("test00", "This test has not been implemented yet."); + } + + /** + * Tests that the comparator is {@code null}. + */ + private void testComparatorIsNull() throws Exception { + SortedSet sortedSet = Collections.emptySortedSet(); + Comparator comparator = sortedSet.comparator(); + + if (comparator != null) { + throwException("testComparatorIsNull", "Comparator is not null."); + } + } + + /** + * Tests that the contains method returns {@code false}. + */ + private void testContains() throws Exception { + SortedSet sortedSet = Collections.emptySortedSet(); + + if (sortedSet.contains(new Object())) { + throwException("testContains", "Should not contain any elements."); + } + } + + /** + * Tests that the containsAll method returns {@code false}. + */ + private void testContainsAll() throws Exception { + SortedSet sortedSet = Collections.emptySortedSet(); + TreeSet treeSet = new TreeSet(); + treeSet.add("1"); + treeSet.add("2"); + treeSet.add("3"); + + if (sortedSet.containsAll(treeSet)) { + throwException("testContainsAll", + "Should not contain any elements."); + } + } + + /** + * Tests that the iterator is empty. + */ + private void testEmptyIterator() throws Exception { + SortedSet sortedSet = Collections.emptySortedSet(); + Iterator emptyIterator = sortedSet.iterator(); + + if ((emptyIterator != null) && (emptyIterator.hasNext())) { + throwException("testEmptyIterator", "The iterator is not empty."); + } + } + + /** + * Tests that the set is empty. + */ + private void testIsEmpty() throws Exception { + SortedSet sortedSet = Collections.emptySortedSet(); + + if ((sortedSet != null) && (!sortedSet.isEmpty())) { + throwException("testSizeIsZero", "The set is not empty."); + } + } + + /** + * Tests that the first() method throws NoSuchElementException + */ + private void testFirst() throws Exception { + SortedSet sortedSet = Collections.emptySortedSet(); + + try { + sortedSet.first(); + throwException("testFirst", + "NoSuchElemenException was not thrown."); + } catch(NoSuchElementException nsee) { + // Do nothing + } + } + + /** + * Tests the headSet() method. + */ + private void testHeadSet() throws Exception { + SortedSet sortedSet = Collections.emptySortedSet(); + SortedSet ss; + + try { + ss = sortedSet.headSet(null); + throwException("testHeadSet", + "Must throw NullPointerException for null element"); + } catch(NullPointerException npe) { + // Do nothing + } + + try { + ss = sortedSet.headSet(new Object()); + throwException("testHeadSet", + "Must throw ClassCastException for non-Comparable element"); + } catch(ClassCastException cce) { + // Do nothing. + } + + ss = sortedSet.headSet("1"); + + if ((ss == null) || !isEmptySortedSet(ss)) { + throwException("testHeadSet", + "Returned value is null or not an EmptySortedSet."); + } + } + + /** + * Tests that the last() method throws NoSuchElementException + */ + private void testLast() throws Exception { + SortedSet sortedSet = Collections.emptySortedSet(); + + try { + sortedSet.last(); + throwException("testLast", + "NoSuchElemenException was not thrown."); + } catch(NoSuchElementException nsee) { + // Do nothing + } + } + + /** + * Tests that the size is 0. + */ + private void testSizeIsZero() throws Exception { + SortedSet sortedSet = Collections.emptySortedSet(); + int size = sortedSet.size(); + + if (size > 0) { + throwException("testSizeIsZero", + "The size of the set is greater then 0."); + } + } + + /** + * Tests the subSet() method. + */ + private void testSubSet() throws Exception { + SortedSet sortedSet = Collections.emptySortedSet(); + SortedSet ss = sortedSet.headSet("1"); + + try { + ss = sortedSet.subSet(null, BigInteger.TEN); + ss = sortedSet.subSet(BigInteger.ZERO, null); + ss = sortedSet.subSet(null, null); + throwException("testSubSet", + "Must throw NullPointerException for null element"); + } catch(NullPointerException npe) { + // Do nothing + } + + try { + Object obj1 = new Object(); + Object obj2 = new Object(); + ss = sortedSet.subSet(obj1, BigInteger.TEN); + ss = sortedSet.subSet(BigInteger.ZERO, obj2); + ss = sortedSet.subSet(obj1, obj2); + throwException("testSubSet", + "Must throw ClassCastException for parameter which is " + + "not Comparable."); + } catch(ClassCastException cce) { + // Do nothing. + } + + try { + ss = sortedSet.subSet(BigInteger.ZERO, BigInteger.ZERO); + ss = sortedSet.subSet(BigInteger.TEN, BigInteger.ZERO); + throwException("testSubSet", + "Must throw IllegalArgumentException when fromElement is " + + "not less then then toElement."); + } catch(IllegalArgumentException iae) { + // Do nothing. + } + + ss = sortedSet.subSet(BigInteger.ZERO, BigInteger.TEN); + + if (!isEmptySortedSet(ss)) { + throw new Exception("Returned value is not empty sorted set."); + } + } + + /** + * Tests the tailSet() method. + */ + private void testTailSet() throws Exception { + SortedSet sortedSet = Collections.emptySortedSet(); + SortedSet ss; + + try { + ss = sortedSet.tailSet(null); + throwException("testTailSet", + "Must throw NullPointerException for null element"); + } catch(NullPointerException npe) { + // Do nothing + } + + try { + SortedSet ss2 = sortedSet.tailSet(new Object()); + throwException("testTailSet", + "Must throw ClassCastException for non-Comparable element"); + } catch(ClassCastException cce) { + // Do nothing. + } + + ss = sortedSet.tailSet("1"); + + if ((ss == null) || !isEmptySortedSet(ss)) { + throwException("testTailSet", + "Returned value is null or not an EmptySortedSet."); + } + } + + /** + * Tests that the array has a size of 0. + */ + private void testToArray() throws Exception { + SortedSet sortedSet = Collections.emptySortedSet(); + Object[] emptySortedSetArray = sortedSet.toArray(); + + if ((emptySortedSetArray == null) || (emptySortedSetArray.length > 0)) { + throwException("testToArray", + "Returned null array or array with length > 0."); + } + + String[] strings = new String[2]; + strings[0] = "1"; + strings[1] = "2"; + emptySortedSetArray = sortedSet.toArray(strings); + + if ((emptySortedSetArray == null) || (emptySortedSetArray[0] != null)) { + throwException("testToArray", + "Returned null array or array with length > 0."); + } + } +} diff --git a/test/javax/xml/crypto/dsig/GenerationTests.java b/test/javax/xml/crypto/dsig/GenerationTests.java index e4a963847ec63f34f789d383ec30edcb3e44dab9..60ce1c66de2e89518a72cd60d9e1b3f9c41dbd08 100644 --- a/test/javax/xml/crypto/dsig/GenerationTests.java +++ b/test/javax/xml/crypto/dsig/GenerationTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /** * @test - * @bug 4635230 6283345 6303830 6824440 6867348 + * @bug 4635230 6283345 6303830 6824440 6867348 7094155 * @summary Basic unit tests for generating XML Signatures with JSR 105 * @compile -XDignore.symbol.file KeySelectors.java SignatureValidator.java * X509KeySelector.java GenerationTests.java @@ -134,6 +134,7 @@ public class GenerationTests { test_create_signature_enveloping_sha512_rsa_sha384(); test_create_signature_enveloping_sha512_rsa_sha512(); test_create_signature_reference_dependency(); + test_create_signature_with_attr_in_no_namespace(); } private static void setup() throws Exception { @@ -443,6 +444,52 @@ public class GenerationTests { sig.sign(dsc); +// dumpDocument(doc, new PrintWriter(System.out)); + + DOMValidateContext dvc = new DOMValidateContext + (kvks, doc.getDocumentElement()); + XMLSignature sig2 = fac.unmarshalXMLSignature(dvc); + + if (sig.equals(sig2) == false) { + throw new Exception + ("Unmarshalled signature is not equal to generated signature"); + } + if (sig2.validate(dvc) == false) { + throw new Exception("Validation of generated signature failed"); + } + + System.out.println(); + } + + static void test_create_signature_with_attr_in_no_namespace() + throws Exception + { + System.out.println + ("* Generating signature-with-attr-in-no-namespace.xml"); + + // create references + List refs = Collections.singletonList + (fac.newReference("#unknown", sha1)); + + // create SignedInfo + SignedInfo si = fac.newSignedInfo(withoutComments, rsaSha1, refs); + + // create object-1 + Document doc = db.newDocument(); + Element nc = doc.createElementNS(null, "NonCommentandus"); + // add attribute with no namespace + nc.setAttribute("Id", "unknown"); + XMLObject obj = fac.newXMLObject(Collections.singletonList + (new DOMStructure(nc)), "object-1", null, null); + + // create XMLSignature + XMLSignature sig = fac.newXMLSignature(si, rsa, + Collections.singletonList(obj), + "signature", null); + DOMSignContext dsc = new DOMSignContext(getPrivateKey("RSA"), doc); + + sig.sign(dsc); + // dumpDocument(doc, new PrintWriter(System.out)); DOMValidateContext dvc = new DOMValidateContext diff --git a/test/sun/nio/cs/TestStringCoding.java b/test/sun/nio/cs/TestStringCoding.java index c4837e956ae14a465a9bccb23b882cbd0bc0ba71..09e614448896640d51a65added4b1a905a2ecfdf 100644 --- a/test/sun/nio/cs/TestStringCoding.java +++ b/test/sun/nio/cs/TestStringCoding.java @@ -24,7 +24,7 @@ */ /* @test - @bug 6636323 6636319 7040220 + @bug 6636323 6636319 7040220 7096080 @summary Test if StringCoding and NIO result have the same de/encoding result * @run main/othervm/timeout=2000 TestStringCoding */ @@ -111,7 +111,8 @@ public class TestStringCoding { //encode unmappable surrogates if (enc instanceof sun.nio.cs.ArrayEncoder && cs.contains(Charset.forName("ASCII"))) { - if (cs.name().equals("UTF-8")) // utf8 handles surrogates + if (cs.name().equals("UTF-8") || // utf8 handles surrogates + cs.name().equals("CESU-8")) // utf8 handles surrogates return; enc.replaceWith(new byte[] { (byte)'A'}); sun.nio.cs.ArrayEncoder cae = (sun.nio.cs.ArrayEncoder)enc; @@ -136,7 +137,6 @@ public class TestStringCoding { cs.name()))) throw new RuntimeException("encode3(surrogates) failed -> " + cs.name()); - ba = new byte[str.length() - 1]; n = cae.encode(str.toCharArray(), 0, str.length(), ba); if (n != 7 || !"abABABc".equals(new String(ba, 0, n, diff --git a/test/sun/nio/cs/TestStringCodingUTF8.java b/test/sun/nio/cs/TestStringCodingUTF8.java index fdc204849b7a9bb2035f2bb0f5aa543efea667ed..d1f699506846a9b67829830be8847d6b4d98befc 100644 --- a/test/sun/nio/cs/TestStringCodingUTF8.java +++ b/test/sun/nio/cs/TestStringCodingUTF8.java @@ -33,14 +33,16 @@ import java.nio.charset.*; public class TestStringCodingUTF8 { public static void main(String[] args) throws Throwable { - test(); + test("UTF-8"); + test("CESU-8"); // security manager on System.setSecurityManager(new PermissiveSecurityManger()); - test(); + test("UTF-8"); + test("CESU-8"); } - static void test() throws Throwable { - Charset cs = Charset.forName("UTF-8"); + static void test(String csn) throws Throwable { + Charset cs = Charset.forName(csn); char[] bmp = new char[0x10000]; for (int i = 0; i < 0x10000; i++) { bmp[i] = (char)i; diff --git a/test/sun/nio/cs/TestUTF8.java b/test/sun/nio/cs/TestUTF8.java index f339eae046b5a6134a6a7fb136984caf5f4af0f3..e83f8fbb51af9e22ee26bb93ee3663df12436b47 100644 --- a/test/sun/nio/cs/TestUTF8.java +++ b/test/sun/nio/cs/TestUTF8.java @@ -23,7 +23,7 @@ /* * @test - * @bug 4486841 7040220 + * @bug 4486841 7040220 7096080 * @summary Test UTF-8 charset */ @@ -156,15 +156,22 @@ public class TestUTF8 { return 3; } + static int to4ByteUTF8(int uc, byte[] bb, int pos) { + bb[pos++] = (byte)(0xf0 | ((uc >> 18))); + bb[pos++] = (byte)(0x80 | ((uc >> 12) & 0x3f)); + bb[pos++] = (byte)(0x80 | ((uc >> 6) & 0x3f)); + bb[pos++] = (byte)(0x80 | (uc & 0x3f)); + return 4; + } + static void checkRoundtrip(String csn) throws Exception { System.out.printf(" Check roundtrip <%s>...", csn); char[] cc = getUTFChars(); byte[] bb = encode(cc, csn, false); char[] ccO = decode(bb, csn, false); - if (!Arrays.equals(cc, ccO)) { + if (!Arrays.equals(cc, ccO)) System.out.printf(" non-direct failed"); - } bb = encode(cc, csn, true); ccO = decode(bb, csn, true); if (!Arrays.equals(cc, ccO)) { @@ -180,19 +187,24 @@ public class TestUTF8 { System.out.println(); } - static void check6ByteSurrs(String csn) throws Exception { - System.out.printf(" Check 6-byte Surrogates <%s>...%n", csn); - byte[] bb = new byte[(0x110000 - 0x10000) * 6]; + static void check4ByteSurrs(String csn) throws Exception { + System.out.printf(" Check 4-byte Surrogates <%s>...%n", csn); + byte[] bb = new byte[(0x110000 - 0x10000) * 4]; char[] cc = new char[(0x110000 - 0x10000) * 2]; int bpos = 0; int cpos = 0; for (int i = 0x10000; i < 0x110000; i++) { Character.toChars(i, cc, cpos); - bpos += to3ByteUTF8(cc[cpos], bb, bpos); - bpos += to3ByteUTF8(cc[cpos + 1], bb, bpos); + bpos += to4ByteUTF8(i, bb, bpos); cpos += 2; } + checkSurrs(csn, bb, cc); + } + + static void checkSurrs(String csn, byte[] bb, char[] cc) + throws Exception + { char[] ccO = decode(bb, csn, false); if (!Arrays.equals(cc, ccO)) { System.out.printf(" decoding failed%n"); @@ -201,14 +213,30 @@ public class TestUTF8 { if (!Arrays.equals(cc, ccO)) { System.out.printf(" decoding(direct) failed%n"); } - // new String(bb, csn).getBytes(csn) will not return - // the 6 bytes surrogates as in bb, so only test - // toCharArray() here. if (!Arrays.equals(cc, new String(bb, csn).toCharArray())) { System.out.printf(" String.toCharArray() failed"); } + if (!Arrays.equals(bb, new String(cc).getBytes(csn))) { + System.out.printf(" String.getBytes() failed"); + } + } + + static void check6ByteSurrs(String csn) throws Exception { + System.out.printf(" Check 6-byte Surrogates <%s>...%n", csn); + byte[] bb = new byte[(0x110000 - 0x10000) * 6]; + char[] cc = new char[(0x110000 - 0x10000) * 2]; + int bpos = 0; + int cpos = 0; + for (int i = 0x10000; i < 0x110000; i++) { + Character.toChars(i, cc, cpos); + bpos += to3ByteUTF8(cc[cpos], bb, bpos); + bpos += to3ByteUTF8(cc[cpos + 1], bb, bpos); + cpos += 2; + } + checkSurrs(csn, bb, cc); } + static void compare(String csn1, String csn2) throws Exception { System.out.printf(" Diff <%s> <%s>...%n", csn1, csn2); char[] cc = getUTFChars(); @@ -266,6 +294,10 @@ public class TestUTF8 { {1, (byte)0xFF, (byte)0xFF, (byte)0xFF }, // all ones {1, (byte)0xE0, (byte)0xC0, (byte)0x80 }, // invalid second byte {1, (byte)0xE0, (byte)0x80, (byte)0xC0 }, // invalid first byte + {1, (byte)0xE0, (byte)0x41,}, // invalid second byte & 2 bytes + {3, (byte)0xED, (byte)0xAE, (byte)0x80 }, // 3 bytes surrogate + {3, (byte)0xED, (byte)0xB0, (byte)0x80 }, // 3 bytes surrogate + // Four-byte sequences {1, (byte)0xF0, (byte)0x80, (byte)0x80, (byte)0x80 }, // U+0000 zero-padded @@ -276,8 +308,13 @@ public class TestUTF8 { {1, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF }, // all ones {1, (byte)0xF0, (byte)0x80, (byte)0x80, (byte)0x80}, // invalid second byte {1, (byte)0xF0, (byte)0xC0, (byte)0x80, (byte)0x80 }, // invalid second byte + {1, (byte)0xF0, (byte)41 }, // invalid second byte + // & only 2 bytes + {2, (byte)0xF0, (byte)0x90, (byte)0xC0, (byte)0x80 }, // invalid third byte - {3, (byte)0xF0, (byte)0x90, (byte)0x80, (byte)0xC0 }, // invalid third byte + {3, (byte)0xF0, (byte)0x90, (byte)0x80, (byte)0xC0 }, // invalid forth byte + {2, (byte)0xF0, (byte)0x90, (byte)0x41 }, // invalid third byte + // & 3 bytes input {1, (byte)0xF1, (byte)0xC0, (byte)0x80, (byte)0x80 }, // invalid second byte {2, (byte)0xF1, (byte)0x80, (byte)0xC0, (byte)0x80 }, // invalid third byte @@ -287,30 +324,113 @@ public class TestUTF8 { {1, (byte)0xF5, (byte)0x80, (byte)0x80, (byte)0xC0 }, // out-range 4-byte // Five-byte sequences - {5, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0x80, (byte)0x80}, // invalid first byte - {5, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0x80, (byte)0x80 }, // U+0000 zero-padded - {5, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0x81, (byte)0xBF }, // U+007F zero-padded - {5, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0x9F, (byte)0xBF }, // U+07FF zero-padded - {5, (byte)0xF8, (byte)0x80, (byte)0x8F, (byte)0xBF, (byte)0xBF }, // U+FFFF zero-padded + {1, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0x80, (byte)0x80}, // invalid first byte + {1, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0x80, (byte)0x80 }, // U+0000 zero-padded + {1, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0x81, (byte)0xBF }, // U+007F zero-padded + {1, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0x9F, (byte)0xBF }, // U+07FF zero-padded + {1, (byte)0xF8, (byte)0x80, (byte)0x8F, (byte)0xBF, (byte)0xBF }, // U+FFFF zero-padded {1, (byte)0xF8, (byte)0xC0, (byte)0x80, (byte)0x80, (byte)0x80}, - {2, (byte)0xF8, (byte)0x80, (byte)0xC0, (byte)0x80, (byte)0x80 }, - {3, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0xC1, (byte)0xBF }, - {4, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0x9F, (byte)0xC0 }, + {1, (byte)0xF8, (byte)0x80, (byte)0xC0, (byte)0x80, (byte)0x80 }, + {1, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0xC1, (byte)0xBF }, + {1, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0x9F, (byte)0xC0 }, // Six-byte sequences - {6, (byte)0xFC, (byte)0x80, (byte)0x80, (byte)0x80, (byte)0x80, (byte)0x80 }, // U+0000 zero-padded - {6, (byte)0xFC, (byte)0x80, (byte)0x80, (byte)0x80, (byte)0x81, (byte)0xBF }, // U+007F zero-padded - {6, (byte)0xFC, (byte)0x80, (byte)0x80, (byte)0x80, (byte)0x9F, (byte)0xBF }, // U+07FF zero-padded - {6, (byte)0xFC, (byte)0x80, (byte)0x80, (byte)0x8F, (byte)0xBF, (byte)0xBF }, // U+FFFF zero-padded + {1, (byte)0xFC, (byte)0x80, (byte)0x80, (byte)0x80, (byte)0x80, (byte)0x80 }, // U+0000 zero-padded + {1, (byte)0xFC, (byte)0x80, (byte)0x80, (byte)0x80, (byte)0x81, (byte)0xBF }, // U+007F zero-padded + {1, (byte)0xFC, (byte)0x80, (byte)0x80, (byte)0x80, (byte)0x9F, (byte)0xBF }, // U+07FF zero-padded + {1, (byte)0xFC, (byte)0x80, (byte)0x80, (byte)0x8F, (byte)0xBF, (byte)0xBF }, // U+FFFF zero-padded {1, (byte)0xF8, (byte)0xC0, (byte)0x80, (byte)0x80, (byte)0x80, (byte)0x80 }, - {2, (byte)0xF8, (byte)0x80, (byte)0xC0, (byte)0x80, (byte)0x80, (byte)0x80 }, - {3, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0xC1, (byte)0xBF, (byte)0x80 }, - {4, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0x9F, (byte)0xC0, (byte)0x80 }, - {5, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0x9F, (byte)0x80, (byte)0xC0 }, + {1, (byte)0xF8, (byte)0x80, (byte)0xC0, (byte)0x80, (byte)0x80, (byte)0x80 }, + {1, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0xC1, (byte)0xBF, (byte)0x80 }, + {1, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0x9F, (byte)0xC0, (byte)0x80 }, + {1, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0x9F, (byte)0x80, (byte)0xC0 }, }; - static void checkMalformed(String csn) throws Exception { + // The first byte is the length of malformed bytes + static byte[][] malformed_cesu8 = { + // One-byte sequences: + {1, (byte)0xFF }, + {1, (byte)0xC0 }, + {1, (byte)0x80 }, + + {1, (byte)0xFF, (byte)0xFF}, // all ones + {1, (byte)0xA0, (byte)0x80}, // 101x first byte first nibble + + // Two-byte sequences: + {1, (byte)0xC0, (byte)0x80}, // invalid first byte + {1, (byte)0xC1, (byte)0xBF}, // invalid first byte + {1, (byte)0xC2, (byte)0x00}, // invalid second byte + {1, (byte)0xC2, (byte)0xC0}, // invalid second byte + {1, (byte)0xD0, (byte)0x00}, // invalid second byte + {1, (byte)0xD0, (byte)0xC0}, // invalid second byte + {1, (byte)0xDF, (byte)0x00}, // invalid second byte + {1, (byte)0xDF, (byte)0xC0}, // invalid second byte + + // Three-byte sequences + {1, (byte)0xE0, (byte)0x80, (byte)0x80}, // 111x first byte first nibble + {1, (byte)0xE0, (byte)0x80, (byte)0x80 }, // U+0000 zero-padded + {1, (byte)0xE0, (byte)0x81, (byte)0xBF }, // U+007F zero-padded + {1, (byte)0xE0, (byte)0x9F, (byte)0xBF }, // U+07FF zero-padded + + {1, (byte)0xE0, (byte)0xC0, (byte)0xBF }, // invalid second byte + {2, (byte)0xE0, (byte)0xA0, (byte)0x7F }, // invalid third byte + {2, (byte)0xE0, (byte)0xA0, (byte)0xC0 }, // invalid third byte + {1, (byte)0xFF, (byte)0xFF, (byte)0xFF }, // all ones + {1, (byte)0xE0, (byte)0xC0, (byte)0x80 }, // invalid second byte + {1, (byte)0xE0, (byte)0x80, (byte)0xC0 }, // invalid first byte + {1, (byte)0xE0, (byte)0x41,}, // invalid second byte & 2 bytes + + // CESU-8 does not have 4, 5, 6 bytes sequenc + // Four-byte sequences + {1, (byte)0xF0, (byte)0x80, (byte)0x80, (byte)0x80 }, // U+0000 zero-padded + {1, (byte)0xF0, (byte)0x80, (byte)0x81, (byte)0xBF }, // U+007F zero-padded + {1, (byte)0xF0, (byte)0x80, (byte)0x9F, (byte)0xBF }, // U+007F zero-padded + {1, (byte)0xF0, (byte)0x8F, (byte)0xBF, (byte)0xBF }, // U+07FF zero-padded + + {1, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF }, // all ones + {1, (byte)0xF0, (byte)0x80, (byte)0x80, (byte)0x80}, // invalid second byte + {1, (byte)0xF0, (byte)0xC0, (byte)0x80, (byte)0x80 }, // invalid second byte + {1, (byte)0xF0, (byte)41 }, // invalid second byte + // & only 2 bytes + {1, (byte)0xF0, (byte)0x90, (byte)0xC0, (byte)0x80 }, // invalid third byte + {1, (byte)0xF0, (byte)0x90, (byte)0x80, (byte)0xC0 }, // invalid forth byte + {1, (byte)0xF0, (byte)0x90, (byte)0x41 }, // invalid third byte + // & 3 bytes input + + {1, (byte)0xF1, (byte)0xC0, (byte)0x80, (byte)0x80 }, // invalid second byte + {1, (byte)0xF1, (byte)0x80, (byte)0xC0, (byte)0x80 }, // invalid third byte + {1, (byte)0xF1, (byte)0x80, (byte)0x80, (byte)0xC0 }, // invalid forth byte + {1, (byte)0xF4, (byte)0x90, (byte)0x80, (byte)0xC0 }, // out-range 4-byte + {1, (byte)0xF4, (byte)0xC0, (byte)0x80, (byte)0xC0 }, // out-range 4-byte + {1, (byte)0xF5, (byte)0x80, (byte)0x80, (byte)0xC0 }, // out-range 4-byte + + // Five-byte sequences + {1, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0x80, (byte)0x80}, // invalid first byte + {1, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0x80, (byte)0x80 }, // U+0000 zero-padded + {1, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0x81, (byte)0xBF }, // U+007F zero-padded + {1, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0x9F, (byte)0xBF }, // U+07FF zero-padded + {1, (byte)0xF8, (byte)0x80, (byte)0x8F, (byte)0xBF, (byte)0xBF }, // U+FFFF zero-padded + + {1, (byte)0xF8, (byte)0xC0, (byte)0x80, (byte)0x80, (byte)0x80}, + {1, (byte)0xF8, (byte)0x80, (byte)0xC0, (byte)0x80, (byte)0x80 }, + {1, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0xC1, (byte)0xBF }, + {1, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0x9F, (byte)0xC0 }, + + // Six-byte sequences + {1, (byte)0xFC, (byte)0x80, (byte)0x80, (byte)0x80, (byte)0x80, (byte)0x80 }, // U+0000 zero-padded + {1, (byte)0xFC, (byte)0x80, (byte)0x80, (byte)0x80, (byte)0x81, (byte)0xBF }, // U+007F zero-padded + {1, (byte)0xFC, (byte)0x80, (byte)0x80, (byte)0x80, (byte)0x9F, (byte)0xBF }, // U+07FF zero-padded + {1, (byte)0xFC, (byte)0x80, (byte)0x80, (byte)0x8F, (byte)0xBF, (byte)0xBF }, // U+FFFF zero-padded + {1, (byte)0xF8, (byte)0xC0, (byte)0x80, (byte)0x80, (byte)0x80, (byte)0x80 }, + {1, (byte)0xF8, (byte)0x80, (byte)0xC0, (byte)0x80, (byte)0x80, (byte)0x80 }, + {1, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0xC1, (byte)0xBF, (byte)0x80 }, + {1, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0x9F, (byte)0xC0, (byte)0x80 }, + {1, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0x9F, (byte)0x80, (byte)0xC0 }, + }; + + + static void checkMalformed(String csn, byte[][] malformed) throws Exception { boolean failed = false; System.out.printf(" Check malformed <%s>...%n", csn); Charset cs = Charset.forName(csn); @@ -430,9 +550,12 @@ public class TestUTF8 { public static void main(String[] args) throws Exception { checkRoundtrip("UTF-8"); - check6ByteSurrs("UTF-8"); - //compare("UTF-8", "UTF-8-OLD"); - checkMalformed("UTF-8"); + check4ByteSurrs("UTF-8"); + checkMalformed("UTF-8", malformed); checkUnderOverflow("UTF-8"); + + checkRoundtrip("CESU-8"); + check6ByteSurrs("CESU-8"); + checkMalformed("CESU-8", malformed_cesu8); } } diff --git a/test/sun/security/pkcs11/Provider/Absolute.java b/test/sun/security/pkcs11/Provider/Absolute.java index e35f9c60c5841af14e8a1a675441413ec0da1922..fc035dc7c73e6d5b0a73e9e8969114546ee08fc3 100644 --- a/test/sun/security/pkcs11/Provider/Absolute.java +++ b/test/sun/security/pkcs11/Provider/Absolute.java @@ -27,7 +27,6 @@ */ import java.security.*; import java.lang.reflect.*; -import sun.security.pkcs11.*; public class Absolute { diff --git a/test/sun/security/pkcs11/fips/CipherTest.java b/test/sun/security/pkcs11/fips/CipherTest.java index 0d9f8b363e08f7e145381e834deee6ef4db0de4e..32bc6df4e160f16b1bf9ee4857291997e473cc56 100644 --- a/test/sun/security/pkcs11/fips/CipherTest.java +++ b/test/sun/security/pkcs11/fips/CipherTest.java @@ -394,52 +394,47 @@ public class CipherTest { public static void main(PeerFactory peerFactory, KeyStore keyStore, String[] args) throws Exception { - SSLContext reservedSSLContext = SSLContext.getDefault(); - try { - long time = System.currentTimeMillis(); - String relPath; - if ((args != null) && (args.length > 0) && args[0].equals("sh")) { - relPath = pathToStoresSH; - } else { - relPath = pathToStores; - } - PATH = new File(System.getProperty("test.src", "."), relPath); - CipherTest.peerFactory = peerFactory; - System.out.print( - "Initializing test '" + peerFactory.getName() + "'..."); -// secureRandom = new SecureRandom(); -// secureRandom.nextInt(); -// trustStore = readKeyStore(trustStoreFile); - CipherTest.keyStore = keyStore; -// keyStore = readKeyStore(keyStoreFile); - KeyManagerFactory keyFactory = - KeyManagerFactory.getInstance( - KeyManagerFactory.getDefaultAlgorithm()); - keyFactory.init(keyStore, "test12".toCharArray()); - keyManager = (X509ExtendedKeyManager)keyFactory.getKeyManagers()[0]; - - TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); - tmf.init(keyStore); - trustManager = (X509TrustManager)tmf.getTrustManagers()[0]; - -// trustManager = new AlwaysTrustManager(); - SSLContext context = SSLContext.getInstance("TLS"); - context.init(new KeyManager[] {keyManager}, - new TrustManager[] {trustManager}, null); - SSLContext.setDefault(context); - - CipherTest cipherTest = new CipherTest(peerFactory); - Thread serverThread = new Thread(peerFactory.newServer(cipherTest), - "Server"); - serverThread.setDaemon(true); - serverThread.start(); - System.out.println("Done"); - cipherTest.run(); - time = System.currentTimeMillis() - time; - System.out.println("Done. (" + time + " ms)"); - } finally { - SSLContext.setDefault(reservedSSLContext); + long time = System.currentTimeMillis(); + String relPath; + if ((args != null) && (args.length > 0) && args[0].equals("sh")) { + relPath = pathToStoresSH; + } else { + relPath = pathToStores; } + PATH = new File(System.getProperty("test.src", "."), relPath); + CipherTest.peerFactory = peerFactory; + System.out.print( + "Initializing test '" + peerFactory.getName() + "'..."); +// secureRandom = new SecureRandom(); +// secureRandom.nextInt(); +// trustStore = readKeyStore(trustStoreFile); + CipherTest.keyStore = keyStore; +// keyStore = readKeyStore(keyStoreFile); + KeyManagerFactory keyFactory = + KeyManagerFactory.getInstance( + KeyManagerFactory.getDefaultAlgorithm()); + keyFactory.init(keyStore, "test12".toCharArray()); + keyManager = (X509ExtendedKeyManager)keyFactory.getKeyManagers()[0]; + + TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + tmf.init(keyStore); + trustManager = (X509TrustManager)tmf.getTrustManagers()[0]; + +// trustManager = new AlwaysTrustManager(); + SSLContext context = SSLContext.getInstance("TLS"); + context.init(new KeyManager[] {keyManager}, + new TrustManager[] {trustManager}, null); + SSLContext.setDefault(context); + + CipherTest cipherTest = new CipherTest(peerFactory); + Thread serverThread = new Thread(peerFactory.newServer(cipherTest), + "Server"); + serverThread.setDaemon(true); + serverThread.start(); + System.out.println("Done"); + cipherTest.run(); + time = System.currentTimeMillis() - time; + System.out.println("Done. (" + time + " ms)"); } static abstract class PeerFactory { diff --git a/test/sun/security/pkcs11/fips/ClientJSSEServerJSSE.java b/test/sun/security/pkcs11/fips/ClientJSSEServerJSSE.java index 4cf931d969e9d9a6b7ec24dbbe90863973527e81..98dbdeea5e47cb99889f30fdee39f8a70a71d2c5 100644 --- a/test/sun/security/pkcs11/fips/ClientJSSEServerJSSE.java +++ b/test/sun/security/pkcs11/fips/ClientJSSEServerJSSE.java @@ -26,9 +26,9 @@ * @bug 6313675 6323647 * @summary Verify that all ciphersuites work in FIPS mode * @library .. - * @run main/othervm ClientJSSEServerJSSE * @ignore JSSE supported cipher suites are changed with CR 6916074, * need to update this test case in JDK 7 soon + * @run main/othervm ClientJSSEServerJSSE * @author Andreas Sterbenz */ diff --git a/test/sun/security/ssl/templates/SSLSocketSSLEngineTemplate.java b/test/sun/security/ssl/templates/SSLSocketSSLEngineTemplate.java new file mode 100644 index 0000000000000000000000000000000000000000..e31409a0f7495590e27963f3d2b0c8b4db32dea1 --- /dev/null +++ b/test/sun/security/ssl/templates/SSLSocketSSLEngineTemplate.java @@ -0,0 +1,479 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 7105780 + * @summary Add SSLSocket client/SSLEngine server to templates directory. + * + * SunJSSE does not support dynamic system properties, no way to re-use + * system properties in samevm/agentvm mode. + * + * @run main/othervm SSLSocketSSLEngineTemplate + */ + +/** + * A SSLSocket/SSLEngine interop test case. This is not the way to + * code SSLEngine-based servers, but works for what we need to do here, + * which is to make sure that SSLEngine/SSLSockets can talk to each other. + * SSLEngines can use direct or indirect buffers, and different code + * is used to get at the buffer contents internally, so we test that here. + * + * The test creates one SSLSocket (client) and one SSLEngine (server). + * The SSLSocket talks to a raw ServerSocket, and the server code + * does the translation between byte [] and ByteBuffers that the SSLEngine + * can use. The "transport" layer consists of a Socket Input/OutputStream + * and two byte buffers for the SSLEngines: think of them + * as directly connected pipes. + * + * Again, this is a *very* simple example: real code will be much more + * involved. For example, different threading and I/O models could be + * used, transport mechanisms could close unexpectedly, and so on. + * + * When this application runs, notice that several messages + * (wrap/unwrap) pass before any application data is consumed or + * produced. (For more information, please see the SSL/TLS + * specifications.) There may several steps for a successful handshake, + * so it's typical to see the following series of operations: + * + * client server message + * ====== ====== ======= + * write() ... ClientHello + * ... unwrap() ClientHello + * ... wrap() ServerHello/Certificate + * read() ... ServerHello/Certificate + * write() ... ClientKeyExchange + * write() ... ChangeCipherSpec + * write() ... Finished + * ... unwrap() ClientKeyExchange + * ... unwrap() ChangeCipherSpec + * ... unwrap() Finished + * ... wrap() ChangeCipherSpec + * ... wrap() Finished + * read() ... ChangeCipherSpec + * read() ... Finished + */ +import javax.net.ssl.*; +import javax.net.ssl.SSLEngineResult.*; +import java.io.*; +import java.net.*; +import java.security.*; +import java.nio.*; + +public class SSLSocketSSLEngineTemplate { + + /* + * Enables logging of the SSL/TLS operations. + */ + private static boolean logging = true; + + /* + * Enables the JSSE system debugging system property: + * + * -Djavax.net.debug=all + * + * This gives a lot of low-level information about operations underway, + * including specific handshake messages, and might be best examined + * after gaining some familiarity with this application. + */ + private static boolean debug = false; + private SSLContext sslc; + private SSLEngine serverEngine; // server-side SSLEngine + private SSLSocket sslSocket; // client-side socket + private ServerSocket serverSocket; // server-side Socket, generates the... + private Socket socket; // server-side socket that will read + + private final byte[] serverMsg = + "Hi there Client, I'm a Server.".getBytes(); + private final byte[] clientMsg = + "Hello Server, I'm a Client! Pleased to meet you!".getBytes(); + + private ByteBuffer serverOut; // write side of serverEngine + private ByteBuffer serverIn; // read side of serverEngine + + private volatile Exception clientException; + private volatile Exception serverException; + + /* + * For data transport, this example uses local ByteBuffers. + */ + private ByteBuffer cTOs; // "reliable" transport client->server + private ByteBuffer sTOc; // "reliable" transport server->client + + /* + * The following is to set up the keystores/trust material. + */ + private static final String pathToStores = "../etc/"; + private static final String keyStoreFile = "keystore"; + private static final String trustStoreFile = "truststore"; + private static final String passwd = "passphrase"; + private static String keyFilename = + System.getProperty("test.src", ".") + "/" + pathToStores + + "/" + keyStoreFile; + private static String trustFilename = + System.getProperty("test.src", ".") + "/" + pathToStores + + "/" + trustStoreFile; + + /* + * Main entry point for this test. + */ + public static void main(String args[]) throws Exception { + if (debug) { + System.setProperty("javax.net.debug", "all"); + } + + String [] protocols = new String [] { + "SSLv3", "TLSv1", "TLSv1.1", "TLSv1.2" }; + + for (String protocol : protocols) { + log("Testing " + protocol); + /* + * Run the tests with direct and indirect buffers. + */ + SSLSocketSSLEngineTemplate test = + new SSLSocketSSLEngineTemplate(protocol); + test.runTest(true); + test.runTest(false); + } + + System.out.println("Test Passed."); + } + + /* + * Create an initialized SSLContext to use for these tests. + */ + public SSLSocketSSLEngineTemplate(String protocol) throws Exception { + + KeyStore ks = KeyStore.getInstance("JKS"); + KeyStore ts = KeyStore.getInstance("JKS"); + + char[] passphrase = "passphrase".toCharArray(); + + ks.load(new FileInputStream(keyFilename), passphrase); + ts.load(new FileInputStream(trustFilename), passphrase); + + KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); + kmf.init(ks, passphrase); + + TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); + tmf.init(ts); + + SSLContext sslCtx = SSLContext.getInstance(protocol); + + sslCtx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); + + sslc = sslCtx; + } + + /* + * Run the test. + * + * Sit in a tight loop, with the server engine calling wrap/unwrap + * regardless of whether data is available or not. We do this until + * we get the application data. Then we shutdown and go to the next one. + * + * The main loop handles all of the I/O phases of the SSLEngine's + * lifetime: + * + * initial handshaking + * application data transfer + * engine closing + * + * One could easily separate these phases into separate + * sections of code. + */ + private void runTest(boolean direct) throws Exception { + boolean serverClose = direct; + + serverSocket = new ServerSocket(0); + int port = serverSocket.getLocalPort(); + Thread thread = createClientThread(port, serverClose); + + socket = serverSocket.accept(); + socket.setSoTimeout(500); + serverSocket.close(); + + createSSLEngine(); + createBuffers(direct); + + try { + boolean closed = false; + + InputStream is = socket.getInputStream(); + OutputStream os = socket.getOutputStream(); + + SSLEngineResult serverResult; // results from last operation + + /* + * Examining the SSLEngineResults could be much more involved, + * and may alter the overall flow of the application. + * + * For example, if we received a BUFFER_OVERFLOW when trying + * to write to the output pipe, we could reallocate a larger + * pipe, but instead we wait for the peer to drain it. + */ + byte[] inbound = new byte[8192]; + byte[] outbound = new byte[8192]; + + while (!isEngineClosed(serverEngine)) { + int len = 0; + + // Inbound data + log("================"); + + // Read from the Client side. + try { + len = is.read(inbound); + if (len == -1) { + throw new Exception("Unexpected EOF"); + } + cTOs.put(inbound, 0, len); + } catch (SocketTimeoutException ste) { + // swallow. Nothing yet, probably waiting on us. + } + + cTOs.flip(); + + serverResult = serverEngine.unwrap(cTOs, serverIn); + log("server unwrap: ", serverResult); + runDelegatedTasks(serverResult, serverEngine); + cTOs.compact(); + + // Outbound data + log("----"); + + serverResult = serverEngine.wrap(serverOut, sTOc); + log("server wrap: ", serverResult); + runDelegatedTasks(serverResult, serverEngine); + + sTOc.flip(); + + if ((len = sTOc.remaining()) != 0) { + sTOc.get(outbound, 0, len); + os.write(outbound, 0, len); + // Give the other side a chance to process + } + + sTOc.compact(); + + if (!closed && (serverOut.remaining() == 0)) { + closed = true; + + /* + * We'll alternate initiatating the shutdown. + * When the server initiates, it will take one more + * loop, but tests the orderly shutdown. + */ + if (serverClose) { + serverEngine.closeOutbound(); + } + serverIn.flip(); + + /* + * A sanity check to ensure we got what was sent. + */ + if (serverIn.remaining() != clientMsg.length) { + throw new Exception("Client: Data length error"); + } + + for (int i = 0; i < clientMsg.length; i++) { + if (clientMsg[i] != serverIn.get()) { + throw new Exception("Client: Data content error"); + } + } + serverIn.compact(); + } + } + return; + } catch (Exception e) { + serverException = e; + } finally { + socket.close(); + + // Wait for the client to join up with us. + thread.join(); + if (serverException != null) { + throw serverException; + } + if (clientException != null) { + throw clientException; + } + } + } + + /* + * Create a client thread which does simple SSLSocket operations. + * We'll write and read one data packet. + */ + private Thread createClientThread(final int port, + final boolean serverClose) throws Exception { + + Thread t = new Thread("ClientThread") { + + @Override + public void run() { + try { + Thread.sleep(1000); // Give server time to finish setup. + + sslSocket = (SSLSocket) sslc.getSocketFactory(). + createSocket("localhost", port); + OutputStream os = sslSocket.getOutputStream(); + InputStream is = sslSocket.getInputStream(); + + // write(byte[]) goes in one shot. + os.write(clientMsg); + + byte[] inbound = new byte[2048]; + int pos = 0; + + int len; +done: + while ((len = is.read(inbound, pos, 2048 - pos)) != -1) { + pos += len; + // Let the client do the closing. + if ((pos == serverMsg.length) && !serverClose) { + sslSocket.close(); + break done; + } + } + + if (pos != serverMsg.length) { + throw new Exception("Client: Data length error"); + } + + for (int i = 0; i < serverMsg.length; i++) { + if (inbound[i] != serverMsg[i]) { + throw new Exception("Client: Data content error"); + } + } + } catch (Exception e) { + clientException = e; + } + } + }; + t.start(); + return t; + } + + /* + * Using the SSLContext created during object creation, + * create/configure the SSLEngines we'll use for this test. + */ + private void createSSLEngine() throws Exception { + /* + * Configure the serverEngine to act as a server in the SSL/TLS + * handshake. + */ + serverEngine = sslc.createSSLEngine(); + serverEngine.setUseClientMode(false); + serverEngine.getNeedClientAuth(); + } + + /* + * Create and size the buffers appropriately. + */ + private void createBuffers(boolean direct) { + + SSLSession session = serverEngine.getSession(); + int appBufferMax = session.getApplicationBufferSize(); + int netBufferMax = session.getPacketBufferSize(); + + /* + * We'll make the input buffers a bit bigger than the max needed + * size, so that unwrap()s following a successful data transfer + * won't generate BUFFER_OVERFLOWS. + * + * We'll use a mix of direct and indirect ByteBuffers for + * tutorial purposes only. In reality, only use direct + * ByteBuffers when they give a clear performance enhancement. + */ + if (direct) { + serverIn = ByteBuffer.allocateDirect(appBufferMax + 50); + cTOs = ByteBuffer.allocateDirect(netBufferMax); + sTOc = ByteBuffer.allocateDirect(netBufferMax); + } else { + serverIn = ByteBuffer.allocate(appBufferMax + 50); + cTOs = ByteBuffer.allocate(netBufferMax); + sTOc = ByteBuffer.allocate(netBufferMax); + } + + serverOut = ByteBuffer.wrap(serverMsg); + } + + /* + * If the result indicates that we have outstanding tasks to do, + * go ahead and run them in this thread. + */ + private static void runDelegatedTasks(SSLEngineResult result, + SSLEngine engine) throws Exception { + + if (result.getHandshakeStatus() == HandshakeStatus.NEED_TASK) { + Runnable runnable; + while ((runnable = engine.getDelegatedTask()) != null) { + log("\trunning delegated task..."); + runnable.run(); + } + HandshakeStatus hsStatus = engine.getHandshakeStatus(); + if (hsStatus == HandshakeStatus.NEED_TASK) { + throw new Exception( + "handshake shouldn't need additional tasks"); + } + log("\tnew HandshakeStatus: " + hsStatus); + } + } + + private static boolean isEngineClosed(SSLEngine engine) { + return (engine.isOutboundDone() && engine.isInboundDone()); + } + + /* + * Logging code + */ + private static boolean resultOnce = true; + + private static void log(String str, SSLEngineResult result) { + if (!logging) { + return; + } + if (resultOnce) { + resultOnce = false; + System.out.println("The format of the SSLEngineResult is: \n" + + "\t\"getStatus() / getHandshakeStatus()\" +\n" + + "\t\"bytesConsumed() / bytesProduced()\"\n"); + } + HandshakeStatus hsStatus = result.getHandshakeStatus(); + log(str + + result.getStatus() + "/" + hsStatus + ", " + + result.bytesConsumed() + "/" + result.bytesProduced() + + " bytes"); + if (hsStatus == HandshakeStatus.FINISHED) { + log("\t...ready for application data"); + } + } + + private static void log(String str) { + if (logging) { + System.out.println(str); + } + } +} diff --git a/test/sun/tools/jinfo/Basic.sh b/test/sun/tools/jinfo/Basic.sh index 9d5cb468f9593322a375ff9bb1b7e0b67b053639..432dd62b403a18c4e28f0116daaa43a6198c0dbd 100644 --- a/test/sun/tools/jinfo/Basic.sh +++ b/test/sun/tools/jinfo/Basic.sh @@ -44,7 +44,19 @@ set +e failed=0 -if [ $isWindows = false ]; then +runSA=true + +if [ $isLinux = true ]; then + # Some Linux systems disable non-child ptrace (see 7050524) + ptrace_scope=`/sbin/sysctl -n kernel.yama.ptrace_scope` + if [ $? = 0 ]; then + if [ $ptrace_scope = 1 ]; then + runSA=false + fi + fi +fi + +if [ $runSA = true ]; then # -sysprops option ${JINFO} -J-XX:+UsePerfData -sysprops $appJavaPid if [ $? != 0 ]; then failed=1; fi