OpenJDK / jdk7u / jdk7u-dev / jdk
changeset 2942:faccd8fcd36c
Merge
author | lana |
---|---|
date | Mon, 18 Oct 2010 21:50:02 -0700 |
parents | cf13977eb9c0 426e5f2dbea3 |
children | 4e04d1e8f533 |
files | |
diffstat | 135 files changed, 3973 insertions(+), 2168 deletions(-) [+] |
line wrap: on
line diff
--- a/make/java/java/FILES_java.gmk Mon Oct 18 21:46:27 2010 -0700 +++ b/make/java/java/FILES_java.gmk Mon Oct 18 21:50:02 2010 -0700 @@ -465,14 +465,11 @@ java/security/ProtectionDomain.java \ java/net/URLClassLoader.java \ java/net/URLConnection.java \ + sun/misc/BootClassLoaderHook.java \ sun/misc/Launcher.java \ sun/misc/MetaIndex.java \ sun/misc/URLClassPath.java \ sun/misc/Version.java \ - sun/net/www/protocol/jar/Handler.java \ - sun/net/www/protocol/jar/JarURLConnection.java \ - sun/net/www/protocol/file/Handler.java \ - sun/net/www/protocol/file/FileURLConnection.java \ sun/misc/FileURLMapper.java \ sun/misc/MessageUtils.java \ sun/misc/GC.java \ @@ -482,6 +479,10 @@ sun/misc/JavaIOFileDescriptorAccess.java \ sun/misc/JavaNioAccess.java \ sun/misc/Perf.java \ - sun/misc/PerfCounter.java + sun/misc/PerfCounter.java \ + sun/net/www/protocol/jar/Handler.java \ + sun/net/www/protocol/jar/JarURLConnection.java \ + sun/net/www/protocol/file/Handler.java \ + sun/net/www/protocol/file/FileURLConnection.java FILES_java = $(JAVA_JAVA_java)
--- a/src/share/classes/com/sun/java/util/jar/pack/Attribute.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/com/sun/java/util/jar/pack/Attribute.java Mon Oct 18 21:50:02 2010 -0700 @@ -654,8 +654,8 @@ String layout; public FormatException(String message, int ctype, String name, String layout) { - super(ATTR_CONTEXT_NAME[ctype]+"."+name - +(message == null? "": (": "+message))); + super(ATTR_CONTEXT_NAME[ctype]+ " attribute \"" + name + "\"" + + (message == null? "" : (": " + message))); this.ctype = ctype; this.name = name; this.layout = layout;
--- a/src/share/classes/com/sun/java/util/jar/pack/ClassReader.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/com/sun/java/util/jar/pack/ClassReader.java Mon Oct 18 21:50:02 2010 -0700 @@ -30,6 +30,7 @@ import com.sun.java.util.jar.pack.Package.Class; import com.sun.java.util.jar.pack.Package.InnerClass; import com.sun.java.util.jar.pack.ConstantPool.*; +import com.sun.tools.classfile.AttributeException; /** * Reader for a class file that is being incorporated into a package. @@ -246,7 +247,9 @@ fixups[fptr++] = in.readUnsignedShort(); break; default: - throw new IOException("Bad constant pool tag "+tag); + throw new ClassFormatException("Bad constant pool tag " + + tag + " in File: " + cls.file.nameString + + " at pos: " + inPos); } } @@ -403,7 +406,7 @@ skip(length, "unknown "+name+" attribute in "+h); continue; } else { - String message = "unknown in "+h; + String message = " is unknown attribute in class " + h; throw new Attribute.FormatException(message, ctype, name, unknownAttrCommand); } @@ -415,7 +418,12 @@ if (a.name() == "Code") { Class.Method m = (Class.Method) h; m.code = new Code(m); - readCode(m.code); + try { + readCode(m.code); + } catch (Instruction.FormatException iie) { + String message = iie.getMessage() + " in " + h; + throw new ClassReader.ClassFormatException(message); + } } else { assert(h == cls); readInnerClasses(cls); @@ -427,6 +435,10 @@ in.readFully(bytes); a = a.addContent(bytes); } + if (a.size() == 0 && !a.layout().isEmpty()) { + throw new ClassFormatException(name + + ": attribute length cannot be zero, in " + h); + } h.addAttribute(a); if (verbose > 2) Utils.log.fine("read "+a); @@ -438,6 +450,7 @@ code.max_locals = readUnsignedShort(); code.bytes = new byte[readInt()]; in.readFully(code.bytes); + Instruction.opcodeChecker(code.bytes); int nh = readUnsignedShort(); code.setHandlerCount(nh); for (int i = 0; i < nh; i++) { @@ -463,4 +476,10 @@ cls.innerClasses = ics; // set directly; do not use setInnerClasses. // (Later, ics may be transferred to the pkg.) } + + class ClassFormatException extends IOException { + public ClassFormatException(String message) { + super(message); + } + } }
--- a/src/share/classes/com/sun/java/util/jar/pack/Instruction.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/com/sun/java/util/jar/pack/Instruction.java Mon Oct 18 21:50:02 2010 -0700 @@ -25,6 +25,8 @@ package com.sun.java.util.jar.pack; +import java.io.IOException; + /** * A parsed bytecode instruction. * Provides accessors to various relevant bits. @@ -628,4 +630,21 @@ } } } + + public static void opcodeChecker(byte[] code) throws FormatException { + Instruction i = at(code, 0); + while (i != null) { + int opcode = i.getBC(); + if (opcode == _xxxunusedxxx || opcode < _nop || opcode > _jsr_w) { + String message = "illegal opcode: " + opcode + " " + i; + throw new FormatException(message); + } + i = i.next(); + } + } + static class FormatException extends IOException { + FormatException(String message) { + super(message); + } + } }
--- a/src/share/classes/com/sun/java/util/jar/pack/PackerImpl.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/com/sun/java/util/jar/pack/PackerImpl.java Mon Oct 18 21:50:02 2010 -0700 @@ -496,15 +496,29 @@ reader.unknownAttrCommand = unknownAttrCommand; try { reader.read(); - } catch (Attribute.FormatException ee) { - // He passed up the category to us in layout. - if (ee.layout.equals(Pack200.Packer.PASS)) { - Utils.log.warning("Passing class file uncompressed due to unrecognized attribute: "+fname); - Utils.log.info(ee.toString()); - return null; + } catch (IOException ioe) { + String message = "Passing class file uncompressed due to"; + if (ioe instanceof Attribute.FormatException) { + Attribute.FormatException ee = (Attribute.FormatException) ioe; + // He passed up the category to us in layout. + if (ee.layout.equals(Pack200.Packer.PASS)) { + Utils.log.info(ee.toString()); + Utils.log.warning(message + " unrecognized attribute: " + + fname); + return null; + } + } else if (ioe instanceof ClassReader.ClassFormatException) { + ClassReader.ClassFormatException ce = (ClassReader.ClassFormatException) ioe; + // %% TODO: Do we invent a new property for this or reuse %% + if (unknownAttrCommand.equals(Pack200.Packer.PASS)) { + Utils.log.info(ce.toString()); + Utils.log.warning(message + " unknown class format: " + + fname); + return null; + } } // Otherwise, it must be an error. - throw ee; + throw ioe; } pkg.addClass(cls); return cls.file;
--- a/src/share/classes/com/sun/java/util/jar/pack/Utils.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/com/sun/java/util/jar/pack/Utils.java Mon Oct 18 21:50:02 2010 -0700 @@ -182,11 +182,8 @@ } public void warning(String msg, Object param) { - int verbose = currentPropMap().getInteger(DEBUG_VERBOSE); - if (verbose > 0) { getLogger().warning(msg, param); } - } public void warning(String msg) { warning(msg, null); @@ -216,7 +213,9 @@ // Returns the Max Version String of this implementation static String getVersionString() { - return "Pack200, Vendor: Sun Microsystems, Version: " + + return "Pack200, Vendor: " + + System.getProperty("java.vendor") + + ", Version: " + Constants.JAVA6_PACKAGE_MAJOR_VERSION + "." + Constants.JAVA6_PACKAGE_MINOR_VERSION; }
--- a/src/share/classes/com/sun/jndi/dns/DnsContextFactory.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/com/sun/jndi/dns/DnsContextFactory.java Mon Oct 18 21:50:02 2010 -0700 @@ -54,6 +54,7 @@ public class DnsContextFactory implements InitialContextFactory { private static final String DEFAULT_URL = "dns:"; + private static final int DEFAULT_PORT = 53; public Context getInitialContext(Hashtable<?,?> env) throws NamingException { @@ -89,7 +90,9 @@ * Public for use by product test suite. */ public static boolean platformServersAvailable() { - return !ResolverConfiguration.open().nameservers().isEmpty(); + return !filterNameServers( + ResolverConfiguration.open().nameservers(), true + ).isEmpty(); } private static Context urlToContext(String url, Hashtable env) @@ -142,8 +145,8 @@ // No server or port given, so look to underlying platform. // ResolverConfiguration does some limited caching, so the // following is reasonably efficient even if called rapid-fire. - List<String> platformServers = - ResolverConfiguration.open().nameservers(); + List<String> platformServers = filterNameServers( + ResolverConfiguration.open().nameservers(), false); if (!platformServers.isEmpty()) { servers.addAll(platformServers); continue; // on to next URL (if any, which is unlikely) @@ -213,4 +216,44 @@ String url = (String) env.get(Context.PROVIDER_URL); return ((url != null) ? url : DEFAULT_URL); } + + /** + * Removes any DNS server that's not permitted to access + * @param input the input server[:port] list, must not be null + * @param oneIsEnough return output once there exists one ok + * @return the filtered list, all non-permitted input removed + */ + private static List filterNameServers(List input, boolean oneIsEnough) { + SecurityManager security = System.getSecurityManager(); + if (security == null || input == null || input.isEmpty()) { + return input; + } else { + List output = new ArrayList(); + for (Object o: input) { + if (o instanceof String) { + String platformServer = (String)o; + int colon = platformServer.indexOf(':', + platformServer.indexOf(']') + 1); + + int p = (colon < 0) + ? DEFAULT_PORT + : Integer.parseInt( + platformServer.substring(colon + 1)); + String s = (colon < 0) + ? platformServer + : platformServer.substring(0, colon); + try { + security.checkConnect(s, p); + output.add(platformServer); + if (oneIsEnough) { + return output; + } + } catch (SecurityException se) { + continue; + } + } + } + return output; + } + } }
--- a/src/share/classes/com/sun/net/httpserver/BasicAuthenticator.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/com/sun/net/httpserver/BasicAuthenticator.java Mon Oct 18 21:50:02 2010 -0700 @@ -24,9 +24,6 @@ */ package com.sun.net.httpserver; -import java.net.*; -import java.io.*; -import java.util.*; /** * BasicAuthenticator provides an implementation of HTTP Basic @@ -57,7 +54,6 @@ public Result authenticate (HttpExchange t) { - HttpContext context = t.getHttpContext(); Headers rmap = (Headers) t.getRequestHeaders(); /* * look for auth token
--- a/src/share/classes/com/sun/net/httpserver/Filter.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/com/sun/net/httpserver/Filter.java Mon Oct 18 21:50:02 2010 -0700 @@ -25,11 +25,7 @@ package com.sun.net.httpserver; -import java.net.*; -import java.io.*; -import java.nio.*; -import java.nio.channels.*; -import sun.net.www.MessageHeader; +import java.io.IOException; import java.util.*; /** @@ -56,12 +52,10 @@ /* the last element in the chain must invoke the users * handler */ - private List<Filter> filters; private ListIterator<Filter> iter; private HttpHandler handler; public Chain (List<Filter> filters, HttpHandler handler) { - this.filters = filters; iter = filters.listIterator(); this.handler = handler; }
--- a/src/share/classes/com/sun/net/httpserver/Headers.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/com/sun/net/httpserver/Headers.java Mon Oct 18 21:50:02 2010 -0700 @@ -26,7 +26,6 @@ package com.sun.net.httpserver; import java.util.*; -import java.io.*; /** * HTTP request and response headers are represented by this class which implements @@ -77,19 +76,16 @@ if (len == 0) { return key; } - char[] b = new char [len]; - String s = null; - b = key.toCharArray(); - if (b[0] >= 'a' && b[0] <= 'z') { - b[0] = (char)(b[0] - ('a' - 'A')); + char[] b = key.toCharArray(); + if (b[0] >= 'a' && b[0] <= 'z') { + b[0] = (char)(b[0] - ('a' - 'A')); + } + for (int i=1; i<len; i++) { + if (b[i] >= 'A' && b[i] <= 'Z') { + b[i] = (char) (b[i] + ('a' - 'A')); } - for (int i=1; i<len; i++) { - if (b[i] >= 'A' && b[i] <= 'Z') { - b[i] = (char) (b[i] + ('a' - 'A')); - } - } - s = new String (b); - return s; + } + return new String(b); } public int size() {return map.size();}
--- a/src/share/classes/com/sun/net/httpserver/HttpsParameters.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/com/sun/net/httpserver/HttpsParameters.java Mon Oct 18 21:50:02 2010 -0700 @@ -24,9 +24,7 @@ */ package com.sun.net.httpserver; -import java.net.*; -import java.io.*; -import java.util.*; +import java.net.InetSocketAddress; import javax.net.ssl.SSLParameters; /** @@ -90,7 +88,7 @@ * have been set. */ public String[] getCipherSuites() { - return cipherSuites; + return cipherSuites != null ? cipherSuites.clone() : null; } /** @@ -99,7 +97,7 @@ * @param cipherSuites the array of ciphersuites (or null) */ public void setCipherSuites(String[] cipherSuites) { - this.cipherSuites = cipherSuites; + this.cipherSuites = cipherSuites != null ? cipherSuites.clone() : null; } /** @@ -110,7 +108,7 @@ * have been set. */ public String[] getProtocols() { - return protocols; + return protocols != null ? protocols.clone() : null; } /** @@ -119,7 +117,7 @@ * @param protocols the array of protocols (or null) */ public void setProtocols(String[] protocols) { - this.protocols = protocols; + this.protocols = protocols != null ? protocols.clone() : null; } /**
--- a/src/share/classes/com/sun/org/apache/xml/internal/security/utils/UnsyncByteArrayOutputStream.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/com/sun/org/apache/xml/internal/security/utils/UnsyncByteArrayOutputStream.java Mon Oct 18 21:50:02 2010 -0700 @@ -3,7 +3,7 @@ * DO NOT REMOVE OR ALTER! */ /* - * Copyright 1999-2005 The Apache Software Foundation. + * Copyright 1999-2010 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,66 +23,70 @@ import java.io.OutputStream; /** - * A simple Unsynced ByteArryOutputStream + * A simple Unsynced ByteArrayOutputStream * @author raul * */ public class UnsyncByteArrayOutputStream extends OutputStream { - private static ThreadLocal bufCahce = new ThreadLocal() { + private static final int INITIAL_SIZE = 8192; + private static ThreadLocal bufCache = new ThreadLocal() { protected synchronized Object initialValue() { - return new byte[8*1024]; + return new byte[INITIAL_SIZE]; } }; - byte[] buf; - int size=8*1024;//buf.length; - int pos=0; - public UnsyncByteArrayOutputStream() { - buf=(byte[])bufCahce.get(); + + private byte[] buf; + private int size = INITIAL_SIZE; + private int pos = 0; + + public UnsyncByteArrayOutputStream() { + buf = (byte[])bufCache.get(); + } + + public void write(byte[] arg0) { + int newPos = pos + arg0.length; + if (newPos > size) { + expandSize(newPos); } - /** @inheritDoc */ - public void write(byte[] arg0) { - int newPos=pos+arg0.length; - if (newPos>size) { - expandSize(); - } - System.arraycopy(arg0,0,buf,pos,arg0.length); - pos=newPos; - } - /** @inheritDoc */ - public void write(byte[] arg0, int arg1, int arg2) { - int newPos=pos+arg2; - if (newPos>size) { - expandSize(); - } - System.arraycopy(arg0,arg1,buf,pos,arg2); - pos=newPos; + System.arraycopy(arg0, 0, buf, pos, arg0.length); + pos = newPos; + } + + public void write(byte[] arg0, int arg1, int arg2) { + int newPos = pos + arg2; + if (newPos > size) { + expandSize(newPos); } - /** @inheritDoc */ - public void write(int arg0) { - if (pos>=size) { - expandSize(); - } - buf[pos++]=(byte)arg0; + System.arraycopy(arg0, arg1, buf, pos, arg2); + pos = newPos; + } + + public void write(int arg0) { + int newPos = pos + 1; + if (newPos > size) { + expandSize(newPos); } - /** @inheritDoc */ - public byte[] toByteArray() { - byte result[]=new byte[pos]; - System.arraycopy(buf,0,result,0,pos); - return result; - } + buf[pos++] = (byte)arg0; + } - /** @inheritDoc */ - public void reset() { - pos=0; - } + public byte[] toByteArray() { + byte result[] = new byte[pos]; + System.arraycopy(buf, 0, result, 0, pos); + return result; + } + + public void reset() { + pos = 0; + } - /** @inheritDoc */ - void expandSize() { - int newSize=size<<2; - byte newBuf[]=new byte[newSize]; - System.arraycopy(buf,0,newBuf,0,pos); - buf=newBuf; - size=newSize; - + private void expandSize(int newPos) { + int newSize = size; + while (newPos > newSize) { + newSize = newSize<<2; } + byte newBuf[] = new byte[newSize]; + System.arraycopy(buf, 0, newBuf, 0, pos); + buf = newBuf; + size = newSize; + } }
--- a/src/share/classes/java/awt/image/IndexColorModel.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/java/awt/image/IndexColorModel.java Mon Oct 18 21:50:02 2010 -0700 @@ -129,6 +129,8 @@ private boolean allgrayopaque; private BigInteger validBits; + private sun.awt.image.BufImgSurfaceData.ICMColorData colorData = null; + private static int[] opaqueBits = {8, 8, 8}; private static int[] alphaBits = {8, 8, 8, 8}; @@ -1511,7 +1513,6 @@ * longer referenced. */ public void finalize() { - sun.awt.image.BufImgSurfaceData.freeNativeICMData(this); } /**
--- a/src/share/classes/java/dyn/InvokeDynamicBootstrapError.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/java/dyn/InvokeDynamicBootstrapError.java Mon Oct 18 21:50:02 2010 -0700 @@ -39,8 +39,11 @@ * {@link Linkage#registerBootstrapMethod registerBootstrapMethod}. * * @author John Rose, JSR 292 EG + * @since 1.7 */ public class InvokeDynamicBootstrapError extends LinkageError { + private static final long serialVersionUID = 292L; + /** * Constructs an {@code InvokeDynamicBootstrapError} with no detail message. */ @@ -63,10 +66,9 @@ * detail message and cause. * * @param s the detail message. - * @param cause the cause. + * @param cause the cause, may be {@code null}. */ public InvokeDynamicBootstrapError(String s, Throwable cause) { - super(s); - this.initCause(cause); + super(s, cause); } }
--- a/src/share/classes/java/dyn/LinkagePermission.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/java/dyn/LinkagePermission.java Mon Oct 18 21:50:02 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2010, 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 @@ -81,6 +81,8 @@ */ public final class LinkagePermission extends BasicPermission { + private static final long serialVersionUID = 292L; + /** * Create a new LinkagePermission with the given name. * The name is the symbolic name of the LinkagePermission, such as
--- a/src/share/classes/java/dyn/NoAccessException.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/java/dyn/NoAccessException.java Mon Oct 18 21:50:02 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2010, 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 @@ -35,8 +35,11 @@ * on behalf of the method handle creator, * at the time of creation. * @author John Rose, JSR 292 EG + * @since 1.7 */ public class NoAccessException extends RuntimeException { + private static final long serialVersionUID = 292L; + /** * Constructs a {@code NoAccessException} with no detail message. */
--- a/src/share/classes/java/dyn/WrongMethodTypeException.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/java/dyn/WrongMethodTypeException.java Mon Oct 18 21:50:02 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2010, 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 @@ -38,8 +38,11 @@ * instead of when the mismatched method handle is called. * * @author John Rose, JSR 292 EG + * @since 1.7 */ public class WrongMethodTypeException extends RuntimeException { + private static final long serialVersionUID = 292L; + /** * Constructs a {@code WrongMethodTypeException} with no detail message. */
--- a/src/share/classes/java/io/package.html Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/java/io/package.html Mon Oct 18 21:50:02 2010 -0700 @@ -44,7 +44,7 @@ For overviews, tutorials, examples, guides, and tool documentation, please see: <ul> - <li><a href="../../../guide/serialization">Serialization Enhancements</a> + <li><a href="../../../technotes/guides/serialization">Serialization Enhancements</a> </ul> @since JDK1.0
--- a/src/share/classes/java/lang/ClassLoader.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/java/lang/ClassLoader.java Mon Oct 18 21:50:02 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2010, 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 @@ -100,8 +100,11 @@ * themselves at their class initialization time by invoking the * {@link * #registerAsParallelCapable <tt>ClassLoader.registerAsParallelCapable</tt>} - * method. In environments in which the delegation model is not strictly - * hierarchical, class loaders need to be parallel capable, otherise class + * method. Note that the <tt>ClassLoader</tt> class is registered as parallel + * capable by default. However, its subclasses still need to register themselves + * if they are parallel capable. <br> + * In environments in which the delegation model is not strictly + * hierarchical, class loaders need to be parallel capable, otherwise class * loading can lead to deadlocks because the loader lock is held for the * duration of the class loading process (see {@link #loadClass * <tt>loadClass</tt>} methods). @@ -1218,14 +1221,14 @@ private static native Class<? extends ClassLoader> getCaller(int index); /** - * Registers the caller class loader as parallel capable. - * In order for the registration to succeed, all super classes - * of the caller class loader must also be registered as - * parallel capable when this method is called. </p> - * Note that once a class loader is registered as - * parallel capable, there is no way to change it back. - * In addition, registration should be done statically before - * any instance of the caller classloader being constructed. </p> + * Registers the caller as parallel capable.</p> + * The registration succeeds if and only if all of the following + * conditions are met: <br> + * 1. no instance of the caller has been created</p> + * 2. all of the super classes (except class Object) of the caller are + * registered as parallel capable</p> + * Note that once a class loader is registered as parallel capable, there + * is no way to change it back. </p> * * @return true if the caller is successfully registered as * parallel capable and false if otherwise.
--- a/src/share/classes/java/lang/Integer.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/java/lang/Integer.java Mon Oct 18 21:50:02 2010 -0700 @@ -586,25 +586,13 @@ * Cache to support the object identity semantics of autoboxing for values between * -128 and 127 (inclusive) as required by JLS. * - * The cache is initialized on first usage. During VM initialization the - * getAndRemoveCacheProperties method may be used to get and remove any system - * properites that configure the cache size. At this time, the size of the - * cache may be controlled by the -XX:AutoBoxCacheMax=<size> option. + * The cache is initialized on first usage. The size of the cache + * may be controlled by the -XX:AutoBoxCacheMax=<size> option. + * During VM initialization, java.lang.Integer.IntegerCache.high property + * may be set and saved in the private system properties in the + * sun.misc.VM class. */ - // value of java.lang.Integer.IntegerCache.high property (obtained during VM init) - private static String integerCacheHighPropValue; - - static void getAndRemoveCacheProperties() { - if (!sun.misc.VM.isBooted()) { - Properties props = System.getProperties(); - integerCacheHighPropValue = - (String)props.remove("java.lang.Integer.IntegerCache.high"); - if (integerCacheHighPropValue != null) - System.setProperties(props); // remove from system props - } - } - private static class IntegerCache { static final int low = -128; static final int high; @@ -613,6 +601,8 @@ static { // high value may be configured by property int h = 127; + String integerCacheHighPropValue = + sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high"); if (integerCacheHighPropValue != null) { int i = parseInt(integerCacheHighPropValue); i = Math.max(i, 127);
--- a/src/share/classes/java/lang/LinkageError.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/java/lang/LinkageError.java Mon Oct 18 21:50:02 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2010, 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 @@ -26,7 +26,7 @@ package java.lang; /** - * Subclasses of <code>LinkageError</code> indicate that a class has + * Subclasses of {@code LinkageError} indicate that a class has * some dependency on another class; however, the latter class has * incompatibly changed after the compilation of the former class. * @@ -39,14 +39,14 @@ private static final long serialVersionUID = 3579600108157160122L; /** - * Constructs a <code>LinkageError</code> with no detail message. + * Constructs a {@code LinkageError} with no detail message. */ public LinkageError() { super(); } /** - * Constructs a <code>LinkageError</code> with the specified detail + * Constructs a {@code LinkageError} with the specified detail * message. * * @param s the detail message. @@ -54,4 +54,16 @@ public LinkageError(String s) { super(s); } + + /** + * Constructs a {@code LinkageError} with the specified detail + * message and cause. + * + * @param s the detail message. + * @param cause the cause, may be {@code null} + * @since 1.7 + */ + public LinkageError(String s, Throwable cause) { + super(s, cause); + } }
--- a/src/share/classes/java/lang/System.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/java/lang/System.java Mon Oct 18 21:50:02 2010 -0700 @@ -53,7 +53,13 @@ */ public final class System { - /* First thing---register the natives */ + /* register the natives via the static initializer. + * + * VM will invoke the initializeSystemClass method to complete + * the initialization for this class separated from clinit. + * Note that to use properties set by the VM, see the constraints + * described in the initializeSystemClass method. + */ private static native void registerNatives(); static { registerNatives(); @@ -1096,17 +1102,21 @@ * Initialize the system class. Called after thread initialization. */ private static void initializeSystemClass() { - props = new Properties(); - initProperties(props); + // There are certain system configurations that may be controlled by + // VM options such as the maximum amount of direct memory and + // Integer cache size used to support the object identity semantics + // of autoboxing. Typically, the library will obtain these values + // from the properties set by the VM. If the properties are for + // internal implementation use only, these properties should be + // removed from the system properties. + // + // See java.lang.Integer.IntegerCache and the + // sun.misc.VM.saveAndRemoveProperties method for example. + props = initSystemProperties(); + lineSeparator = props.getProperty("line.separator"); sun.misc.Version.init(); - // Gets and removes system properties that configure the Integer - // cache used to support the object identity semantics of autoboxing. - // At this time, the size of the cache may be controlled by the - // vm option -XX:AutoBoxCacheMax=<size>. - Integer.getAndRemoveCacheProperties(); - FileInputStream fdIn = new FileInputStream(FileDescriptor.in); FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out); FileOutputStream fdErr = new FileOutputStream(FileDescriptor.err); @@ -1127,17 +1137,6 @@ // classes are used. sun.misc.VM.initializeOSEnvironment(); - // Set the maximum amount of direct memory. This value is controlled - // by the vm option -XX:MaxDirectMemorySize=<size>. This method acts - // as an initializer only if it is called before sun.misc.VM.booted(). - sun.misc.VM.maxDirectMemory(); - - // Set a boolean to determine whether ClassLoader.loadClass accepts - // array syntax. This value is controlled by the system property - // "sun.lang.ClassLoader.allowArraySyntax". This method acts as - // an initializer only if it is called before sun.misc.VM.booted(). - sun.misc.VM.allowArraySyntax(); - // Subsystems that are invoked during initialization can invoke // sun.misc.VM.isBooted() in order to avoid doing things that should // wait until the application class loader has been set up. @@ -1152,6 +1151,18 @@ setJavaLangAccess(); } + private static Properties initSystemProperties() { + Properties props = new Properties(); + initProperties(props); // initialized by the VM + + // Save a private copy of the system properties object that + // can only be accessed by the internal implementation. Remove + // certain system properties that are not intended for public access. + sun.misc.VM.saveAndRemoveProperties(props); + + return props; + } + private static void setJavaLangAccess() { // Allow privileged classes outside of java.lang sun.misc.SharedSecrets.setJavaLangAccess(new sun.misc.JavaLangAccess(){
--- a/src/share/classes/java/net/HttpURLConnection.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/java/net/HttpURLConnection.java Mon Oct 18 21:50:02 2010 -0700 @@ -399,6 +399,8 @@ * @param method the HTTP method * @exception ProtocolException if the method cannot be reset or if * the requested method isn't valid for HTTP. + * @exception SecurityException if a security manager is set and the + * "allowHttpTrace" NetPermission is not granted. * @see #getRequestMethod() */ public void setRequestMethod(String method) throws ProtocolException { @@ -412,6 +414,12 @@ for (int i = 0; i < methods.length; i++) { if (methods[i].equals(method)) { + if (method.equals("TRACE")) { + SecurityManager s = System.getSecurityManager(); + if (s != null) { + s.checkPermission(new NetPermission("allowHttpTrace")); + } + } this.method = method; return; }
--- a/src/share/classes/java/net/NetPermission.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/java/net/NetPermission.java Mon Oct 18 21:50:02 2010 -0700 @@ -54,44 +54,23 @@ * <th>What the Permission Allows</th> * <th>Risks of Allowing this Permission</th> * </tr> - * * <tr> - * <td>setDefaultAuthenticator</td> - * <td>The ability to set the - * way authentication information is retrieved when - * a proxy or HTTP server asks for authentication</td> - * <td>Malicious - * code can set an authenticator that monitors and steals user - * authentication input as it retrieves the input from the user.</td> - * </tr> + * <td>allowHttpTrace</td> + * <td>The ability to use the HTTP TRACE method in HttpURLConnection.</td> + * <td>Malicious code using HTTP TRACE could get access to security sensitive + * information in the HTTP headers (such as cookies) that it might not + * otherwise have access to.</td> + * </tr> * * <tr> - * <td>requestPasswordAuthentication</td> - * <td>The ability - * to ask the authenticator registered with the system for - * a password</td> - * <td>Malicious code may steal this password.</td> - * </tr> - * - * <tr> - * <td>specifyStreamHandler</td> - * <td>The ability - * to specify a stream handler when constructing a URL</td> - * <td>Malicious code may create a URL with resources that it would -normally not have access to (like file:/foo/fum/), specifying a -stream handler that gets the actual bytes from someplace it does -have access to. Thus it might be able to trick the system into -creating a ProtectionDomain/CodeSource for a class even though -that class really didn't come from that location.</td> - * </tr> - * - * <tr> - * <td>setProxySelector</td> - * <td>The ability to set the proxy selector used to make decisions - * on which proxies to use when making network connections.</td> - * <td>Malicious code can set a ProxySelector that directs network - * traffic to an arbitrary network host.</td> - * </tr> + * <td>getCookieHandler</td> + * <td>The ability to get the cookie handler that processes highly + * security sensitive cookie information for an Http session.</td> + * <td>Malicious code can get a cookie handler to obtain access to + * highly security sensitive cookie information. Some web servers + * use cookies to save user private information such as access + * control information, or to track user browsing habit.</td> + * </tr> * * <tr> * <td>getProxySelector</td> @@ -103,6 +82,22 @@ * </tr> * * <tr> + * <td>getResponseCache</td> + * <td>The ability to get the response cache that provides + * access to a local response cache.</td> + * <td>Malicious code getting access to the local response cache + * could access security sensitive information.</td> + * </tr> + * + * <tr> + * <td>requestPasswordAuthentication</td> + * <td>The ability + * to ask the authenticator registered with the system for + * a password</td> + * <td>Malicious code may steal this password.</td> + * </tr> + * + * <tr> * <td>setCookieHandler</td> * <td>The ability to set the cookie handler that processes highly * security sensitive cookie information for an Http session.</td> @@ -113,14 +108,22 @@ * </tr> * * <tr> - * <td>getCookieHandler</td> - * <td>The ability to get the cookie handler that processes highly - * security sensitive cookie information for an Http session.</td> - * <td>Malicious code can get a cookie handler to obtain access to - * highly security sensitive cookie information. Some web servers - * use cookies to save user private information such as access - * control information, or to track user browsing habit.</td> - * </tr> + * <td>setDefaultAuthenticator</td> + * <td>The ability to set the + * way authentication information is retrieved when + * a proxy or HTTP server asks for authentication</td> + * <td>Malicious + * code can set an authenticator that monitors and steals user + * authentication input as it retrieves the input from the user.</td> + * </tr> + * + * <tr> + * <td>setProxySelector</td> + * <td>The ability to set the proxy selector used to make decisions + * on which proxies to use when making network connections.</td> + * <td>Malicious code can set a ProxySelector that directs network + * traffic to an arbitrary network host.</td> + * </tr> * * <tr> * <td>setResponseCache</td> @@ -132,13 +135,16 @@ * </tr> * * <tr> - * <td>getResponseCache</td> - * <td>The ability to get the response cache that provides - * access to a local response cache.</td> - * <td>Malicious code getting access to the local response cache - * could access security sensitive information.</td> - * </tr> - * + * <td>specifyStreamHandler</td> + * <td>The ability + * to specify a stream handler when constructing a URL</td> + * <td>Malicious code may create a URL with resources that it would +normally not have access to (like file:/foo/fum/), specifying a +stream handler that gets the actual bytes from someplace it does +have access to. Thus it might be able to trick the system into +creating a ProtectionDomain/CodeSource for a class even though +that class really didn't come from that location.</td> + * </tr> * </table> * * @see java.security.BasicPermission
--- a/src/share/classes/java/net/NetworkInterface.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/java/net/NetworkInterface.java Mon Oct 18 21:50:02 2010 -0700 @@ -86,7 +86,9 @@ * If there is a security manager, its <code>checkConnect</code> * method is called for each InetAddress. Only InetAddresses where * the <code>checkConnect</code> doesn't throw a SecurityException - * will be returned in the Enumeration. + * will be returned in the Enumeration. However, if the caller has the + * {@link NetPermission}("getNetworkInformation") permission, then all + * InetAddresses are returned. * @return an Enumeration object with all or a subset of the InetAddresses * bound to this network interface */ @@ -99,11 +101,19 @@ checkedAddresses() { local_addrs = new InetAddress[addrs.length]; + boolean trusted = true; SecurityManager sec = System.getSecurityManager(); + if (sec != null) { + try { + sec.checkPermission(new NetPermission("getNetworkInformation")); + } catch (SecurityException e) { + trusted = false; + } + } for (int j=0; j<addrs.length; j++) { try { - if (sec != null) { + if (sec != null && !trusted) { sec.checkConnect(addrs[j].getHostAddress(), -1); } local_addrs[count++] = addrs[j]; @@ -402,13 +412,29 @@ /** * Returns the hardware address (usually MAC) of the interface if it * has one and if it can be accessed given the current privileges. + * If a security manager is set, then the caller must have + * the permission {@link NetPermission}("getNetworkInformation"). * - * @return a byte array containing the address or <code>null</code> if - * the address doesn't exist or is not accessible. + * @return a byte array containing the address, or <code>null</code> if + * the address doesn't exist, is not accessible or a security + * manager is set and the caller does not have the permission + * NetPermission("getNetworkInformation") + * * @exception SocketException if an I/O error occurs. * @since 1.6 */ public byte[] getHardwareAddress() throws SocketException { + SecurityManager sec = System.getSecurityManager(); + if (sec != null) { + try { + sec.checkPermission(new NetPermission("getNetworkInformation")); + } catch (SecurityException e) { + if (!getInetAddresses().hasMoreElements()) { + // don't have connect permission to any local address + return null; + } + } + } for (InetAddress addr : addrs) { if (addr instanceof Inet4Address) { return getMacAddr0(((Inet4Address)addr).getAddress(), name, index); @@ -523,11 +549,10 @@ } public int hashCode() { - int count = 0; - if (addrs != null) { - for (int i = 0; i < addrs.length; i++) { - count += addrs[i].hashCode(); - } + int count = name == null? 0: name.hashCode(); + Enumeration<InetAddress> addrs = getInetAddresses(); + while (addrs.hasMoreElements()) { + count += addrs.nextElement().hashCode(); } return count; }
--- a/src/share/classes/java/nio/Bits.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/java/nio/Bits.java Mon Oct 18 21:50:02 2010 -0700 @@ -622,7 +622,7 @@ // initialization if it is launched with "-XX:MaxDirectMemorySize=<size>". private static volatile long maxMemory = VM.maxDirectMemory(); private static volatile long reservedMemory; - private static volatile long usedMemory; + private static volatile long totalCapacity; private static volatile long count; private static boolean memoryLimitSet = false; @@ -630,15 +630,17 @@ // freed. They allow the user to control the amount of direct memory // which a process may access. All sizes are specified in bytes. static void reserveMemory(long size, int cap) { - synchronized (Bits.class) { if (!memoryLimitSet && VM.isBooted()) { maxMemory = VM.maxDirectMemory(); memoryLimitSet = true; } - if (size <= maxMemory - reservedMemory) { + // -XX:MaxDirectMemorySize limits the total capacity rather than the + // actual memory usage, which will differ when buffers are page + // aligned. + if (cap <= maxMemory - totalCapacity) { reservedMemory += size; - usedMemory += cap; + totalCapacity += cap; count++; return; } @@ -652,10 +654,10 @@ Thread.currentThread().interrupt(); } synchronized (Bits.class) { - if (reservedMemory + size > maxMemory) + if (totalCapacity + cap > maxMemory) throw new OutOfMemoryError("Direct buffer memory"); reservedMemory += size; - usedMemory += cap; + totalCapacity += cap; count++; } @@ -664,7 +666,7 @@ static synchronized void unreserveMemory(long size, int cap) { if (reservedMemory > 0) { reservedMemory -= size; - usedMemory -= cap; + totalCapacity -= cap; count--; assert (reservedMemory > -1); } @@ -689,7 +691,7 @@ } @Override public long getTotalCapacity() { - return Bits.usedMemory; + return Bits.totalCapacity; } @Override public long getMemoryUsed() {
--- a/src/share/classes/java/nio/Direct-X-Buffer.java.template Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/java/nio/Direct-X-Buffer.java.template Mon Oct 18 21:50:02 2010 -0700 @@ -29,6 +29,7 @@ import sun.misc.Cleaner; import sun.misc.Unsafe; +import sun.misc.VM; import sun.nio.ch.DirectBuffer; @@ -114,8 +115,9 @@ Direct$Type$Buffer$RW$(int cap) { // package-private #if[rw] super(-1, 0, cap, cap, false); + boolean pa = VM.isDirectMemoryPageAligned(); int ps = Bits.pageSize(); - int size = cap + ps; + long size = Math.max(1L, (long)cap + (pa ? ps : 0)); Bits.reserveMemory(size, cap); long base = 0; @@ -126,7 +128,7 @@ throw x; } unsafe.setMemory(base, size, (byte) 0); - if (base % ps != 0) { + if (pa && (base % ps != 0)) { // Round up to page boundary address = base + ps - (base & (ps - 1)); } else {
--- a/src/share/classes/java/security/cert/CertificateRevokedException.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/java/security/cert/CertificateRevokedException.java Mon Oct 18 21:50:02 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2010, 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 @@ -61,8 +61,8 @@ */ private final CRLReason reason; /** - * @serial the name of the authority that signed the certificate's - * revocation status information + * @serial the <code>X500Principal</code> that represents the name of the + * authority that signed the certificate's revocation status information */ private final X500Principal authority; @@ -79,8 +79,9 @@ * @param extensions a map of X.509 Extensions. Each key is an OID String * that maps to the corresponding Extension. The map is copied to * prevent subsequent modification. - * @param authority the name of the authority that signed the certificate's - * revocation status information + * @param authority the <code>X500Principal</code> that represents the name + * of the authority that signed the certificate's revocation status + * information * @throws NullPointerException if <code>revocationDate</code>, * <code>reason</code>, <code>authority</code>, or * <code>extensions</code> is <code>null</code> @@ -121,8 +122,8 @@ * Returns the name of the authority that signed the certificate's * revocation status information. * - * @return the name of the authority that signed the certificate's - * revocation status information + * @return the <code>X500Principal</code> that represents the name of the + * authority that signed the certificate's revocation status information */ public X500Principal getAuthorityName() { return authority;
--- a/src/share/classes/java/util/Arrays.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/java/util/Arrays.java Mon Oct 18 21:50:02 2010 -0700 @@ -97,7 +97,8 @@ * if {@code fromIndex < 0} or {@code toIndex > a.length} */ public static void sort(int[] a, int fromIndex, int toIndex) { - DualPivotQuicksort.sort(a, fromIndex, toIndex); + rangeCheck(a.length, fromIndex, toIndex); + DualPivotQuicksort.sort(a, fromIndex, toIndex - 1); } /** @@ -136,7 +137,8 @@ * if {@code fromIndex < 0} or {@code toIndex > a.length} */ public static void sort(long[] a, int fromIndex, int toIndex) { - DualPivotQuicksort.sort(a, fromIndex, toIndex); + rangeCheck(a.length, fromIndex, toIndex); + DualPivotQuicksort.sort(a, fromIndex, toIndex - 1); } /** @@ -175,7 +177,8 @@ * if {@code fromIndex < 0} or {@code toIndex > a.length} */ public static void sort(short[] a, int fromIndex, int toIndex) { - DualPivotQuicksort.sort(a, fromIndex, toIndex); + rangeCheck(a.length, fromIndex, toIndex); + DualPivotQuicksort.sort(a, fromIndex, toIndex - 1); } /** @@ -214,7 +217,8 @@ * if {@code fromIndex < 0} or {@code toIndex > a.length} */ public static void sort(char[] a, int fromIndex, int toIndex) { - DualPivotQuicksort.sort(a, fromIndex, toIndex); + rangeCheck(a.length, fromIndex, toIndex); + DualPivotQuicksort.sort(a, fromIndex, toIndex - 1); } /** @@ -253,7 +257,8 @@ * if {@code fromIndex < 0} or {@code toIndex > a.length} */ public static void sort(byte[] a, int fromIndex, int toIndex) { - DualPivotQuicksort.sort(a, fromIndex, toIndex); + rangeCheck(a.length, fromIndex, toIndex); + DualPivotQuicksort.sort(a, fromIndex, toIndex - 1); } /** @@ -308,7 +313,8 @@ * if {@code fromIndex < 0} or {@code toIndex > a.length} */ public static void sort(float[] a, int fromIndex, int toIndex) { - DualPivotQuicksort.sort(a, fromIndex, toIndex); + rangeCheck(a.length, fromIndex, toIndex); + DualPivotQuicksort.sort(a, fromIndex, toIndex - 1); } /** @@ -363,12 +369,12 @@ * if {@code fromIndex < 0} or {@code toIndex > a.length} */ public static void sort(double[] a, int fromIndex, int toIndex) { - DualPivotQuicksort.sort(a, fromIndex, toIndex); + rangeCheck(a.length, fromIndex, toIndex); + DualPivotQuicksort.sort(a, fromIndex, toIndex - 1); } /* * Sorting of complex type arrays. - * */ /**
--- a/src/share/classes/java/util/DualPivotQuicksort.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/java/util/DualPivotQuicksort.java Mon Oct 18 21:50:02 2010 -0700 @@ -36,7 +36,7 @@ * @author Jon Bentley * @author Josh Bloch * - * @version 2010.06.21 m765.827.12i:5\7 + * @version 2010.10.13 m765.827.12i:5\7p * @since 1.7 */ final class DualPivotQuicksort { @@ -54,26 +54,26 @@ * If the length of an array to be sorted is less than this * constant, insertion sort is used in preference to Quicksort. */ - private static final int INSERTION_SORT_THRESHOLD = 32; + private static final int INSERTION_SORT_THRESHOLD = 47; /** - * If the length of a byte array to be sorted is greater than - * this constant, counting sort is used in preference to Quicksort. + * If the length of a byte array to be sorted is greater than this + * constant, counting sort is used in preference to insertion sort. */ - private static final int COUNTING_SORT_THRESHOLD_FOR_BYTE = 128; + private static final int COUNTING_SORT_THRESHOLD_FOR_BYTE = 29; /** * If the length of a short or char array to be sorted is greater * than this constant, counting sort is used in preference to Quicksort. */ - private static final int COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR = 32768; + private static final int COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR = 3200; /* * Sorting methods for seven primitive types. */ /** - * Sorts the specified array into ascending numerical order. + * Sorts the specified array. * * @param a the array to be sorted */ @@ -82,58 +82,34 @@ } /** - * Sorts the specified range of the array into ascending order. The range - * to be sorted extends from the index {@code fromIndex}, inclusive, to - * the index {@code toIndex}, exclusive. If {@code fromIndex == toIndex}, - * the range to be sorted is empty (and the call is a no-op). - * - * @param a the array to be sorted - * @param fromIndex the index of the first element, inclusive, to be sorted - * @param toIndex the index of the last element, exclusive, to be sorted - * @throws IllegalArgumentException if {@code fromIndex > toIndex} - * @throws ArrayIndexOutOfBoundsException - * if {@code fromIndex < 0} or {@code toIndex > a.length} - */ - public static void sort(int[] a, int fromIndex, int toIndex) { - rangeCheck(a.length, fromIndex, toIndex); - sort(a, fromIndex, toIndex - 1, true); - } - - /** - * Sorts the specified range of the array into ascending order by the - * Dual-Pivot Quicksort algorithm. This method differs from the public - * {@code sort} method in that the {@code right} index is inclusive, - * it does no range checking on {@code left} or {@code right}, and has - * boolean flag whether insertion sort with sentinel is used or not. + * Sorts the specified range of the array. * * @param a the array to be sorted * @param left the index of the first element, inclusive, to be sorted * @param right the index of the last element, inclusive, to be sorted - * @param leftmost indicates if the part is the most left in the range + */ + public static void sort(int[] a, int left, int right) { + sort(a, left, right, true); + } + + /** + * Sorts the specified range of the array by Dual-Pivot Quicksort. + * + * @param a the array to be sorted + * @param left the index of the first element, inclusive, to be sorted + * @param right the index of the last element, inclusive, to be sorted + * @param leftmost indicates if this part is the leftmost in the range */ private static void sort(int[] a, int left, int right, boolean leftmost) { int length = right - left + 1; - // Use insertion sort on tiny arrays + // Use insertion sort on small arrays if (length < INSERTION_SORT_THRESHOLD) { - if (!leftmost) { + if (leftmost) { /* - * Every element in adjoining part plays the role - * of sentinel, therefore this allows us to avoid - * the j >= left check on each iteration. - */ - for (int j, i = left + 1; i <= right; i++) { - int ai = a[i]; - for (j = i - 1; ai < a[j]; j--) { - // assert j >= left; - a[j + 1] = a[j]; - } - a[j + 1] = ai; - } - } else { - /* - * For case of leftmost part traditional (without a sentinel) - * insertion sort, optimized for server JVM, is used. + * Traditional (without sentinel) insertion sort, + * optimized for server VM, is used in case of + * the leftmost part. */ for (int i = left, j = i; i < right; j = ++i) { int ai = a[i + 1]; @@ -145,12 +121,54 @@ } a[j + 1] = ai; } + } else { + /* + * Skip the longest ascending sequence. + */ + do { + if (left++ >= right) { + return; + } + } while (a[left - 1] <= a[left]); + + /* + * Every element from adjoining part plays the role + * of sentinel, therefore this allows us to avoid the + * left range check on each iteration. Moreover, we use + * the best improved algorithm, so called pair insertion + * sort, which is faster than traditional implementation + * in the context of Dual-Pivot Quicksort. + */ + for (int k = left--; (left += 2) <= right; ) { + int a1, a2; k = left - 1; + + if (a[k] < a[left]) { + a2 = a[k]; a1 = a[left]; + } else { + a1 = a[k]; a2 = a[left]; + } + while (a1 < a[--k]) { + a[k + 2] = a[k]; + } + a[++k + 1] = a1; + + while (a2 < a[--k]) { + a[k + 1] = a[k]; + } + a[k + 1] = a2; + } + int last = a[right]; + + while (last < a[--right]) { + a[right + 1] = a[right]; + } + a[right + 1] = last; } return; } // Inexpensive approximation of length / 7 - int seventh = (length >>> 3) + (length >>> 6) + 1; + int seventh = (length >> 3) + (length >> 6) + 1; /* * Sort five evenly spaced elements around (and including) the @@ -232,10 +250,14 @@ * Pointer k is the first index of ?-part. */ outer: - for (int k = less; k <= great; k++) { + for (int k = less - 1; ++k <= great; ) { int ak = a[k]; if (ak < pivot1) { // Move a[k] to left part a[k] = a[less]; + /* + * Here and below we use "a[i] = b; i++;" instead + * of "a[i++] = b;" due to performance issue. + */ a[less] = ak; less++; } else if (ak > pivot2) { // Move a[k] to right part @@ -244,13 +266,17 @@ break outer; } } - if (a[great] < pivot1) { + if (a[great] < pivot1) { // a[great] <= pivot2 a[k] = a[less]; a[less] = a[great]; less++; } else { // pivot1 <= a[great] <= pivot2 a[k] = a[great]; } + /* + * Here and below we use "a[i] = b; i--;" instead + * of "a[i--] = b;" due to performance issue. + */ a[great] = ak; great--; } @@ -265,7 +291,7 @@ sort(a, great + 2, right, false); /* - * If center part is too large (comprises > 5/7 of the array), + * If center part is too large (comprises > 4/7 of the array), * swap internal pivot values to ends. */ if (less < e1 && e5 < great) { @@ -299,7 +325,7 @@ * Pointer k is the first index of ?-part. */ outer: - for (int k = less; k <= great; k++) { + for (int k = less - 1; ++k <= great; ) { int ak = a[k]; if (ak == pivot1) { // Move a[k] to left part a[k] = a[less]; @@ -311,7 +337,7 @@ break outer; } } - if (a[great] == pivot1) { + if (a[great] == pivot1) { // a[great] < pivot2 a[k] = a[less]; /* * Even though a[great] equals to pivot1, the @@ -337,7 +363,7 @@ } else { // Pivots are equal /* - * Partition degenerates to the traditional 3-way + * Partitioning degenerates to the traditional 3-way * (or "Dutch National Flag") schema: * * left part center part right part @@ -356,28 +382,20 @@ * * Pointer k is the first index of ?-part. */ - for (int k = left; k <= great; k++) { + for (int k = less; k <= great; ++k) { if (a[k] == pivot1) { continue; } int ak = a[k]; - if (ak < pivot1) { // Move a[k] to left part a[k] = a[less]; a[less] = ak; less++; } else { // a[k] > pivot1 - Move a[k] to right part - /* - * We know that pivot1 == a[e3] == pivot2. Thus, we know - * that great will still be >= k when the following loop - * terminates, even though we don't test for it explicitly. - * In other words, a[e3] acts as a sentinel for great. - */ while (a[great] > pivot1) { - // assert great > k; great--; } - if (a[great] < pivot1) { + if (a[great] < pivot1) { // a[great] <= pivot1 a[k] = a[less]; a[less] = a[great]; less++; @@ -397,14 +415,18 @@ } } - // Sort left and right parts recursively + /* + * Sort left and right parts recursively. + * All elements from center part are equal + * and, therefore, already sorted. + */ sort(a, left, less - 1, leftmost); sort(a, great + 1, right, false); } } /** - * Sorts the specified array into ascending numerical order. + * Sorts the specified array. * * @param a the array to be sorted */ @@ -413,58 +435,34 @@ } /** - * Sorts the specified range of the array into ascending order. The range - * to be sorted extends from the index {@code fromIndex}, inclusive, to - * the index {@code toIndex}, exclusive. If {@code fromIndex == toIndex}, - * the range to be sorted is empty (and the call is a no-op). - * - * @param a the array to be sorted - * @param fromIndex the index of the first element, inclusive, to be sorted - * @param toIndex the index of the last element, exclusive, to be sorted - * @throws IllegalArgumentException if {@code fromIndex > toIndex} - * @throws ArrayIndexOutOfBoundsException - * if {@code fromIndex < 0} or {@code toIndex > a.length} - */ - public static void sort(long[] a, int fromIndex, int toIndex) { - rangeCheck(a.length, fromIndex, toIndex); - sort(a, fromIndex, toIndex - 1, true); - } - - /** - * Sorts the specified range of the array into ascending order by the - * Dual-Pivot Quicksort algorithm. This method differs from the public - * {@code sort} method in that the {@code right} index is inclusive, - * it does no range checking on {@code left} or {@code right}, and has - * boolean flag whether insertion sort with sentinel is used or not. + * Sorts the specified range of the array. * * @param a the array to be sorted * @param left the index of the first element, inclusive, to be sorted * @param right the index of the last element, inclusive, to be sorted - * @param leftmost indicates if the part is the most left in the range + */ + public static void sort(long[] a, int left, int right) { + sort(a, left, right, true); + } + + /** + * Sorts the specified range of the array by Dual-Pivot Quicksort. + * + * @param a the array to be sorted + * @param left the index of the first element, inclusive, to be sorted + * @param right the index of the last element, inclusive, to be sorted + * @param leftmost indicates if this part is the leftmost in the range */ private static void sort(long[] a, int left, int right, boolean leftmost) { int length = right - left + 1; - // Use insertion sort on tiny arrays + // Use insertion sort on small arrays if (length < INSERTION_SORT_THRESHOLD) { - if (!leftmost) { + if (leftmost) { /* - * Every element in adjoining part plays the role - * of sentinel, therefore this allows us to avoid - * the j >= left check on each iteration. - */ - for (int j, i = left + 1; i <= right; i++) { - long ai = a[i]; - for (j = i - 1; ai < a[j]; j--) { - // assert j >= left; - a[j + 1] = a[j]; - } - a[j + 1] = ai; - } - } else { - /* - * For case of leftmost part traditional (without a sentinel) - * insertion sort, optimized for server JVM, is used. + * Traditional (without sentinel) insertion sort, + * optimized for server VM, is used in case of + * the leftmost part. */ for (int i = left, j = i; i < right; j = ++i) { long ai = a[i + 1]; @@ -476,12 +474,54 @@ } a[j + 1] = ai; } + } else { + /* + * Skip the longest ascending sequence. + */ + do { + if (left++ >= right) { + return; + } + } while (a[left - 1] <= a[left]); + + /* + * Every element from adjoining part plays the role + * of sentinel, therefore this allows us to avoid the + * left range check on each iteration. Moreover, we use + * the best improved algorithm, so called pair insertion + * sort, which is faster than traditional implementation + * in the context of Dual-Pivot Quicksort. + */ + for (int k = left--; (left += 2) <= right; ) { + long a1, a2; k = left - 1; + + if (a[k] < a[left]) { + a2 = a[k]; a1 = a[left]; + } else { + a1 = a[k]; a2 = a[left]; + } + while (a1 < a[--k]) { + a[k + 2] = a[k]; + } + a[++k + 1] = a1; + + while (a2 < a[--k]) { + a[k + 1] = a[k]; + } + a[k + 1] = a2; + } + long last = a[right]; + + while (last < a[--right]) { + a[right + 1] = a[right]; + } + a[right + 1] = last; } return; } // Inexpensive approximation of length / 7 - int seventh = (length >>> 3) + (length >>> 6) + 1; + int seventh = (length >> 3) + (length >> 6) + 1; /* * Sort five evenly spaced elements around (and including) the @@ -563,10 +603,14 @@ * Pointer k is the first index of ?-part. */ outer: - for (int k = less; k <= great; k++) { + for (int k = less - 1; ++k <= great; ) { long ak = a[k]; if (ak < pivot1) { // Move a[k] to left part a[k] = a[less]; + /* + * Here and below we use "a[i] = b; i++;" instead + * of "a[i++] = b;" due to performance issue. + */ a[less] = ak; less++; } else if (ak > pivot2) { // Move a[k] to right part @@ -575,13 +619,17 @@ break outer; } } - if (a[great] < pivot1) { + if (a[great] < pivot1) { // a[great] <= pivot2 a[k] = a[less]; a[less] = a[great]; less++; } else { // pivot1 <= a[great] <= pivot2 a[k] = a[great]; } + /* + * Here and below we use "a[i] = b; i--;" instead + * of "a[i--] = b;" due to performance issue. + */ a[great] = ak; great--; } @@ -596,7 +644,7 @@ sort(a, great + 2, right, false); /* - * If center part is too large (comprises > 5/7 of the array), + * If center part is too large (comprises > 4/7 of the array), * swap internal pivot values to ends. */ if (less < e1 && e5 < great) { @@ -630,7 +678,7 @@ * Pointer k is the first index of ?-part. */ outer: - for (int k = less; k <= great; k++) { + for (int k = less - 1; ++k <= great; ) { long ak = a[k]; if (ak == pivot1) { // Move a[k] to left part a[k] = a[less]; @@ -642,7 +690,7 @@ break outer; } } - if (a[great] == pivot1) { + if (a[great] == pivot1) { // a[great] < pivot2 a[k] = a[less]; /* * Even though a[great] equals to pivot1, the @@ -668,7 +716,7 @@ } else { // Pivots are equal /* - * Partition degenerates to the traditional 3-way + * Partitioning degenerates to the traditional 3-way * (or "Dutch National Flag") schema: * * left part center part right part @@ -687,28 +735,20 @@ * * Pointer k is the first index of ?-part. */ - for (int k = left; k <= great; k++) { + for (int k = less; k <= great; ++k) { if (a[k] == pivot1) { continue; } long ak = a[k]; - if (ak < pivot1) { // Move a[k] to left part a[k] = a[less]; a[less] = ak; less++; } else { // a[k] > pivot1 - Move a[k] to right part - /* - * We know that pivot1 == a[e3] == pivot2. Thus, we know - * that great will still be >= k when the following loop - * terminates, even though we don't test for it explicitly. - * In other words, a[e3] acts as a sentinel for great. - */ while (a[great] > pivot1) { - // assert great > k; great--; } - if (a[great] < pivot1) { + if (a[great] < pivot1) { // a[great] <= pivot1 a[k] = a[less]; a[less] = a[great]; less++; @@ -728,45 +768,51 @@ } } - // Sort left and right parts recursively + /* + * Sort left and right parts recursively. + * All elements from center part are equal + * and, therefore, already sorted. + */ sort(a, left, less - 1, leftmost); sort(a, great + 1, right, false); } } /** - * Sorts the specified array into ascending numerical order. + * Sorts the specified array. * * @param a the array to be sorted */ public static void sort(short[] a) { - if (a.length > COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) { - countingSort(a, 0, a.length - 1); - } else { - sort(a, 0, a.length - 1, true); - } + sort(a, 0, a.length - 1); } /** - * Sorts the specified range of the array into ascending order. The range - * to be sorted extends from the index {@code fromIndex}, inclusive, to - * the index {@code toIndex}, exclusive. If {@code fromIndex == toIndex}, - * the range to be sorted is empty (and the call is a no-op). + * Sorts the specified range of the array. * * @param a the array to be sorted - * @param fromIndex the index of the first element, inclusive, to be sorted - * @param toIndex the index of the last element, exclusive, to be sorted - * @throws IllegalArgumentException if {@code fromIndex > toIndex} - * @throws ArrayIndexOutOfBoundsException - * if {@code fromIndex < 0} or {@code toIndex > a.length} + * @param left the index of the first element, inclusive, to be sorted + * @param right the index of the last element, inclusive, to be sorted */ - public static void sort(short[] a, int fromIndex, int toIndex) { - rangeCheck(a.length, fromIndex, toIndex); + public static void sort(short[] a, int left, int right) { + // Use counting sort on large arrays + if (right - left > COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) { + int[] count = new int[NUM_SHORT_VALUES]; - if (toIndex - fromIndex > COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) { - countingSort(a, fromIndex, toIndex - 1); - } else { - sort(a, fromIndex, toIndex - 1, true); + for (int i = left - 1; ++i <= right; ) { + count[a[i] - Short.MIN_VALUE]++; + } + for (int i = NUM_SHORT_VALUES, k = right + 1; k > left; ) { + while (count[--i] == 0); + short value = (short) (i + Short.MIN_VALUE); + int s = count[i]; + + do { + a[--k] = value; + } while (--s > 0); + } + } else { // Use Dual-Pivot Quicksort on small arrays + sort(a, left, right, true); } } @@ -774,66 +820,23 @@ private static final int NUM_SHORT_VALUES = 1 << 16; /** - * Sorts the specified range of the array by counting sort. + * Sorts the specified range of the array by Dual-Pivot Quicksort. * * @param a the array to be sorted * @param left the index of the first element, inclusive, to be sorted * @param right the index of the last element, inclusive, to be sorted - */ - private static void countingSort(short[] a, int left, int right) { - int[] count = new int[NUM_SHORT_VALUES]; - - for (int i = left; i <= right; i++) { - count[a[i] - Short.MIN_VALUE]++; - } - for (int i = NUM_SHORT_VALUES - 1, k = right; k >= left; i--) { - while (count[i] == 0) { - i--; - } - short value = (short) (i + Short.MIN_VALUE); - int s = count[i]; - - do { - a[k--] = value; - } while (--s > 0); - } - } - - /** - * Sorts the specified range of the array into ascending order by the - * Dual-Pivot Quicksort algorithm. This method differs from the public - * {@code sort} method in that the {@code right} index is inclusive, - * it does no range checking on {@code left} or {@code right}, and has - * boolean flag whether insertion sort with sentinel is used or not. - * - * @param a the array to be sorted - * @param left the index of the first element, inclusive, to be sorted - * @param right the index of the last element, inclusive, to be sorted - * @param leftmost indicates if the part is the most left in the range + * @param leftmost indicates if this part is the leftmost in the range */ private static void sort(short[] a, int left, int right,boolean leftmost) { int length = right - left + 1; - // Use insertion sort on tiny arrays + // Use insertion sort on small arrays if (length < INSERTION_SORT_THRESHOLD) { - if (!leftmost) { + if (leftmost) { /* - * Every element in adjoining part plays the role - * of sentinel, therefore this allows us to avoid - * the j >= left check on each iteration. - */ - for (int j, i = left + 1; i <= right; i++) { - short ai = a[i]; - for (j = i - 1; ai < a[j]; j--) { - // assert j >= left; - a[j + 1] = a[j]; - } - a[j + 1] = ai; - } - } else { - /* - * For case of leftmost part traditional (without a sentinel) - * insertion sort, optimized for server JVM, is used. + * Traditional (without sentinel) insertion sort, + * optimized for server VM, is used in case of + * the leftmost part. */ for (int i = left, j = i; i < right; j = ++i) { short ai = a[i + 1]; @@ -845,12 +848,54 @@ } a[j + 1] = ai; } + } else { + /* + * Skip the longest ascending sequence. + */ + do { + if (left++ >= right) { + return; + } + } while (a[left - 1] <= a[left]); + + /* + * Every element from adjoining part plays the role + * of sentinel, therefore this allows us to avoid the + * left range check on each iteration. Moreover, we use + * the best improved algorithm, so called pair insertion + * sort, which is faster than traditional implementation + * in the context of Dual-Pivot Quicksort. + */ + for (int k = left--; (left += 2) <= right; ) { + short a1, a2; k = left - 1; + + if (a[k] < a[left]) { + a2 = a[k]; a1 = a[left]; + } else { + a1 = a[k]; a2 = a[left]; + } + while (a1 < a[--k]) { + a[k + 2] = a[k]; + } + a[++k + 1] = a1; + + while (a2 < a[--k]) { + a[k + 1] = a[k]; + } + a[k + 1] = a2; + } + short last = a[right]; + + while (last < a[--right]) { + a[right + 1] = a[right]; + } + a[right + 1] = last; } return; } // Inexpensive approximation of length / 7 - int seventh = (length >>> 3) + (length >>> 6) + 1; + int seventh = (length >> 3) + (length >> 6) + 1; /* * Sort five evenly spaced elements around (and including) the @@ -932,10 +977,14 @@ * Pointer k is the first index of ?-part. */ outer: - for (int k = less; k <= great; k++) { + for (int k = less - 1; ++k <= great; ) { short ak = a[k]; if (ak < pivot1) { // Move a[k] to left part a[k] = a[less]; + /* + * Here and below we use "a[i] = b; i++;" instead + * of "a[i++] = b;" due to performance issue. + */ a[less] = ak; less++; } else if (ak > pivot2) { // Move a[k] to right part @@ -944,13 +993,17 @@ break outer; } } - if (a[great] < pivot1) { + if (a[great] < pivot1) { // a[great] <= pivot2 a[k] = a[less]; a[less] = a[great]; less++; } else { // pivot1 <= a[great] <= pivot2 a[k] = a[great]; } + /* + * Here and below we use "a[i] = b; i--;" instead + * of "a[i--] = b;" due to performance issue. + */ a[great] = ak; great--; } @@ -965,7 +1018,7 @@ sort(a, great + 2, right, false); /* - * If center part is too large (comprises > 5/7 of the array), + * If center part is too large (comprises > 4/7 of the array), * swap internal pivot values to ends. */ if (less < e1 && e5 < great) { @@ -999,7 +1052,7 @@ * Pointer k is the first index of ?-part. */ outer: - for (int k = less; k <= great; k++) { + for (int k = less - 1; ++k <= great; ) { short ak = a[k]; if (ak == pivot1) { // Move a[k] to left part a[k] = a[less]; @@ -1011,7 +1064,7 @@ break outer; } } - if (a[great] == pivot1) { + if (a[great] == pivot1) { // a[great] < pivot2 a[k] = a[less]; /* * Even though a[great] equals to pivot1, the @@ -1037,7 +1090,7 @@ } else { // Pivots are equal /* - * Partition degenerates to the traditional 3-way + * Partitioning degenerates to the traditional 3-way * (or "Dutch National Flag") schema: * * left part center part right part @@ -1056,28 +1109,20 @@ * * Pointer k is the first index of ?-part. */ - for (int k = left; k <= great; k++) { + for (int k = less; k <= great; ++k) { if (a[k] == pivot1) { continue; } short ak = a[k]; - if (ak < pivot1) { // Move a[k] to left part a[k] = a[less]; a[less] = ak; less++; } else { // a[k] > pivot1 - Move a[k] to right part - /* - * We know that pivot1 == a[e3] == pivot2. Thus, we know - * that great will still be >= k when the following loop - * terminates, even though we don't test for it explicitly. - * In other words, a[e3] acts as a sentinel for great. - */ while (a[great] > pivot1) { - // assert great > k; great--; } - if (a[great] < pivot1) { + if (a[great] < pivot1) { // a[great] <= pivot1 a[k] = a[less]; a[less] = a[great]; less++; @@ -1097,45 +1142,51 @@ } } - // Sort left and right parts recursively + /* + * Sort left and right parts recursively. + * All elements from center part are equal + * and, therefore, already sorted. + */ sort(a, left, less - 1, leftmost); sort(a, great + 1, right, false); } } /** - * Sorts the specified array into ascending numerical order. + * Sorts the specified array. * * @param a the array to be sorted */ public static void sort(char[] a) { - if (a.length > COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) { - countingSort(a, 0, a.length - 1); - } else { - sort(a, 0, a.length - 1, true); - } + sort(a, 0, a.length - 1); } /** - * Sorts the specified range of the array into ascending order. The range - * to be sorted extends from the index {@code fromIndex}, inclusive, to - * the index {@code toIndex}, exclusive. If {@code fromIndex == toIndex}, - * the range to be sorted is empty (and the call is a no-op). + * Sorts the specified range of the array. * * @param a the array to be sorted - * @param fromIndex the index of the first element, inclusive, to be sorted - * @param toIndex the index of the last element, exclusive, to be sorted - * @throws IllegalArgumentException if {@code fromIndex > toIndex} - * @throws ArrayIndexOutOfBoundsException - * if {@code fromIndex < 0} or {@code toIndex > a.length} + * @param left the index of the first element, inclusive, to be sorted + * @param right the index of the last element, inclusive, to be sorted */ - public static void sort(char[] a, int fromIndex, int toIndex) { - rangeCheck(a.length, fromIndex, toIndex); + public static void sort(char[] a, int left, int right) { + // Use counting sort on large arrays + if (right - left > COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) { + int[] count = new int[NUM_CHAR_VALUES]; - if (toIndex - fromIndex > COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) { - countingSort(a, fromIndex, toIndex - 1); - } else { - sort(a, fromIndex, toIndex - 1, true); + for (int i = left - 1; ++i <= right; ) { + count[a[i]]++; + } + for (int i = NUM_CHAR_VALUES, k = right + 1; k > left; ) { + while (count[--i] == 0); + char value = (char) i; + int s = count[i]; + + do { + a[--k] = value; + } while (--s > 0); + } + } else { // Use Dual-Pivot Quicksort on small arrays + sort(a, left, right, true); } } @@ -1143,66 +1194,23 @@ private static final int NUM_CHAR_VALUES = 1 << 16; /** - * Sorts the specified range of the array by counting sort. + * Sorts the specified range of the array by Dual-Pivot Quicksort. * * @param a the array to be sorted * @param left the index of the first element, inclusive, to be sorted * @param right the index of the last element, inclusive, to be sorted - */ - private static void countingSort(char[] a, int left, int right) { - int[] count = new int[NUM_CHAR_VALUES]; - - for (int i = left; i <= right; i++) { - count[a[i]]++; - } - for (int i = 0, k = left; k <= right; i++) { - while (count[i] == 0) { - i++; - } - char value = (char) i; - int s = count[i]; - - do { - a[k++] = value; - } while (--s > 0); - } - } - - /** - * Sorts the specified range of the array into ascending order by the - * Dual-Pivot Quicksort algorithm. This method differs from the public - * {@code sort} method in that the {@code right} index is inclusive, - * it does no range checking on {@code left} or {@code right}, and has - * boolean flag whether insertion sort with sentinel is used or not. - * - * @param a the array to be sorted - * @param left the index of the first element, inclusive, to be sorted - * @param right the index of the last element, inclusive, to be sorted - * @param leftmost indicates if the part is the most left in the range + * @param leftmost indicates if this part is the leftmost in the range */ private static void sort(char[] a, int left, int right, boolean leftmost) { int length = right - left + 1; - // Use insertion sort on tiny arrays + // Use insertion sort on small arrays if (length < INSERTION_SORT_THRESHOLD) { - if (!leftmost) { + if (leftmost) { /* - * Every element in adjoining part plays the role - * of sentinel, therefore this allows us to avoid - * the j >= left check on each iteration. - */ - for (int j, i = left + 1; i <= right; i++) { - char ai = a[i]; - for (j = i - 1; ai < a[j]; j--) { - // assert j >= left; - a[j + 1] = a[j]; - } - a[j + 1] = ai; - } - } else { - /* - * For case of leftmost part traditional (without a sentinel) - * insertion sort, optimized for server JVM, is used. + * Traditional (without sentinel) insertion sort, + * optimized for server VM, is used in case of + * the leftmost part. */ for (int i = left, j = i; i < right; j = ++i) { char ai = a[i + 1]; @@ -1214,12 +1222,54 @@ } a[j + 1] = ai; } + } else { + /* + * Skip the longest ascending sequence. + */ + do { + if (left++ >= right) { + return; + } + } while (a[left - 1] <= a[left]); + + /* + * Every element from adjoining part plays the role + * of sentinel, therefore this allows us to avoid the + * left range check on each iteration. Moreover, we use + * the best improved algorithm, so called pair insertion + * sort, which is faster than traditional implementation + * in the context of Dual-Pivot Quicksort. + */ + for (int k = left--; (left += 2) <= right; ) { + char a1, a2; k = left - 1; + + if (a[k] < a[left]) { + a2 = a[k]; a1 = a[left]; + } else { + a1 = a[k]; a2 = a[left]; + } + while (a1 < a[--k]) { + a[k + 2] = a[k]; + } + a[++k + 1] = a1; + + while (a2 < a[--k]) { + a[k + 1] = a[k]; + } + a[k + 1] = a2; + } + char last = a[right]; + + while (last < a[--right]) { + a[right + 1] = a[right]; + } + a[right + 1] = last; } return; } // Inexpensive approximation of length / 7 - int seventh = (length >>> 3) + (length >>> 6) + 1; + int seventh = (length >> 3) + (length >> 6) + 1; /* * Sort five evenly spaced elements around (and including) the @@ -1301,10 +1351,14 @@ * Pointer k is the first index of ?-part. */ outer: - for (int k = less; k <= great; k++) { + for (int k = less - 1; ++k <= great; ) { char ak = a[k]; if (ak < pivot1) { // Move a[k] to left part a[k] = a[less]; + /* + * Here and below we use "a[i] = b; i++;" instead + * of "a[i++] = b;" due to performance issue. + */ a[less] = ak; less++; } else if (ak > pivot2) { // Move a[k] to right part @@ -1313,13 +1367,17 @@ break outer; } } - if (a[great] < pivot1) { + if (a[great] < pivot1) { // a[great] <= pivot2 a[k] = a[less]; a[less] = a[great]; less++; } else { // pivot1 <= a[great] <= pivot2 a[k] = a[great]; } + /* + * Here and below we use "a[i] = b; i--;" instead + * of "a[i--] = b;" due to performance issue. + */ a[great] = ak; great--; } @@ -1334,7 +1392,7 @@ sort(a, great + 2, right, false); /* - * If center part is too large (comprises > 5/7 of the array), + * If center part is too large (comprises > 4/7 of the array), * swap internal pivot values to ends. */ if (less < e1 && e5 < great) { @@ -1368,7 +1426,7 @@ * Pointer k is the first index of ?-part. */ outer: - for (int k = less; k <= great; k++) { + for (int k = less - 1; ++k <= great; ) { char ak = a[k]; if (ak == pivot1) { // Move a[k] to left part a[k] = a[less]; @@ -1380,7 +1438,7 @@ break outer; } } - if (a[great] == pivot1) { + if (a[great] == pivot1) { // a[great] < pivot2 a[k] = a[less]; /* * Even though a[great] equals to pivot1, the @@ -1406,7 +1464,7 @@ } else { // Pivots are equal /* - * Partition degenerates to the traditional 3-way + * Partitioning degenerates to the traditional 3-way * (or "Dutch National Flag") schema: * * left part center part right part @@ -1425,28 +1483,20 @@ * * Pointer k is the first index of ?-part. */ - for (int k = left; k <= great; k++) { + for (int k = less; k <= great; ++k) { if (a[k] == pivot1) { continue; } char ak = a[k]; - if (ak < pivot1) { // Move a[k] to left part a[k] = a[less]; a[less] = ak; less++; } else { // a[k] > pivot1 - Move a[k] to right part - /* - * We know that pivot1 == a[e3] == pivot2. Thus, we know - * that great will still be >= k when the following loop - * terminates, even though we don't test for it explicitly. - * In other words, a[e3] acts as a sentinel for great. - */ while (a[great] > pivot1) { - // assert great > k; great--; } - if (a[great] < pivot1) { + if (a[great] < pivot1) { // a[great] <= pivot1 a[k] = a[less]; a[less] = a[great]; less++; @@ -1466,442 +1516,90 @@ } } - // Sort left and right parts recursively + /* + * Sort left and right parts recursively. + * All elements from center part are equal + * and, therefore, already sorted. + */ sort(a, left, less - 1, leftmost); sort(a, great + 1, right, false); } } - /** - * Sorts the specified array into ascending numerical order. - * - * @param a the array to be sorted - */ - public static void sort(byte[] a) { - if (a.length > COUNTING_SORT_THRESHOLD_FOR_BYTE) { - countingSort(a, 0, a.length - 1); - } else { - sort(a, 0, a.length - 1, true); - } - } - - /** - * Sorts the specified range of the array into ascending order. The range - * to be sorted extends from the index {@code fromIndex}, inclusive, to - * the index {@code toIndex}, exclusive. If {@code fromIndex == toIndex}, - * the range to be sorted is empty (and the call is a no-op). - * - * @param a the array to be sorted - * @param fromIndex the index of the first element, inclusive, to be sorted - * @param toIndex the index of the last element, exclusive, to be sorted - * @throws IllegalArgumentException if {@code fromIndex > toIndex} - * @throws ArrayIndexOutOfBoundsException - * if {@code fromIndex < 0} or {@code toIndex > a.length} - */ - public static void sort(byte[] a, int fromIndex, int toIndex) { - rangeCheck(a.length, fromIndex, toIndex); - - if (toIndex - fromIndex > COUNTING_SORT_THRESHOLD_FOR_BYTE) { - countingSort(a, fromIndex, toIndex - 1); - } else { - sort(a, fromIndex, toIndex - 1, true); - } - } - /** The number of distinct byte values. */ private static final int NUM_BYTE_VALUES = 1 << 8; /** - * Sorts the specified range of the array by counting sort. + * Sorts the specified array. + * + * @param a the array to be sorted + */ + public static void sort(byte[] a) { + sort(a, 0, a.length - 1); + } + + /** + * Sorts the specified range of the array. * * @param a the array to be sorted * @param left the index of the first element, inclusive, to be sorted * @param right the index of the last element, inclusive, to be sorted */ - private static void countingSort(byte[] a, int left, int right) { - int[] count = new int[NUM_BYTE_VALUES]; + public static void sort(byte[] a, int left, int right) { + // Use counting sort on large arrays + if (right - left > COUNTING_SORT_THRESHOLD_FOR_BYTE) { + int[] count = new int[NUM_BYTE_VALUES]; + + for (int i = left - 1; ++i <= right; ) { + count[a[i] - Byte.MIN_VALUE]++; + } + for (int i = NUM_BYTE_VALUES, k = right + 1; k > left; ) { + while (count[--i] == 0); + byte value = (byte) (i + Byte.MIN_VALUE); + int s = count[i]; - for (int i = left; i <= right; i++) { - count[a[i] - Byte.MIN_VALUE]++; - } - for (int i = NUM_BYTE_VALUES - 1, k = right; k >= left; i--) { - while (count[i] == 0) { - i--; + do { + a[--k] = value; + } while (--s > 0); } - byte value = (byte) (i + Byte.MIN_VALUE); - int s = count[i]; - - do { - a[k--] = value; - } while (--s > 0); + } else { // Use insertion sort on small arrays + for (int i = left, j = i; i < right; j = ++i) { + byte ai = a[i + 1]; + while (ai < a[j]) { + a[j + 1] = a[j]; + if (j-- == left) { + break; + } + } + a[j + 1] = ai; + } } } /** - * Sorts the specified range of the array into ascending order by the - * Dual-Pivot Quicksort algorithm. This method differs from the public - * {@code sort} method in that the {@code right} index is inclusive, - * it does no range checking on {@code left} or {@code right}, and has - * boolean flag whether insertion sort with sentinel is used or not. - * - * @param a the array to be sorted - * @param left the index of the first element, inclusive, to be sorted - * @param right the index of the last element, inclusive, to be sorted - * @param leftmost indicates if the part is the most left in the range - */ - private static void sort(byte[] a, int left, int right, boolean leftmost) { - int length = right - left + 1; - - // Use insertion sort on tiny arrays - if (length < INSERTION_SORT_THRESHOLD) { - if (!leftmost) { - /* - * Every element in adjoining part plays the role - * of sentinel, therefore this allows us to avoid - * the j >= left check on each iteration. - */ - for (int j, i = left + 1; i <= right; i++) { - byte ai = a[i]; - for (j = i - 1; ai < a[j]; j--) { - // assert j >= left; - a[j + 1] = a[j]; - } - a[j + 1] = ai; - } - } else { - /* - * For case of leftmost part traditional (without a sentinel) - * insertion sort, optimized for server JVM, is used. - */ - for (int i = left, j = i; i < right; j = ++i) { - byte ai = a[i + 1]; - while (ai < a[j]) { - a[j + 1] = a[j]; - if (j-- == left) { - break; - } - } - a[j + 1] = ai; - } - } - return; - } - - // Inexpensive approximation of length / 7 - int seventh = (length >>> 3) + (length >>> 6) + 1; - - /* - * Sort five evenly spaced elements around (and including) the - * center element in the range. These elements will be used for - * pivot selection as described below. The choice for spacing - * these elements was empirically determined to work well on - * a wide variety of inputs. - */ - int e3 = (left + right) >>> 1; // The midpoint - int e2 = e3 - seventh; - int e1 = e2 - seventh; - int e4 = e3 + seventh; - int e5 = e4 + seventh; - - // Sort these elements using insertion sort - if (a[e2] < a[e1]) { byte t = a[e2]; a[e2] = a[e1]; a[e1] = t; } - - if (a[e3] < a[e2]) { byte t = a[e3]; a[e3] = a[e2]; a[e2] = t; - if (t < a[e1]) { a[e2] = a[e1]; a[e1] = t; } - } - if (a[e4] < a[e3]) { byte t = a[e4]; a[e4] = a[e3]; a[e3] = t; - if (t < a[e2]) { a[e3] = a[e2]; a[e2] = t; - if (t < a[e1]) { a[e2] = a[e1]; a[e1] = t; } - } - } - if (a[e5] < a[e4]) { byte t = a[e5]; a[e5] = a[e4]; a[e4] = t; - if (t < a[e3]) { a[e4] = a[e3]; a[e3] = t; - if (t < a[e2]) { a[e3] = a[e2]; a[e2] = t; - if (t < a[e1]) { a[e2] = a[e1]; a[e1] = t; } - } - } - } - - /* - * Use the second and fourth of the five sorted elements as pivots. - * These values are inexpensive approximations of the first and - * second terciles of the array. Note that pivot1 <= pivot2. - */ - byte pivot1 = a[e2]; - byte pivot2 = a[e4]; - - // Pointers - int less = left; // The index of the first element of center part - int great = right; // The index before the first element of right part - - if (pivot1 != pivot2) { - /* - * The first and the last elements to be sorted are moved to the - * locations formerly occupied by the pivots. When partitioning - * is complete, the pivots are swapped back into their final - * positions, and excluded from subsequent sorting. - */ - a[e2] = a[left]; - a[e4] = a[right]; - - /* - * Skip elements, which are less or greater than pivot values. - */ - while (a[++less] < pivot1); - while (a[--great] > pivot2); - - /* - * Partitioning: - * - * left part center part right part - * +--------------------------------------------------------------+ - * | < pivot1 | pivot1 <= && <= pivot2 | ? | > pivot2 | - * +--------------------------------------------------------------+ - * ^ ^ ^ - * | | | - * less k great - * - * Invariants: - * - * all in (left, less) < pivot1 - * pivot1 <= all in [less, k) <= pivot2 - * all in (great, right) > pivot2 - * - * Pointer k is the first index of ?-part. - */ - outer: - for (int k = less; k <= great; k++) { - byte ak = a[k]; - if (ak < pivot1) { // Move a[k] to left part - a[k] = a[less]; - a[less] = ak; - less++; - } else if (ak > pivot2) { // Move a[k] to right part - while (a[great] > pivot2) { - if (great-- == k) { - break outer; - } - } - if (a[great] < pivot1) { - a[k] = a[less]; - a[less] = a[great]; - less++; - } else { // pivot1 <= a[great] <= pivot2 - a[k] = a[great]; - } - a[great] = ak; - great--; - } - } - - // Swap pivots into their final positions - a[left] = a[less - 1]; a[less - 1] = pivot1; - a[right] = a[great + 1]; a[great + 1] = pivot2; - - // Sort left and right parts recursively, excluding known pivots - sort(a, left, less - 2, leftmost); - sort(a, great + 2, right, false); - - /* - * If center part is too large (comprises > 5/7 of the array), - * swap internal pivot values to ends. - */ - if (less < e1 && e5 < great) { - /* - * Skip elements, which are equal to pivot values. - */ - while (a[less] == pivot1) { - less++; - } - while (a[great] == pivot2) { - great--; - } - - /* - * Partitioning: - * - * left part center part right part - * +----------------------------------------------------------+ - * | == pivot1 | pivot1 < && < pivot2 | ? | == pivot2 | - * +----------------------------------------------------------+ - * ^ ^ ^ - * | | | - * less k great - * - * Invariants: - * - * all in (*, less) == pivot1 - * pivot1 < all in [less, k) < pivot2 - * all in (great, *) == pivot2 - * - * Pointer k is the first index of ?-part. - */ - outer: - for (int k = less; k <= great; k++) { - byte ak = a[k]; - if (ak == pivot1) { // Move a[k] to left part - a[k] = a[less]; - a[less] = ak; - less++; - } else if (ak == pivot2) { // Move a[k] to right part - while (a[great] == pivot2) { - if (great-- == k) { - break outer; - } - } - if (a[great] == pivot1) { - a[k] = a[less]; - /* - * Even though a[great] equals to pivot1, the - * assignment a[less] = pivot1 may be incorrect, - * if a[great] and pivot1 are floating-point zeros - * of different signs. Therefore in float and - * double sorting methods we have to use more - * accurate assignment a[less] = a[great]. - */ - a[less] = pivot1; - less++; - } else { // pivot1 < a[great] < pivot2 - a[k] = a[great]; - } - a[great] = ak; - great--; - } - } - } - - // Sort center part recursively - sort(a, less, great, false); - - } else { // Pivots are equal - /* - * Partition degenerates to the traditional 3-way - * (or "Dutch National Flag") schema: - * - * left part center part right part - * +-------------------------------------------------+ - * | < pivot | == pivot | ? | > pivot | - * +-------------------------------------------------+ - * ^ ^ ^ - * | | | - * less k great - * - * Invariants: - * - * all in (left, less) < pivot - * all in [less, k) == pivot - * all in (great, right) > pivot - * - * Pointer k is the first index of ?-part. - */ - for (int k = left; k <= great; k++) { - if (a[k] == pivot1) { - continue; - } - byte ak = a[k]; - - if (ak < pivot1) { // Move a[k] to left part - a[k] = a[less]; - a[less] = ak; - less++; - } else { // a[k] > pivot1 - Move a[k] to right part - /* - * We know that pivot1 == a[e3] == pivot2. Thus, we know - * that great will still be >= k when the following loop - * terminates, even though we don't test for it explicitly. - * In other words, a[e3] acts as a sentinel for great. - */ - while (a[great] > pivot1) { - // assert great > k; - great--; - } - if (a[great] < pivot1) { - a[k] = a[less]; - a[less] = a[great]; - less++; - } else { // a[great] == pivot1 - /* - * Even though a[great] equals to pivot1, the - * assignment a[k] = pivot1 may be incorrect, - * if a[great] and pivot1 are floating-point - * zeros of different signs. Therefore in float - * and double sorting methods we have to use - * more accurate assignment a[k] = a[great]. - */ - a[k] = pivot1; - } - a[great] = ak; - great--; - } - } - - // Sort left and right parts recursively - sort(a, left, less - 1, leftmost); - sort(a, great + 1, right, false); - } - } - - /** - * Sorts the specified array into ascending numerical order. - * - * <p>The {@code <} relation does not provide a total order on all float - * values: {@code -0.0f == 0.0f} is {@code true} and a {@code Float.NaN} - * value compares neither less than, greater than, nor equal to any value, - * even itself. This method uses the total order imposed by the method - * {@link Float#compareTo}: {@code -0.0f} is treated as less than value - * {@code 0.0f} and {@code Float.NaN} is considered greater than any - * other value and all {@code Float.NaN} values are considered equal. + * Sorts the specified array. * * @param a the array to be sorted */ public static void sort(float[] a) { - sortNegZeroAndNaN(a, 0, a.length - 1); + sort(a, 0, a.length - 1); } /** - * Sorts the specified range of the array into ascending order. The range - * to be sorted extends from the index {@code fromIndex}, inclusive, to - * the index {@code toIndex}, exclusive. If {@code fromIndex == toIndex}, - * the range to be sorted is empty (and the call is a no-op). - * - * <p>The {@code <} relation does not provide a total order on all float - * values: {@code -0.0f == 0.0f} is {@code true} and a {@code Float.NaN} - * value compares neither less than, greater than, nor equal to any value, - * even itself. This method uses the total order imposed by the method - * {@link Float#compareTo}: {@code -0.0f} is treated as less than value - * {@code 0.0f} and {@code Float.NaN} is considered greater than any - * other value and all {@code Float.NaN} values are considered equal. - * - * @param a the array to be sorted - * @param fromIndex the index of the first element, inclusive, to be sorted - * @param toIndex the index of the last element, exclusive, to be sorted - * @throws IllegalArgumentException if {@code fromIndex > toIndex} - * @throws ArrayIndexOutOfBoundsException - * if {@code fromIndex < 0} or {@code toIndex > a.length} - */ - public static void sort(float[] a, int fromIndex, int toIndex) { - rangeCheck(a.length, fromIndex, toIndex); - sortNegZeroAndNaN(a, fromIndex, toIndex - 1); - } - - /** - * Sorts the specified range of the array into ascending order. The - * sort is done in three phases to avoid expensive comparisons in the - * inner loop. The comparisons would be expensive due to anomalies - * associated with negative zero {@code -0.0f} and {@code Float.NaN}. + * Sorts the specified range of the array. * * @param a the array to be sorted * @param left the index of the first element, inclusive, to be sorted * @param right the index of the last element, inclusive, to be sorted */ - private static void sortNegZeroAndNaN(float[] a, int left, int right) { + public static void sort(float[] a, int left, int right) { /* * Phase 1: Move NaNs to the end of the array. */ while (left <= right && Float.isNaN(a[right])) { right--; } - for (int k = right - 1; k >= left; k--) { + for (int k = right; --k >= left; ) { float ak = a[k]; if (ak != ak) { // a[k] is NaN a[k] = a[right]; @@ -1921,7 +1619,7 @@ int hi = right; /* - * Search first zero, or first positive, or last negative element. + * Find the first zero, or first positive, or last negative element. */ while (left < hi) { int middle = (left + hi) >>> 1; @@ -1946,12 +1644,12 @@ * * Partitioning: * - * +---------------------------------------------------+ - * | < 0.0 | -0.0 | 0.0 | ? ( >= 0.0 ) | - * +---------------------------------------------------+ - * ^ ^ ^ - * | | | - * left p k + * +----------------------------------------------------+ + * | < 0.0 | -0.0 | 0.0 | ? ( >= 0.0 ) | + * +----------------------------------------------------+ + * ^ ^ ^ + * | | | + * left p k * * Invariants: * @@ -1962,53 +1660,36 @@ * * Pointer k is the first index of ?-part. */ - for (int k = left + 1, p = left; k <= right; k++) { + for (int k = left, p = left - 1; ++k <= right; ) { float ak = a[k]; if (ak != 0.0f) { break; } if (Float.floatToRawIntBits(ak) < 0) { // ak is -0.0f a[k] = 0.0f; - a[p++] = -0.0f; + a[++p] = -0.0f; } } } /** - * Sorts the specified range of the array into ascending order by the - * Dual-Pivot Quicksort algorithm. This method differs from the public - * {@code sort} method in that the {@code right} index is inclusive, - * it does no range checking on {@code left} or {@code right}, and has - * boolean flag whether insertion sort with sentinel is used or not. + * Sorts the specified range of the array by Dual-Pivot Quicksort. * * @param a the array to be sorted * @param left the index of the first element, inclusive, to be sorted * @param right the index of the last element, inclusive, to be sorted - * @param leftmost indicates if the part is the most left in the range + * @param leftmost indicates if this part is the leftmost in the range */ private static void sort(float[] a, int left, int right,boolean leftmost) { int length = right - left + 1; - // Use insertion sort on tiny arrays + // Use insertion sort on small arrays if (length < INSERTION_SORT_THRESHOLD) { - if (!leftmost) { + if (leftmost) { /* - * Every element in adjoining part plays the role - * of sentinel, therefore this allows us to avoid - * the j >= left check on each iteration. - */ - for (int j, i = left + 1; i <= right; i++) { - float ai = a[i]; - for (j = i - 1; ai < a[j]; j--) { - // assert j >= left; - a[j + 1] = a[j]; - } - a[j + 1] = ai; - } - } else { - /* - * For case of leftmost part traditional (without a sentinel) - * insertion sort, optimized for server JVM, is used. + * Traditional (without sentinel) insertion sort, + * optimized for server VM, is used in case of + * the leftmost part. */ for (int i = left, j = i; i < right; j = ++i) { float ai = a[i + 1]; @@ -2020,12 +1701,54 @@ } a[j + 1] = ai; } + } else { + /* + * Skip the longest ascending sequence. + */ + do { + if (left++ >= right) { + return; + } + } while (a[left - 1] <= a[left]); + + /* + * Every element from adjoining part plays the role + * of sentinel, therefore this allows us to avoid the + * left range check on each iteration. Moreover, we use + * the best improved algorithm, so called pair insertion + * sort, which is faster than traditional implementation + * in the context of Dual-Pivot Quicksort. + */ + for (int k = left--; (left += 2) <= right; ) { + float a1, a2; k = left - 1; + + if (a[k] < a[left]) { + a2 = a[k]; a1 = a[left]; + } else { + a1 = a[k]; a2 = a[left]; + } + while (a1 < a[--k]) { + a[k + 2] = a[k]; + } + a[++k + 1] = a1; + + while (a2 < a[--k]) { + a[k + 1] = a[k]; + } + a[k + 1] = a2; + } + float last = a[right]; + + while (last < a[--right]) { + a[right + 1] = a[right]; + } + a[right + 1] = last; } return; } // Inexpensive approximation of length / 7 - int seventh = (length >>> 3) + (length >>> 6) + 1; + int seventh = (length >> 3) + (length >> 6) + 1; /* * Sort five evenly spaced elements around (and including) the @@ -2107,10 +1830,14 @@ * Pointer k is the first index of ?-part. */ outer: - for (int k = less; k <= great; k++) { + for (int k = less - 1; ++k <= great; ) { float ak = a[k]; if (ak < pivot1) { // Move a[k] to left part a[k] = a[less]; + /* + * Here and below we use "a[i] = b; i++;" instead + * of "a[i++] = b;" due to performance issue. + */ a[less] = ak; less++; } else if (ak > pivot2) { // Move a[k] to right part @@ -2119,13 +1846,17 @@ break outer; } } - if (a[great] < pivot1) { + if (a[great] < pivot1) { // a[great] <= pivot2 a[k] = a[less]; a[less] = a[great]; less++; } else { // pivot1 <= a[great] <= pivot2 a[k] = a[great]; } + /* + * Here and below we use "a[i] = b; i--;" instead + * of "a[i--] = b;" due to performance issue. + */ a[great] = ak; great--; } @@ -2140,7 +1871,7 @@ sort(a, great + 2, right, false); /* - * If center part is too large (comprises > 5/7 of the array), + * If center part is too large (comprises > 4/7 of the array), * swap internal pivot values to ends. */ if (less < e1 && e5 < great) { @@ -2174,7 +1905,7 @@ * Pointer k is the first index of ?-part. */ outer: - for (int k = less; k <= great; k++) { + for (int k = less - 1; ++k <= great; ) { float ak = a[k]; if (ak == pivot1) { // Move a[k] to left part a[k] = a[less]; @@ -2186,7 +1917,7 @@ break outer; } } - if (a[great] == pivot1) { + if (a[great] == pivot1) { // a[great] < pivot2 a[k] = a[less]; /* * Even though a[great] equals to pivot1, the @@ -2212,7 +1943,7 @@ } else { // Pivots are equal /* - * Partition degenerates to the traditional 3-way + * Partitioning degenerates to the traditional 3-way * (or "Dutch National Flag") schema: * * left part center part right part @@ -2231,28 +1962,20 @@ * * Pointer k is the first index of ?-part. */ - for (int k = left; k <= great; k++) { + for (int k = less; k <= great; ++k) { if (a[k] == pivot1) { continue; } float ak = a[k]; - if (ak < pivot1) { // Move a[k] to left part a[k] = a[less]; a[less] = ak; less++; } else { // a[k] > pivot1 - Move a[k] to right part - /* - * We know that pivot1 == a[e3] == pivot2. Thus, we know - * that great will still be >= k when the following loop - * terminates, even though we don't test for it explicitly. - * In other words, a[e3] acts as a sentinel for great. - */ while (a[great] > pivot1) { - // assert great > k; great--; } - if (a[great] < pivot1) { + if (a[great] < pivot1) { // a[great] <= pivot1 a[k] = a[less]; a[less] = a[great]; less++; @@ -2272,73 +1995,40 @@ } } - // Sort left and right parts recursively + /* + * Sort left and right parts recursively. + * All elements from center part are equal + * and, therefore, already sorted. + */ sort(a, left, less - 1, leftmost); sort(a, great + 1, right, false); } } /** - * Sorts the specified array into ascending numerical order. - * - * <p>The {@code <} relation does not provide a total order on all double - * values: {@code -0.0d == 0.0d} is {@code true} and a {@code Double.NaN} - * value compares neither less than, greater than, nor equal to any value, - * even itself. This method uses the total order imposed by the method - * {@link Double#compareTo}: {@code -0.0d} is treated as less than value - * {@code 0.0d} and {@code Double.NaN} is considered greater than any - * other value and all {@code Double.NaN} values are considered equal. + * Sorts the specified array. * * @param a the array to be sorted */ public static void sort(double[] a) { - sortNegZeroAndNaN(a, 0, a.length - 1); + sort(a, 0, a.length - 1); } /** - * Sorts the specified range of the array into ascending order. The range - * to be sorted extends from the index {@code fromIndex}, inclusive, to - * the index {@code toIndex}, exclusive. If {@code fromIndex == toIndex}, - * the range to be sorted is empty (and the call is a no-op). - * - * <p>The {@code <} relation does not provide a total order on all double - * values: {@code -0.0d == 0.0d} is {@code true} and a {@code Double.NaN} - * value compares neither less than, greater than, nor equal to any value, - * even itself. This method uses the total order imposed by the method - * {@link Double#compareTo}: {@code -0.0d} is treated as less than value - * {@code 0.0d} and {@code Double.NaN} is considered greater than any - * other value and all {@code Double.NaN} values are considered equal. - * - * @param a the array to be sorted - * @param fromIndex the index of the first element, inclusive, to be sorted - * @param toIndex the index of the last element, exclusive, to be sorted - * @throws IllegalArgumentException if {@code fromIndex > toIndex} - * @throws ArrayIndexOutOfBoundsException - * if {@code fromIndex < 0} or {@code toIndex > a.length} - */ - public static void sort(double[] a, int fromIndex, int toIndex) { - rangeCheck(a.length, fromIndex, toIndex); - sortNegZeroAndNaN(a, fromIndex, toIndex - 1); - } - - /** - * Sorts the specified range of the array into ascending order. The - * sort is done in three phases to avoid expensive comparisons in the - * inner loop. The comparisons would be expensive due to anomalies - * associated with negative zero {@code -0.0d} and {@code Double.NaN}. + * Sorts the specified range of the array. * * @param a the array to be sorted * @param left the index of the first element, inclusive, to be sorted * @param right the index of the last element, inclusive, to be sorted */ - private static void sortNegZeroAndNaN(double[] a, int left, int right) { + public static void sort(double[] a, int left, int right) { /* * Phase 1: Move NaNs to the end of the array. */ while (left <= right && Double.isNaN(a[right])) { right--; } - for (int k = right - 1; k >= left; k--) { + for (int k = right; --k >= left; ) { double ak = a[k]; if (ak != ak) { // a[k] is NaN a[k] = a[right]; @@ -2358,7 +2048,7 @@ int hi = right; /* - * Search first zero, or first positive, or last negative element. + * Find the first zero, or first positive, or last negative element. */ while (left < hi) { int middle = (left + hi) >>> 1; @@ -2383,12 +2073,12 @@ * * Partitioning: * - * +---------------------------------------------------+ - * | < 0.0 | -0.0 | 0.0 | ? ( >= 0.0 ) | - * +---------------------------------------------------+ - * ^ ^ ^ - * | | | - * left p k + * +----------------------------------------------------+ + * | < 0.0 | -0.0 | 0.0 | ? ( >= 0.0 ) | + * +----------------------------------------------------+ + * ^ ^ ^ + * | | | + * left p k * * Invariants: * @@ -2399,53 +2089,36 @@ * * Pointer k is the first index of ?-part. */ - for (int k = left + 1, p = left; k <= right; k++) { + for (int k = left, p = left - 1; ++k <= right; ) { double ak = a[k]; if (ak != 0.0d) { break; } if (Double.doubleToRawLongBits(ak) < 0) { // ak is -0.0d a[k] = 0.0d; - a[p++] = -0.0d; + a[++p] = -0.0d; } } } /** - * Sorts the specified range of the array into ascending order by the - * Dual-Pivot Quicksort algorithm. This method differs from the public - * {@code sort} method in that the {@code right} index is inclusive, - * it does no range checking on {@code left} or {@code right}, and has - * boolean flag whether insertion sort with sentinel is used or not. + * Sorts the specified range of the array by Dual-Pivot Quicksort. * * @param a the array to be sorted * @param left the index of the first element, inclusive, to be sorted * @param right the index of the last element, inclusive, to be sorted - * @param leftmost indicates if the part is the most left in the range + * @param leftmost indicates if this part is the leftmost in the range */ private static void sort(double[] a, int left,int right,boolean leftmost) { int length = right - left + 1; - // Use insertion sort on tiny arrays + // Use insertion sort on small arrays if (length < INSERTION_SORT_THRESHOLD) { - if (!leftmost) { + if (leftmost) { /* - * Every element in adjoining part plays the role - * of sentinel, therefore this allows us to avoid - * the j >= left check on each iteration. - */ - for (int j, i = left + 1; i <= right; i++) { - double ai = a[i]; - for (j = i - 1; ai < a[j]; j--) { - // assert j >= left; - a[j + 1] = a[j]; - } - a[j + 1] = ai; - } - } else { - /* - * For case of leftmost part traditional (without a sentinel) - * insertion sort, optimized for server JVM, is used. + * Traditional (without sentinel) insertion sort, + * optimized for server VM, is used in case of + * the leftmost part. */ for (int i = left, j = i; i < right; j = ++i) { double ai = a[i + 1]; @@ -2457,12 +2130,54 @@ } a[j + 1] = ai; } + } else { + /* + * Skip the longest ascending sequence. + */ + do { + if (left++ >= right) { + return; + } + } while (a[left - 1] <= a[left]); + + /* + * Every element from adjoining part plays the role + * of sentinel, therefore this allows us to avoid the + * left range check on each iteration. Moreover, we use + * the best improved algorithm, so called pair insertion + * sort, which is faster than traditional implementation + * in the context of Dual-Pivot Quicksort. + */ + for (int k = left--; (left += 2) <= right; ) { + double a1, a2; k = left - 1; + + if (a[k] < a[left]) { + a2 = a[k]; a1 = a[left]; + } else { + a1 = a[k]; a2 = a[left]; + } + while (a1 < a[--k]) { + a[k + 2] = a[k]; + } + a[++k + 1] = a1; + + while (a2 < a[--k]) { + a[k + 1] = a[k]; + } + a[k + 1] = a2; + } + double last = a[right]; + + while (last < a[--right]) { + a[right + 1] = a[right]; + } + a[right + 1] = last; } return; } // Inexpensive approximation of length / 7 - int seventh = (length >>> 3) + (length >>> 6) + 1; + int seventh = (length >> 3) + (length >> 6) + 1; /* * Sort five evenly spaced elements around (and including) the @@ -2544,10 +2259,14 @@ * Pointer k is the first index of ?-part. */ outer: - for (int k = less; k <= great; k++) { + for (int k = less - 1; ++k <= great; ) { double ak = a[k]; if (ak < pivot1) { // Move a[k] to left part a[k] = a[less]; + /* + * Here and below we use "a[i] = b; i++;" instead + * of "a[i++] = b;" due to performance issue. + */ a[less] = ak; less++; } else if (ak > pivot2) { // Move a[k] to right part @@ -2556,13 +2275,17 @@ break outer; } } - if (a[great] < pivot1) { + if (a[great] < pivot1) { // a[great] <= pivot2 a[k] = a[less]; a[less] = a[great]; less++; } else { // pivot1 <= a[great] <= pivot2 a[k] = a[great]; } + /* + * Here and below we use "a[i] = b; i--;" instead + * of "a[i--] = b;" due to performance issue. + */ a[great] = ak; great--; } @@ -2577,7 +2300,7 @@ sort(a, great + 2, right, false); /* - * If center part is too large (comprises > 5/7 of the array), + * If center part is too large (comprises > 4/7 of the array), * swap internal pivot values to ends. */ if (less < e1 && e5 < great) { @@ -2611,7 +2334,7 @@ * Pointer k is the first index of ?-part. */ outer: - for (int k = less; k <= great; k++) { + for (int k = less - 1; ++k <= great; ) { double ak = a[k]; if (ak == pivot1) { // Move a[k] to left part a[k] = a[less]; @@ -2623,7 +2346,7 @@ break outer; } } - if (a[great] == pivot1) { + if (a[great] == pivot1) { // a[great] < pivot2 a[k] = a[less]; /* * Even though a[great] equals to pivot1, the @@ -2649,7 +2372,7 @@ } else { // Pivots are equal /* - * Partition degenerates to the traditional 3-way + * Partitioning degenerates to the traditional 3-way * (or "Dutch National Flag") schema: * * left part center part right part @@ -2668,28 +2391,20 @@ * * Pointer k is the first index of ?-part. */ - for (int k = left; k <= great; k++) { + for (int k = less; k <= great; ++k) { if (a[k] == pivot1) { continue; } double ak = a[k]; - if (ak < pivot1) { // Move a[k] to left part a[k] = a[less]; a[less] = ak; less++; } else { // a[k] > pivot1 - Move a[k] to right part - /* - * We know that pivot1 == a[e3] == pivot2. Thus, we know - * that great will still be >= k when the following loop - * terminates, even though we don't test for it explicitly. - * In other words, a[e3] acts as a sentinel for great. - */ while (a[great] > pivot1) { - // assert great > k; great--; } - if (a[great] < pivot1) { + if (a[great] < pivot1) { // a[great] <= pivot1 a[k] = a[less]; a[less] = a[great]; less++; @@ -2709,26 +2424,13 @@ } } - // Sort left and right parts recursively + /* + * Sort left and right parts recursively. + * All elements from center part are equal + * and, therefore, already sorted. + */ sort(a, left, less - 1, leftmost); sort(a, great + 1, right, false); } } - - /** - * Checks that {@code fromIndex} and {@code toIndex} are in the range, - * otherwise throws an appropriate exception. - */ - private static void rangeCheck(int length, int fromIndex, int toIndex) { - if (fromIndex > toIndex) { - throw new IllegalArgumentException( - "fromIndex: " + fromIndex + " > toIndex: " + toIndex); - } - if (fromIndex < 0) { - throw new ArrayIndexOutOfBoundsException(fromIndex); - } - if (toIndex > length) { - throw new ArrayIndexOutOfBoundsException(toIndex); - } - } }
--- a/src/share/classes/java/util/Properties.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/java/util/Properties.java Mon Oct 18 21:50:02 2010 -0700 @@ -705,7 +705,7 @@ * <code>Strings</code>. */ @Deprecated - public synchronized void save(OutputStream out, String comments) { + public void save(OutputStream out, String comments) { try { store(out, comments); } catch (IOException e) { @@ -890,7 +890,7 @@ * @see #loadFromXML(InputStream) * @since 1.5 */ - public synchronized void storeToXML(OutputStream os, String comment) + public void storeToXML(OutputStream os, String comment) throws IOException { if (os == null) @@ -929,8 +929,7 @@ * @see #loadFromXML(InputStream) * @since 1.5 */ - public synchronized void storeToXML(OutputStream os, String comment, - String encoding) + public void storeToXML(OutputStream os, String comment, String encoding) throws IOException { if (os == null)
--- a/src/share/classes/java/util/XMLUtils.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/java/util/XMLUtils.java Mon Oct 18 21:50:02 2010 -0700 @@ -141,14 +141,13 @@ comments.appendChild(doc.createTextNode(comment)); } - Set keys = props.keySet(); - Iterator i = keys.iterator(); - while(i.hasNext()) { - String key = (String)i.next(); - Element entry = (Element)properties.appendChild( - doc.createElement("entry")); - entry.setAttribute("key", key); - entry.appendChild(doc.createTextNode(props.getProperty(key))); + synchronized (props) { + for (String key : props.stringPropertyNames()) { + Element entry = (Element)properties.appendChild( + doc.createElement("entry")); + entry.setAttribute("key", key); + entry.appendChild(doc.createTextNode(props.getProperty(key))); + } } emitDocument(doc, os, encoding); }
--- a/src/share/classes/java/util/zip/ZipFile.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/java/util/zip/ZipFile.java Mon Oct 18 21:50:02 2010 -0700 @@ -85,8 +85,7 @@ static { // A system prpperty to disable mmap use to avoid vm crash when // in-use zip file is accidently overwritten by others. - String prop = AccessController.doPrivileged( - new GetPropertyAction("sun.zip.disableMemoryMapping")); + String prop = sun.misc.VM.getSavedProperty("sun.zip.disableMemoryMapping"); usemmap = (prop == null || !(prop.length() == 0 || prop.equalsIgnoreCase("true"))); }
--- a/src/share/classes/javax/sql/rowset/RowSetProvider.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/javax/sql/rowset/RowSetProvider.java Mon Oct 18 21:50:02 2010 -0700 @@ -28,6 +28,7 @@ import java.security.AccessController; import java.security.PrivilegedAction; import java.sql.SQLException; +import java.util.ServiceConfigurationError; import java.util.ServiceLoader; /** @@ -255,13 +256,19 @@ * Use the ServiceLoader mechanism to load the default RowSetFactory * @return default RowSetFactory Implementation */ - static private RowSetFactory loadViaServiceLoader() { + static private RowSetFactory loadViaServiceLoader() throws SQLException { RowSetFactory theFactory = null; - trace("***in loadViaServiceLoader()"); - for (RowSetFactory factory : ServiceLoader.load(javax.sql.rowset.RowSetFactory.class)) { - trace(" Loading done by the java.util.ServiceLoader :" + factory.getClass().getName()); - theFactory = factory; - break; + try { + trace("***in loadViaServiceLoader():"); + for (RowSetFactory factory : ServiceLoader.load(javax.sql.rowset.RowSetFactory.class)) { + trace(" Loading done by the java.util.ServiceLoader :" + factory.getClass().getName()); + theFactory = factory; + break; + } + } catch (ServiceConfigurationError e) { + throw new SQLException( + "RowSetFactory: Error locating RowSetFactory using Service " + + "Loader API: " + e, e); } return theFactory;
--- a/src/share/classes/javax/sql/rowset/spi/SyncFactory.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/javax/sql/rowset/spi/SyncFactory.java Mon Oct 18 21:50:02 2010 -0700 @@ -652,7 +652,10 @@ * required * @throws java.lang.SecurityException if a security manager exists and its * {@code checkPermission} method denies calling {@code setLogger} + * @throws java.util.logging.LoggingPermission if a security manager exists and its + * {@code checkPermission} method denies calling {@code setLevel} * @see SecurityManager#checkPermission + * @see LoggingPermission */ public static void setLogger(Logger logger, Level level) { // singleton
--- a/src/share/classes/javax/swing/UIDefaults.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/javax/swing/UIDefaults.java Mon Oct 18 21:50:02 2010 -0700 @@ -52,6 +52,7 @@ import java.security.PrivilegedAction; import sun.reflect.misc.MethodUtil; +import sun.reflect.misc.ReflectUtil; import sun.util.CoreResourceBundleControl; /** @@ -1078,6 +1079,9 @@ // In order to pick up the security policy in effect at the // time of creation we use a doPrivileged with the // AccessControlContext that was in place when this was created. + if (acc == null && System.getSecurityManager() != null) { + throw new SecurityException("null AccessControlContext"); + } return AccessController.doPrivileged(new PrivilegedAction<Object>() { public Object run() { try { @@ -1093,7 +1097,9 @@ cl = ClassLoader.getSystemClassLoader(); } } + ReflectUtil.checkPackageAccess(className); c = Class.forName(className, true, (ClassLoader)cl); + checkAccess(c.getModifiers()); if (methodName != null) { Class[] types = getClassArray(args); Method m = c.getMethod(methodName, types); @@ -1101,6 +1107,7 @@ } else { Class[] types = getClassArray(args); Constructor constructor = c.getConstructor(types); + checkAccess(constructor.getModifiers()); return constructor.newInstance(args); } } catch(Exception e) { @@ -1115,6 +1122,13 @@ }, acc); } + private void checkAccess(int modifiers) { + if(System.getSecurityManager() != null && + !Modifier.isPublic(modifiers)) { + throw new SecurityException("Resource is not accessible"); + } + } + /* * Coerce the array of class types provided into one which * looks the way the Reflection APIs expect. This is done
--- a/src/share/classes/javax/swing/text/html/HTMLEditorKit.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/javax/swing/text/html/HTMLEditorKit.java Mon Oct 18 21:50:02 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2010, 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 @@ -24,6 +24,8 @@ */ package javax.swing.text.html; +import sun.awt.AppContext; + import java.lang.reflect.Method; import java.awt.*; import java.awt.event.*; @@ -369,7 +371,11 @@ * if desired. */ public void setStyleSheet(StyleSheet s) { - defaultStyles = s; + if (s == null) { + AppContext.getAppContext().remove(DEFAULT_STYLES_KEY); + } else { + AppContext.getAppContext().put(DEFAULT_STYLES_KEY, s); + } } /** @@ -379,8 +385,12 @@ * instances. */ public StyleSheet getStyleSheet() { + AppContext appContext = AppContext.getAppContext(); + StyleSheet defaultStyles = (StyleSheet) appContext.get(DEFAULT_STYLES_KEY); + if (defaultStyles == null) { defaultStyles = new StyleSheet(); + appContext.put(DEFAULT_STYLES_KEY, defaultStyles); try { InputStream is = HTMLEditorKit.getResourceAsStream(DEFAULT_CSS); Reader r = new BufferedReader( @@ -620,7 +630,7 @@ private static final ViewFactory defaultFactory = new HTMLFactory(); MutableAttributeSet input; - private static StyleSheet defaultStyles = null; + private static final Object DEFAULT_STYLES_KEY = new Object(); private LinkController linkHandler = new LinkController(); private static Parser defaultParser = null; private Cursor defaultCursor = DefaultCursor;
--- a/src/share/classes/javax/swing/text/html/parser/DTD.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/javax/swing/text/html/parser/DTD.java Mon Oct 18 21:50:02 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2010, 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 @@ -25,6 +25,8 @@ package javax.swing.text.html.parser; +import sun.awt.AppContext; + import java.io.PrintStream; import java.io.File; import java.io.FileInputStream; @@ -314,13 +316,14 @@ } /** - * The hashtable of DTDs. + * The hashtable key of DTDs in AppContext. */ - static Hashtable<String, DTD> dtdHash = new Hashtable<String, DTD>(); + private static final Object DTD_HASH_KEY = new Object(); - public static void putDTDHash(String name, DTD dtd) { - dtdHash.put(name, dtd); - } + public static void putDTDHash(String name, DTD dtd) { + getDtdHash().put(name, dtd); + } + /** * Returns a DTD with the specified <code>name</code>. If * a DTD with that name doesn't exist, one is created @@ -332,13 +335,27 @@ */ public static DTD getDTD(String name) throws IOException { name = name.toLowerCase(); - DTD dtd = dtdHash.get(name); + DTD dtd = getDtdHash().get(name); if (dtd == null) dtd = new DTD(name); return dtd; } + private static Hashtable<String, DTD> getDtdHash() { + AppContext appContext = AppContext.getAppContext(); + + Hashtable<String, DTD> result = (Hashtable<String, DTD>) appContext.get(DTD_HASH_KEY); + + if (result == null) { + result = new Hashtable<String, DTD>(); + + appContext.put(DTD_HASH_KEY, result); + } + + return result; + } + /** * Recreates a DTD from an archived format. * @param in the <code>DataInputStream</code> to read from
--- a/src/share/classes/javax/swing/text/html/parser/ParserDelegator.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/javax/swing/text/html/parser/ParserDelegator.java Mon Oct 18 21:50:02 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2002, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2010, 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 @@ -25,6 +25,8 @@ package javax.swing.text.html.parser; +import sun.awt.AppContext; + import javax.swing.text.html.HTMLEditorKit; import java.io.BufferedInputStream; import java.io.IOException; @@ -33,7 +35,6 @@ import java.io.ObjectInputStream; import java.io.Reader; import java.io.Serializable; -import java.lang.reflect.Method; /** * Responsible for starting up a new DocumentParser @@ -45,9 +46,13 @@ public class ParserDelegator extends HTMLEditorKit.Parser implements Serializable { - private static DTD dtd = null; + private static final Object DTD_KEY = new Object(); protected static synchronized void setDefaultDTD() { + AppContext appContext = AppContext.getAppContext(); + + DTD dtd = (DTD) appContext.get(DTD_KEY); + if (dtd == null) { DTD _dtd = null; // (PENDING) Hate having to hard code! @@ -59,6 +64,8 @@ System.out.println("Throw an exception: could not get default dtd: " + nm); } dtd = createDTD(_dtd, nm); + + appContext.put(DTD_KEY, dtd); } } @@ -81,13 +88,11 @@ public ParserDelegator() { - if (dtd == null) { - setDefaultDTD(); - } + setDefaultDTD(); } public void parse(Reader r, HTMLEditorKit.ParserCallback cb, boolean ignoreCharSet) throws IOException { - new DocumentParser(dtd).parse(r, cb, ignoreCharSet); + new DocumentParser((DTD) AppContext.getAppContext().get(DTD_KEY)).parse(r, cb, ignoreCharSet); } /** @@ -113,8 +118,6 @@ private void readObject(ObjectInputStream s) throws ClassNotFoundException, IOException { s.defaultReadObject(); - if (dtd == null) { - setDefaultDTD(); - } + setDefaultDTD(); } }
--- a/src/share/classes/sun/awt/image/BufImgSurfaceData.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/sun/awt/image/BufImgSurfaceData.java Mon Oct 18 21:50:02 2010 -0700 @@ -49,7 +49,7 @@ private BufferedImageGraphicsConfig graphicsConfig; RenderLoops solidloops; - private static native void initIDs(Class ICM); + private static native void initIDs(Class ICM, Class ICMColorData); private static final int DCM_RGBX_RED_MASK = 0xff000000; private static final int DCM_RGBX_GREEN_MASK = 0x00ff0000; @@ -67,7 +67,7 @@ private static final int DCM_ARGBBM_BLUE_MASK = 0x000000ff; static { - initIDs(IndexColorModel.class); + initIDs(IndexColorModel.class, ICMColorData.class); } public static SurfaceData createData(BufferedImage bufImg) { @@ -403,7 +403,7 @@ // their pixels are immediately retrievable anyway. } - public static native void freeNativeICMData(IndexColorModel icm); + private static native void freeNativeICMData(long pData); /** * Returns destination Image associated with this SurfaceData. @@ -411,4 +411,19 @@ public Object getDestination() { return bufImg; } + + public static final class ICMColorData { + private long pData = 0L; + + private ICMColorData(long pData) { + this.pData = pData; + } + + public void finalize() { + if (pData != 0L) { + BufImgSurfaceData.freeNativeICMData(pData); + pData = 0L; + } + } + } }
--- a/src/share/classes/sun/jkernel/DownloadManager.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/sun/jkernel/DownloadManager.java Mon Oct 18 21:50:02 2010 -0700 @@ -25,13 +25,18 @@ package sun.jkernel; import java.io.*; +import java.net.URLStreamHandlerFactory; +import java.net.URL; +import java.net.MalformedURLException; import java.security.*; import java.util.*; import java.util.concurrent.*; import java.util.jar.*; import java.util.zip.*; +import sun.misc.BootClassLoaderHook; import sun.misc.Launcher; -import sun.misc.BootClassLoaderHook; +import sun.misc.URLClassPath; +import sun.net.www.ParseUtil; /** * Handles the downloading of additional JRE components. The bootstrap class @@ -658,31 +663,61 @@ return getAppDataLocalLow() + getKernelJREDir(); } - /** - * Returns an array of JAR files which have been added to the boot strap - * class path since the JVM was first booted. - */ - public static synchronized File[] getAdditionalBootStrapPaths() { - return additionalBootStrapPaths != null ? additionalBootStrapPaths : - new File[0]; - } - - + // To be revisited: + // How DownloadManager maintains its bootstrap class path. + // sun.misc.Launcher.getBootstrapClassPath() returns + // DownloadManager.getBootstrapClassPath() instead. + // + // So should no longer need to lock the Launcher.class. + // In addition, additionalBootStrapPaths is not really needed + // if it obtains the initial bootclasspath during DownloadManager's + // initialization. private static void addEntryToBootClassPath(File path) { // Must acquire these locks in this order synchronized(Launcher.class) { - synchronized(DownloadManager.class) { + synchronized(DownloadManager.class) { File[] newBootStrapPaths = new File[ additionalBootStrapPaths.length + 1]; System.arraycopy(additionalBootStrapPaths, 0, newBootStrapPaths, 0, additionalBootStrapPaths.length); newBootStrapPaths[newBootStrapPaths.length - 1] = path; additionalBootStrapPaths = newBootStrapPaths; - Launcher.flushBootstrapClassPath(); + if (bootstrapClassPath != null) + bootstrapClassPath.addURL(getFileURL(path)); } } } + /** + * Returns the kernel's bootstrap class path which includes the additional + * JARs downloaded + */ + private static URLClassPath bootstrapClassPath = null; + private synchronized static + URLClassPath getBootClassPath(URLClassPath bcp, + URLStreamHandlerFactory factory) + { + if (bootstrapClassPath == null) { + bootstrapClassPath = new URLClassPath(bcp.getURLs(), factory); + for (File path : additionalBootStrapPaths) { + bootstrapClassPath.addURL(getFileURL(path)); + } + } + return bootstrapClassPath; + } + + private static URL getFileURL(File file) { + try { + file = file.getCanonicalFile(); + } catch (IOException e) {} + + try { + return ParseUtil.fileToEncodedURL(file); + } catch (MalformedURLException e) { + // Should never happen since we specify the protocol... + throw new InternalError(); + } + } /** * Scan through java.ext.dirs to see if the lib/ext directory is included. @@ -1680,8 +1715,10 @@ } } - public File[] getAdditionalBootstrapPaths() { - return DownloadManager.getAdditionalBootStrapPaths(); + public URLClassPath getBootstrapClassPath(URLClassPath bcp, + URLStreamHandlerFactory factory) + { + return DownloadManager.getBootClassPath(bcp, factory); } public boolean isCurrentThreadPrefetching() {
--- a/src/share/classes/sun/launcher/resources/launcher.properties Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/sun/launcher/resources/launcher.properties Mon Oct 18 21:50:02 2010 -0700 @@ -49,7 +49,7 @@ \ -version:<value>\n\ \ require the specified version to run\n\ \ -showversion print product version and continue\n\ -\ -jre-restrict-search | -jre-no-restrict-search\n\ +\ -jre-restrict-search | -no-jre-restrict-search\n\ \ include/exclude user private JREs in the version search\n\ \ -? -help print this help message\n\ \ -X print help on non-standard options\n\
--- a/src/share/classes/sun/launcher/resources/launcher_de.properties Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/sun/launcher/resources/launcher_de.properties Mon Oct 18 21:50:02 2010 -0700 @@ -34,7 +34,7 @@ java.launcher.ergo.message2 =\ da Sie auf einem Server-Class-Computer ausf\u00fchren.\n # Translators please note do not translate the options themselves -java.launcher.opt.footer =\ -cp <Pfad zur Klassensuche von Verzeichnissen und Zip-/Jar-Dateien>\n\ -classpath <Pfad zur Klassensuche von Verzeichnissen und Zip-/Jar-Dateien >\n\ A {0} getrennte Liste von Verzeichnissen, JAR-Archiven,\n\ und ZIP-Archiven f\u00fcr die Suche nach Klassendateien .\n\ -D<Name>=<Wert>\n\ Systemeigenschaft festlegen\n\ -verbose[:class|gc|jni]\n\ ausf\u00fchrliche Ausgabe aktivieren\n\ -version Produktversion drucken und beenden\n\ -version:<Wert>\n\ angegebene Version zum Ausf\u00fchren erforderlich \n\ -showversion Produktversion drucken und fortfahren\n\ -jre-restrict-search | -jre-no-restrict-search\n\ private JREs der Benutzer in Versionssuche ein-/ausschlie\u00dfen\n\ -? -help diese Hilfemeldung drucken\n\ -X Hilfe zu nicht standardm\u00e4\u00dfigen Optionen drucken\n\ -ea[:<Paketname>...|:<Klassenname>]\n\ -enableassertions[:<Paketname>...|:<Klassenname>]\n\ Assertions mit spezifizierter Granularit\u00e4t aktivieren\n\ -da[:<Paketname>...|:<Klassenname>]\n\ -disableassertions[:<Paketname>...|:<Klassenname>]\n\ Assertions mit spezifizierter Granularit\u00e4t deaktivieren\n\ -esa | --enablesystemassertions\n\ System-Assertions aktivieren\n\ -dsa | --disablesystemassertions\n\ System-Assertions deaktivieren\n\ -agentlib:<Name der Bibliothek>[=<Optionen>]\n\ systemeigene Agent-Bibliothek laden <Name der Bibliothek>, z.B. -agentlib:hprof\n\ siehe auch, -agentlib:jdwp=help und -agentlib:hprof=help\n\ -agentpath:<Pfadname>[=<Optionen>]\n\ systemeigene Agent-Bibliothek \u00fcber vollst\u00e4ndigen Pfadnamen laden\n\ -javaagent:<Jar-Pfad>[=<Optionen>]\n\ Java Programmierungs-Sprachagenten laden, siehe java.lang.instrument\n\ -splash:<Bildpfad>\n\ Eingangsbildschirm mit spezifiziertem Bild anzeigen\nWeitere Informationen finden Sie unter http://java.sun.com/javase/reference. +java.launcher.opt.footer =\ -cp <Pfad zur Klassensuche von Verzeichnissen und Zip-/Jar-Dateien>\n\ -classpath <Pfad zur Klassensuche von Verzeichnissen und Zip-/Jar-Dateien >\n\ A {0} getrennte Liste von Verzeichnissen, JAR-Archiven,\n\ und ZIP-Archiven f\u00fcr die Suche nach Klassendateien .\n\ -D<Name>=<Wert>\n\ Systemeigenschaft festlegen\n\ -verbose[:class|gc|jni]\n\ ausf\u00fchrliche Ausgabe aktivieren\n\ -version Produktversion drucken und beenden\n\ -version:<Wert>\n\ angegebene Version zum Ausf\u00fchren erforderlich \n\ -showversion Produktversion drucken und fortfahren\n\ -jre-restrict-search | -no-jre-restrict-search\n\ private JREs der Benutzer in Versionssuche ein-/ausschlie\u00dfen\n\ -? -help diese Hilfemeldung drucken\n\ -X Hilfe zu nicht standardm\u00e4\u00dfigen Optionen drucken\n\ -ea[:<Paketname>...|:<Klassenname>]\n\ -enableassertions[:<Paketname>...|:<Klassenname>]\n\ Assertions mit spezifizierter Granularit\u00e4t aktivieren\n\ -da[:<Paketname>...|:<Klassenname>]\n\ -disableassertions[:<Paketname>...|:<Klassenname>]\n\ Assertions mit spezifizierter Granularit\u00e4t deaktivieren\n\ -esa | --enablesystemassertions\n\ System-Assertions aktivieren\n\ -dsa | --disablesystemassertions\n\ System-Assertions deaktivieren\n\ -agentlib:<Name der Bibliothek>[=<Optionen>]\n\ systemeigene Agent-Bibliothek laden <Name der Bibliothek>, z.B. -agentlib:hprof\n\ siehe auch, -agentlib:jdwp=help und -agentlib:hprof=help\n\ -agentpath:<Pfadname>[=<Optionen>]\n\ systemeigene Agent-Bibliothek \u00fcber vollst\u00e4ndigen Pfadnamen laden\n\ -javaagent:<Jar-Pfad>[=<Optionen>]\n\ Java Programmierungs-Sprachagenten laden, siehe java.lang.instrument\n\ -splash:<Bildpfad>\n\ Eingangsbildschirm mit spezifiziertem Bild anzeigen\nWeitere Informationen finden Sie unter http://java.sun.com/javase/reference. # Translators please note do not translate the options themselves java.launcher.X.usage=\ -Xmixed gemischte Ausf\u00fchrung des Modus (Standard)\n\ -Xint nur interpretierte Ausf\u00fchrung des Modus\n\ -Xbootclasspath:<Verzeichnisse und Zip-/Jar-Dateien, die durch {0} getrennt sind>\n\ Suchpfad f\u00fcr Bootstrap-Klassen und Ressourcen einrichten\n\ -Xbootclasspath/a:<Verzeichnisse und Zip-/Jar-Dateien, die durch {0} getrennt sind>\n\ an das Ende des Bootstrap-Klassenpfads anh\u00e4ngen\n\ -Xbootclasspath/p:<Verzeichnisse und Zip-/Jar-Dateien, die durch {0} getrennt sind>\n\ an den Beginn des Bootstrap-Klassenpfads anh\u00e4ngen\n\ -Xnoclassgc Klassen-Speicherbereinigung deaktivieren\n\ -Xincgc inkrementelle Speicherbereinigung aktivieren\n\ -Xloggc:<Datei> GC-Status f\u00fcr eine Datei mit Zeitstempeln einrichten\n\ -Xbatch Hintergrund-Kompilation deaktivieren\n\ -Xms<Gr\u00f6\u00dfe> anf\u00e4ngliche Java Heap-Gr\u00f6\u00dfe einstellen\n\ -Xmx<Gr\u00f6\u00dfe> maximale Java Heap-Gr\u00f6\u00dfe einstellen\n\ -Xss<Gr\u00f6\u00dfe> Gr\u00f6\u00dfe des Java Thread-Stack einstellen\n\ -Xprof CPU-Profildaten ausgeben\n\ -Xfuture genaueste Pr\u00fcfungen aktivieren und zuk\u00fcnftige Standards absehen\n\ -Xrs Verwendung von OS-Signalen durch Java/VM reduzieren (siehe Dokumentation)\n\ -Xcheck:jni zus\u00e4tzliche Pr\u00fcfungen f\u00fcr JNI- Funktionen ausf\u00fchren\n\ -Xshare:off Nicht versuchen, freigegebene Klassendaten zu verwenden\n\ -Xshare:auto Freigegebene Klassendaten verwenden, wenn m\u00f6glich (Standard)\n\ -Xshare:on Nutzung freigegebener Daten ist erforderlich, ansonsten schl\u00e4gt der Vorgang fehl.\n\nDie -X-Optionen sind kein Standard und k\u00f6nnen \u00c4nderungen unterliegen.\n
--- a/src/share/classes/sun/launcher/resources/launcher_es.properties Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/sun/launcher/resources/launcher_es.properties Mon Oct 18 21:50:02 2010 -0700 @@ -34,7 +34,7 @@ java.launcher.ergo.message2 =\ porque est\u00e1 trabajando en una m\u00e1quina de clase servidor.\n # Translators please note do not translate the options themselves -java.launcher.opt.footer =\ -cp <class search path of directories and zip/jar files>\n\ -classpath <class search path of directories and zip/jar files>\n\ Una {0} lista de directorios, archivos JAR,\n\ y archivos ZIP en los que buscar los archivos de clase.\n\ -D<name>=<value>\n\ establecer una propiedad de sistema\n\ -verbose[:class|gc|jni]\n\ permitir la salida detallada\n\ -version imprimir versi\u00f3n del producto y salir\n\ -version:<value>\n\ solicitar la versi\u00f3n especificada para ejecutar\n\ -showversion imprimir versi\u00f3n del producto y continuar\n\ -jre-restrict-search | -jre-no-restrict-search\n\ incluir/excluir JRE privados del usuario en la b\u00fasqueda de la versi\u00f3n\n\ -? -help imprimir este mensaje de ayuda\n\ -X imprimir ayuda en las opciones no est\u00e1ndar\n\ -ea[:<packagename>...|:<classname>]\n\ -enableassertions[:<packagename>...|:<classname>]\n\ permitir afirmaciones con granularidad especificada\n\ -da[:<packagename>...|:<classname>]\n\ -disableassertions[:<packagename>...|:<classname>]\n\ desactivar afirmaciones con granularidad especificada\n\ -esa | -enablesystemassertions\n\ permitir afirmaciones del sistema\n\ -dsa | -disablesystemassertions\n\ desactivar afirmaciones del sistema\n\ -agentlib:<libname>[=<options>]\n\ cargar biblioteca de agente nativo<libname>, por ejemplo -agentlib:hprof\n\ consulte tambi\u00e9n, -agentlib:jdwp=help y -agentlib:hprof=help\n\ -agentpath:<pathname>[=<options>]\n\ cargar biblioteca de agente nativo por ruta completa\n\ -javaagent:<jarpath>[=<options>]\n\ cargar agente del lenguaje de programaci\u00f3n Java, consulte java.lang.instrument\n\ -splash:<imagepath>\n\ mostrar pantalla de bienvenida con imagen especificada\nConsulte http://java.sun.com/javase/reference para m\u00e1s informaci\u00f3n. +java.launcher.opt.footer =\ -cp <class search path of directories and zip/jar files>\n\ -classpath <class search path of directories and zip/jar files>\n\ Una {0} lista de directorios, archivos JAR,\n\ y archivos ZIP en los que buscar los archivos de clase.\n\ -D<name>=<value>\n\ establecer una propiedad de sistema\n\ -verbose[:class|gc|jni]\n\ permitir la salida detallada\n\ -version imprimir versi\u00f3n del producto y salir\n\ -version:<value>\n\ solicitar la versi\u00f3n especificada para ejecutar\n\ -showversion imprimir versi\u00f3n del producto y continuar\n\ -jre-restrict-search | -no-jre-restrict-search\n\ incluir/excluir JRE privados del usuario en la b\u00fasqueda de la versi\u00f3n\n\ -? -help imprimir este mensaje de ayuda\n\ -X imprimir ayuda en las opciones no est\u00e1ndar\n\ -ea[:<packagename>...|:<classname>]\n\ -enableassertions[:<packagename>...|:<classname>]\n\ permitir afirmaciones con granularidad especificada\n\ -da[:<packagename>...|:<classname>]\n\ -disableassertions[:<packagename>...|:<classname>]\n\ desactivar afirmaciones con granularidad especificada\n\ -esa | -enablesystemassertions\n\ permitir afirmaciones del sistema\n\ -dsa | -disablesystemassertions\n\ desactivar afirmaciones del sistema\n\ -agentlib:<libname>[=<options>]\n\ cargar biblioteca de agente nativo<libname>, por ejemplo -agentlib:hprof\n\ consulte tambi\u00e9n, -agentlib:jdwp=help y -agentlib:hprof=help\n\ -agentpath:<pathname>[=<options>]\n\ cargar biblioteca de agente nativo por ruta completa\n\ -javaagent:<jarpath>[=<options>]\n\ cargar agente del lenguaje de programaci\u00f3n Java, consulte java.lang.instrument\n\ -splash:<imagepath>\n\ mostrar pantalla de bienvenida con imagen especificada\nConsulte http://java.sun.com/javase/reference para m\u00e1s informaci\u00f3n. # Translators please note do not translate the options themselves java.launcher.X.usage=\ -Xmixed modo mixto de ejecuci\u00f3n (predeterminado)\n\ -Xint s\u00f3lo modo de ejecuci\u00f3n interpretado\n\ -Xbootclasspath:<directories and zip/jar files separated by {0}>\n\ definir ruta de b\u00fasqueda para clases y recursos de la rutina de carga\n\ -Xbootclasspath/a:<directories and zip/jar files separated by {0}>\n\ a\u00f1adir al final de la ruta de clase de la rutina de carga\n\ -Xbootclasspath/p:<directories and zip/jar files separated by {0}>\n\ a\u00f1adir al principio de la ruta de clase de la rutina de carga\n\ -Xnoclassgc desactivar recolecci\u00f3n de residuos de clase\n\ -Xincgc permitir recolecci\u00f3n de residuos incremental\n\ -Xloggc:<file> registrar estado de GC en un archivo con marcas de tiempo\n\ -Xbatch desactivar recopilaci\u00f3n de fondos\n\ -Xms<size> definir tama\u00f1o del mont\u00f3n de Java inicial\n\ -Xmx<size> definir tama\u00f1o m\u00e1ximo del mont\u00f3n de Java\n\ -Xss<size> definir tama\u00f1o de la pila del subproceso de java\n\ -Xprof salida de datos del perfil de la cpu\n\ -Xfuture permitir comprobaciones m\u00e1s estrictas para los procesos predeterminados futuros\n\ -Xrs reducir el uso de se\u00f1ales del SO por parte de Java o la m\u00e1quina virtual (consulte la documentaci\u00f3n)\n\ -Xcheck:jni realizar comprobaciones adicionales para las funciones de JNI\n\ -Xshare:off no intentar utilizar datos de clase compartidos\n\ -Xshare:auto utilizar datos de clase compartidos siempre que sea posible (predeterminado)\n\ -Xshare:on solicitar el uso obligatorio de datos de clase compartidos.\n\nLas opciones "-X" no son est\u00e1ndar y pueden sufrir modificaciones sin previo aviso.\n
--- a/src/share/classes/sun/launcher/resources/launcher_fr.properties Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/sun/launcher/resources/launcher_fr.properties Mon Oct 18 21:50:02 2010 -0700 @@ -34,7 +34,7 @@ java.launcher.ergo.message2 =\ car vous utilisez une machine de type serveur.\n # Translators please note do not translate the options themselves -java.launcher.opt.footer =\ -cp <chemin de recherche de classe des r\u00e9pertoires et fichiers zip/jar>\n\ -classpath <chemin de recherche de classe des r\u00e9pertoires et fichiers zip/jar>\n\ Une liste s\u00e9par\u00e9e {0} de r\u00e9pertoires, archives JAR\n\ et archives ZIP dans laquelle rechercher des fichiers de classe.\n\ -D<nom>=<valeur>\n\ d\u00e9finir une propri\u00e9t\u00e9 syst\u00e8me\n\ -verbose[:class|gc|jni]\n\ activer une sortie d\u00e9taill\u00e9ee\n\ -version imprimer la version du produit et quitter\n\ -version:<valeur>\n\ utiliser la version sp\u00e9cifi\u00e9e pour l''ex\u00e9cution\n\ -showversion imprimer la version du produit et continuer\n\ -jre-restrict-search | -jre-no-restrict-search\n\ inclure/exclure les JRE priv\u00e9s d''utilisateur dans la recherche de version\n\ -? -help imprimer ce message d''aide\n\ -X imprimer l''aide relative aux options non standard\n\ -ea[:<nom du package>...|:<nom de la classe>]\n\ -enableassertions[:<nom du package>...|:<nom de la classe>]\n\ activer les assertions avec la granularit\u00e9 sp\u00e9cifi\u00e9e\n\ -da[:<nom du package>...|:<nom de la classe>]\n\ -disableassertions[:<nom du package>...|:<nom de la classe>]\n\ d\u00e9sactiver les assertions avec la granularit\u00e9 sp\u00e9cifi\u00e9e\n\ -esa | -enablesystemassertions\n\ activer les assertions syst\u00e8me\n\ -dsa | -disablesystemassertions\n\ d\u00e9sactiver les assertions syst\u00e8me\n\ -agentlib:<nom de la biblioth\u00e8que>[=<options>]\n\ charger la biblioth\u00e8que d''agents natifs<nom de la biblioth\u00e8que>, par exemple -agentlib:hprof\n\ voir \u00e9galement, -agentlib:jdwp=help et -agentlib:hprof=help\n\ -agentpath:<nom du chemin>[=<options>]\n\ charger la biblioth\u00e8que d''agents natifs en indiquant le chemin complet\n\ -javaagent:<chemin jar>[=<options>]\n\ charger l''agent de langage de programmation Java, voir java.lang.instrument\n\ -splash:<chemin de l''image>\n\ afficher l''\u00e9cran de bienvenue avec l''image sp\u00e9cifi\u00e9e\nPour plus de d\u00e9tails, reportez-vous \u00e0 la page http://java.sun.com/javase/reference. +java.launcher.opt.footer =\ -cp <chemin de recherche de classe des r\u00e9pertoires et fichiers zip/jar>\n\ -classpath <chemin de recherche de classe des r\u00e9pertoires et fichiers zip/jar>\n\ Une liste s\u00e9par\u00e9e {0} de r\u00e9pertoires, archives JAR\n\ et archives ZIP dans laquelle rechercher des fichiers de classe.\n\ -D<nom>=<valeur>\n\ d\u00e9finir une propri\u00e9t\u00e9 syst\u00e8me\n\ -verbose[:class|gc|jni]\n\ activer une sortie d\u00e9taill\u00e9ee\n\ -version imprimer la version du produit et quitter\n\ -version:<valeur>\n\ utiliser la version sp\u00e9cifi\u00e9e pour l''ex\u00e9cution\n\ -showversion imprimer la version du produit et continuer\n\ -jre-restrict-search | -no-jre-restrict-search\n\ inclure/exclure les JRE priv\u00e9s d''utilisateur dans la recherche de version\n\ -? -help imprimer ce message d''aide\n\ -X imprimer l''aide relative aux options non standard\n\ -ea[:<nom du package>...|:<nom de la classe>]\n\ -enableassertions[:<nom du package>...|:<nom de la classe>]\n\ activer les assertions avec la granularit\u00e9 sp\u00e9cifi\u00e9e\n\ -da[:<nom du package>...|:<nom de la classe>]\n\ -disableassertions[:<nom du package>...|:<nom de la classe>]\n\ d\u00e9sactiver les assertions avec la granularit\u00e9 sp\u00e9cifi\u00e9e\n\ -esa | -enablesystemassertions\n\ activer les assertions syst\u00e8me\n\ -dsa | -disablesystemassertions\n\ d\u00e9sactiver les assertions syst\u00e8me\n\ -agentlib:<nom de la biblioth\u00e8que>[=<options>]\n\ charger la biblioth\u00e8que d''agents natifs<nom de la biblioth\u00e8que>, par exemple -agentlib:hprof\n\ voir \u00e9galement, -agentlib:jdwp=help et -agentlib:hprof=help\n\ -agentpath:<nom du chemin>[=<options>]\n\ charger la biblioth\u00e8que d''agents natifs en indiquant le chemin complet\n\ -javaagent:<chemin jar>[=<options>]\n\ charger l''agent de langage de programmation Java, voir java.lang.instrument\n\ -splash:<chemin de l''image>\n\ afficher l''\u00e9cran de bienvenue avec l''image sp\u00e9cifi\u00e9e\nPour plus de d\u00e9tails, reportez-vous \u00e0 la page http://java.sun.com/javase/reference. # Translators please note do not translate the options themselves java.launcher.X.usage=\ -Xmixed ex\u00e9cution du mode compil\u00e9 (par d\u00e9faut)\n\ -Xint ex\u00e9cution du mode interpr\u00e9t\u00e9 uniquement\n\ -Xbootclasspath:<r\u00e9pertoires et fichiers zip/jar s\u00e9par\u00e9s par {0}>\n\ d\u00e9finir le chemin de recherche pour les classes et ressources bootstrap\n\ -Xbootclasspath/a:<r\u00e9pertoires et fichiers zip/jar s\u00e9par\u00e9s par {0}>\n\ ajouter \u00e0 la fin du chemin de la classe bootstrap\n\ -Xbootclasspath/p:<r\u00e9pertoires et fichiers zip/jar s\u00e9par\u00e9s par {0}>\n\ ajouter au d\u00e9but du chemin de la classe bootstrap\n\ -Xnoclassgc d\u00e9sactiver la collection d''informations parasites sur la classe\n\ -Xincgc activer la collection incr\u00e9mentielle d''informations parasites\n\ -Xloggc:<fichier> enregistrer le statut GC dans un fichier horodat\u00e9\n\ -Xbatch d\u00e9sactiver la compilation d''arri\u00e8re-plans\n\ -Xms<taille> d\u00e9finir la taille initiale des tas Java\n\ -Xmx<taille> d\u00e9finir la taille maximale des tas Java\n\ -Xss<taille> d\u00e9finir la taille des piles de fil Java\n\ -Xprof \u00e9mettre des donn\u00e9es de profilage d''UC\n\ -Xfuture activer des contr\u00f4les plus stricts, en anticipant les erreurs futures\n\ -Xrs r\u00e9duire l''utilisation des signaux d''OS par Java/la machine virtuelle (reportez-vous \u00e0 la documentation)\n\ -Xcheck:jni effectuer des contr\u00f4les suppl\u00e9mentaires pour les fonctions JNI\n\ -Xshare:off ne pas tenter d''utiliser les donn\u00e9es de classe partag\u00e9es\n\ -Xshare:auto utiliser les donn\u00e9es de classe partag\u00e9es si possible (par d\u00e9faut)\n\ -Xshare:on forcer l''utilisation de donn\u00e9es de classe partag\u00e9es, sinon \u00e9chec.\n\nLes options\u00a0X ne sont pas standard et sont sujettes \u00e0 modification sans pr\u00e9avis.\n
--- a/src/share/classes/sun/launcher/resources/launcher_it.properties Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/sun/launcher/resources/launcher_it.properties Mon Oct 18 21:50:02 2010 -0700 @@ -34,7 +34,7 @@ java.launcher.ergo.message2 =\ perch\u00e9 l'esecuzione avviene su una macchina di classe server.\n # Translators please note do not translate the options themselves -java.launcher.opt.footer =\ -cp <percorso di ricerca classe di directory e file zip/jar>\n\ -classpath <percorso di ricerca classe di directory e file zip/jar>\n\ Elenco separato da {0} di directory, archivi JAR\n\ e archivi ZIP in cui cercare i file di classe.\n\ -D<nome>=<valore>\n\ imposta una propriet\u00e0 di sistema\n\ -verbose[:class|gc|jni]\n\ attiva l''output dettagliato\n\ -version stampa la versione del prodotto ed esce\n\ -version:<valore>\n\ richiede la versione specificata per l''esecuzione\n\ -showversion stampa la versione del prodotto e procede\n\ -jre-restrict-search | -jre-no-restrict-search\n\ consente di includere/escludere JRE privati dell''utente nella ricerca della versione\n\ -? -help stampa il presente messaggio della Guida\n\ -X stampa la Guida delle opzioni non standard\n\ -ea[:<nomepacchetto>...|:<nomeclasse>]\n\ -enableassertions[:<nomepacchetto>...|:<nomeclasse>]\n\ attiva le asserzioni con la granularit\u00e0 specificata\n\ -da[:<nomepacchetto>...|:<nomeclasse>]\n\ -disableassertions[:<nomepacchetto>...|:<nomeclasse>]\n\ disattiva le asserzioni con la granularit\u00e0 specificata\n\ -esa | -enablesystemassertions\n\ attiva le asserzioni di sistema\n\ -dsa | -disablesystemassertions\n\ disattiva le asserzioni di sistema\n\ -agentlib:<nomelibreria>[=<opzioni>]\n\ carica la libreria agente nativa <nomelibreria>, ad es. -agentlib:hprof\n\ vedere anche, -agentlib:jdwp=help e -agentlib:hprof=help\n\ -agentpath:<percorso>[=<opzioni>]\n\ carica la libreria agente nativa in base al percorso completo\n\ -javaagent:<percorsojar>[=<opzioni>]\n\ carica l''agente del linguaggio di programmazione Java, vedere java.lang.instrument\n\ -splash:<percorsoimmagine>\n\ mostra la schermata iniziale con l''immagine specificata\nPer ulteriori informazioni, visitare http://java.sun.com/javase/reference. +java.launcher.opt.footer =\ -cp <percorso di ricerca classe di directory e file zip/jar>\n\ -classpath <percorso di ricerca classe di directory e file zip/jar>\n\ Elenco separato da {0} di directory, archivi JAR\n\ e archivi ZIP in cui cercare i file di classe.\n\ -D<nome>=<valore>\n\ imposta una propriet\u00e0 di sistema\n\ -verbose[:class|gc|jni]\n\ attiva l''output dettagliato\n\ -version stampa la versione del prodotto ed esce\n\ -version:<valore>\n\ richiede la versione specificata per l''esecuzione\n\ -showversion stampa la versione del prodotto e procede\n\ -jre-restrict-search | -no-jre-restrict-search\n\ consente di includere/escludere JRE privati dell''utente nella ricerca della versione\n\ -? -help stampa il presente messaggio della Guida\n\ -X stampa la Guida delle opzioni non standard\n\ -ea[:<nomepacchetto>...|:<nomeclasse>]\n\ -enableassertions[:<nomepacchetto>...|:<nomeclasse>]\n\ attiva le asserzioni con la granularit\u00e0 specificata\n\ -da[:<nomepacchetto>...|:<nomeclasse>]\n\ -disableassertions[:<nomepacchetto>...|:<nomeclasse>]\n\ disattiva le asserzioni con la granularit\u00e0 specificata\n\ -esa | -enablesystemassertions\n\ attiva le asserzioni di sistema\n\ -dsa | -disablesystemassertions\n\ disattiva le asserzioni di sistema\n\ -agentlib:<nomelibreria>[=<opzioni>]\n\ carica la libreria agente nativa <nomelibreria>, ad es. -agentlib:hprof\n\ vedere anche, -agentlib:jdwp=help e -agentlib:hprof=help\n\ -agentpath:<percorso>[=<opzioni>]\n\ carica la libreria agente nativa in base al percorso completo\n\ -javaagent:<percorsojar>[=<opzioni>]\n\ carica l''agente del linguaggio di programmazione Java, vedere java.lang.instrument\n\ -splash:<percorsoimmagine>\n\ mostra la schermata iniziale con l''immagine specificata\nPer ulteriori informazioni, visitare http://java.sun.com/javase/reference. # Translators please note do not translate the options themselves java.launcher.X.usage=\ -Xmixed esecuzione in modalit\u00e0 mista (predefinita)\n\ -Xint solo esecuzione in modalit\u00e0 interpretata\n\ -Xbootclasspath:<directory e file zip/jar separati da {0}>\n\ imposta il percorso di ricerca per classi e risorse di bootstrap\n\ -Xbootclasspath/a:<directory e file zip/jar separati da {0}>\n\ accoda alla fine del percorso della classe di bootstrap\n\ -Xbootclasspath/p:<directory e file zip/jar separati da {0}>\n\ antepone al percorso della classe di bootsrap\n\ -Xnoclassgc disattiva Garbage Collection per la classe\n\ -Xincgc attiva Garbage Collection incrementale\n\ -Xloggc:<file> registra lo stato GC in un file con timestamp\n\ -Xbatch disattiva la compilazione in background\n\ -Xms<dimensione> imposta la dimensione heap Java iniziale\n\ -Xmx<dimensione> imposta la dimensione heap Java massima\n\ -Xss<dimensione> imposta la dimensione dello stack del thread Java\n\ -Xprof dati di profilo della CPU di output\n\ -Xfuture attiva verifiche pi\u00f9 dettagliate, anticipa le impostazioni predefinite future\n\ -Xrs riduce l''uso di segnali OS da parte di Java o della macchina virtuale (vedere la documentazione)\n\ -Xcheck:jni esegue verifiche aggiuntive per le funzioni JNI\n\ -Xshare:off esclude l''utilizzo di dati classe condivisi\n\ -Xshare:auto imposta l''utilizzo di dati classe condivisi ogni volta che \u00e8 possibile (impostazione predefinita)\n\ -Xshare:on richiede l''utilizzo di dati classe condivisi, in caso contrario origina un errore.\n\nLe opzioni -X sono non standard e soggette a modifiche senza preavviso.\n
--- a/src/share/classes/sun/launcher/resources/launcher_ja.properties Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/sun/launcher/resources/launcher_ja.properties Mon Oct 18 21:50:02 2010 -0700 @@ -34,7 +34,7 @@ java.launcher.ergo.message2 =\ \u7406\u7531\u306f\u3001\u30b5\u30fc\u30d0\u30fc\u30af\u30e9\u30b9\u306e\u30de\u30b7\u30f3\u3092\u4f7f\u7528\u3057\u3066\u3044\u308b\u304b\u3089\u3067\u3059\u3002\n # Translators please note do not translate the options themselves -java.launcher.opt.footer =\ -cp <\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u304a\u3088\u3073 ZIP/JAR \u30d5\u30a1\u30a4\u30eb\u306e\u30af\u30e9\u30b9\u691c\u7d22\u30d1\u30b9>\n\ -classpath <\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u304a\u3088\u3073 ZIP/JAR \u30d5\u30a1\u30a4\u30eb\u306e\u30af\u30e9\u30b9\u691c\u7d22\u30d1\u30b9>\n\ \u30af\u30e9\u30b9\u30d5\u30a1\u30a4\u30eb\u3092\u691c\u7d22\u3059\u308b\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u3001JAR \u30a2\u30fc\u30ab\u30a4\u30d6\u3001\n\ \u304a\u3088\u3073 ZIP \u30a2\u30fc\u30ab\u30a4\u30d6\u306e {0} \u3067\u5206\u5272\u3055\u308c\u305f\u30ea\u30b9\u30c8\u3002\n\ -D<name>=<value>\n\ \u30b7\u30b9\u30c6\u30e0\u30d7\u30ed\u30d1\u30c6\u30a3\u30fc\u306e\u8a2d\u5b9a\n\ -verbose[:class|gc|jni]\n\ \u8a73\u7d30\u51fa\u529b\u306e\u6709\u52b9\u5316\n\ -version \u88fd\u54c1\u30d0\u30fc\u30b8\u30e7\u30f3\u3092\u5370\u5237\u3057\u3066\u7d42\u4e86\n\ -version:<value>\n\ \u5b9f\u884c\u306b\u5fc5\u8981\u306a\u30d0\u30fc\u30b8\u30e7\u30f3\u3092\u8981\u6c42\n\ -showversion \u88fd\u54c1\u30d0\u30fc\u30b8\u30e7\u30f3\u3092\u5370\u5237\u3057\u3066\u7d99\u7d9a\n\ -jre-restrict-search | -jre-no-restrict-search\n\ \u30d0\u30fc\u30b8\u30e7\u30f3\u691c\u7d22\u306b\u30e6\u30fc\u30b6\u30fc\u306e\u975e\u516c\u958b JRE \u3092\u542b\u3081\u308b\u304b\u9664\u5916\u3059\u308b\u304b\u3092\u5207\u308a\u66ff\u3048\u308b\n\ -? -help \u3053\u306e\u30d8\u30eb\u30d7\u30e1\u30c3\u30bb\u30fc\u30b8\u3092\u5370\u5237\n\ -X \u975e\u6a19\u6e96\u30aa\u30d7\u30b7\u30e7\u30f3\u306e\u30d8\u30eb\u30d7\u3092\u5370\u5237\n\ -ea[:<packagename>...|:<classname>]\n\ -enableassertions[:<packagename>...|:<classname>]\n\ \u6307\u5b9a\u3057\u305f\u7c92\u5ea6\u3067\u30a2\u30b5\u30fc\u30b7\u30e7\u30f3\u3092\u6709\u52b9\u5316\n\ -da[:<packagename>...|:<classname>]\n\ -disableassertions[:<packagename>...|:<classname>]\n\ \u6307\u5b9a\u3057\u305f\u7c92\u5ea6\u3067\u30a2\u30b5\u30fc\u30b7\u30e7\u30f3\u3092\u7121\u52b9\u5316\n\ -esa | -enablesystemassertions\n\ \u30b7\u30b9\u30c6\u30e0\u30a2\u30b5\u30fc\u30b7\u30e7\u30f3\u3092\u6709\u52b9\u5316\n\ -dsa | -disablesystemassertions\n\ \u30b7\u30b9\u30c6\u30e0\u30a2\u30b5\u30fc\u30b7\u30e7\u30f3\u3092\u7121\u52b9\u5316\n\ -agentlib:<libname>[=<options>]\n\ \u30cd\u30a4\u30c6\u30a3\u30d6\u30a8\u30fc\u30b8\u30a7\u30f3\u30c8\u30e9\u30a4\u30d6\u30e9\u30ea <libname> (\u4f8b: -agentlib:hprof) \u3092\u30ed\u30fc\u30c9\n\ \u95a2\u9023\u9805\u76ee\u3001 -agentlib:jdwp=help and -agentlib:hprof=help\n\ -agentpath:<pathname>[=<options>]\n\ \u5b8c\u5168\u306a\u30d1\u30b9\u540d\u3067\u30cd\u30a4\u30c6\u30a3\u30d6\u30a8\u30fc\u30b8\u30a7\u30f3\u30c8\u30e9\u30a4\u30d6\u30e9\u30ea\u3092\u30ed\u30fc\u30c9\n\ -javaagent:<jarpath>[=<options>]\n\ Java \u30d7\u30ed\u30b0\u30e9\u30df\u30f3\u30b0\u8a00\u8a9e\u30a8\u30fc\u30b8\u30a7\u30f3\u30c8\u3092\u30ed\u30fc\u30c9\u3002java.lang.instrument \u3092\u53c2\u7167\n\ -splash:<imagepath>\n\ \u6307\u5b9a\u3057\u305f\u753b\u50cf\u306e\u30b9\u30d7\u30e9\u30c3\u30b7\u30e5\u753b\u9762\u3092\u8868\u793a\n\u8a73\u7d30\u306f http://java.sun.com/javase/reference \u3092\u53c2\u7167\u3057\u3066\u304f\u3060\u3055\u3044\u3002 +java.launcher.opt.footer =\ -cp <\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u304a\u3088\u3073 ZIP/JAR \u30d5\u30a1\u30a4\u30eb\u306e\u30af\u30e9\u30b9\u691c\u7d22\u30d1\u30b9>\n\ -classpath <\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u304a\u3088\u3073 ZIP/JAR \u30d5\u30a1\u30a4\u30eb\u306e\u30af\u30e9\u30b9\u691c\u7d22\u30d1\u30b9>\n\ \u30af\u30e9\u30b9\u30d5\u30a1\u30a4\u30eb\u3092\u691c\u7d22\u3059\u308b\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u3001JAR \u30a2\u30fc\u30ab\u30a4\u30d6\u3001\n\ \u304a\u3088\u3073 ZIP \u30a2\u30fc\u30ab\u30a4\u30d6\u306e {0} \u3067\u5206\u5272\u3055\u308c\u305f\u30ea\u30b9\u30c8\u3002\n\ -D<name>=<value>\n\ \u30b7\u30b9\u30c6\u30e0\u30d7\u30ed\u30d1\u30c6\u30a3\u30fc\u306e\u8a2d\u5b9a\n\ -verbose[:class|gc|jni]\n\ \u8a73\u7d30\u51fa\u529b\u306e\u6709\u52b9\u5316\n\ -version \u88fd\u54c1\u30d0\u30fc\u30b8\u30e7\u30f3\u3092\u5370\u5237\u3057\u3066\u7d42\u4e86\n\ -version:<value>\n\ \u5b9f\u884c\u306b\u5fc5\u8981\u306a\u30d0\u30fc\u30b8\u30e7\u30f3\u3092\u8981\u6c42\n\ -showversion \u88fd\u54c1\u30d0\u30fc\u30b8\u30e7\u30f3\u3092\u5370\u5237\u3057\u3066\u7d99\u7d9a\n\ -jre-restrict-search | -no-jre-restrict-search\n\ \u30d0\u30fc\u30b8\u30e7\u30f3\u691c\u7d22\u306b\u30e6\u30fc\u30b6\u30fc\u306e\u975e\u516c\u958b JRE \u3092\u542b\u3081\u308b\u304b\u9664\u5916\u3059\u308b\u304b\u3092\u5207\u308a\u66ff\u3048\u308b\n\ -? -help \u3053\u306e\u30d8\u30eb\u30d7\u30e1\u30c3\u30bb\u30fc\u30b8\u3092\u5370\u5237\n\ -X \u975e\u6a19\u6e96\u30aa\u30d7\u30b7\u30e7\u30f3\u306e\u30d8\u30eb\u30d7\u3092\u5370\u5237\n\ -ea[:<packagename>...|:<classname>]\n\ -enableassertions[:<packagename>...|:<classname>]\n\ \u6307\u5b9a\u3057\u305f\u7c92\u5ea6\u3067\u30a2\u30b5\u30fc\u30b7\u30e7\u30f3\u3092\u6709\u52b9\u5316\n\ -da[:<packagename>...|:<classname>]\n\ -disableassertions[:<packagename>...|:<classname>]\n\ \u6307\u5b9a\u3057\u305f\u7c92\u5ea6\u3067\u30a2\u30b5\u30fc\u30b7\u30e7\u30f3\u3092\u7121\u52b9\u5316\n\ -esa | -enablesystemassertions\n\ \u30b7\u30b9\u30c6\u30e0\u30a2\u30b5\u30fc\u30b7\u30e7\u30f3\u3092\u6709\u52b9\u5316\n\ -dsa | -disablesystemassertions\n\ \u30b7\u30b9\u30c6\u30e0\u30a2\u30b5\u30fc\u30b7\u30e7\u30f3\u3092\u7121\u52b9\u5316\n\ -agentlib:<libname>[=<options>]\n\ \u30cd\u30a4\u30c6\u30a3\u30d6\u30a8\u30fc\u30b8\u30a7\u30f3\u30c8\u30e9\u30a4\u30d6\u30e9\u30ea <libname> (\u4f8b: -agentlib:hprof) \u3092\u30ed\u30fc\u30c9\n\ \u95a2\u9023\u9805\u76ee\u3001 -agentlib:jdwp=help and -agentlib:hprof=help\n\ -agentpath:<pathname>[=<options>]\n\ \u5b8c\u5168\u306a\u30d1\u30b9\u540d\u3067\u30cd\u30a4\u30c6\u30a3\u30d6\u30a8\u30fc\u30b8\u30a7\u30f3\u30c8\u30e9\u30a4\u30d6\u30e9\u30ea\u3092\u30ed\u30fc\u30c9\n\ -javaagent:<jarpath>[=<options>]\n\ Java \u30d7\u30ed\u30b0\u30e9\u30df\u30f3\u30b0\u8a00\u8a9e\u30a8\u30fc\u30b8\u30a7\u30f3\u30c8\u3092\u30ed\u30fc\u30c9\u3002java.lang.instrument \u3092\u53c2\u7167\n\ -splash:<imagepath>\n\ \u6307\u5b9a\u3057\u305f\u753b\u50cf\u306e\u30b9\u30d7\u30e9\u30c3\u30b7\u30e5\u753b\u9762\u3092\u8868\u793a\n\u8a73\u7d30\u306f http://java.sun.com/javase/reference \u3092\u53c2\u7167\u3057\u3066\u304f\u3060\u3055\u3044\u3002 # Translators please note do not translate the options themselves java.launcher.X.usage=\ -Xmixed \u6df7\u5408\u30e2\u30fc\u30c9\u3067\u306e\u5b9f\u884c (\u30c7\u30d5\u30a9\u30eb\u30c8)\n\ -Xint \u30a4\u30f3\u30bf\u30fc\u30d7\u30ea\u30bf\u30e2\u30fc\u30c9\u3067\u306e\u307f\u5b9f\u884c\n\ -Xbootclasspath:<directories and zip/jar files separated by {0}>\n\ \u30d6\u30fc\u30c8\u30b9\u30c8\u30e9\u30c3\u30d7\u30af\u30e9\u30b9\u304a\u3088\u3073\u30ea\u30bd\u30fc\u30b9\u306e\u691c\u7d22\u30d1\u30b9\u3092\u8a2d\u5b9a\n\ -Xbootclasspath/a:<directories and zip/jar files separated by {0}>\n\ \u30d6\u30fc\u30c8\u30b9\u30c8\u30e9\u30c3\u30d7\u30af\u30e9\u30b9\u306e\u30d1\u30b9\u306e\u672b\u5c3e\u306b\u8ffd\u52a0\n\ -Xbootclasspath/p:<directories and zip/jar files separated by {0}>\n\ \u30d6\u30fc\u30c8\u30b9\u30c8\u30e9\u30c3\u30d7\u30af\u30e9\u30b9\u306e\u30d1\u30b9\u306e\u5192\u982d\u306b\u8ffd\u52a0\n\ -Xnoclassgc \u30af\u30e9\u30b9\u30ac\u30fc\u30d9\u30fc\u30b8\u30b3\u30ec\u30af\u30b7\u30e7\u30f3\u3092\u7121\u52b9\u5316\n\ -Xincgc \u5897\u5206\u30ac\u30fc\u30d9\u30fc\u30b8\u30b3\u30ec\u30af\u30b7\u30e7\u30f3\u3092\u7121\u52b9\u5316\n\ -Xloggc:<file> \u30d5\u30a1\u30a4\u30eb\u306e GC \u30b9\u30c6\u30fc\u30bf\u30b9\u3092\u30bf\u30a4\u30e0\u30b9\u30bf\u30f3\u30d7\u4ed8\u304d\u3067\u8a18\u9332\n\ -Xbatch \u30d0\u30c3\u30af\u30b0\u30e9\u30a6\u30f3\u30c9\u30b3\u30f3\u30d1\u30a4\u30eb\u3092\u7121\u52b9\u5316\n\ -Xms<size> \u521d\u671f Java \u30d2\u30fc\u30d7\u30b5\u30a4\u30ba\u3092\u8a2d\u5b9a\n\ -Xmx<size> \u6700\u5927 Java \u30d2\u30fc\u30d7\u30b5\u30a4\u30ba\u3092\u8a2d\u5b9a\n\ -Xss<size> Java \u30b9\u30ec\u30c3\u30c9\u30b9\u30bf\u30c3\u30af\u30b5\u30a4\u30ba\u3092\u8a2d\u5b9a\n\ -Xprof CPU \u30d7\u30ed\u30d5\u30a1\u30a4\u30ea\u30f3\u30b0\u30c7\u30fc\u30bf\u3092\u51fa\u529b\n\ -Xfuture \u4eca\u5f8c\u30c7\u30d5\u30a9\u30eb\u30c8\u3068\u3059\u308b\u6700\u3082\u53b3\u683c\u306a\u30c1\u30a7\u30c3\u30af\u3092\u6709\u52b9\u5316\n\ -Xrs Java/VM \u306e OS \u30b7\u30b0\u30ca\u30eb\u4f7f\u7528\u3092\u524a\u6e1b (\u30de\u30cb\u30e5\u30a2\u30eb\u3092\u53c2\u7167)\n\ -Xcheck:jni JNI \u95a2\u6570\u306e\u8ffd\u52a0\u30c1\u30a7\u30c3\u30af\u3092\u5b9f\u884c\n\ -Xshare:off \u5171\u6709\u30af\u30e9\u30b9\u30c7\u30fc\u30bf\u306e\u4f7f\u7528\u3092\u8a66\u884c\u3057\u306a\u3044\n\ -Xshare:auto \u53ef\u80fd\u306a\u5834\u5408\u306f\u5171\u6709\u30af\u30e9\u30b9\u30c7\u30fc\u30bf\u3092\u4f7f\u7528 (\u30c7\u30d5\u30a9\u30eb\u30c8)\n\ -Xshare:on \u5171\u6709\u30af\u30e9\u30b9\u30c7\u30fc\u30bf\u306e\u4f7f\u7528\u3092\u8981\u6c42 (\u305d\u3046\u3057\u306a\u3044\u3068\u969c\u5bb3\u304c\u767a\u751f\u3059\u308b\u5834\u5408)\n\n-X \u30aa\u30d7\u30b7\u30e7\u30f3\u306f\u975e\u6a19\u6e96\u306e\u30aa\u30d7\u30b7\u30e7\u30f3\u3067\u3042\u308a\u3001\u4e88\u544a\u306a\u304f\u5909\u66f4\u3055\u308c\u308b\u5834\u5408\u304c\u3042\u308a\u307e\u3059\u3002\n
--- a/src/share/classes/sun/launcher/resources/launcher_ko.properties Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/sun/launcher/resources/launcher_ko.properties Mon Oct 18 21:50:02 2010 -0700 @@ -34,7 +34,7 @@ java.launcher.ergo.message2 =\ \uadf8 \uc774\uc720\ub294 \uc11c\ubc84 \ud074\ub798\uc2a4 \uc2dc\uc2a4\ud15c\uc5d0\uc11c \uc2e4\ud589 \uc911\uc774\uae30 \ub54c\ubb38\uc785\ub2c8\ub2e4.\n # Translators please note do not translate the options themselves -java.launcher.opt.footer =\ -cp <\ub514\ub809\ud1a0\ub9ac \ubc0f zip/jar \ud30c\uc77c\uc758 \ud074\ub798\uc2a4 \uac80\uc0c9 \uacbd\ub85c>\n\ -classpath <\ub514\ub809\ud1a0\ub9ac \ubc0f zip/jar \ud30c\uc77c\uc758 \ud074\ub798\uc2a4 \uac80\uc0c9 \uacbd\ub85c>\n\ \ud074\ub798\uc2a4 \ud30c\uc77c\uc744 \uac80\uc0c9\ud558\uae30 \uc704\ud55c \ub514\ub809\ud1a0\ub9ac, JAR \uc544\uce74\uc774\ube0c \ubc0f\n\ ZIP \uc544\uce74\uc774\ube0c\uc758 {0} \uad6c\ubd84\ub41c \ubaa9\ub85d\uc785\ub2c8\ub2e4.\n\ -D<name>=<value>\n\ \uc2dc\uc2a4\ud15c \ub4f1\ub85d \uc815\ubcf4 \uc124\uc815\n\ -verbose[:class|gc|jni]\n\ \ucd94\uac00 \ucd9c\ub825 \uc0ac\uc6a9\n\ -version \uc81c\ud488 \ubc84\uc804\uc744 \uc778\uc1c4\ud558\uace0 \uc885\ub8cc\n\ -version:<value>\n\ \uc2e4\ud589\ud558\ub824\uba74 \uc9c0\uc815\ud55c \ubc84\uc804 \ud544\uc694\n\ -showversion \uc81c\ud488 \ubc84\uc804\uc744 \uc778\uc1c4\ud558\uace0 \uacc4\uc18d\n\ -jre-restrict-search | -jre-no-restrict-search\n\ \ubc84\uc804 \uac80\uc0c9\uc5d0\uc11c \uc0ac\uc6a9\uc790 \uac1c\uc778 JRE \ud3ec\ud568/\uc81c\uc678\n\ -? -help \uc774 \ub3c4\uc6c0\ub9d0 \uba54\uc2dc\uc9c0 \uc778\uc1c4\n\ -X \ube44\ud45c\uc900 \uc635\uc158\uc5d0 \ub300\ud55c \ub3c4\uc6c0\ub9d0 \uc778\uc1c4\n\ -ea[:<packagename>...|:<classname>]\n\ -enableassertions[:<packagename>...|:<classname>]\n\ \uc9c0\uc815\ud55c \uc815\ubc00\ub3c4\uc758 \uba85\uc81c \uc0ac\uc6a9\n\ -da[:<packagename>...|:<classname>]\n\ -disableassertions[:<packagename>...|:<classname>]\n\ \uc9c0\uc815\ud55c \uc815\ubc00\ub3c4\uc758 \uba85\uc81c \uc0ac\uc6a9 \uc548 \ud568\n\ -esa | -enablesystemassertions\n\ \uc2dc\uc2a4\ud15c \uba85\uc81c \uc0ac\uc6a9\n\ -dsa | -disablesystemassertions\n\ \uc2dc\uc2a4\ud15c \uba85\uc81c \uc0ac\uc6a9 \uc548 \ud568\n\ -agentlib:<libname>[=<options>]\n\ \uc6d0\uc2dc \uc5d0\uc774\uc804\ud2b8 \ub77c\uc774\ube0c\ub7ec\ub9ac <libname> \ub85c\ub4dc, \uc608: -agentlib:hprof\n\ \ucc38\uc870: -agentlib:jdwp=help \ubc0f -agentlib:hprof=help\n\ -agentpath:<pathname>[=<options>]\n\ \uc804\uccb4 \uacbd\ub85c \uc774\ub984\uc73c\ub85c \uc6d0\uc2dc \uc5d0\uc774\uc804\ud2b8 \ub77c\uc774\ube0c\ub7ec\ub9ac \ub85c\ub4dc\n\ -javaagent:<jarpath>[=<options>]\n\ Java \ud504\ub85c\uadf8\ub798\ubc0d \uc5b8\uc5b4 \uc5d0\uc774\uc804\ud2b8 \ub85c\ub4dc, java.lang.instrument \ucc38\uc870\n\ -splash:<imagepath>\n\ \uc9c0\uc815\ud55c \uc774\ubbf8\uc9c0\uc758 \uc2a4\ud50c\ub798\uc2dc \ud654\uba74 \ud45c\uc2dc\n\uc790\uc138\ud55c \ub0b4\uc6a9\uc740 http://java.sun.com/javase/reference\ub97c \ucc38\uc870\ud558\uc2ed\uc2dc\uc624. +java.launcher.opt.footer =\ -cp <\ub514\ub809\ud1a0\ub9ac \ubc0f zip/jar \ud30c\uc77c\uc758 \ud074\ub798\uc2a4 \uac80\uc0c9 \uacbd\ub85c>\n\ -classpath <\ub514\ub809\ud1a0\ub9ac \ubc0f zip/jar \ud30c\uc77c\uc758 \ud074\ub798\uc2a4 \uac80\uc0c9 \uacbd\ub85c>\n\ \ud074\ub798\uc2a4 \ud30c\uc77c\uc744 \uac80\uc0c9\ud558\uae30 \uc704\ud55c \ub514\ub809\ud1a0\ub9ac, JAR \uc544\uce74\uc774\ube0c \ubc0f\n\ ZIP \uc544\uce74\uc774\ube0c\uc758 {0} \uad6c\ubd84\ub41c \ubaa9\ub85d\uc785\ub2c8\ub2e4.\n\ -D<name>=<value>\n\ \uc2dc\uc2a4\ud15c \ub4f1\ub85d \uc815\ubcf4 \uc124\uc815\n\ -verbose[:class|gc|jni]\n\ \ucd94\uac00 \ucd9c\ub825 \uc0ac\uc6a9\n\ -version \uc81c\ud488 \ubc84\uc804\uc744 \uc778\uc1c4\ud558\uace0 \uc885\ub8cc\n\ -version:<value>\n\ \uc2e4\ud589\ud558\ub824\uba74 \uc9c0\uc815\ud55c \ubc84\uc804 \ud544\uc694\n\ -showversion \uc81c\ud488 \ubc84\uc804\uc744 \uc778\uc1c4\ud558\uace0 \uacc4\uc18d\n\ -jre-restrict-search | -no-jre-restrict-search\n\ \ubc84\uc804 \uac80\uc0c9\uc5d0\uc11c \uc0ac\uc6a9\uc790 \uac1c\uc778 JRE \ud3ec\ud568/\uc81c\uc678\n\ -? -help \uc774 \ub3c4\uc6c0\ub9d0 \uba54\uc2dc\uc9c0 \uc778\uc1c4\n\ -X \ube44\ud45c\uc900 \uc635\uc158\uc5d0 \ub300\ud55c \ub3c4\uc6c0\ub9d0 \uc778\uc1c4\n\ -ea[:<packagename>...|:<classname>]\n\ -enableassertions[:<packagename>...|:<classname>]\n\ \uc9c0\uc815\ud55c \uc815\ubc00\ub3c4\uc758 \uba85\uc81c \uc0ac\uc6a9\n\ -da[:<packagename>...|:<classname>]\n\ -disableassertions[:<packagename>...|:<classname>]\n\ \uc9c0\uc815\ud55c \uc815\ubc00\ub3c4\uc758 \uba85\uc81c \uc0ac\uc6a9 \uc548 \ud568\n\ -esa | -enablesystemassertions\n\ \uc2dc\uc2a4\ud15c \uba85\uc81c \uc0ac\uc6a9\n\ -dsa | -disablesystemassertions\n\ \uc2dc\uc2a4\ud15c \uba85\uc81c \uc0ac\uc6a9 \uc548 \ud568\n\ -agentlib:<libname>[=<options>]\n\ \uc6d0\uc2dc \uc5d0\uc774\uc804\ud2b8 \ub77c\uc774\ube0c\ub7ec\ub9ac <libname> \ub85c\ub4dc, \uc608: -agentlib:hprof\n\ \ucc38\uc870: -agentlib:jdwp=help \ubc0f -agentlib:hprof=help\n\ -agentpath:<pathname>[=<options>]\n\ \uc804\uccb4 \uacbd\ub85c \uc774\ub984\uc73c\ub85c \uc6d0\uc2dc \uc5d0\uc774\uc804\ud2b8 \ub77c\uc774\ube0c\ub7ec\ub9ac \ub85c\ub4dc\n\ -javaagent:<jarpath>[=<options>]\n\ Java \ud504\ub85c\uadf8\ub798\ubc0d \uc5b8\uc5b4 \uc5d0\uc774\uc804\ud2b8 \ub85c\ub4dc, java.lang.instrument \ucc38\uc870\n\ -splash:<imagepath>\n\ \uc9c0\uc815\ud55c \uc774\ubbf8\uc9c0\uc758 \uc2a4\ud50c\ub798\uc2dc \ud654\uba74 \ud45c\uc2dc\n\uc790\uc138\ud55c \ub0b4\uc6a9\uc740 http://java.sun.com/javase/reference\ub97c \ucc38\uc870\ud558\uc2ed\uc2dc\uc624. # Translators please note do not translate the options themselves java.launcher.X.usage=\ -Xmixed \ud63c\ud569 \ubaa8\ub4dc \uc2e4\ud589(\uae30\ubcf8\uac12)\n\ -Xint \ud574\uc11d\ub41c \ubaa8\ub4dc \uc2e4\ud589 \uc804\uc6a9\n\ -Xbootclasspath:<directories and zip/jar files separated by {0}>\n\ \ubd80\ud2b8\uc2a4\ud2b8\ub7a9 \ud074\ub798\uc2a4\uc640 \uc790\uc6d0\uc758 \uac80\uc0c9 \uacbd\ub85c \uc124\uc815\n\ -Xbootclasspath/a:<directories and zip/jar files separated by {0}>\n\ \ubd80\ud2b8\uc2a4\ud2b8\ub7a9 \ud074\ub798\uc2a4 \uacbd\ub85c \ub05d\uc5d0 \ucd94\uac00\n\ -Xbootclasspath/p:<directories and zip/jar files separated by {0}>\n\ \ubd80\ud2b8\uc2a4\ud2b8\ub7a9 \ud074\ub798\uc2a4 \uacbd\ub85c \uc55e\uc5d0 \ucd94\uac00\n\ -Xnoclassgc \ud074\ub798\uc2a4 \uac00\ube44\uc9c0 \uceec\ub809\uc158 \uc0ac\uc6a9 \uc548 \ud568\n\ -Xincgc \uc99d\ubd84 \uac00\ube44\uc9c0 \uceec\ub809\uc158 \uc0ac\uc6a9\n\ -Xloggc:<file> GC \uc0c1\ud0dc\ub97c \ud0c0\uc784 \uc2a4\ud0ec\ud504\uc640 \ud568\uaed8 \ud30c\uc77c\uc5d0 \ub85c\uadf8\n\ -Xbatch \ubc31\uadf8\ub77c\uc6b4\ub4dc \ucef4\ud30c\uc77c \uc0ac\uc6a9 \uc548 \ud568\n\ -Xms<size> \ucd08\uae30 Java \ud799 \ud06c\uae30 \uc124\uc815\n\ -Xmx<size> \ucd5c\ub300 Java \ud799 \ud06c\uae30 \uc124\uc815\n\ -Xss<size> java \uc2a4\ub808\ub4dc \uc2a4\ud0dd \ud06c\uae30 \uc124\uc815\n\ -Xprof cpu \ud504\ub85c\ud30c\uc77c\ub9c1 \ub370\uc774\ud130 \ucd9c\ub825\n\ -Xfuture \ubbf8\ub798 \uae30\ubcf8\uac12\uc744 \uc608\uce21\ud558\uc5ec \uac00\uc7a5 \uc5c4\uaca9\ud55c \uac80\uc0ac \uc0ac\uc6a9\n\ -Xrs Java/VM\uc5d0 \uc758\ud55c OS \uc2e0\ud638 \uc0ac\uc6a9 \uac10\uc18c(\uc124\uba85\uc11c \ucc38\uc870)\n\ -Xcheck:jni JNI \uae30\ub2a5\uc5d0 \ub300\ud55c \ucd94\uac00\uc801\uc778 \uac80\uc0ac \uc218\ud589\n\ -Xshare:off \uacf5\uc720\ub41c \ud074\ub798\uc2a4 \ub370\uc774\ud130\uc758 \uc0ac\uc6a9\uc744 \uc2dc\ub3c4\ud558\uc9c0 \uc54a\uc74c\n\ -Xshare:auto \uac00\ub2a5\ud55c \uacbd\uc6b0 \uacf5\uc720\ub41c \ud074\ub798\uc2a4 \ub370\uc774\ud130 \uc0ac\uc6a9(\uae30\ubcf8\uac12)\n\ -Xshare:on \uacf5\uc720\ub41c \ud074\ub798\uc2a4 \ub370\uc774\ud130\ub97c \uc0ac\uc6a9\ud574\uc57c \ud558\uba70 \uadf8\ub807\uc9c0 \uc54a\uc73c\uba74 \uc2e4\ud328.\n\n-X \uc635\uc158\uc740 \ud45c\uc900\uc774 \uc544\ub2c8\uba70 \uc54c\ub9bc \uc5c6\uc774 \ubcc0\uacbd\ub420 \uc218 \uc788\uc2b5\ub2c8\ub2e4.\n
--- a/src/share/classes/sun/launcher/resources/launcher_sv.properties Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/sun/launcher/resources/launcher_sv.properties Mon Oct 18 21:50:02 2010 -0700 @@ -34,7 +34,7 @@ java.launcher.ergo.message2 =\ eftersom du k\u00f6r p\u00e5 en dator med server-klass.\n # Translators please note do not translate the options themselves -java.launcher.opt.footer =\ -cp <klass\u00f6kv\u00e4g till kataloger och zip-/jar-filers>\n\ -classpath <klass\u00f6kv\u00e4g till kataloger och zip-/jar-filer>\n\ en med {0} avgr\u00e4nsad lista \u00f6ver kataloger, JAR-arkiv\n\ och ZIP-arkiv f\u00f6r s\u00f6kning efter klassfiler.\n\ -D<namn>=<v\u00e4rde>\n\ ange en systemegenskap\n\ -verbose[:klass|gc|jni]\n\ visa mer text\n\ -version skriv ut produktversionen och avsluta\n\ -version:<value>\n\ kr\u00e4ver den angivna versionen f\u00f6r att kunna k\u00f6ras\n\ -showversion skriv ut produktversion och forts\u00e4tt\n\ -jre-restrict-search | -jre-no-restrict-search\n\ inkludera/exkludera anv\u00e4ndarens privata JRE-filer i versionss\u00f6kningen\n\ -? -help skriver ut det h\u00e4r hj\u00e4lpmeddelandet\n\ -X skriv ut hj\u00e4lp f\u00f6r alternativ som inte \u00e4r standard\n\ -ea[:<paketnamn>...|:<klassnamn>]\n\ -enableassertions[:<paketnamn>...|:<klassnamn>]\n\ aktivera bekr\u00e4ftelser med angiven precision\n\ -da[:<paketnamn>...|:<klassnamn>]\n\ -disableassertions[:<paketnamn>...|:<klassnamn>]\n\ inaktivera bekr\u00e4ftelser med angiven precision\n\ -esa | -enablesystemassertions\n\ aktivera systembekr\u00e4ftelser\n\ -dsa | -disablesystemassertions\n\ inaktivera systembekr\u00e4ftelser\n\ -agentlib:<biblnamn>[=<alternativ>]\n\ l\u00e4s in det interna agentbiblioteket <biblnamn>, t.ex. -agentlib:hprof\n\ se \u00e4ven, -agentlib:jdwp=help och -agentlib:hprof=help\n\ -agentpath:<filnamn>[=<alternativ>]\n\ l\u00e4s in internt agentbibliotek utifr\u00e5n fullst\u00e4ndig s\u00f6kv\u00e4g\n\ -javaagent:<jar-s\u00f6kv\u00e4g>[=<alternativ>]\n\ l\u00e4s in agenten f\u00f6r programmeringsspr\u00e5ket Java, se java.lang.instrument\n\ -splash:<bilds\u00f6kv\u00e4g>\n\ visa v\u00e4lkomstf\u00f6nster med angiven bild\nMer information finns p\u00e5 http://java.sun.com/javase/reference. +java.launcher.opt.footer =\ -cp <klass\u00f6kv\u00e4g till kataloger och zip-/jar-filers>\n\ -classpath <klass\u00f6kv\u00e4g till kataloger och zip-/jar-filer>\n\ en med {0} avgr\u00e4nsad lista \u00f6ver kataloger, JAR-arkiv\n\ och ZIP-arkiv f\u00f6r s\u00f6kning efter klassfiler.\n\ -D<namn>=<v\u00e4rde>\n\ ange en systemegenskap\n\ -verbose[:klass|gc|jni]\n\ visa mer text\n\ -version skriv ut produktversionen och avsluta\n\ -version:<value>\n\ kr\u00e4ver den angivna versionen f\u00f6r att kunna k\u00f6ras\n\ -showversion skriv ut produktversion och forts\u00e4tt\n\ -jre-restrict-search | -no-jre-restrict-search\n\ inkludera/exkludera anv\u00e4ndarens privata JRE-filer i versionss\u00f6kningen\n\ -? -help skriver ut det h\u00e4r hj\u00e4lpmeddelandet\n\ -X skriv ut hj\u00e4lp f\u00f6r alternativ som inte \u00e4r standard\n\ -ea[:<paketnamn>...|:<klassnamn>]\n\ -enableassertions[:<paketnamn>...|:<klassnamn>]\n\ aktivera bekr\u00e4ftelser med angiven precision\n\ -da[:<paketnamn>...|:<klassnamn>]\n\ -disableassertions[:<paketnamn>...|:<klassnamn>]\n\ inaktivera bekr\u00e4ftelser med angiven precision\n\ -esa | -enablesystemassertions\n\ aktivera systembekr\u00e4ftelser\n\ -dsa | -disablesystemassertions\n\ inaktivera systembekr\u00e4ftelser\n\ -agentlib:<biblnamn>[=<alternativ>]\n\ l\u00e4s in det interna agentbiblioteket <biblnamn>, t.ex. -agentlib:hprof\n\ se \u00e4ven, -agentlib:jdwp=help och -agentlib:hprof=help\n\ -agentpath:<filnamn>[=<alternativ>]\n\ l\u00e4s in internt agentbibliotek utifr\u00e5n fullst\u00e4ndig s\u00f6kv\u00e4g\n\ -javaagent:<jar-s\u00f6kv\u00e4g>[=<alternativ>]\n\ l\u00e4s in agenten f\u00f6r programmeringsspr\u00e5ket Java, se java.lang.instrument\n\ -splash:<bilds\u00f6kv\u00e4g>\n\ visa v\u00e4lkomstf\u00f6nster med angiven bild\nMer information finns p\u00e5 http://java.sun.com/javase/reference. # Translators please note do not translate the options themselves java.launcher.X.usage=\ -Xmixed k\u00f6rning i blandat l\u00e4ge (standard)\n\ -Xint endast k\u00f6rning i tolkat l\u00e4ge\n\ -Xbootclasspath:<kataloger och zip-/jar-filer som avgr\u00e4nsas med {0}>\n\ ange s\u00f6kv\u00e4g f\u00f6r bootstrap-klasser och -resurser\n\ -Xbootclasspath/a:<kataloger och zip-/jar-filer som avgr\u00e4nsas med {0}>\n\ l\u00e4gg till p\u00e5 slutet av s\u00f6kv\u00e4gen till bootstrap-klassen\n\ -Xbootclasspath/p:<kataloger och zip-/jar-filer som avgr\u00e4nsas med {0}>\n\ l\u00e4gg till i b\u00f6rjan av s\u00f6kv\u00e4gen till bootstrap-klassen\n\ -Xnoclassgc inaktivera skr\u00e4pinsamling f\u00f6r klass\n\ -Xincgc aktivera inkrementell skr\u00e4pinsaming\n\ -Xloggc:<file> logga GC-status till en fil med tidsst\u00e4mpel\n\ -Xbatch inaktivera kompilering i bakgrunden\n\ -Xms<size> st\u00e4ll in ursprunglig heapstorlek f\u00f6r Java\n\ -Xmx<size> st\u00e4ll in st\u00f6rsta heapstorlek f\u00f6r Java\n\ -Xss<size> st\u00e4ll in tr\u00e5dstackens storlek f\u00f6r Java\n\ -Xprof visa profileringsdata om processorn\n\ -Xfuture aktivera de mest rigor\u00f6sa kontrollerna och f\u00f6regrip framtida standardl\u00e4ge\n\ -Xrs minska anv\u00e4ndningen av signaler fr\u00e5n operativsystemet i Java/VM (mer information finns i dokumentationen)\n\ -Xcheck:jni utf\u00f6r ytterligare kontroller f\u00f6r JNI-funktioner\n\ -Xshare:off f\u00f6rs\u00f6k inte att anv\u00e4nda delade klassdata\n\ -Xshare:auto anv\u00e4nd om m\u00f6jligt delade klassdata (standard)\n\ -Xshare:on kr\u00e4v att delade klassdata anv\u00e4nds, skicka fel om s\u00e5 inte \u00e4r fallet.\n\n -X-alternativen betraktas inte som standard och kan \u00e4ndras utan att detta meddelas.\n
--- a/src/share/classes/sun/launcher/resources/launcher_zh_CN.properties Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/sun/launcher/resources/launcher_zh_CN.properties Mon Oct 18 21:50:02 2010 -0700 @@ -34,7 +34,7 @@ java.launcher.ergo.message2 =\ \u56e0\u4e3a\u60a8\u662f\u5728\u670d\u52a1\u5668\u7c7b\u8ba1\u7b97\u673a\u4e0a\u8fd0\u884c\u3002\n # Translators please note do not translate the options themselves -java.launcher.opt.footer =\ -cp <\u76ee\u5f55\u548c zip/jar \u6587\u4ef6\u7684\u7c7b\u641c\u7d22\u8def\u5f84>\n\ -classpath <\u76ee\u5f55\u548c zip/jar \u6587\u4ef6\u7684\u7c7b\u641c\u7d22\u8def\u5f84>\n\ \u4e00\u4e2a\u4ee5 {0} \u5206\u9694\u7684\u76ee\u5f55\u3001JAR \u5f52\u6863\u6587\u4ef6\n\ \u548c ZIP \u5f52\u6863\u6587\u4ef6\u7684\u5217\u8868\uff0c\u7528\u4e8e\u641c\u7d22\u7c7b\u6587\u4ef6\u3002\n\ -D<name>=<value>\n\ \u8bbe\u7f6e\u7cfb\u7edf\u5c5e\u6027\n\ -verbose[:class|gc|jni]\n\ \u542f\u7528\u8be6\u7ec6\u8f93\u51fa\n\ -version \u663e\u793a\u4ea7\u54c1\u7248\u672c\u5e76\u9000\u51fa\n\ -version:<value>\n\ \u8981\u6c42\u8fd0\u884c\u6307\u5b9a\u7684\u7248\u672c\n\ -showversion \u663e\u793a\u4ea7\u54c1\u7248\u672c\u5e76\u7ee7\u7eed\n\ -jre-restrict-search | -jre-no-restrict-search\n\ \u5728\u7248\u672c\u641c\u7d22\u4e2d\u5305\u62ec/\u4e0d\u5305\u62ec\u7528\u6237\u79c1\u6709 JRE\n\ -? -help \u663e\u793a\u6b64\u5e2e\u52a9\u6d88\u606f\n\ -X \u663e\u793a\u6709\u5173\u975e\u6807\u51c6\u9009\u9879\u7684\u5e2e\u52a9\n\ -ea[:<packagename>...|:<classname>]\n\ -enableassertions[:<packagename>...|:<classname>]\n\ \u542f\u7528\u6307\u5b9a\u7c92\u5ea6\u7684\u65ad\u8a00\n\ -da[:<packagename>...|:<classname>]\n\ -disableassertions[:<packagename>...|:<classname>]\n\ \u7981\u7528\u6307\u5b9a\u7c92\u5ea6\u7684\u65ad\u8a00\n\ -esa | -enablesystemassertions\n\ \u542f\u7528\u7cfb\u7edf\u65ad\u8a00\n\ -dsa | -disablesystemassertions\n\ \u7981\u7528\u7cfb\u7edf\u65ad\u8a00\n\ -agentlib:<libname>[=<options>]\n\ \u88c5\u5165\u672c\u673a\u4ee3\u7406\u5e93 <libname>\uff0c\u4f8b\u5982\uff1a-agentlib:hprof\n\ \u53e6\u8bf7\u53c2\u89c1 -agentlib:jdwp=help \u548c -agentlib:hprof=help\n\ -agentpath:<pathname>[=<options>]\n\ \u4ee5\u5168\u8def\u5f84\u540d\u88c5\u5165\u672c\u673a\u4ee3\u7406\u5e93\n\ -javaagent:<jarpath>[=<options>]\n\ \u88c5\u5165 Java \u7f16\u7a0b\u8bed\u8a00\u4ee3\u7406\uff0c\u8bf7\u53c2\u89c1 java.lang.instrument\n\ -splash:<imagepath>\n\ \u4f7f\u7528\u6307\u5b9a\u56fe\u50cf\u663e\u793a\u95ea\u73b0\u5c4f\u5e55\n\u6709\u5173\u66f4\u591a\u8be6\u7ec6\u4fe1\u606f\uff0c\u8bf7\u53c2\u89c1 http://java.sun.com/javase/reference\u3002 +java.launcher.opt.footer =\ -cp <\u76ee\u5f55\u548c zip/jar \u6587\u4ef6\u7684\u7c7b\u641c\u7d22\u8def\u5f84>\n\ -classpath <\u76ee\u5f55\u548c zip/jar \u6587\u4ef6\u7684\u7c7b\u641c\u7d22\u8def\u5f84>\n\ \u4e00\u4e2a\u4ee5 {0} \u5206\u9694\u7684\u76ee\u5f55\u3001JAR \u5f52\u6863\u6587\u4ef6\n\ \u548c ZIP \u5f52\u6863\u6587\u4ef6\u7684\u5217\u8868\uff0c\u7528\u4e8e\u641c\u7d22\u7c7b\u6587\u4ef6\u3002\n\ -D<name>=<value>\n\ \u8bbe\u7f6e\u7cfb\u7edf\u5c5e\u6027\n\ -verbose[:class|gc|jni]\n\ \u542f\u7528\u8be6\u7ec6\u8f93\u51fa\n\ -version \u663e\u793a\u4ea7\u54c1\u7248\u672c\u5e76\u9000\u51fa\n\ -version:<value>\n\ \u8981\u6c42\u8fd0\u884c\u6307\u5b9a\u7684\u7248\u672c\n\ -showversion \u663e\u793a\u4ea7\u54c1\u7248\u672c\u5e76\u7ee7\u7eed\n\ -jre-restrict-search | -no-jre-restrict-search\n\ \u5728\u7248\u672c\u641c\u7d22\u4e2d\u5305\u62ec/\u4e0d\u5305\u62ec\u7528\u6237\u79c1\u6709 JRE\n\ -? -help \u663e\u793a\u6b64\u5e2e\u52a9\u6d88\u606f\n\ -X \u663e\u793a\u6709\u5173\u975e\u6807\u51c6\u9009\u9879\u7684\u5e2e\u52a9\n\ -ea[:<packagename>...|:<classname>]\n\ -enableassertions[:<packagename>...|:<classname>]\n\ \u542f\u7528\u6307\u5b9a\u7c92\u5ea6\u7684\u65ad\u8a00\n\ -da[:<packagename>...|:<classname>]\n\ -disableassertions[:<packagename>...|:<classname>]\n\ \u7981\u7528\u6307\u5b9a\u7c92\u5ea6\u7684\u65ad\u8a00\n\ -esa | -enablesystemassertions\n\ \u542f\u7528\u7cfb\u7edf\u65ad\u8a00\n\ -dsa | -disablesystemassertions\n\ \u7981\u7528\u7cfb\u7edf\u65ad\u8a00\n\ -agentlib:<libname>[=<options>]\n\ \u88c5\u5165\u672c\u673a\u4ee3\u7406\u5e93 <libname>\uff0c\u4f8b\u5982\uff1a-agentlib:hprof\n\ \u53e6\u8bf7\u53c2\u89c1 -agentlib:jdwp=help \u548c -agentlib:hprof=help\n\ -agentpath:<pathname>[=<options>]\n\ \u4ee5\u5168\u8def\u5f84\u540d\u88c5\u5165\u672c\u673a\u4ee3\u7406\u5e93\n\ -javaagent:<jarpath>[=<options>]\n\ \u88c5\u5165 Java \u7f16\u7a0b\u8bed\u8a00\u4ee3\u7406\uff0c\u8bf7\u53c2\u89c1 java.lang.instrument\n\ -splash:<imagepath>\n\ \u4f7f\u7528\u6307\u5b9a\u56fe\u50cf\u663e\u793a\u95ea\u73b0\u5c4f\u5e55\n\u6709\u5173\u66f4\u591a\u8be6\u7ec6\u4fe1\u606f\uff0c\u8bf7\u53c2\u89c1 http://java.sun.com/javase/reference\u3002 # Translators please note do not translate the options themselves java.launcher.X.usage=\ -Xmixed \u6df7\u5408\u6a21\u5f0f\u6267\u884c\uff08\u9ed8\u8ba4\uff09\n\ -Xint \u4ec5\u89e3\u91ca\u6a21\u5f0f\u6267\u884c\n\ -Xbootclasspath:<\u4ee5 {0} \u5206\u9694\u7684\u76ee\u5f55\u548c zip/jar \u6587\u4ef6>\n\ \u8bbe\u7f6e\u5f15\u5bfc\u7c7b\u548c\u8d44\u6e90\u7684\u641c\u7d22\u8def\u5f84\n\ -Xbootclasspath/a:<\u4ee5 {0} \u5206\u9694\u7684\u76ee\u5f55\u548c zip/jar \u6587\u4ef6>\n\ \u9644\u52a0\u5230\u5f15\u5bfc\u7c7b\u8def\u5f84\u5c3e\u90e8\n\ -Xbootclasspath/p:<\u4ee5 {0} \u5206\u9694\u7684\u76ee\u5f55\u548c zip/jar \u6587\u4ef6>\n\ \u7f6e\u4e8e\u5f15\u5bfc\u7c7b\u8def\u5f84\u524d\u9762\n\ -Xnoclassgc \u7981\u7528\u7c7b\u5783\u573e\u6536\u96c6\n\ -Xincgc \u542f\u7528\u589e\u91cf\u5783\u573e\u6536\u96c6\n\ -Xloggc:<\u6587\u4ef6> \u5c06 GC \u72b6\u6001\u8bb0\u5f55\u5230\u4e00\u4e2a\u5e26\u6709\u65f6\u95f4\u6233\u7684\u6587\u4ef6\n\ -Xbatch \u7981\u7528\u540e\u53f0\u7f16\u8bd1\n\ -Xms<\u5927\u5c0f> \u8bbe\u7f6e\u521d\u59cb Java \u5806\u5927\u5c0f\n\ -Xmx<\u5927\u5c0f> \u8bbe\u7f6e\u6700\u5927 Java \u5806\u5927\u5c0f\n\ -Xss<\u5927\u5c0f> \u8bbe\u7f6e Java \u7ebf\u7a0b\u5806\u6808\u5927\u5c0f\n\ -Xprof \u8f93\u51fa CPU \u914d\u7f6e\u6570\u636e\n\ -Xfuture \u542f\u7528\u6700\u4e25\u683c\u7684\u68c0\u67e5\uff0c\u672a\u6765\u53ef\u80fd\u4f1a\u6210\u4e3a\u9ed8\u8ba4\u9009\u9879\n\ -Xrs \u51cf\u5c11 Java/VM \u5bf9\u64cd\u4f5c\u7cfb\u7edf\u4fe1\u53f7\u7684\u4f7f\u7528\uff08\u8bf7\u53c2\u89c1\u6587\u6863\uff09\n\ -Xcheck:jni \u9488\u5bf9 JNI \u529f\u80fd\u6267\u884c\u989d\u5916\u7684\u68c0\u67e5\n\ -Xshare:off \u4e0d\u5c1d\u8bd5\u4f7f\u7528\u5171\u4eab\u7c7b\u6570\u636e\n\ -Xshare:auto \u5982\u679c\u53ef\u80fd\u7684\u8bdd\uff0c\u4f7f\u7528\u5171\u4eab\u7c7b\u6570\u636e\uff08\u9ed8\u8ba4\uff09\n\ -Xshare:on \u8981\u6c42\u4f7f\u7528\u5171\u4eab\u7c7b\u6570\u636e\uff0c\u5426\u5219\u4f1a\u5931\u8d25\u3002\n\n-X \u9009\u9879\u662f\u975e\u6807\u51c6\u9009\u9879\uff0c\u5982\u6709\u66f4\u6539\uff0c\u6055\u4e0d\u53e6\u884c\u901a\u77e5\u3002\n
--- a/src/share/classes/sun/launcher/resources/launcher_zh_TW.properties Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/sun/launcher/resources/launcher_zh_TW.properties Mon Oct 18 21:50:02 2010 -0700 @@ -34,7 +34,7 @@ java.launcher.ergo.message2 =\ \u56e0\u70ba\u60a8\u6b63\u57f7\u884c\u65bc\u4f3a\u670d\u5668\u7d1a\u7684\u6a5f\u5668\u4e0a\u3002\n # Translators please note do not translate the options themselves -java.launcher.opt.footer =\ -cp <\u76ee\u9304\u548c zip/jar \u6a94\u6848\u7684\u985e\u5225\u641c\u5c0b\u8def\u5f91>\n\ -classpath <\u76ee\u9304\u548c zip/jar \u6a94\u6848\u7684\u985e\u5225\u641c\u5c0b\u8def\u5f91>\n\ {0} \u76ee\u9304\u3001JAR \u6b78\u6a94\n\ \u548c ZIP \u6b78\u6a94\u7684\u5206\u9694\u6e05\u55ae\uff0c\u7528\u65bc\u641c\u5c0b\u985e\u5225\u6a94\u6848\u3002\n\ -D<name>=<value>\n\ \u8a2d\u5b9a\u7cfb\u7d71\u7279\u6027\n\ -verbose[:class|gc|jni]\n\ \u555f\u7528\u8a73\u7d30\u8f38\u51fa\n\ -version \u5217\u5370\u7522\u54c1\u7248\u672c\u4e26\u7d50\u675f\n\ -version:<value>\n\ \u9700\u8981\u57f7\u884c\u6307\u5b9a\u7684\u7248\u672c\n\ -showversion \u5217\u5370\u7522\u54c1\u7248\u672c\u4e26\u7e7c\u7e8c\n\ -jre-restrict-search | -jre-no-restrict-search\n\ \u5728\u7248\u672c\u641c\u5c0b\u4e2d\u5305\u542b/\u6392\u9664\u4f7f\u7528\u8005\u79c1\u7528 JRE\n\ -? -help \u5217\u5370\u6b64\u8aaa\u660e\u8a0a\u606f\n\ -X \u5217\u5370\u6709\u95dc\u975e\u6a19\u6e96\u9078\u9805\u7684\u8aaa\u660e\n\ -ea[:<packagename>...|:<classname>]\n\ -enableassertions[:<packagename>...|:<classname>]\n\ \u555f\u7528\u5177\u6709\u6307\u5b9a\u9846\u7c92\u6027\u7684\u5ba3\u544a\n\ -da[:<packagename>...|:<classname>]\n\ -disableassertions[:<packagename>...|:<classname>]\n\ \u505c\u7528\u5177\u6709\u6307\u5b9a\u9846\u7c92\u6027\u7684\u5ba3\u544a\n\ -esa | -enablesystemassertions\n\ \u555f\u7528\u7cfb\u7d71\u5ba3\u544a\n\ -dsa | -disablesystemassertions\n\ \u505c\u7528\u7cfb\u7d71\u5ba3\u544a\n\ -agentlib:<libname>[=<options>]\n\ \u8f09\u5165\u539f\u751f\u4ee3\u7406\u7a0b\u5f0f\u7a0b\u5f0f\u5eab <libname>\uff0c\u4f8b\u5982 -agentlib:hprof\n\ \u53e6\u8acb\u53c3\u95b1 -agentlib:jdwp=help \u548c -agentlib:hprof=help\n\ -agentpath:<pathname>[=<options>]\n\ \u4f9d\u64da\u5b8c\u6574\u8def\u5f91\u540d\u7a31\u8f09\u5165\u539f\u751f\u4ee3\u7406\u7a0b\u5f0f\n\ -javaagent:<jarpath>[=<options>]\n\ \u8f09\u5165 Java \u7a0b\u5f0f\u8a2d\u8a08\u8a9e\u8a00\u4ee3\u7406\u7a0b\u5f0f\uff0c\u8acb\u53c3\u95b1 java.lang.instrument\n\ -splash:<imagepath>\n\ \u986f\u793a\u542b\u6709\u6307\u5b9a\u5f71\u50cf\u7684\u8edf\u9ad4\u8cc7\u8a0a\u756b\u9762\n\u8acb\u53c3\u95b1 http://java.sun.com/javase/reference\uff0c\u4ee5\u53d6\u5f97\u66f4\u591a\u8a73\u7d30\u8cc7\u8a0a\u3002 +java.launcher.opt.footer =\ -cp <\u76ee\u9304\u548c zip/jar \u6a94\u6848\u7684\u985e\u5225\u641c\u5c0b\u8def\u5f91>\n\ -classpath <\u76ee\u9304\u548c zip/jar \u6a94\u6848\u7684\u985e\u5225\u641c\u5c0b\u8def\u5f91>\n\ {0} \u76ee\u9304\u3001JAR \u6b78\u6a94\n\ \u548c ZIP \u6b78\u6a94\u7684\u5206\u9694\u6e05\u55ae\uff0c\u7528\u65bc\u641c\u5c0b\u985e\u5225\u6a94\u6848\u3002\n\ -D<name>=<value>\n\ \u8a2d\u5b9a\u7cfb\u7d71\u7279\u6027\n\ -verbose[:class|gc|jni]\n\ \u555f\u7528\u8a73\u7d30\u8f38\u51fa\n\ -version \u5217\u5370\u7522\u54c1\u7248\u672c\u4e26\u7d50\u675f\n\ -version:<value>\n\ \u9700\u8981\u57f7\u884c\u6307\u5b9a\u7684\u7248\u672c\n\ -showversion \u5217\u5370\u7522\u54c1\u7248\u672c\u4e26\u7e7c\u7e8c\n\ -jre-restrict-search | -no-jre-restrict-search\n\ \u5728\u7248\u672c\u641c\u5c0b\u4e2d\u5305\u542b/\u6392\u9664\u4f7f\u7528\u8005\u79c1\u7528 JRE\n\ -? -help \u5217\u5370\u6b64\u8aaa\u660e\u8a0a\u606f\n\ -X \u5217\u5370\u6709\u95dc\u975e\u6a19\u6e96\u9078\u9805\u7684\u8aaa\u660e\n\ -ea[:<packagename>...|:<classname>]\n\ -enableassertions[:<packagename>...|:<classname>]\n\ \u555f\u7528\u5177\u6709\u6307\u5b9a\u9846\u7c92\u6027\u7684\u5ba3\u544a\n\ -da[:<packagename>...|:<classname>]\n\ -disableassertions[:<packagename>...|:<classname>]\n\ \u505c\u7528\u5177\u6709\u6307\u5b9a\u9846\u7c92\u6027\u7684\u5ba3\u544a\n\ -esa | -enablesystemassertions\n\ \u555f\u7528\u7cfb\u7d71\u5ba3\u544a\n\ -dsa | -disablesystemassertions\n\ \u505c\u7528\u7cfb\u7d71\u5ba3\u544a\n\ -agentlib:<libname>[=<options>]\n\ \u8f09\u5165\u539f\u751f\u4ee3\u7406\u7a0b\u5f0f\u7a0b\u5f0f\u5eab <libname>\uff0c\u4f8b\u5982 -agentlib:hprof\n\ \u53e6\u8acb\u53c3\u95b1 -agentlib:jdwp=help \u548c -agentlib:hprof=help\n\ -agentpath:<pathname>[=<options>]\n\ \u4f9d\u64da\u5b8c\u6574\u8def\u5f91\u540d\u7a31\u8f09\u5165\u539f\u751f\u4ee3\u7406\u7a0b\u5f0f\n\ -javaagent:<jarpath>[=<options>]\n\ \u8f09\u5165 Java \u7a0b\u5f0f\u8a2d\u8a08\u8a9e\u8a00\u4ee3\u7406\u7a0b\u5f0f\uff0c\u8acb\u53c3\u95b1 java.lang.instrument\n\ -splash:<imagepath>\n\ \u986f\u793a\u542b\u6709\u6307\u5b9a\u5f71\u50cf\u7684\u8edf\u9ad4\u8cc7\u8a0a\u756b\u9762\n\u8acb\u53c3\u95b1 http://java.sun.com/javase/reference\uff0c\u4ee5\u53d6\u5f97\u66f4\u591a\u8a73\u7d30\u8cc7\u8a0a\u3002 # Translators please note do not translate the options themselves java.launcher.X.usage=\ -Xmixed \u57f7\u884c\u6df7\u5408\u6a21\u5f0f (\u9810\u8a2d)\n\ -Xint \u50c5\u57f7\u884c\u89e3\u8b6f\u6a21\u5f0f\n\ -Xbootclasspath:<\u4ee5 {0} \u5206\u9694\u7684\u76ee\u9304\u548c zip/jar \u6a94\u6848>\n\ \u8a2d\u5b9a\u555f\u52d5\u985e\u5225\u548c\u8cc7\u6e90\u7684\u641c\u5c0b\u8def\u5f91\n\ -Xbootclasspath/a:<\u4ee5 {0} \u5206\u9694\u7684\u76ee\u9304\u548c zip/jar \u6a94\u6848>\n\ \u9644\u52a0\u81f3\u555f\u52d5\u985e\u5225\u7684\u672b\u5c3e\n\ -Xbootclasspath/p:<\u4ee5 {0} \u5206\u9694\u7684\u76ee\u9304\u548c zip/jar \u6a94\u6848>\n\ \u524d\u7f6e\u65bc\u555f\u52d5\u985e\u5225\u8def\u5f91\u7684\u524d\u9762\n\ -Xnoclassgc \u505c\u7528\u985e\u5225\u56de\u6536\u6536\u96c6\n\ -Xincgc \u555f\u7528\u905e\u589e\u56de\u6536\u6536\u96c6\n\ -Xloggc:<\u6a94\u6848> \u4f7f\u7528\u6642\u9593\u6233\u8a18\u5c07 GC \u72c0\u614b\u8a18\u9304\u81f3\u6a94\u6848\n\ -Xbatch \u505c\u7528\u80cc\u5f71\u7de8\u8b6f\n\ -Xms<\u5927\u5c0f> \u8a2d\u5b9a\u521d\u59cb Java \u5806\u758a\u5927\u5c0f\n\ -Xmx<\u5927\u5c0f> \u8a2d\u5b9a\u6700\u5927 Java \u5806\u758a\u5927\u5c0f\n\ -Xss<\u5927\u5c0f> \u8a2d\u5b9a java \u57f7\u884c\u7dd2\u5806\u758a\u5927\u5c0f\n\ -Xprof \u8f38\u51fa cpu \u8a2d\u5b9a\u6a94\u8cc7\u6599\n\ -Xfuture \u555f\u7528\u6700\u56b4\u683c\u7684\u6aa2\u67e5\uff0c\u9810\u671f\u672a\u4f86\u9810\u8a2d\u503c\n\ -Xrs \u964d\u4f4e Java/VM \u7684 OS \u8a0a\u865f\u4f7f\u7528 (\u8acb\u53c3\u95b1\u6587\u4ef6)\n\ -Xcheck:jni \u5c0d JNI \u529f\u80fd\u57f7\u884c\u5176\u4ed6\u6aa2\u67e5\n\ -Xshare:off \u4e0d\u5617\u8a66\u4f7f\u7528\u5171\u7528\u985e\u5225\u8cc7\u6599\n\ -Xshare:auto \u5982\u53ef\u80fd\uff0c\u4f7f\u7528\u5171\u7528\u985e\u5225\u8cc7\u6599 (\u9810\u8a2d)\n\ -Xshare:on \u9700\u8981\u4f7f\u7528\u5171\u7528\u985e\u5225\u8cc7\u6599\uff0c\u5426\u5247\u6703\u5931\u6557\u3002\n\n-X \u9078\u9805\u70ba\u975e\u6a19\u6e96\u9078\u9805\uff0c\u53ef\u80fd\u6703\u8b8a\u66f4\uff0c\u6055\u4e0d\u53e6\u884c\u901a\u77e5\u3002\n
--- a/src/share/classes/sun/misc/BootClassLoaderHook.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/sun/misc/BootClassLoaderHook.java Mon Oct 18 21:50:02 2010 -0700 @@ -27,6 +27,8 @@ import java.io.File; import java.io.IOException; +import java.net.URLStreamHandlerFactory; +import sun.misc.URLClassPath; /** * BootClassLoaderHook defines an interface for a hook to inject @@ -94,20 +96,6 @@ } } - private static final File[] EMPTY_FILE_ARRAY = new File[0]; - - /** - * Returns bootstrap class paths added by the hook. - */ - public static File[] getBootstrapPaths() { - BootClassLoaderHook hook = getHook(); - if (hook != null) { - return hook.getAdditionalBootstrapPaths(); - } else { - return EMPTY_FILE_ARRAY; - } - } - /** * Returns a pathname of a JAR or class that the hook loads * per this loadClass request; or null. @@ -133,10 +121,13 @@ public abstract boolean loadLibrary(String libname); /** - * Returns additional boot class paths added by the hook that - * should be searched by the boot class loader. + * Returns a bootstrap class path constructed by the hook. + * + * @param bcp VM's bootstrap class path + * @param factory Launcher's URL stream handler */ - public abstract File[] getAdditionalBootstrapPaths(); + public abstract URLClassPath getBootstrapClassPath(URLClassPath bcp, + URLStreamHandlerFactory factory); /** * Returns true if the current thread is in the process of doing
--- a/src/share/classes/sun/misc/Launcher.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/sun/misc/Launcher.java Mon Oct 18 21:50:02 2010 -0700 @@ -47,7 +47,6 @@ import java.security.Permission; import java.security.ProtectionDomain; import java.security.CodeSource; -import sun.security.action.GetPropertyAction; import sun.security.util.SecurityConstants; import sun.net.www.ParseUtil; @@ -57,6 +56,8 @@ public class Launcher { private static URLStreamHandlerFactory factory = new Factory(); private static Launcher launcher = new Launcher(); + private static String bootClassPath = + System.getProperty("sun.boot.class.path"); public static Launcher getLauncher() { return launcher; @@ -227,7 +228,8 @@ File dir = new File(urls[i].getPath()).getParentFile(); if (dir != null && !dir.equals(prevDir)) { // Look in architecture-specific subdirectory first - String arch = System.getProperty("os.arch"); + // Read from the saved system properties to avoid deadlock + String arch = VM.getSavedProperty("os.arch"); if (arch != null) { File file = new File(new File(dir, arch), name); if (file.exists()) { @@ -377,19 +379,15 @@ } } - private static URLClassPath bootstrapClassPath; - - public static synchronized URLClassPath getBootstrapClassPath() { - if (bootstrapClassPath == null) { - String prop = AccessController.doPrivileged( - new GetPropertyAction("sun.boot.class.path")); + private static class BootClassPathHolder { + static final URLClassPath bcp; + static { URL[] urls; - if (prop != null) { - final String path = prop; + if (bootClassPath != null) { urls = AccessController.doPrivileged( new PrivilegedAction<URL[]>() { public URL[] run() { - File[] classPath = getClassPath(path); + File[] classPath = getClassPath(bootClassPath); int len = classPath.length; Set<File> seenDirs = new HashSet<File>(); for (int i = 0; i < len; i++) { @@ -410,25 +408,16 @@ } else { urls = new URL[0]; } - - bootstrapClassPath = new URLClassPath(urls, factory); - final File[] additionalBootStrapPaths = - BootClassLoaderHook.getBootstrapPaths(); - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - for (int i=0; i<additionalBootStrapPaths.length; i++) { - bootstrapClassPath.addURL( - getFileURL(additionalBootStrapPaths[i])); - } - return null; - } - }); + bcp = new URLClassPath(urls, factory); } - return bootstrapClassPath; } - public static synchronized void flushBootstrapClassPath() { - bootstrapClassPath = null; + public static URLClassPath getBootstrapClassPath() { + URLClassPath bcp = BootClassPathHolder.bcp; + // if DownloadManager is installed, return the bootstrap class path + // maintained by the Java kernel + BootClassLoaderHook hook = BootClassLoaderHook.getHook(); + return hook == null ? bcp : hook.getBootstrapClassPath(bcp, factory); } private static URL[] pathToURLs(File[] path) {
--- a/src/share/classes/sun/misc/VM.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/sun/misc/VM.java Mon Oct 18 21:50:02 2010 -0700 @@ -170,34 +170,23 @@ // private static long directMemory = 64 * 1024 * 1024; - // If this method is invoked during VM initialization, it initializes the - // maximum amount of allocatable direct buffer memory (in bytes) from the - // system property sun.nio.MaxDirectMemorySize. The system property will - // be removed when it is accessed. - // - // If this method is invoked after the VM is booted, it returns the - // maximum amount of allocatable direct buffer memory. + // Returns the maximum amount of allocatable direct buffer memory. + // The directMemory variable is initialized during system initialization + // in the saveAndRemoveProperties method. // public static long maxDirectMemory() { - if (booted) - return directMemory; - - Properties p = System.getProperties(); - String s = (String)p.remove("sun.nio.MaxDirectMemorySize"); - System.setProperties(p); + return directMemory; + } - if (s != null) { - if (s.equals("-1")) { - // -XX:MaxDirectMemorySize not given, take default - directMemory = Runtime.getRuntime().maxMemory(); - } else { - long l = Long.parseLong(s); - if (l > -1) - directMemory = l; - } - } + // User-controllable flag that determines if direct buffers should be page + // aligned. The "-XX:+PageAlignDirectMemory" option can be used to force + // buffers, allocated by ByteBuffer.allocateDirect, to be page aligned. + private static boolean pageAlignDirectMemory; - return directMemory; + // Returns {@code true} if the direct buffers should be page aligned. This + // variable is initialized by saveAndRemoveProperties. + public static boolean isDirectMemoryPageAligned() { + return pageAlignDirectMemory; } // A user-settable boolean to determine whether ClassLoader.loadClass should @@ -212,26 +201,87 @@ private static boolean defaultAllowArraySyntax = false; private static boolean allowArraySyntax = defaultAllowArraySyntax; - // If this method is invoked during VM initialization, it initializes the - // allowArraySyntax boolean based on the value of the system property + // The allowArraySyntax boolean is initialized during system initialization + // in the saveAndRemoveProperties method. + // + // It is initialized based on the value of the system property // "sun.lang.ClassLoader.allowArraySyntax". If the system property is not // provided, the default for 1.5 is "true". In 1.6, the default will be // "false". If the system property is provided, then the value of // allowArraySyntax will be equal to "true" if Boolean.parseBoolean() // returns "true". Otherwise, the field will be set to "false". // - // If this method is invoked after the VM is booted, it returns the - // allowArraySyntax boolean set during initialization. + public static boolean allowArraySyntax() { + return allowArraySyntax; + } + + /** + * Returns the system property of the specified key saved at + * system initialization time. This method should only be used + * for the system properties that are not changed during runtime. + * It accesses a private copy of the system properties so + * that user's locking of the system properties object will not + * cause the library to deadlock. + * + * Note that the saved system properties do not include + * the ones set by sun.misc.Version.init(). + * + */ + public static String getSavedProperty(String key) { + if (savedProps.isEmpty()) + throw new IllegalStateException("Should be non-empty if initialized"); + + return savedProps.getProperty(key); + } + + private static final Properties savedProps = new Properties(); + + // Save a private copy of the system properties and remove + // the system properties that are not intended for public access. // - public static boolean allowArraySyntax() { - if (!booted) { - String s - = System.getProperty("sun.lang.ClassLoader.allowArraySyntax"); - allowArraySyntax = (s == null - ? defaultAllowArraySyntax - : Boolean.parseBoolean(s)); + // This method can only be invoked during system initialization. + public static void saveAndRemoveProperties(Properties props) { + if (booted) + throw new IllegalStateException("System initialization has completed"); + + savedProps.putAll(props); + + // Set the maximum amount of direct memory. This value is controlled + // by the vm option -XX:MaxDirectMemorySize=<size>. + // The maximum amount of allocatable direct buffer memory (in bytes) + // from the system property sun.nio.MaxDirectMemorySize set by the VM. + // The system property will be removed. + String s = (String)props.remove("sun.nio.MaxDirectMemorySize"); + if (s != null) { + if (s.equals("-1")) { + // -XX:MaxDirectMemorySize not given, take default + directMemory = Runtime.getRuntime().maxMemory(); + } else { + long l = Long.parseLong(s); + if (l > -1) + directMemory = l; + } } - return allowArraySyntax; + + // Check if direct buffers should be page aligned + s = (String)props.remove("sun.nio.PageAlignDirectMemory"); + if ("true".equals(s)) + pageAlignDirectMemory = true; + + // Set a boolean to determine whether ClassLoader.loadClass accepts + // array syntax. This value is controlled by the system property + // "sun.lang.ClassLoader.allowArraySyntax". + s = props.getProperty("sun.lang.ClassLoader.allowArraySyntax"); + allowArraySyntax = (s == null + ? defaultAllowArraySyntax + : Boolean.parseBoolean(s)); + + // Remove other private system properties + // used by java.lang.Integer.IntegerCache + props.remove("java.lang.Integer.IntegerCache.high"); + + // used by java.util.zip.ZipFile + props.remove("sun.zip.disableMemoryMapping"); } // Initialize any miscellenous operating system settings that need to be
--- a/src/share/classes/sun/net/www/MessageHeader.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/sun/net/www/MessageHeader.java Mon Oct 18 21:50:02 2010 -0700 @@ -196,6 +196,10 @@ } public synchronized Map<String, List<String>> getHeaders(String[] excludeList) { + return filterAndAddHeaders(excludeList, null); + } + + public synchronized Map<String, List<String>> filterAndAddHeaders(String[] excludeList, Map<String, List<String>> include) { boolean skipIt = false; Map<String, List<String>> m = new HashMap<String, List<String>>(); for (int i = nkeys; --i >= 0;) { @@ -223,6 +227,19 @@ } } + if (include != null) { + Iterator entries = include.entrySet().iterator(); + while (entries.hasNext()) { + Map.Entry entry = (Map.Entry)entries.next(); + List l = (List)m.get(entry.getKey()); + if (l == null) { + l = new ArrayList(); + m.put((String)entry.getKey(), l); + } + l.add(entry.getValue()); + } + } + for (String key : m.keySet()) { m.put(key, Collections.unmodifiableList(m.get(key))); }
--- a/src/share/classes/sun/net/www/MimeTable.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/sun/net/www/MimeTable.java Mon Oct 18 21:50:02 2010 -0700 @@ -73,29 +73,32 @@ private static final String filePreamble = "sun.net.www MIME content-types table"; private static final String fileMagic = "#" + filePreamble; - private static MimeTable defaultInstance = null; MimeTable() { load(); } + private static class DefaultInstanceHolder { + static final MimeTable defaultInstance = getDefaultInstance(); + + static MimeTable getDefaultInstance() { + return java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction<MimeTable>() { + public MimeTable run() { + MimeTable instance = new MimeTable(); + URLConnection.setFileNameMap(instance); + return instance; + } + }); + } + } + /** * Get the single instance of this class. First use will load the * table from a data file. */ public static MimeTable getDefaultTable() { - if (defaultInstance == null) { - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<Void>() { - public Void run() { - defaultInstance = new MimeTable(); - URLConnection.setFileNameMap(defaultInstance); - return null; - } - }); - } - - return defaultInstance; + return DefaultInstanceHolder.defaultInstance; } /**
--- a/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java Mon Oct 18 21:50:02 2010 -0700 @@ -51,6 +51,9 @@ import java.util.Locale; import java.util.StringTokenizer; import java.util.Iterator; +import java.util.HashSet; +import java.util.HashMap; +import java.util.Set; import sun.net.*; import sun.net.www.*; import sun.net.www.http.HttpClient; @@ -140,6 +143,54 @@ */ private static int bufSize4ES = 0; + /* + * Restrict setting of request headers through the public api + * consistent with JavaScript XMLHttpRequest2 with a few + * exceptions. Disallowed headers are silently ignored for + * backwards compatibility reasons rather than throwing a + * SecurityException. For example, some applets set the + * Host header since old JREs did not implement HTTP 1.1. + * Additionally, any header starting with Sec- is + * disallowed. + * + * The following headers are allowed for historical reasons: + * + * Accept-Charset, Accept-Encoding, Cookie, Cookie2, Date, + * Referer, TE, User-Agent, headers beginning with Proxy-. + * + * The following headers are allowed in a limited form: + * + * Connection: close + * + * See http://www.w3.org/TR/XMLHttpRequest2. + */ + private static final boolean allowRestrictedHeaders; + private static final Set<String> restrictedHeaderSet; + private static final String[] restrictedHeaders = { + /* Restricted by XMLHttpRequest2 */ + //"Accept-Charset", + //"Accept-Encoding", + "Access-Control-Request-Headers", + "Access-Control-Request-Method", + "Connection", /* close is allowed */ + "Content-Length", + //"Cookie", + //"Cookie2", + "Content-Transfer-Encoding", + //"Date", + //"Expect", + "Host", + "Keep-Alive", + "Origin", + // "Referer", + // "TE", + "Trailer", + "Transfer-Encoding", + "Upgrade", + //"User-Agent", + "Via" + }; + static { maxRedirects = java.security.AccessController.doPrivileged( new sun.security.action.GetIntegerAction( @@ -178,7 +229,17 @@ bufSize4ES = 4096; // use the default } - + allowRestrictedHeaders = ((Boolean)java.security.AccessController.doPrivileged( + new sun.security.action.GetBooleanAction( + "sun.net.http.allowRestrictedHeaders"))).booleanValue(); + if (!allowRestrictedHeaders) { + restrictedHeaderSet = new HashSet<String>(restrictedHeaders.length); + for (int i=0; i < restrictedHeaders.length; i++) { + restrictedHeaderSet.add(restrictedHeaders[i].toLowerCase()); + } + } else { + restrictedHeaderSet = null; + } } static final String httpVersion = "HTTP/1.1"; @@ -191,6 +252,15 @@ "Proxy-Authorization", "Authorization" }; + + // also exclude system cookies when any might be set + private static final String[] EXCLUDE_HEADERS2= { + "Proxy-Authorization", + "Authorization", + "Cookie", + "Cookie2" + }; + protected HttpClient http; protected Handler handler; protected Proxy instProxy; @@ -213,6 +283,7 @@ /* User set Cookies */ private boolean setUserCookies = true; private String userCookies = null; + private String userCookies2 = null; /* We only have a single static authenticator for now. * REMIND: backwards compatibility with JDK 1.1. Should be @@ -329,6 +400,41 @@ }); } + private boolean isRestrictedHeader(String key, String value) { + if (allowRestrictedHeaders) { + return false; + } + + key = key.toLowerCase(); + if (restrictedHeaderSet.contains(key)) { + /* + * Exceptions to restricted headers: + * + * Allow "Connection: close". + */ + if (key.equals("connection") && value.equalsIgnoreCase("close")) { + return false; + } + return true; + } else if (key.startsWith("sec-")) { + return true; + } + return false; + } + + /* + * Checks the validity of http message header and whether the header + * is restricted and throws IllegalArgumentException if invalid or + * restricted. + */ + private boolean isExternalMessageHeaderAllowed(String key, String value) { + checkMessageHeader(key, value); + if (!isRestrictedHeader(key, value)) { + return true; + } + return false; + } + /* Logging support */ public static PlatformLogger getHttpLogger() { return logger; @@ -463,9 +569,12 @@ "application/x-www-form-urlencoded"); } + boolean chunked = false; + if (streaming()) { if (chunkLength != -1) { requests.set ("Transfer-Encoding", "chunked"); + chunked = true; } else { /* fixed content length */ if (fixedContentLengthLong != -1) { requests.set ("Content-Length", @@ -485,6 +594,16 @@ } } + if (!chunked) { + if (requests.findValue("Transfer-Encoding") != null) { + requests.remove("Transfer-Encoding"); + if (logger.isLoggable(PlatformLogger.WARNING)) { + logger.warning( + "use streaming mode for chunked encoding"); + } + } + } + // get applicable cookies based on the uri and request headers // add them to the existing request headers setCookieHeader(); @@ -1034,15 +1153,21 @@ // we only want to capture the user defined Cookies once, as // they cannot be changed by user code after we are connected, // only internally. - if (setUserCookies) { - int k = requests.getKey("Cookie"); - if ( k != -1) - userCookies = requests.getValue(k); - setUserCookies = false; + synchronized (this) { + if (setUserCookies) { + int k = requests.getKey("Cookie"); + if (k != -1) + userCookies = requests.getValue(k); + k = requests.getKey("Cookie2"); + if (k != -1) + userCookies2 = requests.getValue(k); + setUserCookies = false; + } } // remove old Cookie header before setting new one. requests.remove("Cookie"); + requests.remove("Cookie2"); URI uri = ParseUtil.toURI(url); if (uri != null) { @@ -1088,6 +1213,13 @@ else requests.set("Cookie", userCookies); } + if (userCookies2 != null) { + int k; + if ((k = requests.getKey("Cookie2")) != -1) + requests.set("Cookie2", requests.getValue(k) + ";" + userCookies2); + else + requests.set("Cookie2", userCookies2); + } } // end of getting cookies } @@ -2530,8 +2662,9 @@ if (key == null) throw new NullPointerException ("key is null"); - checkMessageHeader(key, value); - requests.set(key, value); + if (isExternalMessageHeaderAllowed(key, value)) { + requests.set(key, value); + } } /** @@ -2552,8 +2685,9 @@ if (key == null) throw new NullPointerException ("key is null"); - checkMessageHeader(key, value); - requests.add(key, value); + if (isExternalMessageHeaderAllowed(key, value)) { + requests.add(key, value); + } } // @@ -2566,13 +2700,23 @@ } @Override - public String getRequestProperty (String key) { + public synchronized String getRequestProperty (String key) { + if (key == null) { + return null; + } + // don't return headers containing security sensitive information - if (key != null) { - for (int i=0; i < EXCLUDE_HEADERS.length; i++) { - if (key.equalsIgnoreCase(EXCLUDE_HEADERS[i])) { - return null; - } + for (int i=0; i < EXCLUDE_HEADERS.length; i++) { + if (key.equalsIgnoreCase(EXCLUDE_HEADERS[i])) { + return null; + } + } + if (!setUserCookies) { + if (key.equalsIgnoreCase("Cookie")) { + return userCookies; + } + if (key.equalsIgnoreCase("Cookie2")) { + return userCookies2; } } return requests.findValue(key); @@ -2591,12 +2735,29 @@ * @since 1.4 */ @Override - public Map<String, List<String>> getRequestProperties() { + public synchronized Map<String, List<String>> getRequestProperties() { if (connected) throw new IllegalStateException("Already connected"); // exclude headers containing security-sensitive info - return requests.getHeaders(EXCLUDE_HEADERS); + if (setUserCookies) { + return requests.getHeaders(EXCLUDE_HEADERS); + } + /* + * The cookies in the requests message headers may have + * been modified. Use the saved user cookies instead. + */ + Map userCookiesMap = null; + if (userCookies != null || userCookies2 != null) { + userCookiesMap = new HashMap(); + if (userCookies != null) { + userCookiesMap.put("Cookie", userCookies); + } + if (userCookies2 != null) { + userCookiesMap.put("Cookie2", userCookies2); + } + } + return requests.filterAndAddHeaders(EXCLUDE_HEADERS2, userCookiesMap); } @Override
--- a/src/share/classes/sun/security/jca/Providers.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/sun/security/jca/Providers.java Mon Oct 18 21:50:02 2010 -0700 @@ -159,15 +159,18 @@ * could not be loaded) removed. This is the list we need to * present to applications. */ - public static synchronized ProviderList getFullProviderList() { - ProviderList list = getThreadProviderList(); - if (list != null) { - ProviderList newList = list.removeInvalid(); - if (newList != list) { - changeThreadProviderList(newList); - list = newList; + public static ProviderList getFullProviderList() { + ProviderList list; + synchronized (Providers.class) { + list = getThreadProviderList(); + if (list != null) { + ProviderList newList = list.removeInvalid(); + if (newList != list) { + changeThreadProviderList(newList); + list = newList; + } + return list; } - return list; } list = getSystemProviderList(); ProviderList newList = list.removeInvalid();
--- a/src/share/classes/sun/security/jgss/krb5/InitialToken.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/sun/security/jgss/krb5/InitialToken.java Mon Oct 18 21:50:02 2010 -0700 @@ -35,7 +35,6 @@ import java.security.NoSuchAlgorithmException; import java.util.Arrays; import sun.security.krb5.*; -import sun.security.jgss.HttpCaller; import sun.security.krb5.internal.Krb5; abstract class InitialToken extends Krb5Token { @@ -217,6 +216,12 @@ int pos = 0; + if (checksum == null) { + GSSException ge = new GSSException(GSSException.FAILURE, -1, + "No cksum in AP_REQ's authenticator"); + ge.initCause(new KrbException(Krb5.KRB_AP_ERR_INAPP_CKSUM)); + throw ge; + } checksumBytes = checksum.getBytes(); if ((checksumBytes[0] != CHECKSUM_FIRST_BYTES[0]) ||
--- a/src/share/classes/sun/security/ssl/Alerts.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/sun/security/ssl/Alerts.java Mon Oct 18 21:50:02 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2010, 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 @@ -74,7 +74,7 @@ static final byte alert_insufficient_security = 71; static final byte alert_internal_error = 80; static final byte alert_user_canceled = 90; - static final byte alert_no_negotiation = 100; + static final byte alert_no_renegotiation = 100; // from RFC 3546 (TLS Extensions) static final byte alert_unsupported_extension = 110; @@ -132,8 +132,8 @@ return "internal_error"; case alert_user_canceled: return "user_canceled"; - case alert_no_negotiation: - return "no_negotiation"; + case alert_no_renegotiation: + return "no_renegotiation"; case alert_unsupported_extension: return "unsupported_extension"; case alert_certificate_unobtainable: @@ -203,7 +203,7 @@ case alert_protocol_version: case alert_internal_error: case alert_user_canceled: - case alert_no_negotiation: + case alert_no_renegotiation: default: e = new SSLException(reason); break;
--- a/src/share/classes/sun/security/ssl/CipherSuite.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/sun/security/ssl/CipherSuite.java Mon Oct 18 21:50:02 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2010, 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 @@ -126,6 +126,8 @@ macAlg = M_SHA; } else if (name.endsWith("_NULL")) { macAlg = M_NULL; + } else if (name.endsWith("_SCSV")) { + macAlg = M_NULL; } else { throw new IllegalArgumentException ("Unknown MAC algorithm for ciphersuite " + name); @@ -160,6 +162,10 @@ return allowed && keyExchange.isAvailable() && cipher.isAvailable(); } + boolean isNegotiable() { + return this != C_SCSV && isAvailable(); + } + /** * Compares CipherSuites based on their priority. Has the effect of * sorting CipherSuites when put in a sorted collection, which is @@ -268,7 +274,10 @@ // Kerberos cipher suites K_KRB5 ("KRB5", true), - K_KRB5_EXPORT("KRB5_EXPORT", true); + K_KRB5_EXPORT("KRB5_EXPORT", true), + + // renegotiation protection request signaling cipher suite + K_SCSV ("SCSV", true); // name of the key exchange algorithm, e.g. DHE_DSS final String name; @@ -352,7 +361,8 @@ this.exportable = true; } - BulkCipher(String transformation, int keySize, int ivSize, boolean allowed) { + BulkCipher(String transformation, int keySize, + int ivSize, boolean allowed) { this.transformation = transformation; this.algorithm = transformation.split("/")[0]; this.description = this.algorithm + "/" + (keySize << 3); @@ -370,7 +380,8 @@ * * @exception NoSuchAlgorithmException if anything goes wrong */ - CipherBox newCipher(ProtocolVersion version, SecretKey key, IvParameterSpec iv, + CipherBox newCipher(ProtocolVersion version, + SecretKey key, IvParameterSpec iv, boolean encrypt) throws NoSuchAlgorithmException { return CipherBox.newCipherBox(version, this, key, iv, encrypt); } @@ -407,8 +418,9 @@ if (b == null) { try { SecretKey key = new SecretKeySpec - (new byte[cipher.expandedKeySize], cipher.algorithm); - IvParameterSpec iv = new IvParameterSpec(new byte[cipher.ivSize]); + (new byte[cipher.expandedKeySize], cipher.algorithm); + IvParameterSpec iv = + new IvParameterSpec(new byte[cipher.ivSize]); cipher.newCipher(ProtocolVersion.DEFAULT, key, iv, true); b = Boolean.TRUE; } catch (NoSuchAlgorithmException e) { @@ -460,18 +472,28 @@ } // export strength ciphers - final static BulkCipher B_NULL = new BulkCipher("NULL", 0, 0, 0, true); - final static BulkCipher B_RC4_40 = new BulkCipher(CIPHER_RC4, 5, 16, 0, true); - final static BulkCipher B_RC2_40 = new BulkCipher("RC2", 5, 16, 8, false); - final static BulkCipher B_DES_40 = new BulkCipher(CIPHER_DES, 5, 8, 8, true); + final static BulkCipher B_NULL = + new BulkCipher("NULL", 0, 0, 0, true); + final static BulkCipher B_RC4_40 = + new BulkCipher(CIPHER_RC4, 5, 16, 0, true); + final static BulkCipher B_RC2_40 = + new BulkCipher("RC2", 5, 16, 8, false); + final static BulkCipher B_DES_40 = + new BulkCipher(CIPHER_DES, 5, 8, 8, true); // domestic strength ciphers - final static BulkCipher B_RC4_128 = new BulkCipher(CIPHER_RC4, 16, 0, true); - final static BulkCipher B_DES = new BulkCipher(CIPHER_DES, 8, 8, true); - final static BulkCipher B_3DES = new BulkCipher(CIPHER_3DES, 24, 8, true); - final static BulkCipher B_IDEA = new BulkCipher("IDEA", 16, 8, false); - final static BulkCipher B_AES_128 = new BulkCipher(CIPHER_AES, 16, 16, true); - final static BulkCipher B_AES_256 = new BulkCipher(CIPHER_AES, 32, 16, true); + final static BulkCipher B_RC4_128 = + new BulkCipher(CIPHER_RC4, 16, 0, true); + final static BulkCipher B_DES = + new BulkCipher(CIPHER_DES, 8, 8, true); + final static BulkCipher B_3DES = + new BulkCipher(CIPHER_3DES, 24, 8, true); + final static BulkCipher B_IDEA = + new BulkCipher("IDEA", 16, 8, false); + final static BulkCipher B_AES_128 = + new BulkCipher(CIPHER_AES, 16, 16, true); + final static BulkCipher B_AES_256 = + new BulkCipher(CIPHER_AES, 32, 16, true); // MACs final static MacAlg M_NULL = new MacAlg("NULL", 0); @@ -487,93 +509,159 @@ // N: ciphersuites only allowed if we are not in FIPS mode final boolean N = (SunJSSE.isFIPS() == false); -add("SSL_NULL_WITH_NULL_NULL", 0x0000, 1, K_NULL, B_NULL, F); + add("SSL_NULL_WITH_NULL_NULL", + 0x0000, 1, K_NULL, B_NULL, F); // Definition of the CipherSuites that are enabled by default. // They are listed in preference order, most preferred first. int p = DEFAULT_SUITES_PRIORITY * 2; -add("SSL_RSA_WITH_RC4_128_MD5", 0x0004, --p, K_RSA, B_RC4_128, N); -add("SSL_RSA_WITH_RC4_128_SHA", 0x0005, --p, K_RSA, B_RC4_128, N); -add("TLS_RSA_WITH_AES_128_CBC_SHA", 0x002f, --p, K_RSA, B_AES_128, T); -add("TLS_RSA_WITH_AES_256_CBC_SHA", 0x0035, --p, K_RSA, B_AES_256, T); + add("SSL_RSA_WITH_RC4_128_MD5", + 0x0004, --p, K_RSA, B_RC4_128, N); + add("SSL_RSA_WITH_RC4_128_SHA", + 0x0005, --p, K_RSA, B_RC4_128, N); + add("TLS_RSA_WITH_AES_128_CBC_SHA", + 0x002f, --p, K_RSA, B_AES_128, T); + add("TLS_RSA_WITH_AES_256_CBC_SHA", + 0x0035, --p, K_RSA, B_AES_256, T); -add("TLS_ECDH_ECDSA_WITH_RC4_128_SHA", 0xC002, --p, K_ECDH_ECDSA, B_RC4_128, N); -add("TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA", 0xC004, --p, K_ECDH_ECDSA, B_AES_128, T); -add("TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA", 0xC005, --p, K_ECDH_ECDSA, B_AES_256, T); -add("TLS_ECDH_RSA_WITH_RC4_128_SHA", 0xC00C, --p, K_ECDH_RSA, B_RC4_128, N); -add("TLS_ECDH_RSA_WITH_AES_128_CBC_SHA", 0xC00E, --p, K_ECDH_RSA, B_AES_128, T); -add("TLS_ECDH_RSA_WITH_AES_256_CBC_SHA", 0xC00F, --p, K_ECDH_RSA, B_AES_256, T); + add("TLS_ECDH_ECDSA_WITH_RC4_128_SHA", + 0xC002, --p, K_ECDH_ECDSA, B_RC4_128, N); + add("TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA", + 0xC004, --p, K_ECDH_ECDSA, B_AES_128, T); + add("TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA", + 0xC005, --p, K_ECDH_ECDSA, B_AES_256, T); + add("TLS_ECDH_RSA_WITH_RC4_128_SHA", + 0xC00C, --p, K_ECDH_RSA, B_RC4_128, N); + add("TLS_ECDH_RSA_WITH_AES_128_CBC_SHA", + 0xC00E, --p, K_ECDH_RSA, B_AES_128, T); + add("TLS_ECDH_RSA_WITH_AES_256_CBC_SHA", + 0xC00F, --p, K_ECDH_RSA, B_AES_256, T); -add("TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", 0xC007, --p, K_ECDHE_ECDSA,B_RC4_128, N); -add("TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", 0xC009, --p, K_ECDHE_ECDSA,B_AES_128, T); -add("TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", 0xC00A, --p, K_ECDHE_ECDSA,B_AES_256, T); -add("TLS_ECDHE_RSA_WITH_RC4_128_SHA", 0xC011, --p, K_ECDHE_RSA, B_RC4_128, N); -add("TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", 0xC013, --p, K_ECDHE_RSA, B_AES_128, T); -add("TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", 0xC014, --p, K_ECDHE_RSA, B_AES_256, T); + add("TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", + 0xC007, --p, K_ECDHE_ECDSA,B_RC4_128, N); + add("TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", + 0xC009, --p, K_ECDHE_ECDSA,B_AES_128, T); + add("TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", + 0xC00A, --p, K_ECDHE_ECDSA,B_AES_256, T); + add("TLS_ECDHE_RSA_WITH_RC4_128_SHA", + 0xC011, --p, K_ECDHE_RSA, B_RC4_128, N); + add("TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", + 0xC013, --p, K_ECDHE_RSA, B_AES_128, T); + add("TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", + 0xC014, --p, K_ECDHE_RSA, B_AES_256, T); -add("TLS_DHE_RSA_WITH_AES_128_CBC_SHA", 0x0033, --p, K_DHE_RSA, B_AES_128, T); -add("TLS_DHE_RSA_WITH_AES_256_CBC_SHA", 0x0039, --p, K_DHE_RSA, B_AES_256, T); -add("TLS_DHE_DSS_WITH_AES_128_CBC_SHA", 0x0032, --p, K_DHE_DSS, B_AES_128, T); -add("TLS_DHE_DSS_WITH_AES_256_CBC_SHA", 0x0038, --p, K_DHE_DSS, B_AES_256, T); + add("TLS_DHE_RSA_WITH_AES_128_CBC_SHA", + 0x0033, --p, K_DHE_RSA, B_AES_128, T); + add("TLS_DHE_RSA_WITH_AES_256_CBC_SHA", + 0x0039, --p, K_DHE_RSA, B_AES_256, T); + add("TLS_DHE_DSS_WITH_AES_128_CBC_SHA", + 0x0032, --p, K_DHE_DSS, B_AES_128, T); + add("TLS_DHE_DSS_WITH_AES_256_CBC_SHA", + 0x0038, --p, K_DHE_DSS, B_AES_256, T); -add("SSL_RSA_WITH_3DES_EDE_CBC_SHA", 0x000a, --p, K_RSA, B_3DES, T); -add("TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA", 0xC003, --p, K_ECDH_ECDSA, B_3DES, T); -add("TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA", 0xC00D, --p, K_ECDH_RSA, B_3DES, T); -add("TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA", 0xC008, --p, K_ECDHE_ECDSA,B_3DES, T); -add("TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", 0xC012, --p, K_ECDHE_RSA, B_3DES, T); -add("SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA", 0x0016, --p, K_DHE_RSA, B_3DES, T); -add("SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA", 0x0013, --p, K_DHE_DSS, B_3DES, N); + add("SSL_RSA_WITH_3DES_EDE_CBC_SHA", + 0x000a, --p, K_RSA, B_3DES, T); + add("TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA", + 0xC003, --p, K_ECDH_ECDSA, B_3DES, T); + add("TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA", + 0xC00D, --p, K_ECDH_RSA, B_3DES, T); + add("TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA", + 0xC008, --p, K_ECDHE_ECDSA,B_3DES, T); + add("TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", + 0xC012, --p, K_ECDHE_RSA, B_3DES, T); + add("SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA", + 0x0016, --p, K_DHE_RSA, B_3DES, T); + add("SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA", + 0x0013, --p, K_DHE_DSS, B_3DES, N); -add("SSL_RSA_WITH_DES_CBC_SHA", 0x0009, --p, K_RSA, B_DES, N); -add("SSL_DHE_RSA_WITH_DES_CBC_SHA", 0x0015, --p, K_DHE_RSA, B_DES, N); -add("SSL_DHE_DSS_WITH_DES_CBC_SHA", 0x0012, --p, K_DHE_DSS, B_DES, N); -add("SSL_RSA_EXPORT_WITH_RC4_40_MD5", 0x0003, --p, K_RSA_EXPORT, B_RC4_40, N); -add("SSL_RSA_EXPORT_WITH_DES40_CBC_SHA", 0x0008, --p, K_RSA_EXPORT, B_DES_40, N); -add("SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA", 0x0014, --p, K_DHE_RSA, B_DES_40, N); -add("SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA", 0x0011, --p, K_DHE_DSS, B_DES_40, N); + add("SSL_RSA_WITH_DES_CBC_SHA", + 0x0009, --p, K_RSA, B_DES, N); + add("SSL_DHE_RSA_WITH_DES_CBC_SHA", + 0x0015, --p, K_DHE_RSA, B_DES, N); + add("SSL_DHE_DSS_WITH_DES_CBC_SHA", + 0x0012, --p, K_DHE_DSS, B_DES, N); + add("SSL_RSA_EXPORT_WITH_RC4_40_MD5", + 0x0003, --p, K_RSA_EXPORT, B_RC4_40, N); + add("SSL_RSA_EXPORT_WITH_DES40_CBC_SHA", + 0x0008, --p, K_RSA_EXPORT, B_DES_40, N); + add("SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA", + 0x0014, --p, K_DHE_RSA, B_DES_40, N); + add("SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA", + 0x0011, --p, K_DHE_DSS, B_DES_40, N); + + // Renegotiation protection request Signalling Cipher Suite Value (SCSV) + add("TLS_EMPTY_RENEGOTIATION_INFO_SCSV", + 0x00ff, --p, K_SCSV, B_NULL, T); // Definition of the CipherSuites that are supported but not enabled // by default. // They are listed in preference order, preferred first. p = DEFAULT_SUITES_PRIORITY; -// Anonymous key exchange and the NULL ciphers -add("SSL_RSA_WITH_NULL_MD5", 0x0001, --p, K_RSA, B_NULL, N); -add("SSL_RSA_WITH_NULL_SHA", 0x0002, --p, K_RSA, B_NULL, N); -add("TLS_ECDH_ECDSA_WITH_NULL_SHA", 0xC001, --p, K_ECDH_ECDSA, B_NULL, N); -add("TLS_ECDH_RSA_WITH_NULL_SHA", 0xC00B, --p, K_ECDH_RSA, B_NULL, N); -add("TLS_ECDHE_ECDSA_WITH_NULL_SHA", 0xC006, --p, K_ECDHE_ECDSA,B_NULL, N); -add("TLS_ECDHE_RSA_WITH_NULL_SHA", 0xC010, --p, K_ECDHE_RSA, B_NULL, N); + // Anonymous key exchange and the NULL ciphers + add("SSL_RSA_WITH_NULL_MD5", + 0x0001, --p, K_RSA, B_NULL, N); + add("SSL_RSA_WITH_NULL_SHA", + 0x0002, --p, K_RSA, B_NULL, N); + add("TLS_ECDH_ECDSA_WITH_NULL_SHA", + 0xC001, --p, K_ECDH_ECDSA, B_NULL, N); + add("TLS_ECDH_RSA_WITH_NULL_SHA", + 0xC00B, --p, K_ECDH_RSA, B_NULL, N); + add("TLS_ECDHE_ECDSA_WITH_NULL_SHA", + 0xC006, --p, K_ECDHE_ECDSA,B_NULL, N); + add("TLS_ECDHE_RSA_WITH_NULL_SHA", + 0xC010, --p, K_ECDHE_RSA, B_NULL, N); -add("SSL_DH_anon_WITH_RC4_128_MD5", 0x0018, --p, K_DH_ANON, B_RC4_128, N); -add("TLS_DH_anon_WITH_AES_128_CBC_SHA", 0x0034, --p, K_DH_ANON, B_AES_128, N); -add("TLS_DH_anon_WITH_AES_256_CBC_SHA", 0x003a, --p, K_DH_ANON, B_AES_256, N); -add("SSL_DH_anon_WITH_3DES_EDE_CBC_SHA", 0x001b, --p, K_DH_ANON, B_3DES, N); -add("SSL_DH_anon_WITH_DES_CBC_SHA", 0x001a, --p, K_DH_ANON, B_DES, N); + add("SSL_DH_anon_WITH_RC4_128_MD5", + 0x0018, --p, K_DH_ANON, B_RC4_128, N); + add("TLS_DH_anon_WITH_AES_128_CBC_SHA", + 0x0034, --p, K_DH_ANON, B_AES_128, N); + add("TLS_DH_anon_WITH_AES_256_CBC_SHA", + 0x003a, --p, K_DH_ANON, B_AES_256, N); + add("SSL_DH_anon_WITH_3DES_EDE_CBC_SHA", + 0x001b, --p, K_DH_ANON, B_3DES, N); + add("SSL_DH_anon_WITH_DES_CBC_SHA", + 0x001a, --p, K_DH_ANON, B_DES, N); -add("TLS_ECDH_anon_WITH_RC4_128_SHA", 0xC016, --p, K_ECDH_ANON, B_RC4_128, N); -add("TLS_ECDH_anon_WITH_AES_128_CBC_SHA", 0xC018, --p, K_ECDH_ANON, B_AES_128, T); -add("TLS_ECDH_anon_WITH_AES_256_CBC_SHA", 0xC019, --p, K_ECDH_ANON, B_AES_256, T); -add("TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA", 0xC017, --p, K_ECDH_ANON, B_3DES, T); + add("TLS_ECDH_anon_WITH_RC4_128_SHA", + 0xC016, --p, K_ECDH_ANON, B_RC4_128, N); + add("TLS_ECDH_anon_WITH_AES_128_CBC_SHA", + 0xC018, --p, K_ECDH_ANON, B_AES_128, T); + add("TLS_ECDH_anon_WITH_AES_256_CBC_SHA", + 0xC019, --p, K_ECDH_ANON, B_AES_256, T); + add("TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA", + 0xC017, --p, K_ECDH_ANON, B_3DES, T); -add("SSL_DH_anon_EXPORT_WITH_RC4_40_MD5", 0x0017, --p, K_DH_ANON, B_RC4_40, N); -add("SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA", 0x0019, --p, K_DH_ANON, B_DES_40, N); + add("SSL_DH_anon_EXPORT_WITH_RC4_40_MD5", + 0x0017, --p, K_DH_ANON, B_RC4_40, N); + add("SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA", + 0x0019, --p, K_DH_ANON, B_DES_40, N); -add("TLS_ECDH_anon_WITH_NULL_SHA", 0xC015, --p, K_ECDH_ANON, B_NULL, N); + add("TLS_ECDH_anon_WITH_NULL_SHA", + 0xC015, --p, K_ECDH_ANON, B_NULL, N); -// Supported Kerberos ciphersuites from RFC2712 -add("TLS_KRB5_WITH_RC4_128_SHA", 0x0020, --p, K_KRB5, B_RC4_128, N); -add("TLS_KRB5_WITH_RC4_128_MD5", 0x0024, --p, K_KRB5, B_RC4_128, N); -add("TLS_KRB5_WITH_3DES_EDE_CBC_SHA", 0x001f, --p, K_KRB5, B_3DES, N); -add("TLS_KRB5_WITH_3DES_EDE_CBC_MD5", 0x0023, --p, K_KRB5, B_3DES, N); -add("TLS_KRB5_WITH_DES_CBC_SHA", 0x001e, --p, K_KRB5, B_DES, N); -add("TLS_KRB5_WITH_DES_CBC_MD5", 0x0022, --p, K_KRB5, B_DES, N); -add("TLS_KRB5_EXPORT_WITH_RC4_40_SHA", 0x0028, --p, K_KRB5_EXPORT, B_RC4_40, N); -add("TLS_KRB5_EXPORT_WITH_RC4_40_MD5", 0x002b, --p, K_KRB5_EXPORT, B_RC4_40, N); -add("TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA", 0x0026, --p, K_KRB5_EXPORT, B_DES_40, N); -add("TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5", 0x0029, --p, K_KRB5_EXPORT, B_DES_40, N); - + // Supported Kerberos ciphersuites from RFC2712 + add("TLS_KRB5_WITH_RC4_128_SHA", + 0x0020, --p, K_KRB5, B_RC4_128, N); + add("TLS_KRB5_WITH_RC4_128_MD5", + 0x0024, --p, K_KRB5, B_RC4_128, N); + add("TLS_KRB5_WITH_3DES_EDE_CBC_SHA", + 0x001f, --p, K_KRB5, B_3DES, N); + add("TLS_KRB5_WITH_3DES_EDE_CBC_MD5", + 0x0023, --p, K_KRB5, B_3DES, N); + add("TLS_KRB5_WITH_DES_CBC_SHA", + 0x001e, --p, K_KRB5, B_DES, N); + add("TLS_KRB5_WITH_DES_CBC_MD5", + 0x0022, --p, K_KRB5, B_DES, N); + add("TLS_KRB5_EXPORT_WITH_RC4_40_SHA", + 0x0028, --p, K_KRB5_EXPORT, B_RC4_40, N); + add("TLS_KRB5_EXPORT_WITH_RC4_40_MD5", + 0x002b, --p, K_KRB5_EXPORT, B_RC4_40, N); + add("TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA", + 0x0026, --p, K_KRB5_EXPORT, B_DES_40, N); + add("TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5", + 0x0029, --p, K_KRB5_EXPORT, B_DES_40, N); // Register the names of a few additional CipherSuites. // Makes them show up as names instead of numbers in @@ -618,4 +706,6 @@ // ciphersuite SSL_NULL_WITH_NULL_NULL final static CipherSuite C_NULL = CipherSuite.valueOf(0, 0); + // ciphersuite TLS_EMPTY_RENEGOTIATION_INFO_SCSV + final static CipherSuite C_SCSV = CipherSuite.valueOf(0x00, 0xff); }
--- a/src/share/classes/sun/security/ssl/CipherSuiteList.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/sun/security/ssl/CipherSuiteList.java Mon Oct 18 21:50:02 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -51,8 +51,9 @@ // null if not yet checked. private volatile Boolean containsEC; - // for use by buildAvailableCache() only - private CipherSuiteList(Collection<CipherSuite> cipherSuites) { + // for use by buildAvailableCache() and + // Handshaker.getKickstartMessage() only + CipherSuiteList(Collection<CipherSuite> cipherSuites) { this.cipherSuites = cipherSuites; } @@ -221,15 +222,18 @@ // SortedSet automatically arranges ciphersuites in default // preference order Set<CipherSuite> cipherSuites = new TreeSet<CipherSuite>(); - Collection<CipherSuite> allowedCipherSuites = CipherSuite.allowedCipherSuites(); + Collection<CipherSuite> allowedCipherSuites = + CipherSuite.allowedCipherSuites(); for (CipherSuite c : allowedCipherSuites) { if ((c.allowed == false) || (c.priority < minPriority)) { continue; } + if (c.isAvailable()) { cipherSuites.add(c); } } + return new CipherSuiteList(cipherSuites); }
--- a/src/share/classes/sun/security/ssl/ClientHandshaker.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/sun/security/ssl/ClientHandshaker.java Mon Oct 18 21:50:02 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2010, 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 @@ -94,16 +94,24 @@ */ ClientHandshaker(SSLSocketImpl socket, SSLContextImpl context, ProtocolList enabledProtocols, - ProtocolVersion activeProtocolVersion) { - super(socket, context, enabledProtocols, true, true); - this.activeProtocolVersion = activeProtocolVersion; + ProtocolVersion activeProtocolVersion, + boolean isInitialHandshake, boolean secureRenegotiation, + byte[] clientVerifyData, byte[] serverVerifyData) { + + super(socket, context, enabledProtocols, true, true, + activeProtocolVersion, isInitialHandshake, secureRenegotiation, + clientVerifyData, serverVerifyData); } ClientHandshaker(SSLEngineImpl engine, SSLContextImpl context, ProtocolList enabledProtocols, - ProtocolVersion activeProtocolVersion) { - super(engine, context, enabledProtocols, true, true); - this.activeProtocolVersion = activeProtocolVersion; + ProtocolVersion activeProtocolVersion, + boolean isInitialHandshake, boolean secureRenegotiation, + byte[] clientVerifyData, byte[] serverVerifyData) { + + super(engine, context, enabledProtocols, true, true, + activeProtocolVersion, isInitialHandshake, secureRenegotiation, + clientVerifyData, serverVerifyData); } /* @@ -279,10 +287,11 @@ // sent the "client hello" but the server's not seen it. // if (state < HandshakeMessage.ht_client_hello) { - if (!renegotiable) { // renegotiation is not allowed. + if (!secureRenegotiation && !allowUnsafeRenegotiation) { + // renegotiation is not allowed. if (activeProtocolVersion.v >= ProtocolVersion.TLS10.v) { - // response with a no_negotiation warning, - warningSE(Alerts.alert_no_negotiation); + // response with a no_renegotiation warning, + warningSE(Alerts.alert_no_renegotiation); // invalidate the handshake so that the caller can // dispose this object. @@ -293,26 +302,24 @@ // and the next handshake message will become incomplete. // // However, according to SSL/TLS specifications, no more - // handshake message could immediately follow ClientHello - // or HelloRequest. But in case of any improper messages, - // we'd better check to ensure there is no remaining bytes - // in the handshake input stream. - if (input.available() > 0) { - fatalSE(Alerts.alert_unexpected_message, - "HelloRequest followed by an unexpected " + - "handshake message"); - } - + // handshake message should immediately follow ClientHello + // or HelloRequest. So just let it be. } else { // For SSLv3, send the handshake_failure fatal error. - // Note that SSLv3 does not define a no_negotiation alert - // like TLSv1. However we cannot ignore the message + // Note that SSLv3 does not define a no_renegotiation + // alert like TLSv1. However we cannot ignore the message // simply, otherwise the other side was waiting for a // response that would never come. fatalSE(Alerts.alert_handshake_failure, - "renegotiation is not allowed"); + "Renegotiation is not allowed"); } } else { + if (!secureRenegotiation) { + if (debug != null && Debug.isOn("handshake")) { + System.out.println( + "Warning: continue with insecure renegotiation"); + } + } kickstart(); } } @@ -347,6 +354,68 @@ // Handshake streams setVersion(mesgVersion); + // check the "renegotiation_info" extension + RenegotiationInfoExtension serverHelloRI = (RenegotiationInfoExtension) + mesg.extensions.get(ExtensionType.EXT_RENEGOTIATION_INFO); + if (serverHelloRI != null) { + if (isInitialHandshake) { + // verify the length of the "renegotiated_connection" field + if (!serverHelloRI.isEmpty()) { + // abort the handshake with a fatal handshake_failure alert + fatalSE(Alerts.alert_handshake_failure, + "The renegotiation_info field is not empty"); + } + + secureRenegotiation = true; + } else { + // For a legacy renegotiation, the client MUST verify that + // it does not contain the "renegotiation_info" extension. + if (!secureRenegotiation) { + fatalSE(Alerts.alert_handshake_failure, + "Unexpected renegotiation indication extension"); + } + + // verify the client_verify_data and server_verify_data values + byte[] verifyData = + new byte[clientVerifyData.length + serverVerifyData.length]; + System.arraycopy(clientVerifyData, 0, verifyData, + 0, clientVerifyData.length); + System.arraycopy(serverVerifyData, 0, verifyData, + clientVerifyData.length, serverVerifyData.length); + if (!Arrays.equals(verifyData, + serverHelloRI.getRenegotiatedConnection())) { + fatalSE(Alerts.alert_handshake_failure, + "Incorrect verify data in ServerHello " + + "renegotiation_info message"); + } + } + } else { + // no renegotiation indication extension + if (isInitialHandshake) { + if (!allowLegacyHelloMessages) { + // abort the handshake with a fatal handshake_failure alert + fatalSE(Alerts.alert_handshake_failure, + "Failed to negotiate the use of secure renegotiation"); + } + + secureRenegotiation = false; + if (debug != null && Debug.isOn("handshake")) { + System.out.println("Warning: No renegotiation " + + "indication extension in ServerHello"); + } + } else { + // For a secure renegotiation, the client must abort the + // handshake if no "renegotiation_info" extension is present. + if (secureRenegotiation) { + fatalSE(Alerts.alert_handshake_failure, + "No renegotiation indication extension"); + } + + // we have already allowed unsafe renegotation before request + // the renegotiation. + } + } + // // Save server nonce, we always use it to compute connection // keys and it's also used to create the master secret if we're @@ -354,10 +423,11 @@ // svr_random = mesg.svr_random; - if (isEnabled(mesg.cipherSuite) == false) { + if (isNegotiable(mesg.cipherSuite) == false) { fatalSE(Alerts.alert_illegal_parameter, - "Server selected disabled ciphersuite " + cipherSuite); + "Server selected improper ciphersuite " + cipherSuite); } + setCipherSuite(mesg.cipherSuite); if (mesg.compression_method != 0) { @@ -452,7 +522,8 @@ for (HelloExtension ext : mesg.extensions.list()) { ExtensionType type = ext.type; if ((type != ExtensionType.EXT_ELLIPTIC_CURVES) - && (type != ExtensionType.EXT_EC_POINT_FORMATS)) { + && (type != ExtensionType.EXT_EC_POINT_FORMATS) + && (type != ExtensionType.EXT_RENEGOTIATION_INFO)) { fatalSE(Alerts.alert_unsupported_extension, "Server sent an unsupported extension: " + type); } @@ -869,6 +940,13 @@ } /* + * save server verify data for secure renegotiation + */ + if (secureRenegotiation) { + serverVerifyData = mesg.getVerifyData(); + } + + /* * OK, it verified. If we're doing the fast handshake, add that * "Finished" message to the hash of handshake messages, then send * our own change_cipher_spec and Finished message for the server @@ -921,6 +999,13 @@ sendChangeCipherSpec(mesg, finishedTag); /* + * save client verify data for secure renegotiation + */ + if (secureRenegotiation) { + clientVerifyData = mesg.getVerifyData(); + } + + /* * Update state machine so server MUST send 'finished' next. * (In "long" handshake case; in short case, we're responding * to its message.) @@ -933,12 +1018,15 @@ * Returns a ClientHello message to kickstart renegotiations */ HandshakeMessage getKickstartMessage() throws SSLException { - ClientHello mesg = new ClientHello(sslContext.getSecureRandom(), - protocolVersion); + // session ID of the ClientHello message + SessionId sessionId = SSLSessionImpl.nullSession.getSessionId(); + + // a list of cipher suites sent by the client + CipherSuiteList cipherSuites = enabledCipherSuites; + + // set the max protocol version this client is supporting. maxProtocolVersion = protocolVersion; - clnt_random = mesg.clnt_random; - // // Try to resume an existing session. This might be mandatory, // given certain API options. @@ -962,9 +1050,9 @@ if (session != null) { CipherSuite sessionSuite = session.getSuite(); ProtocolVersion sessionVersion = session.getProtocolVersion(); - if (isEnabled(sessionSuite) == false) { + if (isNegotiable(sessionSuite) == false) { if (debug != null && Debug.isOn("session")) { - System.out.println("%% can't resume, cipher disabled"); + System.out.println("%% can't resume, unavailable cipher"); } session = null; } @@ -984,9 +1072,8 @@ + " from port " + getLocalPortSE()); } } - mesg.sessionId = session.getSessionId(); - mesg.protocolVersion = sessionVersion; + sessionId = session.getSessionId(); maxProtocolVersion = sessionVersion; // Update SSL version number in underlying SSL socket and @@ -995,33 +1082,78 @@ setVersion(sessionVersion); } - // - // don't say much beyond the obvious if we _must_ resume. - // + /* + * Force use of the previous session ciphersuite, and + * add the SCSV if enabled. + */ if (!enableNewSession) { if (session == null) { throw new SSLException( "Can't reuse existing SSL client session"); } - mesg.setCipherSuites(new CipherSuiteList(sessionSuite)); - return mesg; - } - } - if (session == null) { - if (enableNewSession) { - mesg.sessionId = SSLSessionImpl.nullSession.getSessionId(); - } else { - throw new SSLException("No existing session to resume."); + + Collection<CipherSuite> cipherList = + new ArrayList<CipherSuite>(2); + cipherList.add(sessionSuite); + if (!secureRenegotiation && + cipherSuites.contains(CipherSuite.C_SCSV)) { + cipherList.add(CipherSuite.C_SCSV); + } // otherwise, renegotiation_info extension will be used + + cipherSuites = new CipherSuiteList(cipherList); } } - // - // All we have left to do is fill out the cipher suites. - // (If this changes, change the 'return' above!) - // - mesg.setCipherSuites(enabledCipherSuites); + if (session == null && !enableNewSession) { + throw new SSLException("No existing session to resume"); + } + + // exclude SCSV for secure renegotiation + if (secureRenegotiation && cipherSuites.contains(CipherSuite.C_SCSV)) { + Collection<CipherSuite> cipherList = + new ArrayList<CipherSuite>(cipherSuites.size() - 1); + for (CipherSuite suite : cipherSuites.collection()) { + if (suite != CipherSuite.C_SCSV) { + cipherList.add(suite); + } + } + + cipherSuites = new CipherSuiteList(cipherList); + } - return mesg; + // make sure there is a negotiable cipher suite. + boolean negotiable = false; + for (CipherSuite suite : cipherSuites.collection()) { + if (isNegotiable(suite)) { + negotiable = true; + break; + } + } + + if (!negotiable) { + throw new SSLException("No negotiable cipher suite"); + } + + // create the ClientHello message + ClientHello clientHelloMessage = new ClientHello( + sslContext.getSecureRandom(), maxProtocolVersion, + sessionId, cipherSuites); + + // reset the client random cookie + clnt_random = clientHelloMessage.clnt_random; + + /* + * need to set the renegotiation_info extension for: + * 1: secure renegotiation + * 2: initial handshake and no SCSV in the ClientHello + * 3: insecure renegotiation and no SCSV in the ClientHello + */ + if (secureRenegotiation || + !cipherSuites.contains(CipherSuite.C_SCSV)) { + clientHelloMessage.addRenegotiationInfoExtension(clientVerifyData); + } + + return clientHelloMessage; } /*
--- a/src/share/classes/sun/security/ssl/HandshakeMessage.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/sun/security/ssl/HandshakeMessage.java Mon Oct 18 21:50:02 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2010, 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,9 +172,7 @@ * Server can ask the client to initiate a new handshake, e.g. to change * session parameters after a connection has been (re)established. */ -static final -class HelloRequest extends HandshakeMessage -{ +static final class HelloRequest extends HandshakeMessage { int messageType() { return ht_hello_request; } HelloRequest() { } @@ -210,10 +208,7 @@ * Until we know how to parse it, we will just read what we know * about, and let our caller handle the jumps over unknown data. */ -static final -class ClientHello extends HandshakeMessage -{ - int messageType() { return ht_client_hello; } +static final class ClientHello extends HandshakeMessage { ProtocolVersion protocolVersion; RandomCookie clnt_random; @@ -225,37 +220,20 @@ private final static byte[] NULL_COMPRESSION = new byte[] {0}; - ClientHello(SecureRandom generator, ProtocolVersion protocolVersion) { - this.protocolVersion = protocolVersion; - clnt_random = new RandomCookie(generator); - compression_methods = NULL_COMPRESSION; - // sessionId, cipher_suites TBS later - } + ClientHello(SecureRandom generator, ProtocolVersion protocolVersion, + SessionId sessionId, CipherSuiteList cipherSuites) { - CipherSuiteList getCipherSuites() { - return cipherSuites; - } + this.protocolVersion = protocolVersion; + this.sessionId = sessionId; + this.cipherSuites = cipherSuites; - // Set the ciphersuites. - // This method may only be called once. - void setCipherSuites(CipherSuiteList cipherSuites) { - this.cipherSuites = cipherSuites; if (cipherSuites.containsEC()) { extensions.add(SupportedEllipticCurvesExtension.DEFAULT); extensions.add(SupportedEllipticPointFormatsExtension.DEFAULT); } - } - int messageLength() { - /* - * Add fixed size parts of each field... - * version + random + session + cipher + compress - */ - return (2 + 32 + 1 + 2 + 1 - + sessionId.length() /* ... + variable parts */ - + (cipherSuites.size() * 2) - + compression_methods.length) - + extensions.length(); + clnt_random = new RandomCookie(generator); + compression_methods = NULL_COMPRESSION; } ClientHello(HandshakeInStream s, int messageLength) throws IOException { @@ -269,6 +247,34 @@ } } + CipherSuiteList getCipherSuites() { + return cipherSuites; + } + + // add renegotiation_info extension + void addRenegotiationInfoExtension(byte[] clientVerifyData) { + HelloExtension renegotiationInfo = new RenegotiationInfoExtension( + clientVerifyData, new byte[0]); + extensions.add(renegotiationInfo); + } + + @Override + int messageType() { return ht_client_hello; } + + @Override + int messageLength() { + /* + * Add fixed size parts of each field... + * version + random + session + cipher + compress + */ + return (2 + 32 + 1 + 2 + 1 + + sessionId.length() /* ... + variable parts */ + + (cipherSuites.size() * 2) + + compression_methods.length) + + extensions.length(); + } + + @Override void send(HandshakeOutStream s) throws IOException { s.putInt8(protocolVersion.major); s.putInt8(protocolVersion.minor); @@ -279,6 +285,7 @@ extensions.send(s); } + @Override void print(PrintStream s) throws IOException { s.println("*** ClientHello, " + protocolVersion); @@ -315,7 +322,6 @@ CipherSuite cipherSuite; byte compression_method; HelloExtensions extensions = new HelloExtensions(); - int extensionLength; ServerHello() { // empty @@ -1425,8 +1431,6 @@ */ static final class Finished extends HandshakeMessage { - int messageType() { return ht_finished; } - // constant for a Finished message sent by the client final static int CLIENT = 1; @@ -1468,7 +1472,7 @@ * both client and server are fully in sync, and that the handshake * computations have been successful. */ - boolean verify(ProtocolVersion protocolVersion, + boolean verify(ProtocolVersion protocolVersion, HandshakeHash handshakeHash, int sender, SecretKey master) { byte[] myFinished = getFinished(protocolVersion, handshakeHash, sender, master); @@ -1542,14 +1546,25 @@ CertificateVerify.updateDigest(md, pad1, pad2, masterSecret); } + // get the verify_data of the finished message + byte[] getVerifyData() { + return verifyData; + } + + @Override + int messageType() { return ht_finished; } + + @Override int messageLength() { return verifyData.length; } + @Override void send(HandshakeOutStream out) throws IOException { out.write(verifyData); } + @Override void print(PrintStream s) throws IOException { s.println("*** Finished"); if (debug != null && Debug.isOn("verbose")) { @@ -1557,7 +1572,6 @@ s.println("***"); } } - } //
--- a/src/share/classes/sun/security/ssl/Handshaker.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/sun/security/ssl/Handshaker.java Mon Oct 18 21:50:02 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2010, 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 @@ -66,6 +66,14 @@ // the currently active protocol version during a renegotiation ProtocolVersion activeProtocolVersion; + // security parameters for secure renegotiation. + boolean secureRenegotiation; + byte[] clientVerifyData; + byte[] serverVerifyData; + + // is it an initial negotiation or a renegotiation? + boolean isInitialHandshake; + // list of enabled protocols ProtocolList enabledProtocols; @@ -128,31 +136,66 @@ static final Debug debug = Debug.getInstance("ssl"); // By default, disable the unsafe legacy session renegotiation - static final boolean renegotiable = Debug.getBooleanProperty( + static final boolean allowUnsafeRenegotiation = Debug.getBooleanProperty( "sun.security.ssl.allowUnsafeRenegotiation", false); + // For maximum interoperability and backward compatibility, RFC 5746 + // allows server (or client) to accept ClientHello (or ServerHello) + // message without the secure renegotiation_info extension or SCSV. + // + // For maximum security, RFC 5746 also allows server (or client) to + // reject such message with a fatal "handshake_failure" alert. + // + // By default, allow such legacy hello messages. + static final boolean allowLegacyHelloMessages = Debug.getBooleanProperty( + "sun.security.ssl.allowLegacyHelloMessages", true); + // need to dispose the object when it is invalidated boolean invalidated; Handshaker(SSLSocketImpl c, SSLContextImpl context, ProtocolList enabledProtocols, boolean needCertVerify, - boolean isClient) { + boolean isClient, ProtocolVersion activeProtocolVersion, + boolean isInitialHandshake, boolean secureRenegotiation, + byte[] clientVerifyData, byte[] serverVerifyData) { this.conn = c; - init(context, enabledProtocols, needCertVerify, isClient); + init(context, enabledProtocols, needCertVerify, isClient, + activeProtocolVersion, isInitialHandshake, secureRenegotiation, + clientVerifyData, serverVerifyData); } Handshaker(SSLEngineImpl engine, SSLContextImpl context, ProtocolList enabledProtocols, boolean needCertVerify, - boolean isClient) { + boolean isClient, ProtocolVersion activeProtocolVersion, + boolean isInitialHandshake, boolean secureRenegotiation, + byte[] clientVerifyData, byte[] serverVerifyData) { this.engine = engine; - init(context, enabledProtocols, needCertVerify, isClient); + init(context, enabledProtocols, needCertVerify, isClient, + activeProtocolVersion, isInitialHandshake, secureRenegotiation, + clientVerifyData, serverVerifyData); } private void init(SSLContextImpl context, ProtocolList enabledProtocols, - boolean needCertVerify, boolean isClient) { + boolean needCertVerify, boolean isClient, + ProtocolVersion activeProtocolVersion, + boolean isInitialHandshake, boolean secureRenegotiation, + byte[] clientVerifyData, byte[] serverVerifyData) { + + if (debug != null && Debug.isOn("handshake")) { + System.out.println( + "Allow unsafe renegotiation: " + allowUnsafeRenegotiation + + "\nAllow legacy hello messages: " + allowLegacyHelloMessages + + "\nIs initial handshake: " + isInitialHandshake + + "\nIs secure renegotiation: " + secureRenegotiation); + } this.sslContext = context; this.isClient = isClient; + this.activeProtocolVersion = activeProtocolVersion; + this.isInitialHandshake = isInitialHandshake; + this.secureRenegotiation = secureRenegotiation; + this.clientVerifyData = clientVerifyData; + this.serverVerifyData = serverVerifyData; enableNewSession = true; invalidated = false; @@ -353,8 +396,8 @@ * changed due to change in JCE providers since it was enabled). * Does not check if the required server certificates are available. */ - boolean isEnabled(CipherSuite s) { - return enabledCipherSuites.contains(s) && s.isAvailable(); + boolean isNegotiable(CipherSuite s) { + return enabledCipherSuites.contains(s) && s.isNegotiable(); } /** @@ -459,6 +502,27 @@ } /* + * Returns true if renegotiation is in use for this connection. + */ + boolean isSecureRenegotiation() { + return secureRenegotiation; + } + + /* + * Returns the verify_data from the Finished message sent by the client. + */ + byte[] getClientVerifyData() { + return clientVerifyData; + } + + /* + * Returns the verify_data from the Finished message sent by the server. + */ + byte[] getServerVerifyData() { + return serverVerifyData; + } + + /* * This routine is fed SSL handshake records when they become available, * and processes messages found therein. */
--- a/src/share/classes/sun/security/ssl/HelloExtensions.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/sun/security/ssl/HelloExtensions.java Mon Oct 18 21:50:02 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2010, 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 @@ -81,7 +81,10 @@ } else if (extType == ExtensionType.EXT_ELLIPTIC_CURVES) { extension = new SupportedEllipticCurvesExtension(s, extlen); } else if (extType == ExtensionType.EXT_EC_POINT_FORMATS) { - extension = new SupportedEllipticPointFormatsExtension(s, extlen); + extension = + new SupportedEllipticPointFormatsExtension(s, extlen); + } else if (extType == ExtensionType.EXT_RENEGOTIATION_INFO) { + extension = new RenegotiationInfoExtension(s, extlen); } else { extension = new UnknownExtension(s, extlen, extType); } @@ -89,7 +92,8 @@ len -= extlen + 4; } if (len != 0) { - throw new SSLProtocolException("Error parsing extensions: extra data"); + throw new SSLProtocolException( + "Error parsing extensions: extra data"); } } @@ -162,7 +166,8 @@ return name; } - static List<ExtensionType> knownExtensions = new ArrayList<ExtensionType>(8); + static List<ExtensionType> knownExtensions = + new ArrayList<ExtensionType>(9); static ExtensionType get(int id) { for (ExtensionType ext : knownExtensions) { @@ -180,17 +185,44 @@ } // extensions defined in RFC 3546 - final static ExtensionType EXT_SERVER_NAME = e( 0, "server_name"); - final static ExtensionType EXT_MAX_FRAGMENT_LENGTH = e( 1, "max_fragment_length"); - final static ExtensionType EXT_CLIENT_CERTIFICATE_URL = e( 2, "client_certificate_url"); - final static ExtensionType EXT_TRUSTED_CA_KEYS = e( 3, "trusted_ca_keys"); - final static ExtensionType EXT_TRUNCATED_HMAC = e( 4, "truncated_hmac"); - final static ExtensionType EXT_STATUS_REQUEST = e( 5, "status_request"); + final static ExtensionType EXT_SERVER_NAME = + e(0x0000, "server_name"); // IANA registry value: 0 + final static ExtensionType EXT_MAX_FRAGMENT_LENGTH = + e(0x0001, "max_fragment_length"); // IANA registry value: 1 + final static ExtensionType EXT_CLIENT_CERTIFICATE_URL = + e(0x0002, "client_certificate_url"); // IANA registry value: 2 + final static ExtensionType EXT_TRUSTED_CA_KEYS = + e(0x0003, "trusted_ca_keys"); // IANA registry value: 3 + final static ExtensionType EXT_TRUNCATED_HMAC = + e(0x0004, "truncated_hmac"); // IANA registry value: 4 + final static ExtensionType EXT_STATUS_REQUEST = + e(0x0005, "status_request"); // IANA registry value: 5 + + // extensions defined in RFC 4681 + final static ExtensionType EXT_USER_MAPPING = + e(0x0006, "user_mapping"); // IANA registry value: 6 + + // extensions defined in RFC 5081 + final static ExtensionType EXT_CERT_TYPE = + e(0x0009, "cert_type"); // IANA registry value: 9 // extensions defined in RFC 4492 (ECC) - final static ExtensionType EXT_ELLIPTIC_CURVES = e(10, "elliptic_curves"); - final static ExtensionType EXT_EC_POINT_FORMATS = e(11, "ec_point_formats"); + final static ExtensionType EXT_ELLIPTIC_CURVES = + e(0x000A, "elliptic_curves"); // IANA registry value: 10 + final static ExtensionType EXT_EC_POINT_FORMATS = + e(0x000B, "ec_point_formats"); // IANA registry value: 11 + // extensions defined in RFC 5054 + final static ExtensionType EXT_SRP = + e(0x000C, "srp"); // IANA registry value: 12 + + // extensions defined in RFC 5246 + final static ExtensionType EXT_SIGNATURE_ALGORITHMS = + e(0x000D, "signature_algorithms"); // IANA registry value: 13 + + // extensions defined in RFC 5746 + final static ExtensionType EXT_RENEGOTIATION_INFO = + e(0xff01, "renegotiation_info"); // IANA registry value: 65281 } abstract class HelloExtension { @@ -238,9 +270,11 @@ } } -// Support for the server_name extension is incomplete. Parsing is implemented -// so that we get nicer debug output, but we neither send it nor do we do -// act on it if we receive it. +/* + * Support for the server_name extension is incomplete. Parsing is implemented + * so that we get nicer debug output, but we neither send it nor do we do + * act on it if we receive it. + */ final class ServerNameExtension extends HelloExtension { final static int NAME_HOST_NAME = 0; @@ -268,9 +302,9 @@ final String hostname; ServerName(HandshakeInStream s) throws IOException { - length = s.getInt16(); - type = s.getInt8(); - data = s.getBytes16(); + length = s.getInt16(); // ServerNameList length + type = s.getInt8(); // NameType + data = s.getBytes16(); // HostName (length read in getBytes16) if (type == NAME_HOST_NAME) { hostname = new String(data, "UTF8"); } else { @@ -549,3 +583,85 @@ return "Extension " + type + ", formats: " + list; } } + +/* + * For secure renegotiation, RFC5746 defines a new TLS extension, + * "renegotiation_info" (with extension type 0xff01), which contains a + * cryptographic binding to the enclosing TLS connection (if any) for + * which the renegotiation is being performed. The "extension data" + * field of this extension contains a "RenegotiationInfo" structure: + * + * struct { + * opaque renegotiated_connection<0..255>; + * } RenegotiationInfo; + */ +final class RenegotiationInfoExtension extends HelloExtension { + private final byte[] renegotiated_connection; + + RenegotiationInfoExtension(byte[] clientVerifyData, + byte[] serverVerifyData) { + super(ExtensionType.EXT_RENEGOTIATION_INFO); + + if (clientVerifyData.length != 0) { + renegotiated_connection = + new byte[clientVerifyData.length + serverVerifyData.length]; + System.arraycopy(clientVerifyData, 0, renegotiated_connection, + 0, clientVerifyData.length); + + if (serverVerifyData.length != 0) { + System.arraycopy(serverVerifyData, 0, renegotiated_connection, + clientVerifyData.length, serverVerifyData.length); + } + } else { + // ignore both the client and server verify data. + renegotiated_connection = new byte[0]; + } + } + + RenegotiationInfoExtension(HandshakeInStream s, int len) + throws IOException { + super(ExtensionType.EXT_RENEGOTIATION_INFO); + + // check the extension length + if (len < 1) { + throw new SSLProtocolException("Invalid " + type + " extension"); + } + + int renegoInfoDataLen = s.getInt8(); + if (renegoInfoDataLen + 1 != len) { // + 1 = the byte we just read + throw new SSLProtocolException("Invalid " + type + " extension"); + } + + renegotiated_connection = new byte[renegoInfoDataLen]; + if (renegoInfoDataLen != 0) { + s.read(renegotiated_connection, 0, renegoInfoDataLen); + } + } + + + // Length of the encoded extension, including the type and length fields + int length() { + return 5 + renegotiated_connection.length; + } + + void send(HandshakeOutStream s) throws IOException { + s.putInt16(type.id); + s.putInt16(renegotiated_connection.length + 1); + s.putBytes8(renegotiated_connection); + } + + boolean isEmpty() { + return renegotiated_connection.length == 0; + } + + byte[] getRenegotiatedConnection() { + return renegotiated_connection; + } + + public String toString() { + return "Extension " + type + ", renegotiated_connection: " + + (renegotiated_connection.length == 0 ? "<empty>" : + Debug.toString(renegotiated_connection)); + } + +}
--- a/src/share/classes/sun/security/ssl/OutputRecord.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/sun/security/ssl/OutputRecord.java Mon Oct 18 21:50:02 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2010, 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 @@ -343,6 +343,9 @@ * example, Netscape Commerce 1.0 servers. The V3 message is in the * header and the bytes passed as parameter. This routine translates * the V3 message into an equivalent V2 one. + * + * Note that the translation will strip off all hello extensions as + * SSL V2.0 does not support hello extension. */ private void V3toV2ClientHello(byte v3Msg []) throws SSLException { int v3SessionIdLenOffset = 2 + 32; // version + nonce @@ -361,12 +364,21 @@ int v3CipherSpecOffset = v3CipherSpecLenOffset + 2; // skip length int v2CipherSpecLen = 0; count = 11; + boolean containsRenegoInfoSCSV = false; for (int i = 0; i < cipherSpecs; i++) { byte byte1, byte2; byte1 = v3Msg[v3CipherSpecOffset++]; byte2 = v3Msg[v3CipherSpecOffset++]; v2CipherSpecLen += V3toV2CipherSuite(byte1, byte2); + if (!containsRenegoInfoSCSV && + byte1 == (byte)0x00 && byte2 == (byte)0xFF) { + containsRenegoInfoSCSV = true; + } + } + + if (!containsRenegoInfoSCSV) { + v2CipherSpecLen += V3toV2CipherSuite((byte)0x00, (byte)0xFF); } /*
--- a/src/share/classes/sun/security/ssl/SSLEngineImpl.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/sun/security/ssl/SSLEngineImpl.java Mon Oct 18 21:50:02 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2010, 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 @@ -275,6 +275,12 @@ private CipherBox readCipher, writeCipher; // NOTE: compression state would be saved here + /* + * security parameters for secure renegotiation. + */ + private boolean secureRenegotiation; + private byte[] clientVerifyData; + private byte[] serverVerifyData; /* * READ ME * READ ME * READ ME * READ ME * READ ME * READ ME * @@ -356,6 +362,11 @@ writeCipher = CipherBox.NULL; writeMAC = MAC.NULL; + // default security parameters for secure renegotiation + secureRenegotiation = false; + clientVerifyData = new byte[0]; + serverVerifyData = new byte[0]; + enabledCipherSuites = CipherSuiteList.getDefault(); enabledProtocols = ProtocolList.getDefault(); @@ -434,11 +445,14 @@ } if (roleIsServer) { handshaker = new ServerHandshaker(this, sslContext, - enabledProtocols, doClientAuth, - connectionState == cs_RENEGOTIATE, protocolVersion); + enabledProtocols, doClientAuth, + protocolVersion, connectionState == cs_HANDSHAKE, + secureRenegotiation, clientVerifyData, serverVerifyData); } else { handshaker = new ClientHandshaker(this, sslContext, - enabledProtocols, protocolVersion); + enabledProtocols, + protocolVersion, connectionState == cs_HANDSHAKE, + secureRenegotiation, clientVerifyData, serverVerifyData); } handshaker.enabledCipherSuites = enabledCipherSuites; handshaker.setEnableSessionCreation(enableSessionCreation); @@ -640,8 +654,16 @@ break; case cs_DATA: - if (!Handshaker.renegotiable) { - throw new SSLHandshakeException("renegotiation is not allowed"); + if (!secureRenegotiation && !Handshaker.allowUnsafeRenegotiation) { + throw new SSLHandshakeException( + "Insecure renegotiation is not allowed"); + } + + if (!secureRenegotiation) { + if (debug != null && Debug.isOn("handshake")) { + System.out.println( + "Warning: Using insecure renegotiation"); + } } // initialize the handshaker, move to cs_RENEGOTIATE @@ -978,6 +1000,12 @@ connectionState = cs_DATA; } } else if (handshaker.isDone()) { + // reset the parameters for secure renegotiation. + secureRenegotiation = + handshaker.isSecureRenegotiation(); + clientVerifyData = handshaker.getClientVerifyData(); + serverVerifyData = handshaker.getServerVerifyData(); + sess = handshaker.getSession(); if (!writer.hasOutboundData()) { hsStatus = HandshakeStatus.FINISHED;
--- a/src/share/classes/sun/security/ssl/SSLServerSocketImpl.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/sun/security/ssl/SSLServerSocketImpl.java Mon Oct 18 21:50:02 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2010, 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 @@ -307,8 +307,9 @@ try { ServerHandshaker handshaker = tmp.getServerHandshaker(); - for (Iterator t = enabledCipherSuites.iterator(); t.hasNext(); ) { - CipherSuite suite = (CipherSuite)t.next(); + for (Iterator<CipherSuite> t = enabledCipherSuites.iterator(); + t.hasNext();) { + CipherSuite suite = t.next(); if (handshaker.trySetCipherSuite(suite)) { checkedEnabled = true; return;
--- a/src/share/classes/sun/security/ssl/SSLSocketImpl.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/sun/security/ssl/SSLSocketImpl.java Mon Oct 18 21:50:02 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2010, 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 @@ -275,9 +275,9 @@ * This is necessary so that processing of close_notify alerts * from the peer are handled properly. */ - private Object handshakeLock; - ReentrantLock writeLock; - private Object readLock; + final private Object handshakeLock = new Object(); + final ReentrantLock writeLock = new ReentrantLock(); + final private Object readLock = new Object(); private InputRecord inrec; @@ -289,6 +289,13 @@ // NOTE: compression state would be saved here /* + * security parameters for secure renegotiation. + */ + private boolean secureRenegotiation; + private byte[] clientVerifyData; + private byte[] serverVerifyData; + + /* * The authentication context holds all information used to establish * who this end of the connection is (certificate chains, private keys, * etc) and who is trusted (e.g. as CAs or websites). @@ -528,11 +535,13 @@ writeCipher = CipherBox.NULL; writeMAC = MAC.NULL; + // initial security parameters for secure renegotiation + secureRenegotiation = false; + clientVerifyData = new byte[0]; + serverVerifyData = new byte[0]; + enabledCipherSuites = CipherSuiteList.getDefault(); enabledProtocols = ProtocolList.getDefault(); - handshakeLock = new Object(); - writeLock = new ReentrantLock(); - readLock = new Object(); inrec = null; // save the acc @@ -914,6 +923,12 @@ connectionState = cs_DATA; } } else if (handshaker.isDone()) { + // reset the parameters for secure renegotiation. + secureRenegotiation = + handshaker.isSecureRenegotiation(); + clientVerifyData = handshaker.getClientVerifyData(); + serverVerifyData = handshaker.getServerVerifyData(); + sess = handshaker.getSession(); handshaker = null; connectionState = cs_DATA; @@ -1091,11 +1106,14 @@ } if (roleIsServer) { handshaker = new ServerHandshaker(this, sslContext, - enabledProtocols, doClientAuth, - connectionState == cs_RENEGOTIATE, protocolVersion); + enabledProtocols, doClientAuth, + protocolVersion, connectionState == cs_HANDSHAKE, + secureRenegotiation, clientVerifyData, serverVerifyData); } else { handshaker = new ClientHandshaker(this, sslContext, - enabledProtocols, protocolVersion); + enabledProtocols, + protocolVersion, connectionState == cs_HANDSHAKE, + secureRenegotiation, clientVerifyData, serverVerifyData); } handshaker.enabledCipherSuites = enabledCipherSuites; handshaker.setEnableSessionCreation(enableSessionCreation); @@ -1200,8 +1218,16 @@ break; case cs_DATA: - if (!Handshaker.renegotiable) { - throw new SSLHandshakeException("renegotiation is not allowed"); + if (!secureRenegotiation && !Handshaker.allowUnsafeRenegotiation) { + throw new SSLHandshakeException( + "Insecure renegotiation is not allowed"); + } + + if (!secureRenegotiation) { + if (debug != null && Debug.isOn("handshake")) { + System.out.println( + "Warning: Using insecure renegotiation"); + } } // initialize the handshaker, move to cs_RENEGOTIATE
--- a/src/share/classes/sun/security/ssl/ServerHandshaker.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/sun/security/ssl/ServerHandshaker.java Mon Oct 18 21:50:02 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2010, 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 @@ -69,9 +69,6 @@ // flag to check for clientCertificateVerify message private boolean needClientVerify = false; - // indicate a renegotiation handshaking - private boolean isRenegotiation = false; - /* * For exportable ciphersuites using non-exportable key sizes, we use * ephemeral RSA keys. We could also do anonymous RSA in the same way @@ -100,13 +97,15 @@ */ ServerHandshaker(SSLSocketImpl socket, SSLContextImpl context, ProtocolList enabledProtocols, byte clientAuth, - boolean isRenegotiation, ProtocolVersion activeProtocolVersion) { + ProtocolVersion activeProtocolVersion, boolean isInitialHandshake, + boolean secureRenegotiation, + byte[] clientVerifyData, byte[] serverVerifyData) { super(socket, context, enabledProtocols, - (clientAuth != SSLEngineImpl.clauth_none), false); + (clientAuth != SSLEngineImpl.clauth_none), false, + activeProtocolVersion, isInitialHandshake, secureRenegotiation, + clientVerifyData, serverVerifyData); doClientAuth = clientAuth; - this.isRenegotiation = isRenegotiation; - this.activeProtocolVersion = activeProtocolVersion; } /* @@ -114,13 +113,15 @@ */ ServerHandshaker(SSLEngineImpl engine, SSLContextImpl context, ProtocolList enabledProtocols, byte clientAuth, - boolean isRenegotiation, ProtocolVersion activeProtocolVersion) { + ProtocolVersion activeProtocolVersion, + boolean isInitialHandshake, boolean secureRenegotiation, + byte[] clientVerifyData, byte[] serverVerifyData) { super(engine, context, enabledProtocols, - (clientAuth != SSLEngineImpl.clauth_none), false); + (clientAuth != SSLEngineImpl.clauth_none), false, + activeProtocolVersion, isInitialHandshake, secureRenegotiation, + clientVerifyData, serverVerifyData); doClientAuth = clientAuth; - this.isRenegotiation = isRenegotiation; - this.activeProtocolVersion = activeProtocolVersion; } /* @@ -269,41 +270,122 @@ mesg.print(System.out); } - // if it is a renegotiation request and renegotiation is not allowed - if (isRenegotiation && !renegotiable) { - if (activeProtocolVersion.v >= ProtocolVersion.TLS10.v) { - // response with a no_negotiation warning, - warningSE(Alerts.alert_no_negotiation); + // Does the message include security renegotiation indication? + boolean renegotiationIndicated = false; - // invalidate the handshake so that the caller can - // dispose this object. - invalidated = true; + // check the TLS_EMPTY_RENEGOTIATION_INFO_SCSV + CipherSuiteList cipherSuites = mesg.getCipherSuites(); + if (cipherSuites.contains(CipherSuite.C_SCSV)) { + renegotiationIndicated = true; + if (isInitialHandshake) { + secureRenegotiation = true; + } else { + // abort the handshake with a fatal handshake_failure alert + if (secureRenegotiation) { + fatalSE(Alerts.alert_handshake_failure, + "The SCSV is present in a secure renegotiation"); + } else { + fatalSE(Alerts.alert_handshake_failure, + "The SCSV is present in a insecure renegotiation"); + } + } + } - // If there is still unread block in the handshake - // input stream, it would be truncated with the disposal - // and the next handshake message will become incomplete. - // - // However, according to SSL/TLS specifications, no more - // handshake message could immediately follow ClientHello - // or HelloRequest. But in case of any improper messages, - // we'd better check to ensure there is no remaining bytes - // in the handshake input stream. - if (input.available() > 0) { - fatalSE(Alerts.alert_unexpected_message, - "ClientHello followed by an unexpected " + - "handshake message"); + // check the "renegotiation_info" extension + RenegotiationInfoExtension clientHelloRI = (RenegotiationInfoExtension) + mesg.extensions.get(ExtensionType.EXT_RENEGOTIATION_INFO); + if (clientHelloRI != null) { + renegotiationIndicated = true; + if (isInitialHandshake) { + // verify the length of the "renegotiated_connection" field + if (!clientHelloRI.isEmpty()) { + // abort the handshake with a fatal handshake_failure alert + fatalSE(Alerts.alert_handshake_failure, + "The renegotiation_info field is not empty"); + } + secureRenegotiation = true; + } else { + if (!secureRenegotiation) { + // unexpected RI extension for insecure renegotiation, + // abort the handshake with a fatal handshake_failure alert + fatalSE(Alerts.alert_handshake_failure, + "The renegotiation_info is present in a insecure " + + "renegotiation"); } - return; - } else { - // For SSLv3, send the handshake_failure fatal error. - // Note that SSLv3 does not define a no_negotiation alert - // like TLSv1. However we cannot ignore the message - // simply, otherwise the other side was waiting for a - // response that would never come. - fatalSE(Alerts.alert_handshake_failure, - "renegotiation is not allowed"); + // verify the client_verify_data value + if (!Arrays.equals(clientVerifyData, + clientHelloRI.getRenegotiatedConnection())) { + fatalSE(Alerts.alert_handshake_failure, + "Incorrect verify data in ClientHello " + + "renegotiation_info message"); + } + } + } else if (!isInitialHandshake && secureRenegotiation) { + // if the connection's "secure_renegotiation" flag is set to TRUE + // and the "renegotiation_info" extension is not present, abort + // the handshake. + fatalSE(Alerts.alert_handshake_failure, + "Inconsistent secure renegotiation indication"); + } + + // if there is no security renegotiation indication or the previous + // handshake is insecure. + if (!renegotiationIndicated || !secureRenegotiation) { + if (isInitialHandshake) { + if (!allowLegacyHelloMessages) { + // abort the handshake with a fatal handshake_failure alert + fatalSE(Alerts.alert_handshake_failure, + "Failed to negotiate the use of secure renegotiation"); + } + + // continue with legacy ClientHello + if (debug != null && Debug.isOn("handshake")) { + System.out.println("Warning: No renegotiation " + + "indication in ClientHello, allow legacy ClientHello"); + } + } else if (!allowUnsafeRenegotiation) { + // abort the handshake + if (activeProtocolVersion.v >= ProtocolVersion.TLS10.v) { + // response with a no_renegotiation warning, + warningSE(Alerts.alert_no_renegotiation); + + // invalidate the handshake so that the caller can + // dispose this object. + invalidated = true; + + // If there is still unread block in the handshake + // input stream, it would be truncated with the disposal + // and the next handshake message will become incomplete. + // + // However, according to SSL/TLS specifications, no more + // handshake message could immediately follow ClientHello + // or HelloRequest. But in case of any improper messages, + // we'd better check to ensure there is no remaining bytes + // in the handshake input stream. + if (input.available() > 0) { + fatalSE(Alerts.alert_unexpected_message, + "ClientHello followed by an unexpected " + + "handshake message"); + } + + return; + } else { + // For SSLv3, send the handshake_failure fatal error. + // Note that SSLv3 does not define a no_renegotiation + // alert like TLSv1. However we cannot ignore the message + // simply, otherwise the other side was waiting for a + // response that would never come. + fatalSE(Alerts.alert_handshake_failure, + "Renegotiation is not allowed"); + } + } else { // !isInitialHandshake && allowUnsafeRenegotiation + // continue with unsafe renegotiation. + if (debug != null && Debug.isOn("handshake")) { + System.out.println( + "Warning: continue with insecure renegotiation"); + } } } @@ -454,7 +536,7 @@ // verify that the ciphersuite from the cached session // is in the list of client requested ciphersuites and // we have it enabled - if ((isEnabled(suite) == false) || + if ((isNegotiable(suite) == false) || (mesg.getCipherSuites().contains(suite) == false)) { resumingSession = false; } else { @@ -484,8 +566,8 @@ if (!enableNewSession) { throw new SSLException("Client did not resume a session"); } - supportedCurves = (SupportedEllipticCurvesExtension)mesg.extensions.get - (ExtensionType.EXT_ELLIPTIC_CURVES); + supportedCurves = (SupportedEllipticCurvesExtension) + mesg.extensions.get(ExtensionType.EXT_ELLIPTIC_CURVES); chooseCipherSuite(mesg); session = new SSLSessionImpl(protocolVersion, cipherSuite, sslContext.getSecureRandom(), @@ -498,6 +580,21 @@ m1.sessionId = session.getSessionId(); m1.compression_method = session.getCompression(); + if (secureRenegotiation) { + // For ServerHellos that are initial handshakes, then the + // "renegotiated_connection" field in "renegotiation_info" + // extension is of zero length. + // + // For ServerHellos that are renegotiating, this field contains + // the concatenation of client_verify_data and server_verify_data. + // + // Note that for initial handshakes, both the clientVerifyData + // variable and serverVerifyData variable are of zero length. + HelloExtension serverHelloRI = new RenegotiationInfoExtension( + clientVerifyData, serverVerifyData); + m1.extensions.add(serverHelloRI); + } + if (debug != null && Debug.isOn("handshake")) { m1.print(System.out); System.out.println("Cipher suite: " + session.getSuite()); @@ -686,11 +783,13 @@ */ private void chooseCipherSuite(ClientHello mesg) throws IOException { for (CipherSuite suite : mesg.getCipherSuites().collection()) { - if (isEnabled(suite) == false) { + if (isNegotiable(suite) == false) { continue; } + if (doClientAuth == SSLEngineImpl.clauth_required) { - if ((suite.keyExchange == K_DH_ANON) || (suite.keyExchange == K_ECDH_ANON)) { + if ((suite.keyExchange == K_DH_ANON) || + (suite.keyExchange == K_ECDH_ANON)) { continue; } } @@ -728,7 +827,7 @@ return true; } - if (suite.isAvailable() == false) { + if (suite.isNegotiable() == false) { return false; } @@ -1136,6 +1235,13 @@ } /* + * save client verify data for secure renegotiation + */ + if (secureRenegotiation) { + clientVerifyData = mesg.getVerifyData(); + } + + /* * OK, it verified. If we're doing the full handshake, add that * "Finished" message to the hash of handshake messages, then send * the change_cipher_spec and Finished message. @@ -1185,6 +1291,13 @@ sendChangeCipherSpec(mesg, finishedTag); /* + * save server verify data for secure renegotiation + */ + if (secureRenegotiation) { + serverVerifyData = mesg.getVerifyData(); + } + + /* * Update state machine so client MUST send 'finished' next * The update should only take place if it is not in the fast * handshake mode since the server has to wait for a finished
--- a/src/share/classes/sun/tools/jar/CommandLine.java Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/classes/sun/tools/jar/CommandLine.java Mon Oct 18 21:50:02 2010 -0700 @@ -36,7 +36,7 @@ /** * Various utility methods for processing Java tool command line arguments. * - * <p><b>This is NOT part of any API suppored by Sun Microsystems. If + * <p><b>This is NOT part of any API supported by Oracle. If * you write code that depends on this, you do so at your own risk. * This code and its internal interfaces are subject to change or * deletion without notice.</b>
--- a/src/share/native/common/check_code.c Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/native/common/check_code.c Mon Oct 18 21:50:02 2010 -0700 @@ -2940,7 +2940,7 @@ if (verify_verbose) { jio_fprintf(stdout, " ["); for (i = handler_info_length; --i >= 0; handler_info++) - if (handler_info->start <= inumber && handler_info->end > inumber) + if (handler_info->start <= (int)inumber && handler_info->end > (int)inumber) jio_fprintf(stdout, "%d* ", handler_info->handler); for (i = 0; i < successors_count; i++) jio_fprintf(stdout, "%d ", successors[i]); @@ -3011,7 +3011,8 @@ instruction_data_type *this_idata = &idata[to_inumber]; register_info_type old_reg_info; stack_info_type old_stack_info; - flag_type old_and_flags, old_or_flags; + flag_type old_and_flags = 0; + flag_type old_or_flags = 0; #endif #ifdef DEBUG
--- a/src/share/native/common/jdk_util.c Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/native/common/jdk_util.c Mon Oct 18 21:50:02 2010 -0700 @@ -76,7 +76,7 @@ } - memset(info, 0, sizeof(info_size)); + memset(info, 0, info_size); info->jdk_version = ((jdk_major_version & 0xFF) << 24) | ((jdk_minor_version & 0xFF) << 16) | ((jdk_micro_version & 0xFF) << 8) |
--- a/src/share/native/common/jni_util.c Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/native/common/jni_util.c Mon Oct 18 21:50:02 2010 -0700 @@ -433,7 +433,7 @@ for (i=0; i<len; i++) { jchar unicode = str[i]; if (unicode <= 0x00ff) - result[i] = unicode; + result[i] = (char)unicode; else result[i] = '?'; } @@ -498,7 +498,7 @@ for (i=0; i<len; i++) { jchar unicode = str[i]; if (unicode <= 0x007f ) - result[i] = unicode; + result[i] = (char)unicode; else result[i] = '?'; } @@ -569,7 +569,7 @@ for (i=0; i<len; i++) { jchar c = str[i]; if (c < 256) - result[i] = c; + result[i] = (char)c; else switch(c) { case 0x20AC: result[i] = (char)0x80; break; case 0x201A: result[i] = (char)0x82; break;
--- a/src/share/native/java/lang/Class.c Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/native/java/lang/Class.c Mon Oct 18 21:50:02 2010 -0700 @@ -102,8 +102,8 @@ char *clname; jclass cls = 0; char buf[128]; - int len; - int unicode_len; + jsize len; + jsize unicode_len; if (classname == NULL) { JNU_ThrowNullPointerException(env, 0); @@ -112,7 +112,7 @@ len = (*env)->GetStringUTFLength(env, classname); unicode_len = (*env)->GetStringLength(env, classname); - if (len >= sizeof(buf)) { + if (len >= (jsize)sizeof(buf)) { clname = malloc(len + 1); if (clname == NULL) { JNU_ThrowOutOfMemoryError(env, NULL);
--- a/src/share/native/java/lang/ClassLoader.c Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/native/java/lang/ClassLoader.c Mon Oct 18 21:50:02 2010 -0700 @@ -331,7 +331,7 @@ if (handle) { const char *onLoadSymbols[] = JNI_ONLOAD_SYMBOLS; JNI_OnLoad_t JNI_OnLoad; - int i; + unsigned int i; for (i = 0; i < sizeof(onLoadSymbols) / sizeof(char *); i++) { JNI_OnLoad = (JNI_OnLoad_t) JVM_FindLibraryEntry(handle, onLoadSymbols[i]); @@ -369,7 +369,7 @@ cause = (*env)->ExceptionOccurred(env); if (cause) { (*env)->ExceptionClear(env); - (*env)->SetLongField(env, this, handleID, (jlong)NULL); + (*env)->SetLongField(env, this, handleID, (jlong)0); (*env)->Throw(env, cause); } goto done; @@ -392,7 +392,7 @@ const char *onUnloadSymbols[] = JNI_ONUNLOAD_SYMBOLS; void *handle; JNI_OnUnload_t JNI_OnUnload; - int i; + unsigned int i; if (!initIDs(env)) return;
--- a/src/share/native/java/lang/System.c Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/native/java/lang/System.c Mon Oct 18 21:50:02 2010 -0700 @@ -109,7 +109,7 @@ #error "ERROR: No override of JAVA_SPECIFICATION_VENDOR is allowed" #else #define JAVA_SPECIFICATION_VENDOR "Oracle Corporation" -#endif +#endif static int fmtdefault; // boolean value jobject fillI18nProps(JNIEnv *env, jobject props, char *baseKey,
--- a/src/share/native/java/lang/fdlibm/include/fdlibm.h Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/native/java/lang/fdlibm/include/fdlibm.h Mon Oct 18 21:50:02 2010 -0700 @@ -46,11 +46,13 @@ #define __LOp(x) *(1+(int*)x) #endif +#ifndef __P #ifdef __STDC__ #define __P(p) p #else #define __P(p) () #endif +#endif /* * ANSI/POSIX
--- a/src/share/native/java/lang/reflect/Proxy.c Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/native/java/lang/reflect/Proxy.c Mon Oct 18 21:50:02 2010 -0700 @@ -82,9 +82,9 @@ goto free_body; if (name != NULL) { - int len = (*env)->GetStringUTFLength(env, name); - int unicode_len = (*env)->GetStringLength(env, name); - if (len >= sizeof(buf)) { + jsize len = (*env)->GetStringUTFLength(env, name); + jsize unicode_len = (*env)->GetStringLength(env, name); + if (len >= (jsize)sizeof(buf)) { utfName = malloc(len + 1); if (utfName == NULL) { JNU_ThrowOutOfMemoryError(env, NULL);
--- a/src/share/native/java/nio/Bits.c Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/native/java/nio/Bits.c Mon Oct 18 21:50:02 2010 -0700 @@ -72,7 +72,7 @@ jlong srcPos, jlong dstAddr, jlong length) { jbyte *bytes; - size_t i, size; + size_t size; jshort *srcShort, *dstShort, *endShort; jshort tmpShort; @@ -83,7 +83,7 @@ if (length > MBYTE) size = MBYTE; else - size = length; + size = (size_t)length; GETCRITICAL(bytes, env, src); @@ -107,7 +107,7 @@ jobject dst, jlong dstPos, jlong length) { jbyte *bytes; - size_t i, size; + size_t size; jshort *srcShort, *dstShort, *endShort; jshort tmpShort; @@ -118,7 +118,7 @@ if (length > MBYTE) size = MBYTE; else - size = length; + size = (size_t)length; GETCRITICAL(bytes, env, dst); @@ -142,7 +142,7 @@ jlong srcPos, jlong dstAddr, jlong length) { jbyte *bytes; - size_t i, size; + size_t size; jint *srcInt, *dstInt, *endInt; jint tmpInt; @@ -153,7 +153,7 @@ if (length > MBYTE) size = MBYTE; else - size = length; + size = (size_t)length; GETCRITICAL(bytes, env, src); @@ -177,7 +177,7 @@ jobject dst, jlong dstPos, jlong length) { jbyte *bytes; - size_t i, size; + size_t size; jint *srcInt, *dstInt, *endInt; jint tmpInt; @@ -188,7 +188,7 @@ if (length > MBYTE) size = MBYTE; else - size = length; + size = (size_t)length; GETCRITICAL(bytes, env, dst); @@ -212,7 +212,7 @@ jlong srcPos, jlong dstAddr, jlong length) { jbyte *bytes; - size_t i, size; + size_t size; jlong *srcLong, *dstLong, *endLong; jlong tmpLong; @@ -223,7 +223,7 @@ if (length > MBYTE) size = MBYTE; else - size = length; + size = (size_t)length; GETCRITICAL(bytes, env, src); @@ -247,7 +247,7 @@ jobject dst, jlong dstPos, jlong length) { jbyte *bytes; - size_t i, size; + size_t size; jlong *srcLong, *dstLong, *endLong; jlong tmpLong; @@ -258,7 +258,7 @@ if (length > MBYTE) size = MBYTE; else - size = length; + size = (size_t)length; GETCRITICAL(bytes, env, dst);
--- a/src/share/native/java/util/zip/Inflater.c Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/native/java/util/zip/Inflater.c Mon Oct 18 21:50:02 2010 -0700 @@ -38,6 +38,8 @@ #include "zlib.h" #include "java_util_zip_Inflater.h" +#define MIN2(x, y) ((x) < (y) ? (x) : (y)) + #define ThrowDataFormatException(env, msg) \ JNU_ThrowByName(env, "java/util/zip/DataFormatException", msg) @@ -116,13 +118,27 @@ jbyte *in_buf; jbyte *out_buf; int ret; + /* + * Avoid excess copying. + * zlib stream usually has a few bytes of overhead for header info + * (depends on the underlying data) + * + * (a) 5 bytes per 16KB + * (b) 6 bytes for entire stream + * (c) 4 bytes for gzip header + * (d) 2 bytes for crc + * + * Use 20 bytes as the "safe cutoff" number. + */ + jint in_len = MIN2(this_len, len + 20); + jint consumed; - in_buf = (jbyte *) malloc(this_len); + in_buf = (jbyte *) malloc(in_len); if (in_buf == 0) { JNU_ThrowOutOfMemoryError(env, 0); return 0; } - (*env)->GetByteArrayRegion(env, this_buf, this_off, this_len, in_buf); + (*env)->GetByteArrayRegion(env, this_buf, this_off, in_len, in_buf); out_buf = (jbyte *) malloc(len); if (out_buf == 0) { @@ -133,7 +149,7 @@ strm->next_in = (Bytef *) in_buf; strm->next_out = (Bytef *) out_buf; - strm->avail_in = this_len; + strm->avail_in = in_len; strm->avail_out = len; ret = inflate(strm, Z_PARTIAL_FLUSH); @@ -148,16 +164,16 @@ (*env)->SetBooleanField(env, this, finishedID, JNI_TRUE); /* fall through */ case Z_OK: - this_off += this_len - strm->avail_in; - (*env)->SetIntField(env, this, offID, this_off); - (*env)->SetIntField(env, this, lenID, strm->avail_in); + consumed = in_len - strm->avail_in; + (*env)->SetIntField(env, this, offID, this_off + consumed); + (*env)->SetIntField(env, this, lenID, this_len - consumed); return len - strm->avail_out; case Z_NEED_DICT: (*env)->SetBooleanField(env, this, needDictID, JNI_TRUE); /* Might have consumed some input here! */ - this_off += this_len - strm->avail_in; - (*env)->SetIntField(env, this, offID, this_off); - (*env)->SetIntField(env, this, lenID, strm->avail_in); + consumed = in_len - strm->avail_in; + (*env)->SetIntField(env, this, offID, this_off + consumed); + (*env)->SetIntField(env, this, lenID, this_len - consumed); return 0; case Z_BUF_ERROR: return 0;
--- a/src/share/native/sun/awt/image/BufImgSurfaceData.c Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/native/sun/awt/image/BufImgSurfaceData.c Mon Oct 18 21:50:02 2010 -0700 @@ -48,9 +48,12 @@ static jfieldID rgbID; static jfieldID mapSizeID; -static jfieldID CMpDataID; +static jfieldID colorDataID; +static jfieldID pDataID; static jfieldID allGrayID; +static jclass clsICMCD; +static jmethodID initICMCDmID; /* * Class: sun_awt_image_BufImgSurfaceData * Method: initIDs @@ -58,18 +61,23 @@ */ JNIEXPORT void JNICALL Java_sun_awt_image_BufImgSurfaceData_initIDs - (JNIEnv *env, jclass bisd, jclass icm) +(JNIEnv *env, jclass bisd, jclass icm, jclass cd) { if (sizeof(BufImgRIPrivate) > SD_RASINFO_PRIVATE_SIZE) { JNU_ThrowInternalError(env, "Private RasInfo structure too large!"); return; } + clsICMCD = (*env)->NewWeakGlobalRef(env, cd); + initICMCDmID = (*env)->GetMethodID(env, cd, "<init>", "(J)V"); + pDataID = (*env)->GetFieldID(env, cd, "pData", "J"); + rgbID = (*env)->GetFieldID(env, icm, "rgb", "[I"); allGrayID = (*env)->GetFieldID(env, icm, "allgrayopaque", "Z"); mapSizeID = (*env)->GetFieldID(env, icm, "map_size", "I"); - CMpDataID = (*env)->GetFieldID(env, icm, "pData", "J"); - if (allGrayID == 0 || rgbID == 0 || mapSizeID == 0 || CMpDataID == 0) { + colorDataID = (*env)->GetFieldID(env, icm, "colorData", + "Lsun/awt/image/BufImgSurfaceData$ICMColorData;"); + if (allGrayID == 0 || rgbID == 0 || mapSizeID == 0 || pDataID == 0|| colorDataID == 0 || initICMCDmID == 0) { JNU_ThrowInternalError(env, "Could not get field IDs"); } } @@ -81,18 +89,9 @@ */ JNIEXPORT void JNICALL Java_sun_awt_image_BufImgSurfaceData_freeNativeICMData - (JNIEnv *env, jclass sd, jobject icm) + (JNIEnv *env, jclass sd, jlong pData) { - jlong pData; - ColorData *cdata; - - if (JNU_IsNull(env, icm)) { - JNU_ThrowNullPointerException(env, "IndexColorModel cannot be null"); - return; - } - - pData = (*env)->GetLongField (env, icm, CMpDataID); - cdata = (ColorData *)pData; + ColorData *cdata = (ColorData*)jlong_to_ptr(pData); freeICMColorData(cdata); } @@ -263,32 +262,48 @@ static ColorData *BufImg_SetupICM(JNIEnv *env, BufImgSDOps *bisdo) { - ColorData *cData; + ColorData *cData = NULL; + jobject colorData; if (JNU_IsNull(env, bisdo->icm)) { return (ColorData *) NULL; } - cData = (ColorData *) JNU_GetLongFieldAsPtr(env, bisdo->icm, CMpDataID); + colorData = (*env)->GetObjectField(env, bisdo->icm, colorDataID); - if (cData == NULL) { - cData = (ColorData*)calloc(1, sizeof(ColorData)); + if (JNU_IsNull(env, colorData)) { + if (JNU_IsNull(env, clsICMCD)) { + // we are unable to create a wrapper object + return (ColorData*)NULL; + } + } else { + cData = (ColorData*)JNU_GetLongFieldAsPtr(env, colorData, pDataID); + } + + if (cData != NULL) { + return cData; + } + + cData = (ColorData*)calloc(1, sizeof(ColorData)); - if (cData != NULL) { - jboolean allGray - = (*env)->GetBooleanField(env, bisdo->icm, allGrayID); - int *pRgb = (int *) - ((*env)->GetPrimitiveArrayCritical(env, bisdo->lutarray, NULL)); - cData->img_clr_tbl = initCubemap(pRgb, bisdo->lutsize, 32); - if (allGray == JNI_TRUE) { - initInverseGrayLut(pRgb, bisdo->lutsize, cData); - } - (*env)->ReleasePrimitiveArrayCritical(env, bisdo->lutarray, pRgb, - JNI_ABORT); + if (cData != NULL) { + jboolean allGray + = (*env)->GetBooleanField(env, bisdo->icm, allGrayID); + int *pRgb = (int *) + ((*env)->GetPrimitiveArrayCritical(env, bisdo->lutarray, NULL)); + cData->img_clr_tbl = initCubemap(pRgb, bisdo->lutsize, 32); + if (allGray == JNI_TRUE) { + initInverseGrayLut(pRgb, bisdo->lutsize, cData); + } + (*env)->ReleasePrimitiveArrayCritical(env, bisdo->lutarray, pRgb, + JNI_ABORT); - initDitherTables(cData); + initDitherTables(cData); - JNU_SetLongFieldFromPtr(env, bisdo->icm, CMpDataID, cData); + if (JNU_IsNull(env, colorData)) { + jlong pData = ptr_to_jlong(cData); + colorData = (*env)->NewObjectA(env, clsICMCD, initICMCDmID, (jvalue *)&pData); + (*env)->SetObjectField(env, bisdo->icm, colorDataID, colorData); } }
--- a/src/share/native/sun/awt/image/jpeg/imageioJPEG.c Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/native/sun/awt/image/jpeg/imageioJPEG.c Mon Oct 18 21:50:02 2010 -0700 @@ -2614,7 +2614,8 @@ JSAMPROW scanLinePtr; int i, j; int pixelStride; - unsigned char *in, *out, *pixelLimit; + unsigned char *in, *out, *pixelLimit, *scanLineLimit; + unsigned int scanLineSize, pixelBufferSize; int targetLine; pixelBufferPtr pb; sun_jpeg_error_ptr jerr; @@ -2650,19 +2651,25 @@ } + scanLineSize = destWidth * numBands; if ((inCs < 0) || (inCs > JCS_YCCK) || (outCs < 0) || (outCs > JCS_YCCK) || (numBands < 1) || (numBands > MAX_BANDS) || (srcWidth < 0) || (destWidth < 0) || (destWidth > srcWidth) || (destHeight < 0) || - (stepX < 0) || (stepY < 0)) + (stepX < 0) || (stepY < 0) || + ((scanLineSize / numBands) < destWidth)) /* destWidth causes an integer overflow */ { JNU_ThrowByName(env, "javax/imageio/IIOException", "Invalid argument to native writeImage"); return JNI_FALSE; } + if (stepX > srcWidth) { + stepX = srcWidth; + } + bandSize = (*env)->GetIntArrayElements(env, bandSizes, NULL); for (i = 0; i < numBands; i++) { @@ -2710,7 +2717,7 @@ } // Allocate a 1-scanline buffer - scanLinePtr = (JSAMPROW)malloc(destWidth*numBands); + scanLinePtr = (JSAMPROW)malloc(scanLineSize); if (scanLinePtr == NULL) { RELEASE_ARRAYS(env, data, (const JOCTET *)(dest->next_output_byte)); JNU_ThrowByName( env, @@ -2718,6 +2725,7 @@ "Writing JPEG Stream"); return data->abortFlag; } + scanLineLimit = scanLinePtr + scanLineSize; /* Establish the setjmp return context for sun_jpeg_error_exit to use. */ jerr = (sun_jpeg_error_ptr) cinfo->err; @@ -2866,6 +2874,8 @@ } targetLine = 0; + pixelBufferSize = srcWidth * numBands; + pixelStride = numBands * stepX; // for each line in destHeight while ((data->abortFlag == JNI_FALSE) @@ -2886,9 +2896,9 @@ in = data->pixelBuf.buf.bp; out = scanLinePtr; - pixelLimit = in + srcWidth*numBands; - pixelStride = numBands*stepX; - for (; in < pixelLimit; in += pixelStride) { + pixelLimit = in + ((pixelBufferSize > data->pixelBuf.byteBufferLength) ? + data->pixelBuf.byteBufferLength : pixelBufferSize); + for (; (in < pixelLimit) && (out < scanLineLimit); in += pixelStride) { for (i = 0; i < numBands; i++) { if (scale !=NULL && scale[i] != NULL) { *out++ = scale[i][*(in+i)];
--- a/src/share/native/sun/management/Flag.c Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/native/sun/management/Flag.c Mon Oct 18 21:50:02 2010 -0700 @@ -25,6 +25,7 @@ #include <stdlib.h> #include <stdio.h> +#include <string.h> #include <jni.h> #include "management.h" #include "sun_management_Flag.h" @@ -80,8 +81,6 @@ Java_sun_management_Flag_getFlags (JNIEnv *env, jclass cls, jobjectArray names, jobjectArray flags, jint count) { - char errmsg[128]; - jint num_flags, i, index; jmmVMGlobal* globals; size_t gsize;
--- a/src/share/native/sun/misc/VM.c Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/native/sun/misc/VM.c Mon Oct 18 21:50:02 2010 -0700 @@ -23,6 +23,8 @@ * questions. */ +#include <string.h> + #include "jni.h" #include "jni_util.h" #include "jlong.h" @@ -113,7 +115,6 @@ JNIEXPORT void JNICALL Java_sun_misc_VM_initialize(JNIEnv *env, jclass cls) { - char errmsg[128]; GetJvmVersionInfo_fp func_p; if (!JDK_InitJvmHandle()) { @@ -123,8 +124,6 @@ func_p = (GetJvmVersionInfo_fp) JDK_FindJvmEntry("JVM_GetVersionInfo"); if (func_p != NULL) { - char errmsg[100]; - jfieldID fid; jvm_version_info info; memset(&info, 0, sizeof(info));
--- a/src/share/native/sun/misc/VMSupport.c Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/native/sun/misc/VMSupport.c Mon Oct 18 21:50:02 2010 -0700 @@ -38,8 +38,6 @@ JNIEXPORT jobject JNICALL Java_sun_misc_VMSupport_initAgentProperties(JNIEnv *env, jclass cls, jobject props) { - char errmsg[128]; - if (InitAgentProperties_fp == NULL) { if (!JDK_InitJvmHandle()) { JNU_ThrowInternalError(env,
--- a/src/share/native/sun/security/pkcs11/wrapper/p11_crypt.c Mon Oct 18 21:46:27 2010 -0700 +++ b/src/share/native/sun/security/pkcs11/wrapper/p11_crypt.c Mon Oct 18 21:50:02 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. */ /* Copyright (c) 2002 Graz University of Technology. All rights reserved. @@ -114,8 +114,7 @@ { CK_SESSION_HANDLE ckSessionHandle; CK_RV rv; - CK_BYTE IBUF[MAX_STACK_BUFFER_LEN]; - CK_BYTE OBUF[MAX_STACK_BUFFER_LEN]; + CK_BYTE_PTR inBufP; CK_BYTE_PTR outBufP; CK_ULONG ckEncryptedPartLen; @@ -125,50 +124,27 @@ ckSessionHandle = jLongToCKULong(jSessionHandle); - if (jInLen > MAX_STACK_BUFFER_LEN) { - inBufP = (CK_BYTE_PTR)malloc((size_t)jInLen); - if (inBufP == NULL) { - JNU_ThrowOutOfMemoryError(env, 0); + inBufP = (*env)->GetPrimitiveArrayCritical(env, jIn, NULL); + if (inBufP == NULL) { return 0; } + + outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL); + if (outBufP == NULL) { + // Make sure to release inBufP + (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT); return 0; - } - } else { - inBufP = IBUF; - } - (*env)->GetByteArrayRegion(env, jIn, jInOfs, jInLen, (jbyte *)inBufP); - if ((*env)->ExceptionCheck(env)) { - if (inBufP != IBUF) { free(inBufP); } - return 0; } ckEncryptedPartLen = jOutLen; - if (jOutLen > MAX_STACK_BUFFER_LEN) { - outBufP = (CK_BYTE_PTR)malloc((size_t)jOutLen); - if (outBufP == NULL) { - if (inBufP != IBUF) { - free(inBufP); - } - JNU_ThrowOutOfMemoryError(env, 0); - return 0; - } - } else { - outBufP = OBUF; - } - rv = (*ckpFunctions->C_Encrypt)(ckSessionHandle, inBufP, jInLen, - outBufP, &ckEncryptedPartLen); + rv = (*ckpFunctions->C_Encrypt)(ckSessionHandle, + (CK_BYTE_PTR)(inBufP + jInOfs), jInLen, + (CK_BYTE_PTR)(outBufP + jOutOfs), + &ckEncryptedPartLen); - if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) { - if (ckEncryptedPartLen > 0) { - (*env)->SetByteArrayRegion(env, jOut, jOutOfs, ckEncryptedPartLen, - (jbyte *)outBufP); - } - } - if (inBufP != IBUF) { - free(inBufP); - } - if (outBufP != OBUF) { - free(outBufP); - } + (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_ABORT); + (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT); + + ckAssertReturnValueOK(env, rv); return ckEncryptedPartLen; } #endif @@ -193,8 +169,7 @@ { CK_SESSION_HANDLE ckSessionHandle; CK_RV rv; - CK_BYTE IBUF[MAX_STACK_BUFFER_LEN]; - CK_BYTE OBUF[MAX_STACK_BUFFER_LEN]; + CK_BYTE_PTR inBufP; CK_BYTE_PTR outBufP; CK_ULONG ckEncryptedPartLen; @@ -205,64 +180,45 @@ ckSessionHandle = jLongToCKULong(jSessionHandle); if (directIn != 0) { - inBufP = (CK_BYTE_PTR)(directIn + jInOfs); + inBufP = (CK_BYTE_PTR) directIn; } else { - if (jInLen > MAX_STACK_BUFFER_LEN) { - inBufP = (CK_BYTE_PTR)malloc((size_t)jInLen); - if (inBufP == NULL) { - JNU_ThrowOutOfMemoryError(env, 0); + inBufP = (*env)->GetPrimitiveArrayCritical(env, jIn, NULL); + if (inBufP == NULL) { return 0; } + } + + if (directOut != 0) { + outBufP = (CK_BYTE_PTR) directOut; + } else { + outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL); + if (outBufP == NULL) { + // Make sure to release inBufP + (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT); return 0; - } - } else { - inBufP = IBUF; - } - (*env)->GetByteArrayRegion(env, jIn, jInOfs, jInLen, (jbyte *)inBufP); - if ((*env)->ExceptionCheck(env)) { - if (directIn == 0 && inBufP != IBUF) { free(inBufP); } - return 0; } } ckEncryptedPartLen = jOutLen; - if (directOut != 0) { - outBufP = (CK_BYTE_PTR)(directOut + jOutOfs); - } else { - if (jOutLen > MAX_STACK_BUFFER_LEN) { - outBufP = (CK_BYTE_PTR)malloc((size_t)jOutLen); - if (outBufP == NULL) { - if (directIn == 0 && inBufP != IBUF) { - free(inBufP); - } - JNU_ThrowOutOfMemoryError(env, 0); - return 0; - } - } else { - outBufP = OBUF; - } - } //printf("EU: inBufP=%i, jInOfs=%i, jInLen=%i, outBufP=%i\n", // inBufP, jInOfs, jInLen, outBufP); rv = (*ckpFunctions->C_EncryptUpdate)(ckSessionHandle, - inBufP, jInLen, - outBufP, &ckEncryptedPartLen); + (CK_BYTE_PTR)(inBufP + jInOfs), jInLen, + (CK_BYTE_PTR)(outBufP + jOutOfs), + &ckEncryptedPartLen); //printf("EU: ckEncryptedPartLen=%i\n", ckEncryptedPartLen); - if (directIn == 0 && inBufP != IBUF) { - free(inBufP); + if (directIn == 0) { + (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT); } - if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) { - if (directOut == 0 && ckEncryptedPartLen > 0) { - (*env)->SetByteArrayRegion(env, jOut, jOutOfs, ckEncryptedPartLen, - (jbyte *)outBufP); - } + if (directOut == 0) { + (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_ABORT); } - if (directOut == 0 && outBufP != OBUF) { - free(outBufP); - } + + ckAssertReturnValueOK(env, rv); + return ckEncryptedPartLen; } #endif @@ -284,7 +240,6 @@ { CK_SESSION_HANDLE ckSessionHandle; CK_RV rv; - CK_BYTE BUF[MAX_STACK_BUFFER_LEN]; CK_BYTE_PTR outBufP; CK_ULONG ckLastEncryptedPartLen; @@ -293,31 +248,29 @@ ckSessionHandle = jLongToCKULong(jSessionHandle); - ckLastEncryptedPartLen = jOutLen; if (directOut != 0) { - outBufP = (CK_BYTE_PTR)(directOut + jOutOfs); + outBufP = (CK_BYTE_PTR) directOut; } else { - // output length should always be less than MAX_STACK_BUFFER_LEN - outBufP = BUF; + outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL); + if (outBufP == NULL) { return 0; } } + ckLastEncryptedPartLen = jOutLen; + //printf("EF: outBufP=%i\n", outBufP); - rv = (*ckpFunctions->C_EncryptFinal)(ckSessionHandle, outBufP, + rv = (*ckpFunctions->C_EncryptFinal)(ckSessionHandle, + (CK_BYTE_PTR)(outBufP + jOutOfs), &ckLastEncryptedPartLen); //printf("EF: ckLastEncryptedPartLen=%i", ckLastEncryptedPartLen); - if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) { - if (directOut == 0 && ckLastEncryptedPartLen > 0) { - (*env)->SetByteArrayRegion(env, jOut, jOutOfs, ckLastEncryptedPartLen, - (jbyte *)outBufP); - } + if (directOut == 0) { + (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_ABORT); } - if (directOut == 0 && outBufP != BUF) { - free(outBufP); - } + ckAssertReturnValueOK(env, rv); + return ckLastEncryptedPartLen; } #endif @@ -381,8 +334,7 @@ { CK_SESSION_HANDLE ckSessionHandle; CK_RV rv; - CK_BYTE IBUF[MAX_STACK_BUFFER_LEN]; - CK_BYTE OBUF[MAX_STACK_BUFFER_LEN]; + CK_BYTE_PTR inBufP; CK_BYTE_PTR outBufP; CK_ULONG ckPartLen; @@ -392,49 +344,27 @@ ckSessionHandle = jLongToCKULong(jSessionHandle); - if (jInLen > MAX_STACK_BUFFER_LEN) { - inBufP = (CK_BYTE_PTR)malloc((size_t)jInLen); - if (inBufP == NULL) { - JNU_ThrowOutOfMemoryError(env, 0); + inBufP = (*env)->GetPrimitiveArrayCritical(env, jIn, NULL); + if (inBufP == NULL) { return 0; } + + outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL); + if (outBufP == NULL) { + // Make sure to release inBufP + (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT); return 0; - } - } else { - inBufP = IBUF; - } - (*env)->GetByteArrayRegion(env, jIn, jInOfs, jInLen, (jbyte *)inBufP); - if ((*env)->ExceptionCheck(env)) { - if (inBufP != IBUF) { free(inBufP); } - return 0; } ckPartLen = jOutLen; - if (jOutLen > MAX_STACK_BUFFER_LEN) { - outBufP = (CK_BYTE_PTR)malloc((size_t)jOutLen); - if (outBufP == NULL) { - if (inBufP != IBUF) { - free(inBufP); - } - JNU_ThrowOutOfMemoryError(env, 0); - return 0; - } - } else { - outBufP = OBUF; - } - rv = (*ckpFunctions->C_Decrypt)(ckSessionHandle, inBufP, jInLen, - outBufP, &ckPartLen); - if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) { - if (ckPartLen > 0) { - (*env)->SetByteArrayRegion(env, jOut, jOutOfs, ckPartLen, - (jbyte *)outBufP); - } - } - if (inBufP != IBUF) { - free(inBufP); - } - if (outBufP != OBUF) { - free(outBufP); - } + rv = (*ckpFunctions->C_Decrypt)(ckSessionHandle, + (CK_BYTE_PTR)(inBufP + jInOfs), jInLen, + (CK_BYTE_PTR)(outBufP + jOutOfs), + &ckPartLen); + + (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_ABORT); + (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT); + + ckAssertReturnValueOK(env, rv); return ckPartLen; } @@ -460,8 +390,7 @@ { CK_SESSION_HANDLE ckSessionHandle; CK_RV rv; - CK_BYTE IBUF[MAX_STACK_BUFFER_LEN]; - CK_BYTE OBUF[MAX_STACK_BUFFER_LEN]; + CK_BYTE_PTR inBufP; CK_BYTE_PTR outBufP; CK_ULONG ckDecryptedPartLen; @@ -472,59 +401,39 @@ ckSessionHandle = jLongToCKULong(jSessionHandle); if (directIn != 0) { - inBufP = (CK_BYTE_PTR)(directIn + jInOfs); + inBufP = (CK_BYTE_PTR) directIn; } else { - if (jInLen > MAX_STACK_BUFFER_LEN) { - inBufP = (CK_BYTE_PTR)malloc((size_t)jInLen); - if (inBufP == NULL) { - JNU_ThrowOutOfMemoryError(env, 0); + inBufP = (*env)->GetPrimitiveArrayCritical(env, jIn, NULL); + if (inBufP == NULL) { return 0; } + } + + if (directOut != 0) { + outBufP = (CK_BYTE_PTR) directOut; + } else { + outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL); + if (outBufP == NULL) { + // Make sure to release inBufP + (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT); return 0; - } - } else { - inBufP = IBUF; - } - (*env)->GetByteArrayRegion(env, jIn, jInOfs, jInLen, (jbyte *)inBufP); - if ((*env)->ExceptionCheck(env)) { - if (directIn == 0 && inBufP != IBUF) { free(inBufP); } - return 0; } } ckDecryptedPartLen = jOutLen; - if (directOut != 0) { - outBufP = (CK_BYTE_PTR)(directOut + jOutOfs); - } else { - if (jOutLen > MAX_STACK_BUFFER_LEN) { - outBufP = (CK_BYTE_PTR)malloc((size_t)jOutLen); - if (outBufP == NULL) { - if (directIn == 0 && inBufP != IBUF) { - free(inBufP); - } - JNU_ThrowOutOfMemoryError(env, 0); - return 0; - } - } else { - outBufP = OBUF; - } + + rv = (*ckpFunctions->C_DecryptUpdate)(ckSessionHandle, + (CK_BYTE_PTR)(inBufP + jInOfs), jInLen, + (CK_BYTE_PTR)(outBufP + jOutOfs), + &ckDecryptedPartLen); + if (directIn == 0) { + (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT); } - rv = (*ckpFunctions->C_DecryptUpdate)(ckSessionHandle, inBufP, jInLen, - outBufP, &ckDecryptedPartLen); - - if (directIn == 0 && inBufP != IBUF) { - free(inBufP); + if (directOut == 0) { + (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_ABORT); } - if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) { - if (directOut == 0 && ckDecryptedPartLen > 0) { - (*env)->SetByteArrayRegion(env, jOut, jOutOfs, ckDecryptedPartLen, - (jbyte *)outBufP); - } - } + ckAssertReturnValueOK(env, rv); - if (directOut == 0 && outBufP != OBUF) { - free(outBufP); - } return ckDecryptedPartLen; } @@ -547,7 +456,6 @@ { CK_SESSION_HANDLE ckSessionHandle; CK_RV rv; - CK_BYTE BUF[MAX_STACK_BUFFER_LEN]; CK_BYTE_PTR outBufP; CK_ULONG ckLastPartLen; @@ -556,27 +464,26 @@ ckSessionHandle = jLongToCKULong(jSessionHandle); - ckLastPartLen = jOutLen; if (directOut != 0) { - outBufP = (CK_BYTE_PTR)(directOut + jOutOfs); + outBufP = (CK_BYTE_PTR) directOut; } else { - // jOutLen should always be less than MAX_STACK_BUFFER_LEN - outBufP = BUF; + outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL); + if (outBufP == NULL) { return 0; } } - rv = (*ckpFunctions->C_DecryptFinal)(ckSessionHandle, outBufP, + ckLastPartLen = jOutLen; + + rv = (*ckpFunctions->C_DecryptFinal)(ckSessionHandle, + (CK_BYTE_PTR)(outBufP + jOutOfs), &ckLastPartLen); - if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) { - if (directOut == 0 && ckLastPartLen > 0) { - (*env)->SetByteArrayRegion(env, jOut, jOutOfs, ckLastPartLen, - (jbyte *)outBufP); - } + if (directOut == 0) { + (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_ABORT); + } - if (directOut == 0 && outBufP != BUF) { - free(outBufP); - } + ckAssertReturnValueOK(env, rv); + return ckLastPartLen; } #endif
--- a/src/solaris/native/java/io/UnixFileSystem_md.c Mon Oct 18 21:46:27 2010 -0700 +++ b/src/solaris/native/java/io/UnixFileSystem_md.c Mon Oct 18 21:50:02 2010 -0700 @@ -119,7 +119,7 @@ jobject file, jint a) { jboolean rv = JNI_FALSE; - int mode; + int mode = 0; switch (a) { case java_io_FileSystem_ACCESS_READ: mode = R_OK; @@ -151,7 +151,8 @@ jboolean rv = JNI_FALSE; WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) { - int amode, mode; + int amode = 0; + int mode; switch (access) { case java_io_FileSystem_ACCESS_READ: if (owneronly)
--- a/src/solaris/native/java/io/canonicalize_md.c Mon Oct 18 21:46:27 2010 -0700 +++ b/src/solaris/native/java/io/canonicalize_md.c Mon Oct 18 21:50:02 2010 -0700 @@ -246,7 +246,7 @@ if (r != NULL) { /* Append unresolved subpath to resolved subpath */ int rn = strlen(r); - if (rn + strlen(p) >= len) { + if (rn + (int)strlen(p) >= len) { /* Buffer overflow */ errno = ENAMETOOLONG; return -1;
--- a/src/solaris/native/java/lang/java_props_md.c Mon Oct 18 21:46:27 2010 -0700 +++ b/src/solaris/native/java/lang/java_props_md.c Mon Oct 18 21:50:02 2010 -0700 @@ -46,7 +46,9 @@ #include "java_props.h" #ifdef __linux__ -#define CODESET _NL_CTYPE_CODESET_NAME + #ifndef CODESET + #define CODESET _NL_CTYPE_CODESET_NAME + #endif #else #ifdef ALT_CODESET_KEY #define CODESET ALT_CODESET_KEY @@ -289,7 +291,7 @@ java_props_t * GetJavaProperties(JNIEnv *env) { - static java_props_t sprops = {0}; + static java_props_t sprops; char *v; /* tmp var */ if (sprops.user_dir) {
--- a/src/solaris/native/java/net/PlainDatagramSocketImpl.c Mon Oct 18 21:46:27 2010 -0700 +++ b/src/solaris/native/java/net/PlainDatagramSocketImpl.c Mon Oct 18 21:50:02 2010 -0700 @@ -2255,7 +2255,7 @@ { struct in_addr in; struct in_addr *inP = ∈ - int len = sizeof(struct in_addr); + socklen_t len = sizeof(struct in_addr); #ifdef __linux__ struct ip_mreqn mreqn;
--- a/src/solaris/native/sun/net/sdp/SdpSupport.c Mon Oct 18 21:46:27 2010 -0700 +++ b/src/solaris/native/sun/net/sdp/SdpSupport.c Mon Oct 18 21:50:02 2010 -0700 @@ -68,7 +68,7 @@ */ if (ipv6_available()) { JNU_ThrowIOException(env, "IPv6 not supported"); - return; + return -1; } s = socket(AF_INET_SDP, SOCK_STREAM, 0); #else
--- a/src/solaris/native/sun/net/spi/DefaultProxySelector.c Mon Oct 18 21:46:27 2010 -0700 +++ b/src/solaris/native/sun/net/spi/DefaultProxySelector.c Mon Oct 18 21:50:02 2010 -0700 @@ -158,7 +158,7 @@ char *phost = NULL; char *mode = NULL; int pport = 0; - int use_proxy; + int use_proxy = 0; int use_same_proxy = 0; const char* urlhost; jobject isa = NULL;
--- a/src/solaris/native/sun/nio/ch/Net.c Mon Oct 18 21:46:27 2010 -0700 +++ b/src/solaris/native/sun/nio/ch/Net.c Mon Oct 18 21:50:02 2010 -0700 @@ -298,7 +298,8 @@ struct linger linger; u_char carg; void *arg; - int arglen, n; + socklen_t arglen; + int n; /* Option value is an int except for a few specific cases */ @@ -317,7 +318,7 @@ } if (mayNeedConversion) { - n = NET_GetSockOpt(fdval(env, fdo), level, opt, arg, &arglen); + n = NET_GetSockOpt(fdval(env, fdo), level, opt, arg, (int*)&arglen); } else { n = getsockopt(fdval(env, fdo), level, opt, arg, &arglen); } @@ -527,7 +528,7 @@ Java_sun_nio_ch_Net_getInterface4(JNIEnv* env, jobject this, jobject fdo) { struct in_addr in; - int arglen = sizeof(struct in_addr); + socklen_t arglen = sizeof(struct in_addr); int n; n = getsockopt(fdval(env, fdo), IPPROTO_IP, IP_MULTICAST_IF, (void*)&in, &arglen); @@ -556,7 +557,7 @@ Java_sun_nio_ch_Net_getInterface6(JNIEnv* env, jobject this, jobject fdo) { int index; - int arglen = sizeof(index); + socklen_t arglen = sizeof(index); int n; n = getsockopt(fdval(env, fdo), IPPROTO_IPV6, IPV6_MULTICAST_IF, (void*)&index, &arglen);
--- a/src/solaris/native/sun/nio/ch/SctpNet.c Mon Oct 18 21:46:27 2010 -0700 +++ b/src/solaris/native/sun/nio/ch/SctpNet.c Mon Oct 18 21:50:02 2010 -0700 @@ -537,7 +537,7 @@ int result; struct linger linger; void *arg; - unsigned int arglen; + int arglen; if (mapSocketOption(opt, &klevel, &kopt) < 0) { JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
--- a/src/solaris/native/sun/nio/ch/UnixAsynchronousSocketChannelImpl.c Mon Oct 18 21:46:27 2010 -0700 +++ b/src/solaris/native/sun/nio/ch/UnixAsynchronousSocketChannelImpl.c Mon Oct 18 21:50:02 2010 -0700 @@ -40,10 +40,10 @@ jobject this, int fd) { int error = 0; - int n = sizeof(error); + socklen_t arglen = sizeof(error); int result; - result = getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &n); + result = getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &arglen); if (result < 0) { JNU_ThrowIOExceptionWithLastError(env, "getsockopt"); } else {
--- a/src/windows/native/common/jni_util_md.c Mon Oct 18 21:46:27 2010 -0700 +++ b/src/windows/native/common/jni_util_md.c Mon Oct 18 21:50:02 2010 -0700 @@ -79,7 +79,7 @@ } jstring nativeNewStringPlatform(JNIEnv *env, const char *str) { - static String_char_constructor = NULL; + static jmethodID String_char_constructor; if (useNativeConverter(env)) { // use native Unicode conversion so Kernel isn't required during // System.initProperties
--- a/src/windows/native/java/io/WinNTFileSystem_md.c Mon Oct 18 21:46:27 2010 -0700 +++ b/src/windows/native/java/io/WinNTFileSystem_md.c Mon Oct 18 21:50:02 2010 -0700 @@ -434,7 +434,9 @@ a = GetFileAttributesW(pathbuf); } } - if (a != INVALID_FILE_ATTRIBUTES) { + if ((a != INVALID_FILE_ATTRIBUTES) && + ((a & FILE_ATTRIBUTE_DIRECTORY) == 0)) + { if (enable) a = a & ~FILE_ATTRIBUTE_READONLY; else @@ -796,9 +798,10 @@ } } - if (a != INVALID_FILE_ATTRIBUTES) { + if ((a != INVALID_FILE_ATTRIBUTES) && + ((a & FILE_ATTRIBUTE_DIRECTORY) == 0)) { if (SetFileAttributesW(pathbuf, a | FILE_ATTRIBUTE_READONLY)) - rv = JNI_TRUE; + rv = JNI_TRUE; } free(pathbuf); return rv; @@ -812,7 +815,7 @@ jint drive) { jstring ret = NULL; - jchar *p = _wgetdcwd(drive, NULL, MAX_PATH); + jchar *p = currentDir(drive); jchar *pf = p; if (p == NULL) return NULL; if (iswalpha(*p) && (p[1] == L':')) p += 2;
--- a/src/windows/native/java/io/io_util_md.c Mon Oct 18 21:46:27 2010 -0700 +++ b/src/windows/native/java/io/io_util_md.c Mon Oct 18 21:50:02 2010 -0700 @@ -66,6 +66,25 @@ return pathToNTPath(env, path, JNI_FALSE); } +/* Returns the working directory for the given drive, or NULL */ +WCHAR* +currentDir(int di) { + UINT dt; + WCHAR root[4]; + // verify drive is valid as _wgetdcwd in the VC++ 2010 runtime + // library does not handle invalid drives. + root[0] = L'A' + (WCHAR)(di - 1); + root[1] = L':'; + root[2] = L'\\'; + root[3] = L'\0'; + dt = GetDriveTypeW(root); + if (dt == DRIVE_UNKNOWN || dt == DRIVE_NO_ROOT_DIR) { + return NULL; + } else { + return _wgetdcwd(di, NULL, MAX_PATH); + } +} + /* We cache the length of current working dir here to avoid calling _wgetcwd() every time we need to resolve a relative path. This piece of code needs to be revisited if chdir @@ -83,7 +102,7 @@ if ((d >= L'a') && (d <= L'z')) di = d - L'a' + 1; else if ((d >= L'A') && (d <= L'Z')) di = d - L'A' + 1; else return 0; /* invalid drive name. */ - dir = _wgetdcwd(di, NULL, MAX_PATH); + dir = currentDir(di); if (dir != NULL){ dirlen = wcslen(dir); free(dir);
--- a/src/windows/native/java/io/io_util_md.h Mon Oct 18 21:46:27 2010 -0700 +++ b/src/windows/native/java/io/io_util_md.h Mon Oct 18 21:50:02 2010 -0700 @@ -33,6 +33,7 @@ WCHAR* pathToNTPath(JNIEnv *env, jstring path, jboolean throwFNFE); WCHAR* fileToNTPath(JNIEnv *env, jobject file, jfieldID id); WCHAR* getPrefixed(const WCHAR* path, int pathlen); +WCHAR* currentDir(int di); int currentDirLength(const WCHAR* path, int pathlen); void fileOpen(JNIEnv *env, jobject this, jstring path, jfieldID fid, int flags); int handleAvailable(jlong fd, jlong *pbytes);
--- a/src/windows/native/java/lang/java_props_md.c Mon Oct 18 21:46:27 2010 -0700 +++ b/src/windows/native/java/lang/java_props_md.c Mon Oct 18 21:50:02 2010 -0700 @@ -489,7 +489,7 @@ break; } sprintf(buf, "%d.%d", ver.dwMajorVersion, ver.dwMinorVersion); - sprops.os_version = strdup(buf); + sprops.os_version = _strdup(buf); #if _M_IA64 sprops.os_arch = "ia64"; #elif _M_AMD64 @@ -500,7 +500,7 @@ sprops.os_arch = "unknown"; #endif - sprops.patch_level = strdup(ver.szCSDVersion); + sprops.patch_level = _strdup(ver.szCSDVersion); sprops.desktop = "windows"; }
--- a/src/windows/native/java/util/TimeZone_md.c Mon Oct 18 21:46:27 2010 -0700 +++ b/src/windows/native/java/util/TimeZone_md.c Mon Oct 18 21:50:02 2010 -0700 @@ -26,6 +26,7 @@ #include <windows.h> #include <stdio.h> #include <stdlib.h> +#include "jvm.h" #include "TimeZone_md.h" #define VALUE_UNKNOWN 0 @@ -463,7 +464,7 @@ /* * Found the time zone in the mapping table. */ - javaTZName = strdup(items[TZ_JAVA_NAME]); + javaTZName = _strdup(items[TZ_JAVA_NAME]); break; } /* @@ -473,7 +474,7 @@ strncpy(bestMatch, items[TZ_JAVA_NAME], MAX_ZONE_CHAR); } else if (country != NULL && strcmp(items[TZ_REGION], country) == 0) { if (value_type == VALUE_MAPID) { - javaTZName = strdup(items[TZ_JAVA_NAME]); + javaTZName = _strdup(items[TZ_JAVA_NAME]); break; } strncpy(bestMatch, items[TZ_JAVA_NAME], MAX_ZONE_CHAR); @@ -490,7 +491,7 @@ fclose(fp); if (javaTZName == NULL && bestMatch[0] != '\0') { - javaTZName = strdup(bestMatch); + javaTZName = _strdup(bestMatch); } return javaTZName; @@ -515,7 +516,7 @@ if (result != VALUE_UNKNOWN) { if (result == VALUE_GMTOFFSET) { - std_timezone = strdup(winZoneName); + std_timezone = _strdup(winZoneName); } else { std_timezone = matchJavaTZ(java_home_dir, result, winZoneName, winMapID, country);
--- a/src/windows/native/sun/nio/ch/ServerSocketChannelImpl.c Mon Oct 18 21:46:27 2010 -0700 +++ b/src/windows/native/sun/nio/ch/ServerSocketChannelImpl.c Mon Oct 18 21:50:02 2010 -0700 @@ -84,7 +84,6 @@ jobject remote_ia; int remote_port; jobject isa; - jobject ia; int addrlen = sizeof(sa); memset((char *)&sa, 0, sizeof(sa));
--- a/src/windows/native/sun/nio/ch/WindowsSelectorImpl.c Mon Oct 18 21:46:27 2010 -0700 +++ b/src/windows/native/sun/nio/ch/WindowsSelectorImpl.c Mon Oct 18 21:50:02 2010 -0700 @@ -223,7 +223,7 @@ jboolean discarded = JNI_FALSE; int n; do { - n = recv(s, &data, sizeof(data), MSG_OOB); + n = recv(s, (char*)&data, sizeof(data), MSG_OOB); if (n > 0) { discarded = JNI_TRUE; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/com/sun/org/apache/xml/internal/security/utils/UnsyncByteArrayOutputStream/BufferOverflowTest.java Mon Oct 18 21:50:02 2010 -0700 @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2010, 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 %I% %E% + * @bug 6954275 + * @summary Check that UnsyncByteArrayOutputStream does not + * throw ArrayIndexOutOfBoundsException + * @compile -XDignore.symbol.file BufferOverflowTest.java + * @run main BufferOverflowTest + */ + +import com.sun.org.apache.xml.internal.security.utils.UnsyncByteArrayOutputStream; + +public class BufferOverflowTest { + + public static void main(String[] args) throws Exception { + try { + UnsyncByteArrayOutputStream out = new UnsyncByteArrayOutputStream(); + out.write(new byte[(8192) << 2 + 1]); + System.out.println("PASSED"); + } catch (ArrayIndexOutOfBoundsException e) { + System.err.println("FAILED, got ArrayIndexOutOfBoundsException"); + throw new Exception(e); + } + } +}
--- a/test/java/io/File/SetAccess.java Mon Oct 18 21:46:27 2010 -0700 +++ b/test/java/io/File/SetAccess.java Mon Oct 18 21:50:02 2010 -0700 @@ -22,11 +22,12 @@ */ /* @test - @bug 4167472 5097703 6216563 6284003 + @bug 4167472 5097703 6216563 6284003 6728842 6464744 @summary Basic test for setWritable/Readable/Executable methods */ import java.io.*; +import java.nio.file.attribute.*; public class SetAccess { public static void main(String[] args) throws Exception { @@ -49,8 +50,9 @@ } public static void doTest(File f) throws Exception { - f.setReadOnly(); if (!System.getProperty("os.name").startsWith("Windows")) { + if (!f.setReadOnly()) + throw new Exception(f + ": setReadOnly Failed"); if (!f.setWritable(true, true) || !f.canWrite() || permission(f).charAt(2) != 'w') @@ -119,40 +121,44 @@ throw new Exception(f + ": setReadable(false, true) Failed"); } else { //Windows platform - if (!f.setWritable(true, true) || !f.canWrite()) - throw new Exception(f + ": setWritable(true, ture) Failed"); - if (!f.setWritable(true, false) || !f.canWrite()) - throw new Exception(f + ": setWritable(true, false) Failed"); - if (!f.setWritable(true) || !f.canWrite()) - throw new Exception(f + ": setWritable(true, ture) Failed"); - if (!f.setExecutable(true, true) || !f.canExecute()) - throw new Exception(f + ": setExecutable(true, true) Failed"); - if (!f.setExecutable(true, false) || !f.canExecute()) - throw new Exception(f + ": setExecutable(true, false) Failed"); - if (!f.setExecutable(true) || !f.canExecute()) - throw new Exception(f + ": setExecutable(true, true) Failed"); - if (!f.setReadable(true, true) || !f.canRead()) - throw new Exception(f + ": setReadable(true, true) Failed"); - if (!f.setReadable(true, false) || !f.canRead()) - throw new Exception(f + ": setReadable(true, false) Failed"); - if (!f.setReadable(true) || !f.canRead()) - throw new Exception(f + ": setReadable(true, true) Failed"); + if (f.isFile()) { + if (!f.setReadOnly()) + throw new Exception(f + ": setReadOnly Failed"); + if (!f.setWritable(true, true) || !f.canWrite()) + throw new Exception(f + ": setWritable(true, ture) Failed"); + if (!f.setWritable(true, false) || !f.canWrite()) + throw new Exception(f + ": setWritable(true, false) Failed"); + if (!f.setWritable(true) || !f.canWrite()) + throw new Exception(f + ": setWritable(true, ture) Failed"); + if (!f.setExecutable(true, true) || !f.canExecute()) + throw new Exception(f + ": setExecutable(true, true) Failed"); + if (!f.setExecutable(true, false) || !f.canExecute()) + throw new Exception(f + ": setExecutable(true, false) Failed"); + if (!f.setExecutable(true) || !f.canExecute()) + throw new Exception(f + ": setExecutable(true, true) Failed"); + if (!f.setReadable(true, true) || !f.canRead()) + throw new Exception(f + ": setReadable(true, true) Failed"); + if (!f.setReadable(true, false) || !f.canRead()) + throw new Exception(f + ": setReadable(true, false) Failed"); + if (!f.setReadable(true) || !f.canRead()) + throw new Exception(f + ": setReadable(true, true) Failed"); + } if (f.isDirectory()) { - //All directories on Windows always have read&write access perm, - //setting a directory to "unwritable" actually means "not deletable" - if (!f.setWritable(false, true) || !f.canWrite()) - throw new Exception(f + ": setWritable(false, true) Failed"); - if (!f.setWritable(false, false) || !f.canWrite()) - throw new Exception(f + ": setWritable(false, true) Failed"); - if (!f.setWritable(false) || !f.canWrite()) - throw new Exception(f + ": setWritable(false, true) Failed"); + // setWritable should fail on directories because the DOS readonly + // attribute prevents a directory from being deleted. + if (f.setWritable(false, true)) + throw new Exception(f + ": setWritable(false, true) Succeeded"); + if (f.setWritable(false, false)) + throw new Exception(f + ": setWritable(false, false) Succeeded"); + if (f.setWritable(false)) + throw new Exception(f + ": setWritable(false) Succeeded"); } else { if (!f.setWritable(false, true) || f.canWrite()) throw new Exception(f + ": setWritable(false, true) Failed"); if (!f.setWritable(false, false) || f.canWrite()) - throw new Exception(f + ": setWritable(false, true) Failed"); + throw new Exception(f + ": setWritable(false, false) Failed"); if (!f.setWritable(false) || f.canWrite()) - throw new Exception(f + ": setWritable(false, true) Failed"); + throw new Exception(f + ": setWritable(false) Failed"); } if (f.setExecutable(false, true)) throw new Exception(f + ": setExecutable(false, true) Failed"); @@ -172,14 +178,8 @@ } private static String permission(File f) throws Exception { - byte[] bb = new byte[1024]; - String command = f.isDirectory()?"ls -dl ":"ls -l "; - int len = Runtime.getRuntime() - .exec(command + f.getPath()) - .getInputStream() - .read(bb, 0, 1024); - if (len > 0) - return new String(bb, 0, len).substring(0, 10); - return ""; + PosixFileAttributes attrs = Attributes.readPosixFileAttributes(f.toPath()); + String type = attrs.isDirectory() ? "d" : " "; + return type + PosixFilePermissions.toString(attrs.permissions()); } }
--- a/test/java/io/File/SetReadOnly.java Mon Oct 18 21:46:27 2010 -0700 +++ b/test/java/io/File/SetReadOnly.java Mon Oct 18 21:50:02 2010 -0700 @@ -22,7 +22,7 @@ */ /* @test - @bug 4091757 4939819 + @bug 4091757 4939819 6728842 @summary Basic test for setReadOnly method */ @@ -57,17 +57,8 @@ } if (!f.mkdir()) throw new Exception(f + ": Cannot create directory"); - if (!f.setReadOnly()) - throw new Exception(f + ": Failed on directory"); - // The readonly attribute on Windows does not make a folder read-only - if (System.getProperty("os.name").startsWith("Windows")) { - if (!f.canWrite()) - throw new Exception(f + ": Directory is not writeable"); - } else { - if (f.canWrite()) - throw new Exception(f + ": Directory is writeable"); - } - + if (f.setReadOnly() && f.canWrite()) + throw new Exception(f + ": Directory is writeable"); if (!f.delete()) throw new Exception(f + ": Cannot delete directory");
--- a/test/java/io/pathNames/GeneralWin32.java Mon Oct 18 21:46:27 2010 -0700 +++ b/test/java/io/pathNames/GeneralWin32.java Mon Oct 18 21:50:02 2010 -0700 @@ -22,7 +22,7 @@ */ /* @test - @bug 4032066 4039597 4046914 4054511 4065189 4109131 4875229 + @bug 4032066 4039597 4046914 4054511 4065189 4109131 4875229 6983520 @summary General exhaustive test of win32 pathname handling @author Mark Reinhold
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/lang/ClassLoader/deadlock/GetResource.java Mon Oct 18 21:50:02 2010 -0700 @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.util.Properties; +import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.BrokenBarrierException; +import java.io.IOException; +import java.net.URL; + +/* @test + * @bug 6977738 + * @summary Test ClassLoader.getResource() that should not deadlock + # if another thread is holding the system properties object + * + * @build GetResource + * @run main GetResource + */ + +public class GetResource { + CyclicBarrier go = new CyclicBarrier(2); + CyclicBarrier done = new CyclicBarrier(2); + Thread t1, t2; + public GetResource() { + t1 = new Thread() { + public void run() { + Properties prop = System.getProperties(); + synchronized (prop) { + System.out.println("Thread 1 ready"); + try { + go.await(); + prop.put("property", "value"); + prop.store(System.out, ""); + done.await(); // keep holding the lock until t2 finishes + } catch (InterruptedException e) { + throw new RuntimeException(e); + } catch (BrokenBarrierException e) { + throw new RuntimeException(e); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + System.out.println("Thread 1 exits"); + } + }; + + t2 = new Thread() { + public void run() { + System.out.println("Thread 2 ready"); + try { + go.await(); // wait until t1 holds the lock of the system properties + + URL u1 = Thread.currentThread().getContextClassLoader().getResource("unknownresource"); + URL u2 = Thread.currentThread().getContextClassLoader().getResource("sun/util/resources/CalendarData.class"); + if (u2 == null) { + throw new RuntimeException("Test failed: resource not found"); + } + done.await(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } catch (BrokenBarrierException e) { + throw new RuntimeException(e); + } + System.out.println("Thread 2 exits"); + } + }; + } + + public void run() throws Exception { + t1.start(); + t2.start(); + try { + t1.join(); + } catch (InterruptedException e) { + e.printStackTrace(); + throw e; + } + try { + t2.join(); + } catch (InterruptedException e) { + e.printStackTrace(); + throw e; + } + } + + public static void main(String[] args) throws Exception { + new GetResource().run(); + } +}
--- a/test/java/lang/ProcessBuilder/Basic.java Mon Oct 18 21:46:27 2010 -0700 +++ b/test/java/lang/ProcessBuilder/Basic.java Mon Oct 18 21:50:02 2010 -0700 @@ -1843,9 +1843,11 @@ public void run() { try { stdout.read(); } catch (IOException e) { + // Check that reader failed because stream was + // asynchronously closed. // e.printStackTrace(); if (EnglishUnix.is() && - ! (e.getMessage().matches(".*Bad file descriptor.*"))) + ! (e.getMessage().matches(".*Bad file.*"))) unexpected(e); } catch (Throwable t) { unexpected(t); }}};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/nio/Buffer/LimitDirectMemory.java Mon Oct 18 21:50:02 2010 -0700 @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.nio.ByteBuffer; +import java.util.Properties; + +public class LimitDirectMemory { + private static int K = 1024; + + public static void main(String [] args) throws Exception { + if (args.length < 2) + throw new RuntimeException(); + boolean throwp = parseThrow(args[0]); + int size = parseSize(args[1]); + int incr = (args.length > 2 ? parseSize(args[2]) : size); + + Properties p = System.getProperties(); + if (p.getProperty("sun.nio.MaxDirectMemorySize") != null) + throw new RuntimeException("sun.nio.MaxDirectMemorySize defined"); + + ByteBuffer [] b = new ByteBuffer[K]; + + // Fill up most/all of the direct memory + int i = 0; + while (size >= incr) { + b[i++] = ByteBuffer.allocateDirect(incr); + size -= incr; + } + + if (throwp) { + try { + b[i] = ByteBuffer.allocateDirect(incr); + throw new RuntimeException("OutOfMemoryError not thrown: " + + incr); + } catch (OutOfMemoryError e) { + e.printStackTrace(System.out); + System.out.println("OK - Error thrown as expected "); + } + } else { + b[i] = ByteBuffer.allocateDirect(incr); + System.out.println("OK - Error not thrown"); + } + } + + private static boolean parseThrow(String s) { + if (s.equals("true")) return true; + if (s.equals("false")) return false; + throw new RuntimeException("Unrecognized expectation: " + s); + } + + private static int parseSize(String size) throws Exception { + + if (size.equals("DEFAULT")) + return (int)Runtime.getRuntime().maxMemory(); + if (size.equals("DEFAULT+1")) + return (int)Runtime.getRuntime().maxMemory() + 1; + if (size.equals("DEFAULT+1M")) + return (int)Runtime.getRuntime().maxMemory() + (1 << 20); + if (size.equals("DEFAULT-1")) + return (int)Runtime.getRuntime().maxMemory() - 1; + if (size.equals("DEFAULT/2")) + return (int)Runtime.getRuntime().maxMemory() / 2; + + int idx = 0, len = size.length(); + + int result = 1; + for (int i = 0; i < len; i++) { + if (Character.isDigit(size.charAt(i))) idx++; + else break; + } + + if (idx == 0) + throw new RuntimeException("No digits detected: " + size); + + result = Integer.parseInt(size.substring(0, idx)); + + if (idx < len) { + for (int i = idx; i < len; i++) { + switch(size.charAt(i)) { + case 'T': case 't': result *= K; // fall through + case 'G': case 'g': result *= K; // fall through + case 'M': case 'm': result *= K; // fall through + case 'K': case 'k': result *= K; + break; + default: + throw new RuntimeException("Unrecognized size: " + size); + } + } + } + return result; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/nio/Buffer/LimitDirectMemory.sh Mon Oct 18 21:50:02 2010 -0700 @@ -0,0 +1,91 @@ +#!/bin/sh + +# +# Copyright (c) 2002, 2010, 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 4627316 6743526 +# @summary Test option to limit direct memory allocation +# +# @build LimitDirectMemory +# @run shell LimitDirectMemory.sh + +TMP1=tmp_$$ + +runTest() { + echo "Testing: $*" + ${TESTJAVA}/bin/java $* + if [ $? -eq 0 ] + then echo "--- passed as expected" + else + echo "--- failed" + exit 1 + fi +} + +launchFail() { + echo "Testing: -XX:MaxDirectMemorySize=$* -cp ${TESTCLASSES} \ + LimitDirectMemory true DEFAULT DEFAULT+1M" + ${TESTJAVA}/bin/java -XX:MaxDirectMemorySize=$* -cp ${TESTCLASSES} \ + LimitDirectMemory true DEFAULT DEFAULT+1M > ${TMP1} 2>&1 + cat ${TMP1} + cat ${TMP1} | grep -s "Unrecognized VM option: \'MaxDirectMemorySize=" + if [ $? -ne 0 ] + then echo "--- failed as expected" + else + echo "--- failed" + exit 1 + fi +} + +# $java LimitDirectMemory throwp fill_direct_memory size_per_buffer + +# Memory is properly limited using multiple buffers. +runTest -XX:MaxDirectMemorySize=10 -cp ${TESTCLASSES} LimitDirectMemory true 10 1 +runTest -XX:MaxDirectMemorySize=1k -cp ${TESTCLASSES} LimitDirectMemory true 1k 100 +runTest -XX:MaxDirectMemorySize=10m -cp ${TESTCLASSES} LimitDirectMemory true 10m 10m + +# We can increase the amount of available memory. +runTest -XX:MaxDirectMemorySize=65M -cp ${TESTCLASSES} \ + LimitDirectMemory false 64M 65M + +# Exactly the default amount of memory is available. +runTest -cp ${TESTCLASSES} LimitDirectMemory false 10 1 +runTest -Xmx64m -cp ${TESTCLASSES} LimitDirectMemory false 0 DEFAULT +runTest -Xmx64m -cp ${TESTCLASSES} LimitDirectMemory true 0 DEFAULT+1 + +# We should be able to eliminate direct memory allocation entirely. +runTest -XX:MaxDirectMemorySize=0 -cp ${TESTCLASSES} LimitDirectMemory true 0 1 + +# Setting the system property should not work so we should be able to allocate +# the default amount. +runTest -Dsun.nio.MaxDirectMemorySize=1K -Xmx64m -cp ${TESTCLASSES} \ + LimitDirectMemory false DEFAULT-1 DEFAULT/2 + +# Various bad values fail to launch the VM. +launchFail foo +launchFail 10kmt +launchFail -1 + +# Clean-up +rm ${TMP1}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/nio/channels/Selector/TemporarySelector.java Mon Oct 18 21:50:02 2010 -0700 @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2010, 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 6645197 + * @run main/othervm -Xmx5m TemporarySelector + * @summary Timed read with socket adaptor throws ClosedSelectorException if temporary selector GC'ed. + */ +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.ServerSocket; +import java.net.Socket; +import java.nio.channels.ServerSocketChannel; +import java.nio.channels.SocketChannel; + +public class TemporarySelector { + + static volatile boolean done = false; + + public static void main(String[] args) throws Exception { + + Runnable r = new Runnable() { + public void run() { + while (!done) { + System.gc(); + try { + Thread.sleep(1000); + } catch (Exception e) { + } + } + } + }; + + try { + // Create a server socket that will open and accept on loopback connection + ServerSocketChannel ssc = ServerSocketChannel.open(); + final ServerSocket ss = ssc.socket(); + ss.bind(new InetSocketAddress(0)); + int localPort = ss.getLocalPort(); + + // Create a client socket that will connect and read + System.out.println("Connecting to server socket"); + System.out.flush(); + SocketChannel channel = SocketChannel.open(new InetSocketAddress("localhost", localPort)); + System.out.println("Connected to server socket"); + System.out.flush(); + + // Create a thread to try and cause the GC to run + Thread t = new Thread(r); + t.start(); + byte[] buffer = new byte[500]; + System.out.println("Reading from socket input stream"); + System.out.flush(); + Socket socket = channel.socket(); + socket.setSoTimeout(10000); // The timeout must be set + // to trigger this bug + try { + socket.getInputStream().read(buffer); + } catch (java.net.SocketTimeoutException ste) { + // no java.nio.channels.ClosedSelectorException + } + } finally { + done = true; + } + } +}
--- a/test/java/nio/channels/SocketChannel/VectorIO.java Mon Oct 18 21:46:27 2010 -0700 +++ b/test/java/nio/channels/SocketChannel/VectorIO.java Mon Oct 18 21:50:02 2010 -0700 @@ -60,6 +60,7 @@ static void bufferTest(int port) throws Exception { ByteBuffer[] bufs = new ByteBuffer[testSize]; + long total = 0L; for(int i=0; i<testSize; i++) { String source = "buffer" + i; if (generator.nextBoolean()) @@ -69,6 +70,7 @@ bufs[i].put(source.getBytes("8859_1")); bufs[i].flip(); + total += bufs[i].remaining(); } // Get a connection to the server @@ -76,17 +78,20 @@ InetSocketAddress isa = new InetSocketAddress(lh, port); SocketChannel sc = SocketChannel.open(); sc.connect(isa); - sc.configureBlocking(false); + sc.configureBlocking(generator.nextBoolean()); // Write the data out - long bytesWritten = 0; - do { - bytesWritten = sc.write(bufs); - } while (bytesWritten > 0); - - try { - Thread.currentThread().sleep(500); - } catch (InterruptedException ie) { } + long rem = total; + while (rem > 0L) { + long bytesWritten = sc.write(bufs); + if (bytesWritten == 0) { + if (sc.isBlocking()) + throw new RuntimeException("write did not block"); + Thread.sleep(50); + } else { + rem -= bytesWritten; + } + } // Clean up sc.close(); @@ -115,6 +120,7 @@ } void bufferTest() throws Exception { + long total = 0L; ByteBuffer[] bufs = new ByteBuffer[testSize]; for(int i=0; i<testSize; i++) { String source = "buffer" + i; @@ -122,6 +128,7 @@ bufs[i] = ByteBuffer.allocateDirect(source.length()); else bufs[i] = ByteBuffer.allocate(source.length()); + total += bufs[i].capacity(); } // Get a connection from client @@ -138,11 +145,21 @@ Thread.sleep(50); } + sc.configureBlocking(generator.nextBoolean()); + // Read data into multiple buffers - long bytesRead = 0; - do { - bytesRead = sc.read(bufs); - } while (bytesRead > 0); + long avail = total; + while (avail > 0) { + long bytesRead = sc.read(bufs); + if (bytesRead < 0) + break; + if (bytesRead == 0) { + if (sc.isBlocking()) + throw new RuntimeException("read did not block"); + Thread.sleep(50); + } + avail -= bytesRead; + } // Check results for(int i=0; i<testSize; i++) {
--- a/test/java/util/Arrays/Sorting.java Mon Oct 18 21:46:27 2010 -0700 +++ b/test/java/util/Arrays/Sorting.java Mon Oct 18 21:50:02 2010 -0700 @@ -23,7 +23,7 @@ /* * @test - * @bug 6880672 6896573 6899694 + * @bug 6880672 6896573 6899694 6976036 * @summary Exercise Arrays.sort * @build Sorting * @run main Sorting -shortrun @@ -50,10 +50,10 @@ 1, 2, 3, 21, 55, 1000, 10000 }; // Random initial values used in a long run (default) - private static final long[] LONG_RUN_RANDOMS = {666, 0xC0FFEE, 999}; + private static final long[] LONG_RUN_RANDOMS = { 666, 0xC0FFEE, 999 }; // Random initial values used in a short run - private static final long[] SHORT_RUN_RANDOMS = {666}; + private static final long[] SHORT_RUN_RANDOMS = { 666 }; public static void main(String[] args) { boolean shortRun = args.length > 0 && args[0].equals("-shortrun"); @@ -82,6 +82,11 @@ reset(random); for (int length : lengths) { + testAndCheckWithInsertionSort(length, random); + } + reset(random); + + for (int length : lengths) { testAndCheckWithCheckSum(length, random); } reset(random); @@ -268,9 +273,7 @@ " length = " + length + ", m = " + m); Object convertedGolden = converter.convert(golden); Object convertedTest = converter.convert(test); - // outArray(test); sortSubArray(convertedTest, fromIndex, toIndex); - // outArray(test); checkSubArray(convertedTest, fromIndex, toIndex, m); } } @@ -311,7 +314,7 @@ private static void checkSorted(Pair[] a) { for (int i = 0; i < a.length - 1; i++) { if (a[i].getKey() > a[i + 1].getKey()) { - failed(i, "" + a[i].getKey(), "" + a[i + 1].getKey()); + failedSort(i, "" + a[i].getKey(), "" + a[i + 1].getKey()); } } } @@ -328,7 +331,7 @@ int value4 = a[i++].getValue(); if (!(key1 == key2 && key2 == key3 && key3 == key4)) { - failed("On position " + i + " must keys are different " + + failed("On position " + i + " keys are different " + key1 + ", " + key2 + ", " + key3 + ", " + key4); } if (!(value1 < value2 && value2 < value3 && value3 < value4)) { @@ -385,6 +388,35 @@ private int myValue; } + + private static void testAndCheckWithInsertionSort(int length, long random) { + if (length > 1000) { + return; + } + ourDescription = "Check sorting with insertion sort"; + int[] golden = new int[length]; + + for (int m = 1; m < 2 * length; m *= 2) { + for (UnsortedBuilder builder : UnsortedBuilder.values()) { + builder.build(golden, m); + int[] test = golden.clone(); + + for (TypeConverter converter : TypeConverter.values()) { + out.println("Test 'insertion sort': " + converter + " " + + builder + "random = " + random + ", length = " + + length + ", m = " + m); + Object convertedGolden = converter.convert(golden); + Object convertedTest1 = converter.convert(test); + Object convertedTest2 = converter.convert(test); + sort(convertedTest1); + sortByInsertionSort(convertedTest2); + compare(convertedTest1, convertedTest2); + } + } + } + out.println(); + } + private static void testAndCheckWithCheckSum(int length, long random) { ourDescription = "Check sorting with check sum"; int[] golden = new int[length]; @@ -460,9 +492,7 @@ builder.build(golden, a, g, z, n, p); float[] test = golden.clone(); scramble(test); - // outArray(test); sort(test); - // outArray(test); compare(test, golden, a, n, g); } newLine = true; @@ -500,9 +530,7 @@ builder.build(golden, a, g, z, n, p); double[] test = golden.clone(); scramble(test); - // outArray(test); sort(test); - // outArray(test); compare(test, golden, a, n, g); } newLine = true; @@ -721,12 +749,12 @@ for (int i = numNeg; i < numNeg + numNegZero; i++) { if (NEGATIVE_ZERO != Float.floatToIntBits(a[i])) { - failed("On position " + i + " must be -0.0f instead of " + a[i]); + failed("On position " + i + " must be -0.0 instead of " + a[i]); } } for (int i = 0; i < a.length - numNaN; i++) { if (a[i] != b[i]) { - failed(i, "" + a[i], "" + b[i]); + failedCompare(i, "" + a[i], "" + b[i]); } } } @@ -747,12 +775,12 @@ for (int i = numNeg; i < numNeg + numNegZero; i++) { if (NEGATIVE_ZERO != Double.doubleToLongBits(a[i])) { - failed("On position " + i + " must be -0.0d instead of " + a[i]); + failed("On position " + i + " must be -0.0 instead of " + a[i]); } } for (int i = 0; i < a.length - numNaN; i++) { if (a[i] != b[i]) { - failed(i, "" + a[i], "" + b[i]); + failedCompare(i, "" + a[i], "" + b[i]); } } } @@ -841,8 +869,8 @@ int incCount = 1; int decCount = a.length; int i = 0; - int period = m; - m--; + int period = m--; + while (true) { for (int k = 1; k <= period; k++) { if (i >= a.length) { @@ -922,6 +950,25 @@ } } + private static void checkWithCheckSum(Object test, Object golden) { + checkSorted(test); + checkCheckSum(test, golden); + } + + private static void failed(String message) { + err.format("\n*** TEST FAILED - %s.\n\n%s.\n\n", ourDescription, message); + throw new RuntimeException("Test failed - see log file for details"); + } + + private static void failedSort(int index, String value1, String value2) { + failed("Array is not sorted at " + index + "-th position: " + + value1 + " and " + value2); + } + + private static void failedCompare(int index, String value1, String value2) { + failed("On position " + index + " must be " + value2 + " instead of " + value1); + } + private static void compare(Object test, Object golden) { if (test instanceof int[]) { compare((int[]) test, (int[]) golden); @@ -945,19 +992,68 @@ } } - private static void checkWithCheckSum(Object test, Object golden) { - checkSorted(test); - checkCheckSum(test, golden); + private static void compare(int[] a, int[] b) { + for (int i = 0; i < a.length; i++) { + if (a[i] != b[i]) { + failedCompare(i, "" + a[i], "" + b[i]); + } + } + } + + private static void compare(long[] a, long[] b) { + for (int i = 0; i < a.length; i++) { + if (a[i] != b[i]) { + failedCompare(i, "" + a[i], "" + b[i]); + } + } + } + + private static void compare(short[] a, short[] b) { + for (int i = 0; i < a.length; i++) { + if (a[i] != b[i]) {