diff --git a/make/java/java/FILES_java.gmk b/make/java/java/FILES_java.gmk index fcb61e1beb6aebb94de43cf883b482531294d2d3..f9fdea5cf069d74c50e08d8ea907879eb4679fc8 100644 --- a/make/java/java/FILES_java.gmk +++ b/make/java/java/FILES_java.gmk @@ -465,14 +465,11 @@ JAVA_JAVA_java = \ 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 @@ JAVA_JAVA_java = \ 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) diff --git a/src/share/classes/com/sun/java/util/jar/pack/Attribute.java b/src/share/classes/com/sun/java/util/jar/pack/Attribute.java index 0c1b09543001609f9d5a8e44cac56e36ff2e55e3..b662ebb9683ddfd1e5e4c6ccb8f3c29744fd32b1 100644 --- a/src/share/classes/com/sun/java/util/jar/pack/Attribute.java +++ b/src/share/classes/com/sun/java/util/jar/pack/Attribute.java @@ -654,8 +654,8 @@ class Attribute implements Comparable, Constants { 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; diff --git a/src/share/classes/com/sun/java/util/jar/pack/ClassReader.java b/src/share/classes/com/sun/java/util/jar/pack/ClassReader.java index a14bf350a6f5410952576ee933c2063b0f896045..fd28171a75b7c95eff0997d6f678c96c732ccb44 100644 --- a/src/share/classes/com/sun/java/util/jar/pack/ClassReader.java +++ b/src/share/classes/com/sun/java/util/jar/pack/ClassReader.java @@ -30,6 +30,7 @@ import java.util.*; 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 @@ class ClassReader implements Constants { 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 @@ class ClassReader implements Constants { 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 @@ class ClassReader implements Constants { 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 @@ class ClassReader implements Constants { 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 @@ class ClassReader implements Constants { 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 @@ class ClassReader implements Constants { 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); + } + } } diff --git a/src/share/classes/com/sun/java/util/jar/pack/Instruction.java b/src/share/classes/com/sun/java/util/jar/pack/Instruction.java index bef43fd0f03af11866d1f9b03cdfab7b26ccd535..2eb4604ec08642c29ea9731a347a1433c4971d90 100644 --- a/src/share/classes/com/sun/java/util/jar/pack/Instruction.java +++ b/src/share/classes/com/sun/java/util/jar/pack/Instruction.java @@ -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 @@ class Instruction implements Constants { } } } + + 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); + } + } } diff --git a/src/share/classes/com/sun/java/util/jar/pack/PackerImpl.java b/src/share/classes/com/sun/java/util/jar/pack/PackerImpl.java index 449bbbeb5b1a5376d0440f1cdebf8a1fcecb6570..a45a4bcba094a4bf207784c789e40fac5ffbb6a7 100644 --- a/src/share/classes/com/sun/java/util/jar/pack/PackerImpl.java +++ b/src/share/classes/com/sun/java/util/jar/pack/PackerImpl.java @@ -496,15 +496,29 @@ public class PackerImpl extends TLGlobals implements Pack200.Packer { 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; diff --git a/src/share/classes/com/sun/java/util/jar/pack/Utils.java b/src/share/classes/com/sun/java/util/jar/pack/Utils.java index 2dc47c414642bf4f32a4323f8ba30d8a97a1c7bb..84f65ac2ccfcbbbc769f769e95b43eeef2c6b8da 100644 --- a/src/share/classes/com/sun/java/util/jar/pack/Utils.java +++ b/src/share/classes/com/sun/java/util/jar/pack/Utils.java @@ -182,11 +182,8 @@ class Utils { } 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 @@ class Utils { // 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; } diff --git a/src/share/classes/com/sun/jndi/dns/DnsContextFactory.java b/src/share/classes/com/sun/jndi/dns/DnsContextFactory.java index c006ebdb5b95743510edd86d6556ae1109c3b26d..2ce289e7d4dee431d938244bc3f67d66db573bcb 100644 --- a/src/share/classes/com/sun/jndi/dns/DnsContextFactory.java +++ b/src/share/classes/com/sun/jndi/dns/DnsContextFactory.java @@ -54,6 +54,7 @@ import sun.net.dns.ResolverConfiguration; // available since 1.4.1 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 class DnsContextFactory implements InitialContextFactory { * 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 @@ public class DnsContextFactory implements InitialContextFactory { // 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 platformServers = - ResolverConfiguration.open().nameservers(); + List 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 @@ public class DnsContextFactory implements InitialContextFactory { 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; + } + } } diff --git a/src/share/classes/com/sun/net/httpserver/BasicAuthenticator.java b/src/share/classes/com/sun/net/httpserver/BasicAuthenticator.java index 2b1303b406d345144be33c214674bfdf284549f1..666ab0b2c1bf6de54953e380b54c61fab84ebaab 100644 --- a/src/share/classes/com/sun/net/httpserver/BasicAuthenticator.java +++ b/src/share/classes/com/sun/net/httpserver/BasicAuthenticator.java @@ -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 abstract class BasicAuthenticator extends Authenticator { public Result authenticate (HttpExchange t) { - HttpContext context = t.getHttpContext(); Headers rmap = (Headers) t.getRequestHeaders(); /* * look for auth token diff --git a/src/share/classes/com/sun/net/httpserver/Filter.java b/src/share/classes/com/sun/net/httpserver/Filter.java index 7e8c6e7a95777d58df9622866516ebe506e48ff2..a870d6518d360323ed87b079a677a7d1140b596e 100644 --- a/src/share/classes/com/sun/net/httpserver/Filter.java +++ b/src/share/classes/com/sun/net/httpserver/Filter.java @@ -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 @@ public abstract class Filter { /* the last element in the chain must invoke the users * handler */ - private List filters; private ListIterator iter; private HttpHandler handler; public Chain (List filters, HttpHandler handler) { - this.filters = filters; iter = filters.listIterator(); this.handler = handler; } diff --git a/src/share/classes/com/sun/net/httpserver/Headers.java b/src/share/classes/com/sun/net/httpserver/Headers.java index efac6042861556c3823d73d049363440fe021530..b91769173682659f91b61a2988ebdbedad20da6f 100644 --- a/src/share/classes/com/sun/net/httpserver/Headers.java +++ b/src/share/classes/com/sun/net/httpserver/Headers.java @@ -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 @@ public class Headers implements Map> { 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')); - } - for (int i=1; i= 'A' && b[i] <= 'Z') { - b[i] = (char) (b[i] + ('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= '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();} diff --git a/src/share/classes/com/sun/net/httpserver/HttpsParameters.java b/src/share/classes/com/sun/net/httpserver/HttpsParameters.java index 13ddc3e658c8b08542eb1866d32960469ad480d3..c54e917c02ea38ca50ce120a9ee168fe197e06b0 100644 --- a/src/share/classes/com/sun/net/httpserver/HttpsParameters.java +++ b/src/share/classes/com/sun/net/httpserver/HttpsParameters.java @@ -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 @@ public abstract class HttpsParameters { * have been set. */ public String[] getCipherSuites() { - return cipherSuites; + return cipherSuites != null ? cipherSuites.clone() : null; } /** @@ -99,7 +97,7 @@ public abstract class HttpsParameters { * @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 @@ public abstract class HttpsParameters { * have been set. */ public String[] getProtocols() { - return protocols; + return protocols != null ? protocols.clone() : null; } /** @@ -119,7 +117,7 @@ public abstract class HttpsParameters { * @param protocols the array of protocols (or null) */ public void setProtocols(String[] protocols) { - this.protocols = protocols; + this.protocols = protocols != null ? protocols.clone() : null; } /** diff --git a/src/share/classes/com/sun/org/apache/xml/internal/security/utils/UnsyncByteArrayOutputStream.java b/src/share/classes/com/sun/org/apache/xml/internal/security/utils/UnsyncByteArrayOutputStream.java index d469399b71de15196ed3e2d835eee91e016adf21..bfba75dd2ae251804775e7fcd36eb99d59f52bbe 100644 --- a/src/share/classes/com/sun/org/apache/xml/internal/security/utils/UnsyncByteArrayOutputStream.java +++ b/src/share/classes/com/sun/org/apache/xml/internal/security/utils/UnsyncByteArrayOutputStream.java @@ -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 @@ package com.sun.org.apache.xml.internal.security.utils; 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(); - } - /** @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; - } - /** @inheritDoc */ - public void write(int arg0) { - if (pos>=size) { - expandSize(); - } - buf[pos++]=(byte)arg0; + + 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 byte[] toByteArray() { - byte result[]=new byte[pos]; - System.arraycopy(buf,0,result,0,pos); - return result; + 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); } + System.arraycopy(arg0, arg1, buf, pos, arg2); + pos = newPos; + } - /** @inheritDoc */ - public void reset() { - pos=0; + public void write(int arg0) { + int newPos = pos + 1; + if (newPos > size) { + expandSize(newPos); } + buf[pos++] = (byte)arg0; + } + + public byte[] toByteArray() { + byte result[] = new byte[pos]; + System.arraycopy(buf, 0, result, 0, pos); + return result; + } - /** @inheritDoc */ - void expandSize() { - int newSize=size<<2; - byte newBuf[]=new byte[newSize]; - System.arraycopy(buf,0,newBuf,0,pos); - buf=newBuf; - size=newSize; + public void reset() { + pos = 0; + } + 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; + } } diff --git a/src/share/classes/java/awt/image/IndexColorModel.java b/src/share/classes/java/awt/image/IndexColorModel.java index c5afce8218ceaebda06eb332cd2661dbbf993ae5..969d524f9abaf0d1030838d6fe959913efbafdde 100644 --- a/src/share/classes/java/awt/image/IndexColorModel.java +++ b/src/share/classes/java/awt/image/IndexColorModel.java @@ -129,6 +129,8 @@ public class IndexColorModel extends ColorModel { 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 @@ public class IndexColorModel extends ColorModel { * longer referenced. */ public void finalize() { - sun.awt.image.BufImgSurfaceData.freeNativeICMData(this); } /** diff --git a/src/share/classes/java/dyn/InvokeDynamicBootstrapError.java b/src/share/classes/java/dyn/InvokeDynamicBootstrapError.java index 83ebcd464b47cdfec0bb11f5455b49ea99b341fd..a301dfa42bced3fed14b92b19b5c38c2667bd664 100644 --- a/src/share/classes/java/dyn/InvokeDynamicBootstrapError.java +++ b/src/share/classes/java/dyn/InvokeDynamicBootstrapError.java @@ -39,8 +39,11 @@ package java.dyn; * {@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 @@ public class InvokeDynamicBootstrapError extends LinkageError { * 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); } } diff --git a/src/share/classes/java/dyn/LinkagePermission.java b/src/share/classes/java/dyn/LinkagePermission.java index 4478d959853a1f2f1ceaa1e085df52dfc56d90ce..6f6dc5004eb26046ad34cc771a059019959b177e 100644 --- a/src/share/classes/java/dyn/LinkagePermission.java +++ b/src/share/classes/java/dyn/LinkagePermission.java @@ -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 @@ import java.util.StringTokenizer; */ 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 diff --git a/src/share/classes/java/dyn/NoAccessException.java b/src/share/classes/java/dyn/NoAccessException.java index 5e76f6a4aae574218ce9ec6e08afaaa73c62e9b4..6b2fbcebcae7a49687ecd262183030462c25bf38 100644 --- a/src/share/classes/java/dyn/NoAccessException.java +++ b/src/share/classes/java/dyn/NoAccessException.java @@ -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 @@ package java.dyn; * 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. */ diff --git a/src/share/classes/java/dyn/WrongMethodTypeException.java b/src/share/classes/java/dyn/WrongMethodTypeException.java index 36e687c8d3d4bd56fdb8e483814468cdb6b44d97..4c4c99817ffec82b37b265639887a57023d9672b 100644 --- a/src/share/classes/java/dyn/WrongMethodTypeException.java +++ b/src/share/classes/java/dyn/WrongMethodTypeException.java @@ -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 @@ package java.dyn; * 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. */ diff --git a/src/share/classes/java/io/package.html b/src/share/classes/java/io/package.html index 31c23d589d0283b8c781af1eeb9bc2160a9633a2..b2f0838bbef393aa979f1478f45a2c0a26e43c0f 100644 --- a/src/share/classes/java/io/package.html +++ b/src/share/classes/java/io/package.html @@ -44,7 +44,7 @@ or method in any class or interface in this package will cause a For overviews, tutorials, examples, guides, and tool documentation, please see: @since JDK1.0 diff --git a/src/share/classes/java/lang/ClassLoader.java b/src/share/classes/java/lang/ClassLoader.java index fd9ba91d720dee31da3e731cb6aa273eb568e313..ce7f0e655e8b5d5d5904c9428977a67e2e5a40e0 100644 --- a/src/share/classes/java/lang/ClassLoader.java +++ b/src/share/classes/java/lang/ClassLoader.java @@ -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 @@ import sun.security.util.SecurityConstants; * themselves at their class initialization time by invoking the * {@link * #registerAsParallelCapable ClassLoader.registerAsParallelCapable} - * 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 ClassLoader class is registered as parallel + * capable by default. However, its subclasses still need to register themselves + * if they are parallel capable.
+ * 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 * loadClass} methods). @@ -1218,14 +1221,14 @@ public abstract class ClassLoader { private static native Class 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.

- * 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.

+ * Registers the caller as parallel capable.

+ * The registration succeeds if and only if all of the following + * conditions are met:
+ * 1. no instance of the caller has been created

+ * 2. all of the super classes (except class Object) of the caller are + * registered as parallel capable

+ * Note that once a class loader is registered as parallel capable, there + * is no way to change it back.

* * @return true if the caller is successfully registered as * parallel capable and false if otherwise. diff --git a/src/share/classes/java/lang/Integer.java b/src/share/classes/java/lang/Integer.java index ab68cf23c25586bc4dce93b68c79e42d7acee856..ab68f4b25580821f852a1a9617acf5385aa686b3 100644 --- a/src/share/classes/java/lang/Integer.java +++ b/src/share/classes/java/lang/Integer.java @@ -586,25 +586,13 @@ public final class Integer extends Number implements Comparable { * 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= option. + * The cache is initialized on first usage. The size of the cache + * may be controlled by the -XX:AutoBoxCacheMax= 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 @@ public final class Integer extends Number implements Comparable { 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); diff --git a/src/share/classes/java/lang/LinkageError.java b/src/share/classes/java/lang/LinkageError.java index 0954a17834353cf88a317ff89c0e6f771c579fc1..6b5f060f0e718df4f7806aa6834e1ce6bf6a3311 100644 --- a/src/share/classes/java/lang/LinkageError.java +++ b/src/share/classes/java/lang/LinkageError.java @@ -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 LinkageError 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 @@ class LinkageError extends Error { private static final long serialVersionUID = 3579600108157160122L; /** - * Constructs a LinkageError with no detail message. + * Constructs a {@code LinkageError} with no detail message. */ public LinkageError() { super(); } /** - * Constructs a LinkageError with the specified detail + * Constructs a {@code LinkageError} with the specified detail * message. * * @param s the detail message. @@ -54,4 +54,16 @@ class LinkageError extends Error { 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); + } } diff --git a/src/share/classes/java/lang/System.java b/src/share/classes/java/lang/System.java index 42431865f255584552b584efcff567bd5b851616..6df4af6950507ad1597bc839a3e19f858f1e778f 100644 --- a/src/share/classes/java/lang/System.java +++ b/src/share/classes/java/lang/System.java @@ -53,7 +53,13 @@ import sun.reflect.annotation.AnnotationType; */ 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 @@ public final class System { * 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=. - Integer.getAndRemoveCacheProperties(); - FileInputStream fdIn = new FileInputStream(FileDescriptor.in); FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out); FileOutputStream fdErr = new FileOutputStream(FileDescriptor.err); @@ -1127,17 +1137,6 @@ public final class System { // classes are used. sun.misc.VM.initializeOSEnvironment(); - // Set the maximum amount of direct memory. This value is controlled - // by the vm option -XX:MaxDirectMemorySize=. 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 @@ public final class System { 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(){ diff --git a/src/share/classes/java/net/HttpURLConnection.java b/src/share/classes/java/net/HttpURLConnection.java index c6b1ffab6c9414c97214905d9c010e8ab80061f2..0b3e578022c5eba2cdeba11641fe1e83b593577b 100644 --- a/src/share/classes/java/net/HttpURLConnection.java +++ b/src/share/classes/java/net/HttpURLConnection.java @@ -399,6 +399,8 @@ abstract public class HttpURLConnection extends URLConnection { * @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 @@ abstract public class HttpURLConnection extends URLConnection { 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; } diff --git a/src/share/classes/java/net/NetPermission.java b/src/share/classes/java/net/NetPermission.java index 5083a40fb3467b02c35db375b05213f9f8f7789b..1cff4a8767677583b3be728a19991a7fe1113346 100644 --- a/src/share/classes/java/net/NetPermission.java +++ b/src/share/classes/java/net/NetPermission.java @@ -54,44 +54,23 @@ import java.util.StringTokenizer; * What the Permission Allows * Risks of Allowing this Permission * - * - * - * setDefaultAuthenticator - * The ability to set the - * way authentication information is retrieved when - * a proxy or HTTP server asks for authentication - * Malicious - * code can set an authenticator that monitors and steals user - * authentication input as it retrieves the input from the user. - * - * - * - * requestPasswordAuthentication - * The ability - * to ask the authenticator registered with the system for - * a password - * Malicious code may steal this password. - * - * * - * specifyStreamHandler - * The ability - * to specify a stream handler when constructing a URL - * 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. - * + * allowHttpTrace + * The ability to use the HTTP TRACE method in HttpURLConnection. + * 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. + * * * - * setProxySelector - * The ability to set the proxy selector used to make decisions - * on which proxies to use when making network connections. - * Malicious code can set a ProxySelector that directs network - * traffic to an arbitrary network host. - * + * getCookieHandler + * The ability to get the cookie handler that processes highly + * security sensitive cookie information for an Http session. + * 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. + * * * * getProxySelector @@ -103,6 +82,22 @@ that class really didn't come from that location. * * * + * getResponseCache + * The ability to get the response cache that provides + * access to a local response cache. + * Malicious code getting access to the local response cache + * could access security sensitive information. + * + * + * + * requestPasswordAuthentication + * The ability + * to ask the authenticator registered with the system for + * a password + * Malicious code may steal this password. + * + * + * * setCookieHandler * The ability to set the cookie handler that processes highly * security sensitive cookie information for an Http session. @@ -113,14 +108,22 @@ that class really didn't come from that location. * * * - * getCookieHandler - * The ability to get the cookie handler that processes highly - * security sensitive cookie information for an Http session. - * 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. - * + * setDefaultAuthenticator + * The ability to set the + * way authentication information is retrieved when + * a proxy or HTTP server asks for authentication + * Malicious + * code can set an authenticator that monitors and steals user + * authentication input as it retrieves the input from the user. + * + * + * + * setProxySelector + * The ability to set the proxy selector used to make decisions + * on which proxies to use when making network connections. + * Malicious code can set a ProxySelector that directs network + * traffic to an arbitrary network host. + * * * * setResponseCache @@ -132,13 +135,16 @@ that class really didn't come from that location. * * * - * getResponseCache - * The ability to get the response cache that provides - * access to a local response cache. - * Malicious code getting access to the local response cache - * could access security sensitive information. - * - * + * specifyStreamHandler + * The ability + * to specify a stream handler when constructing a URL + * 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. + * * * * @see java.security.BasicPermission diff --git a/src/share/classes/java/net/NetworkInterface.java b/src/share/classes/java/net/NetworkInterface.java index 51ebf23917bb6afdf863e05232371b67e3e2ac23..2dd0e96a390c6e7e20392bba8a4816408d5bf957 100644 --- a/src/share/classes/java/net/NetworkInterface.java +++ b/src/share/classes/java/net/NetworkInterface.java @@ -86,7 +86,9 @@ public final class NetworkInterface { * If there is a security manager, its checkConnect * method is called for each InetAddress. Only InetAddresses where * the checkConnect 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 @@ public final class NetworkInterface { 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; jnull 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") * - * @return a byte array containing the address or null if - * the address doesn't exist or is not accessible. * @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 final class NetworkInterface { } 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 addrs = getInetAddresses(); + while (addrs.hasMoreElements()) { + count += addrs.nextElement().hashCode(); } return count; } diff --git a/src/share/classes/java/nio/Bits.java b/src/share/classes/java/nio/Bits.java index fa11b6be785540f23bd3f8e2b0df9a20e8b03513..54f004b6ea985bde04d81b2d9e928ecb71bdb5f8 100644 --- a/src/share/classes/java/nio/Bits.java +++ b/src/share/classes/java/nio/Bits.java @@ -622,7 +622,7 @@ class Bits { // package-private // initialization if it is launched with "-XX:MaxDirectMemorySize=". 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 @@ class Bits { // package-private // 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 @@ class Bits { // package-private 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 @@ class Bits { // package-private 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 @@ class Bits { // package-private } @Override public long getTotalCapacity() { - return Bits.usedMemory; + return Bits.totalCapacity; } @Override public long getMemoryUsed() { diff --git a/src/share/classes/java/nio/Direct-X-Buffer.java.template b/src/share/classes/java/nio/Direct-X-Buffer.java.template index 520b9c465040ad8c69bd2a329446cf3ff2df46ea..6c96df87eefe33990f44a5d1f874b517fb37fbcc 100644 --- a/src/share/classes/java/nio/Direct-X-Buffer.java.template +++ b/src/share/classes/java/nio/Direct-X-Buffer.java.template @@ -29,6 +29,7 @@ package java.nio; import sun.misc.Cleaner; import sun.misc.Unsafe; +import sun.misc.VM; import sun.nio.ch.DirectBuffer; @@ -114,8 +115,9 @@ class Direct$Type$Buffer$RW$$BO$ 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 @@ class Direct$Type$Buffer$RW$$BO$ 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 { diff --git a/src/share/classes/java/security/cert/CertificateRevokedException.java b/src/share/classes/java/security/cert/CertificateRevokedException.java index 7f4660bd74cf76490d46440716bab2fd52b20df5..a76299ccc0d2bb4f71d89c2489fd312042911bc8 100644 --- a/src/share/classes/java/security/cert/CertificateRevokedException.java +++ b/src/share/classes/java/security/cert/CertificateRevokedException.java @@ -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 @@ public class CertificateRevokedException extends CertificateException { */ private final CRLReason reason; /** - * @serial the name of the authority that signed the certificate's - * revocation status information + * @serial the X500Principal that represents the name of the + * authority that signed the certificate's revocation status information */ private final X500Principal authority; @@ -79,8 +79,9 @@ public class CertificateRevokedException extends CertificateException { * @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 X500Principal that represents the name + * of the authority that signed the certificate's revocation status + * information * @throws NullPointerException if revocationDate, * reason, authority, or * extensions is null @@ -121,8 +122,8 @@ public class CertificateRevokedException extends CertificateException { * 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 X500Principal that represents the name of the + * authority that signed the certificate's revocation status information */ public X500Principal getAuthorityName() { return authority; diff --git a/src/share/classes/java/util/Arrays.java b/src/share/classes/java/util/Arrays.java index 54abbb27c8dacd15f3913c737b3f1358a5413e4e..b4951e14f111d41d2d3bc0d114ae3d62c59a2acf 100644 --- a/src/share/classes/java/util/Arrays.java +++ b/src/share/classes/java/util/Arrays.java @@ -97,7 +97,8 @@ public class Arrays { * 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 @@ public class Arrays { * 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 @@ public class Arrays { * 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 @@ public class Arrays { * 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 @@ public class Arrays { * 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 @@ public class Arrays { * 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 @@ public class Arrays { * 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. - * */ /** diff --git a/src/share/classes/java/util/DualPivotQuicksort.java b/src/share/classes/java/util/DualPivotQuicksort.java index 873230a2c7394533f9b27775f25e36ef0b01b981..616ee2e2fe2ae30a877bfc7b9c377f316f90c780 100644 --- a/src/share/classes/java/util/DualPivotQuicksort.java +++ b/src/share/classes/java/util/DualPivotQuicksort.java @@ -36,7 +36,7 @@ package java.util; * @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 @@ final class DualPivotQuicksort { * 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 @@ final class DualPivotQuicksort { } /** - * 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(int[] a, int fromIndex, int toIndex) { - rangeCheck(a.length, fromIndex, toIndex); - sort(a, fromIndex, toIndex - 1, true); + public static void sort(int[] a, int left, int right) { + sort(a, left, right, 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 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(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 @@ final class DualPivotQuicksort { } 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 @@ final class DualPivotQuicksort { * 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 @@ final class DualPivotQuicksort { 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 @@ final class DualPivotQuicksort { 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 @@ final class DualPivotQuicksort { * 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 @@ final class DualPivotQuicksort { 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 @@ final class DualPivotQuicksort { } 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 @@ final class DualPivotQuicksort { * * 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 @@ final class DualPivotQuicksort { } } - // 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 @@ final class DualPivotQuicksort { } /** - * 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(long[] a, int fromIndex, int toIndex) { - rangeCheck(a.length, fromIndex, toIndex); - sort(a, fromIndex, toIndex - 1, true); + public static void sort(long[] a, int left, int right) { + sort(a, left, right, 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 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(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) { - /* - * 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 { + if (leftmost) { /* - * 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,381 +474,54 @@ final class DualPivotQuicksort { } 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]) { long t = a[e2]; a[e2] = a[e1]; a[e1] = t; } - - if (a[e3] < a[e2]) { long 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]) { long 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]) { long 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. - */ - long pivot1 = a[e2]; - long 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++) { - long 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) { + } else { /* - * Skip elements, which are equal to pivot values. + * Skip the longest ascending sequence. */ - while (a[less] == pivot1) { - less++; - } - while (a[great] == pivot2) { - great--; - } + do { + if (left++ >= right) { + return; + } + } while (a[left - 1] <= a[left]); /* - * 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. + * 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. */ - outer: - for (int k = less; k <= great; k++) { - long 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--; - } - } - } + for (int k = left--; (left += 2) <= right; ) { + long a1, a2; k = left - 1; - // 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; - } - 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[k] < a[left]) { + a2 = a[k]; a1 = a[left]; + } else { + a1 = a[k]; a2 = a[left]; } - 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; + while (a1 < a[--k]) { + a[k + 2] = a[k]; } - a[great] = ak; - great--; - } - } - - // Sort left and right parts recursively - sort(a, left, less - 1, leftmost); - sort(a, great + 1, right, false); - } - } + a[++k + 1] = a1; - /** - * Sorts the specified array into ascending numerical order. - * - * @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); - } - } - - /** - * 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(short[] a, int fromIndex, int toIndex) { - rangeCheck(a.length, fromIndex, toIndex); - - if (toIndex - fromIndex > COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) { - countingSort(a, fromIndex, toIndex - 1); - } else { - sort(a, fromIndex, toIndex - 1, true); - } - } - - /** The number of distinct short values. */ - private static final int NUM_SHORT_VALUES = 1 << 16; - - /** - * Sorts the specified range of the array by counting sort. - * - * @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 - */ - private static void sort(short[] 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++) { - short ai = a[i]; - for (j = i - 1; ai < a[j]; j--) { - // assert j >= left; - a[j + 1] = a[j]; + while (a2 < a[--k]) { + a[k + 1] = a[k]; } - a[j + 1] = ai; + a[k + 1] = a2; } - } 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) { - short ai = a[i + 1]; - while (ai < a[j]) { - a[j + 1] = a[j]; - if (j-- == left) { - break; - } - } - a[j + 1] = ai; + 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 @@ -866,17 +537,17 @@ final class DualPivotQuicksort { int e5 = e4 + seventh; // Sort these elements using insertion sort - if (a[e2] < a[e1]) { short t = a[e2]; a[e2] = a[e1]; a[e1] = t; } + if (a[e2] < a[e1]) { long t = a[e2]; a[e2] = a[e1]; a[e1] = t; } - if (a[e3] < a[e2]) { short t = a[e3]; a[e3] = a[e2]; a[e2] = t; + if (a[e3] < a[e2]) { long 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]) { short t = a[e4]; a[e4] = a[e3]; a[e3] = t; + if (a[e4] < a[e3]) { long 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]) { short t = a[e5]; a[e5] = a[e4]; a[e4] = t; + if (a[e5] < a[e4]) { long 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; } @@ -889,8 +560,8 @@ final class DualPivotQuicksort { * These values are inexpensive approximations of the first and * second terciles of the array. Note that pivot1 <= pivot2. */ - short pivot1 = a[e2]; - short pivot2 = a[e4]; + long pivot1 = a[e2]; + long pivot2 = a[e4]; // Pointers int less = left; // The index of the first element of center part @@ -932,10 +603,14 @@ final class DualPivotQuicksort { * Pointer k is the first index of ?-part. */ outer: - for (int k = less; k <= great; k++) { - short ak = a[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 @@ -944,13 +619,17 @@ final class DualPivotQuicksort { 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 +644,7 @@ final class DualPivotQuicksort { 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,8 +678,8 @@ final class DualPivotQuicksort { * Pointer k is the first index of ?-part. */ outer: - for (int k = less; k <= great; k++) { - short ak = a[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]; a[less] = ak; @@ -1011,7 +690,7 @@ final class DualPivotQuicksort { 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 +716,7 @@ final class DualPivotQuicksort { } 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 +735,20 @@ final class DualPivotQuicksort { * * 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]; - + 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++; @@ -1097,115 +768,78 @@ final class DualPivotQuicksort { } } - // 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(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); - } - } - - /** - * 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 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} */ - public static void sort(char[] a, int fromIndex, int toIndex) { - rangeCheck(a.length, fromIndex, toIndex); - - if (toIndex - fromIndex > COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) { - countingSort(a, fromIndex, toIndex - 1); - } else { - sort(a, fromIndex, toIndex - 1, true); - } + public static void sort(short[] a) { + sort(a, 0, a.length - 1); } - /** The number of distinct char values. */ - 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. * * @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]; + 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]; - for (int i = left; i <= right; i++) { - count[a[i]]++; - } - for (int i = 0, k = left; k <= right; i++) { - while (count[i] == 0) { - i++; + for (int i = left - 1; ++i <= right; ) { + count[a[i] - Short.MIN_VALUE]++; } - char value = (char) i; - int s = count[i]; - - do { - a[k++] = value; - } while (--s > 0); + 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); } } + /** The number of distinct short values. */ + private static final int NUM_SHORT_VALUES = 1 << 16; + /** - * 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(char[] a, int left, int right, boolean leftmost) { + 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) { - /* - * 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 { + if (leftmost) { /* - * 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]; + short ai = a[i + 1]; while (ai < a[j]) { a[j + 1] = a[j]; if (j-- == left) { @@ -1214,12 +848,54 @@ final class DualPivotQuicksort { } 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 @@ -1235,17 +911,17 @@ final class DualPivotQuicksort { int e5 = e4 + seventh; // Sort these elements using insertion sort - if (a[e2] < a[e1]) { char t = a[e2]; a[e2] = a[e1]; a[e1] = t; } + if (a[e2] < a[e1]) { short t = a[e2]; a[e2] = a[e1]; a[e1] = t; } - if (a[e3] < a[e2]) { char t = a[e3]; a[e3] = a[e2]; a[e2] = t; + if (a[e3] < a[e2]) { short 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]) { char t = a[e4]; a[e4] = a[e3]; a[e3] = t; + if (a[e4] < a[e3]) { short 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]) { char t = a[e5]; a[e5] = a[e4]; a[e4] = t; + if (a[e5] < a[e4]) { short 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; } @@ -1258,8 +934,8 @@ final class DualPivotQuicksort { * These values are inexpensive approximations of the first and * second terciles of the array. Note that pivot1 <= pivot2. */ - char pivot1 = a[e2]; - char pivot2 = a[e4]; + short pivot1 = a[e2]; + short pivot2 = a[e4]; // Pointers int less = left; // The index of the first element of center part @@ -1301,10 +977,14 @@ final class DualPivotQuicksort { * Pointer k is the first index of ?-part. */ outer: - for (int k = less; k <= great; k++) { - char ak = a[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 @@ -1313,13 +993,17 @@ final class DualPivotQuicksort { 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 +1018,7 @@ final class DualPivotQuicksort { 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,8 +1052,8 @@ final class DualPivotQuicksort { * Pointer k is the first index of ?-part. */ outer: - for (int k = less; k <= great; k++) { - char ak = a[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]; a[less] = ak; @@ -1380,7 +1064,7 @@ final class DualPivotQuicksort { 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 +1090,7 @@ final class DualPivotQuicksort { } 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 +1109,20 @@ final class DualPivotQuicksort { * * 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]; - + 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++; @@ -1466,115 +1142,78 @@ final class DualPivotQuicksort { } } - // 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(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); - } + public static void sort(char[] a) { + sort(a, 0, a.length - 1); } - /** 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 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(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]; - 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--; + for (int i = left - 1; ++i <= right; ) { + count[a[i]]++; } - byte value = (byte) (i + Byte.MIN_VALUE); - int s = count[i]; - - do { - a[k--] = value; - } while (--s > 0); + 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); } } + /** The number of distinct char values. */ + private static final int NUM_CHAR_VALUES = 1 << 16; + /** - * 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(byte[] a, int left, int right, boolean leftmost) { + 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) { - /* - * 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 { + if (leftmost) { /* - * 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) { - byte ai = a[i + 1]; + char ai = a[i + 1]; while (ai < a[j]) { a[j + 1] = a[j]; if (j-- == left) { @@ -1583,12 +1222,54 @@ final class DualPivotQuicksort { } 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 @@ -1604,17 +1285,17 @@ final class DualPivotQuicksort { 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[e2] < a[e1]) { char 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 (a[e3] < a[e2]) { char 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 (a[e4] < a[e3]) { char 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 (a[e5] < a[e4]) { char 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; } @@ -1627,8 +1308,8 @@ final class DualPivotQuicksort { * 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]; + char pivot1 = a[e2]; + char pivot2 = a[e4]; // Pointers int less = left; // The index of the first element of center part @@ -1670,10 +1351,14 @@ final class DualPivotQuicksort { * Pointer k is the first index of ?-part. */ outer: - for (int k = less; k <= great; k++) { - byte ak = a[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 @@ -1682,13 +1367,17 @@ final class DualPivotQuicksort { 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--; } @@ -1703,7 +1392,7 @@ final class DualPivotQuicksort { 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) { @@ -1737,8 +1426,8 @@ final class DualPivotQuicksort { * Pointer k is the first index of ?-part. */ outer: - for (int k = less; k <= great; k++) { - byte ak = a[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]; a[less] = ak; @@ -1749,7 +1438,7 @@ final class DualPivotQuicksort { 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 @@ -1775,7 +1464,7 @@ final class DualPivotQuicksort { } 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 @@ -1794,28 +1483,20 @@ final class DualPivotQuicksort { * * 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; } - byte ak = a[k]; - + 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++; @@ -1835,73 +1516,90 @@ final class DualPivotQuicksort { } } - // 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); } } + /** The number of distinct byte values. */ + private static final int NUM_BYTE_VALUES = 1 << 8; + /** - * Sorts the specified array into ascending numerical order. - * - *

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); + public static void sort(byte[] a) { + 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. * - *

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 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(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]; + + 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 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} */ - public static void sort(float[] a, int fromIndex, int toIndex) { - rangeCheck(a.length, fromIndex, toIndex); - sortNegZeroAndNaN(a, fromIndex, toIndex - 1); + public static void sort(float[] a) { + sort(a, 0, a.length - 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 @@ final class DualPivotQuicksort { 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 @@ final class DualPivotQuicksort { * * 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 @@ final class DualPivotQuicksort { * * 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) { - /* - * 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 { + if (leftmost) { /* - * 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 @@ final class DualPivotQuicksort { } 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 @@ final class DualPivotQuicksort { * 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 @@ final class DualPivotQuicksort { 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 @@ final class DualPivotQuicksort { 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 @@ final class DualPivotQuicksort { * 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 @@ final class DualPivotQuicksort { 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 @@ final class DualPivotQuicksort { } 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 @@ final class DualPivotQuicksort { * * 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 @@ final class DualPivotQuicksort { } } - // 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. - * - *

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); - } - - /** - * 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). - * - *

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); + sort(a, 0, a.length - 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 @@ final class DualPivotQuicksort { 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 @@ final class DualPivotQuicksort { * * 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 @@ final class DualPivotQuicksort { * * 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) { - /* - * 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 { + if (leftmost) { /* - * 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 @@ final class DualPivotQuicksort { } 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 @@ final class DualPivotQuicksort { * 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 @@ final class DualPivotQuicksort { 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 @@ final class DualPivotQuicksort { 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 @@ final class DualPivotQuicksort { * 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 @@ final class DualPivotQuicksort { 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 @@ final class DualPivotQuicksort { } 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 @@ final class DualPivotQuicksort { * * 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 @@ final class DualPivotQuicksort { } } - // 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); - } - } } diff --git a/src/share/classes/java/util/Properties.java b/src/share/classes/java/util/Properties.java index 6f9c562e4f8b7729f69946b2a0bccb369475a3e1..ee6d17c4e4da421954719c53ba8efd8ebdb295eb 100644 --- a/src/share/classes/java/util/Properties.java +++ b/src/share/classes/java/util/Properties.java @@ -705,7 +705,7 @@ class Properties extends Hashtable { * Strings. */ @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 @@ class Properties extends Hashtable { * @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 @@ class Properties extends Hashtable { * @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) diff --git a/src/share/classes/java/util/XMLUtils.java b/src/share/classes/java/util/XMLUtils.java index a742675eaa21a99645aecc4c3619d3f17db29eab..8a3ac86ba32c05a1b114287da29ec0b024b3c9ab 100644 --- a/src/share/classes/java/util/XMLUtils.java +++ b/src/share/classes/java/util/XMLUtils.java @@ -141,14 +141,13 @@ class XMLUtils { 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); } diff --git a/src/share/classes/java/util/zip/ZipFile.java b/src/share/classes/java/util/zip/ZipFile.java index 79de443b1b0b108eb8a82e1447786ba1d3f7a28d..e995c4e89eec6fa770ec7571c23841c5c3842b1c 100644 --- a/src/share/classes/java/util/zip/ZipFile.java +++ b/src/share/classes/java/util/zip/ZipFile.java @@ -85,8 +85,7 @@ class ZipFile implements ZipConstants, Closeable { 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"))); } diff --git a/src/share/classes/javax/sql/rowset/RowSetProvider.java b/src/share/classes/javax/sql/rowset/RowSetProvider.java index 75875c7b576503d9486579ab55fec4e60f0cf651..4b81baa575628b756ff63238fa42811f4012d803 100644 --- a/src/share/classes/javax/sql/rowset/RowSetProvider.java +++ b/src/share/classes/javax/sql/rowset/RowSetProvider.java @@ -28,6 +28,7 @@ package javax.sql.rowset; import java.security.AccessController; import java.security.PrivilegedAction; import java.sql.SQLException; +import java.util.ServiceConfigurationError; import java.util.ServiceLoader; /** @@ -255,13 +256,19 @@ public class RowSetProvider { * 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; diff --git a/src/share/classes/javax/sql/rowset/spi/SyncFactory.java b/src/share/classes/javax/sql/rowset/spi/SyncFactory.java index 3369f466b415ffc101809532e7ce30714a332f8e..4c8d6b48e0a1cc6689651d5ff6e7fa0f403d9833 100644 --- a/src/share/classes/javax/sql/rowset/spi/SyncFactory.java +++ b/src/share/classes/javax/sql/rowset/spi/SyncFactory.java @@ -652,7 +652,10 @@ public class SyncFactory { * 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 diff --git a/src/share/classes/javax/swing/UIDefaults.java b/src/share/classes/javax/swing/UIDefaults.java index 2c9f2c34e1dfb6a7de1097cdad2786ac9628f6aa..2a9056f539bad32d70c7d93d21b7ea292f1f69f9 100644 --- a/src/share/classes/javax/swing/UIDefaults.java +++ b/src/share/classes/javax/swing/UIDefaults.java @@ -52,6 +52,7 @@ import java.security.AccessControlContext; import java.security.PrivilegedAction; import sun.reflect.misc.MethodUtil; +import sun.reflect.misc.ReflectUtil; import sun.util.CoreResourceBundleControl; /** @@ -1078,6 +1079,9 @@ public class UIDefaults extends Hashtable // 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() { public Object run() { try { @@ -1093,7 +1097,9 @@ public class UIDefaults extends Hashtable 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 @@ public class UIDefaults extends Hashtable } else { Class[] types = getClassArray(args); Constructor constructor = c.getConstructor(types); + checkAccess(constructor.getModifiers()); return constructor.newInstance(args); } } catch(Exception e) { @@ -1115,6 +1122,13 @@ public class UIDefaults extends Hashtable }, 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 diff --git a/src/share/classes/javax/swing/text/html/HTMLEditorKit.java b/src/share/classes/javax/swing/text/html/HTMLEditorKit.java index 88a3661b0bafb88efeed55f80adb192dcc734b0b..f9642c7bdd75488221443683b66305e8edf2b94c 100644 --- a/src/share/classes/javax/swing/text/html/HTMLEditorKit.java +++ b/src/share/classes/javax/swing/text/html/HTMLEditorKit.java @@ -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 @@ public class HTMLEditorKit extends StyledEditorKit implements Accessible { * 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 @@ public class HTMLEditorKit extends StyledEditorKit implements Accessible { * 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 @@ public class HTMLEditorKit extends StyledEditorKit implements Accessible { 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; diff --git a/src/share/classes/javax/swing/text/html/parser/DTD.java b/src/share/classes/javax/swing/text/html/parser/DTD.java index 4639b8379ba7ed679e9aad673ef5096ab0560719..b0787eabbb07f886b1e201b9c72456118b7a8ea7 100644 --- a/src/share/classes/javax/swing/text/html/parser/DTD.java +++ b/src/share/classes/javax/swing/text/html/parser/DTD.java @@ -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 @@ class DTD implements DTDConstants { } /** - * The hashtable of DTDs. + * The hashtable key of DTDs in AppContext. */ - static Hashtable dtdHash = new Hashtable(); + private static final Object DTD_HASH_KEY = new Object(); + + public static void putDTDHash(String name, DTD dtd) { + getDtdHash().put(name, dtd); + } - public static void putDTDHash(String name, DTD dtd) { - dtdHash.put(name, dtd); - } /** * Returns a DTD with the specified name. If * a DTD with that name doesn't exist, one is created @@ -332,13 +335,27 @@ class DTD implements DTDConstants { */ 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 getDtdHash() { + AppContext appContext = AppContext.getAppContext(); + + Hashtable result = (Hashtable) appContext.get(DTD_HASH_KEY); + + if (result == null) { + result = new Hashtable(); + + appContext.put(DTD_HASH_KEY, result); + } + + return result; + } + /** * Recreates a DTD from an archived format. * @param in the DataInputStream to read from diff --git a/src/share/classes/javax/swing/text/html/parser/ParserDelegator.java b/src/share/classes/javax/swing/text/html/parser/ParserDelegator.java index 89289e080970a4bc46641ce81102b374892bbc9f..06b53483dc082b91319b9502eeba04a6c3d0c645 100644 --- a/src/share/classes/javax/swing/text/html/parser/ParserDelegator.java +++ b/src/share/classes/javax/swing/text/html/parser/ParserDelegator.java @@ -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.DataInputStream; 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 @@ import java.lang.reflect.Method; 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 @@ public class ParserDelegator extends HTMLEditorKit.Parser implements Serializabl 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 class ParserDelegator extends HTMLEditorKit.Parser implements Serializabl 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 @@ public class ParserDelegator extends HTMLEditorKit.Parser implements Serializabl private void readObject(ObjectInputStream s) throws ClassNotFoundException, IOException { s.defaultReadObject(); - if (dtd == null) { - setDefaultDTD(); - } + setDefaultDTD(); } } diff --git a/src/share/classes/sun/awt/image/BufImgSurfaceData.java b/src/share/classes/sun/awt/image/BufImgSurfaceData.java index 082c1f581ff3a8291fa05840f48c6c81d474b882..43ec7286620f9d5e347454a61b21cbff78c3de9c 100644 --- a/src/share/classes/sun/awt/image/BufImgSurfaceData.java +++ b/src/share/classes/sun/awt/image/BufImgSurfaceData.java @@ -49,7 +49,7 @@ public class BufImgSurfaceData extends SurfaceData { 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 @@ public class BufImgSurfaceData extends SurfaceData { 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 @@ public class BufImgSurfaceData extends SurfaceData { // 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 class BufImgSurfaceData extends SurfaceData { 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; + } + } + } } diff --git a/src/share/classes/sun/jkernel/DownloadManager.java b/src/share/classes/sun/jkernel/DownloadManager.java index 1a4f1ff28e626d6bcc205df1548c35578d2f1e71..416cec7feeac67f76d01ced1a27555fb5289dd14 100644 --- a/src/share/classes/sun/jkernel/DownloadManager.java +++ b/src/share/classes/sun/jkernel/DownloadManager.java @@ -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.Launcher; import sun.misc.BootClassLoaderHook; +import sun.misc.Launcher; +import sun.misc.URLClassPath; +import sun.net.www.ParseUtil; /** * Handles the downloading of additional JRE components. The bootstrap class @@ -658,31 +663,61 @@ public class DownloadManager extends BootClassLoaderHook { 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 class DownloadManager extends BootClassLoaderHook { } } - public File[] getAdditionalBootstrapPaths() { - return DownloadManager.getAdditionalBootStrapPaths(); + public URLClassPath getBootstrapClassPath(URLClassPath bcp, + URLStreamHandlerFactory factory) + { + return DownloadManager.getBootClassPath(bcp, factory); } public boolean isCurrentThreadPrefetching() { diff --git a/src/share/classes/sun/launcher/resources/launcher.properties b/src/share/classes/sun/launcher/resources/launcher.properties index cb4718976fb781b55f7b8b1d4c84edf6a1120c52..e89d147a5bba82b96edc51d297343ec426729607 100644 --- a/src/share/classes/sun/launcher/resources/launcher.properties +++ b/src/share/classes/sun/launcher/resources/launcher.properties @@ -49,7 +49,7 @@ java.launcher.opt.footer =\ -cp \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\ diff --git a/src/share/classes/sun/launcher/resources/launcher_de.properties b/src/share/classes/sun/launcher/resources/launcher_de.properties index 275b452a80ba892f602aac0714cd1e20b634808b..99d347d5966d5921a440778986c3ac49a0647669 100644 --- a/src/share/classes/sun/launcher/resources/launcher_de.properties +++ b/src/share/classes/sun/launcher/resources/launcher_de.properties @@ -34,7 +34,7 @@ java.launcher.ergo.message1 =\ Standard-VM ist {0}, 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 \n\ -classpath \n\ A {0} getrennte Liste von Verzeichnissen, JAR-Archiven,\n\ und ZIP-Archiven f\u00fcr die Suche nach Klassendateien .\n\ -D=\n\ Systemeigenschaft festlegen\n\ -verbose[:class|gc|jni]\n\ ausf\u00fchrliche Ausgabe aktivieren\n\ -version Produktversion drucken und beenden\n\ -version:\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[:...|:]\n\ -enableassertions[:...|:]\n\ Assertions mit spezifizierter Granularit\u00e4t aktivieren\n\ -da[:...|:]\n\ -disableassertions[:...|:]\n\ Assertions mit spezifizierter Granularit\u00e4t deaktivieren\n\ -esa | --enablesystemassertions\n\ System-Assertions aktivieren\n\ -dsa | --disablesystemassertions\n\ System-Assertions deaktivieren\n\ -agentlib:[=]\n\ systemeigene Agent-Bibliothek laden , z.B. -agentlib:hprof\n\ siehe auch, -agentlib:jdwp=help und -agentlib:hprof=help\n\ -agentpath:[=]\n\ systemeigene Agent-Bibliothek \u00fcber vollst\u00e4ndigen Pfadnamen laden\n\ -javaagent:[=]\n\ Java Programmierungs-Sprachagenten laden, siehe java.lang.instrument\n\ -splash:\n\ Eingangsbildschirm mit spezifiziertem Bild anzeigen\nWeitere Informationen finden Sie unter http://java.sun.com/javase/reference. +java.launcher.opt.footer =\ -cp \n\ -classpath \n\ A {0} getrennte Liste von Verzeichnissen, JAR-Archiven,\n\ und ZIP-Archiven f\u00fcr die Suche nach Klassendateien .\n\ -D=\n\ Systemeigenschaft festlegen\n\ -verbose[:class|gc|jni]\n\ ausf\u00fchrliche Ausgabe aktivieren\n\ -version Produktversion drucken und beenden\n\ -version:\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[:...|:]\n\ -enableassertions[:...|:]\n\ Assertions mit spezifizierter Granularit\u00e4t aktivieren\n\ -da[:...|:]\n\ -disableassertions[:...|:]\n\ Assertions mit spezifizierter Granularit\u00e4t deaktivieren\n\ -esa | --enablesystemassertions\n\ System-Assertions aktivieren\n\ -dsa | --disablesystemassertions\n\ System-Assertions deaktivieren\n\ -agentlib:[=]\n\ systemeigene Agent-Bibliothek laden , z.B. -agentlib:hprof\n\ siehe auch, -agentlib:jdwp=help und -agentlib:hprof=help\n\ -agentpath:[=]\n\ systemeigene Agent-Bibliothek \u00fcber vollst\u00e4ndigen Pfadnamen laden\n\ -javaagent:[=]\n\ Java Programmierungs-Sprachagenten laden, siehe java.lang.instrument\n\ -splash:\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:\n\ Suchpfad f\u00fcr Bootstrap-Klassen und Ressourcen einrichten\n\ -Xbootclasspath/a:\n\ an das Ende des Bootstrap-Klassenpfads anh\u00e4ngen\n\ -Xbootclasspath/p:\n\ an den Beginn des Bootstrap-Klassenpfads anh\u00e4ngen\n\ -Xnoclassgc Klassen-Speicherbereinigung deaktivieren\n\ -Xincgc inkrementelle Speicherbereinigung aktivieren\n\ -Xloggc: GC-Status f\u00fcr eine Datei mit Zeitstempeln einrichten\n\ -Xbatch Hintergrund-Kompilation deaktivieren\n\ -Xms anf\u00e4ngliche Java Heap-Gr\u00f6\u00dfe einstellen\n\ -Xmx maximale Java Heap-Gr\u00f6\u00dfe einstellen\n\ -Xss 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 diff --git a/src/share/classes/sun/launcher/resources/launcher_es.properties b/src/share/classes/sun/launcher/resources/launcher_es.properties index 11bf04f2a66fcfb0d91dd7a414cecd9aee9d5b68..2daa7a2ffc84dfd0d01d96a70183e4bf60cdd8fa 100644 --- a/src/share/classes/sun/launcher/resources/launcher_es.properties +++ b/src/share/classes/sun/launcher/resources/launcher_es.properties @@ -34,7 +34,7 @@ java.launcher.ergo.message1 =\ La m\u00e1quina virtual predete 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 \n\ -classpath \n\ Una {0} lista de directorios, archivos JAR,\n\ y archivos ZIP en los que buscar los archivos de clase.\n\ -D=\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:\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[:...|:]\n\ -enableassertions[:...|:]\n\ permitir afirmaciones con granularidad especificada\n\ -da[:...|:]\n\ -disableassertions[:...|:]\n\ desactivar afirmaciones con granularidad especificada\n\ -esa | -enablesystemassertions\n\ permitir afirmaciones del sistema\n\ -dsa | -disablesystemassertions\n\ desactivar afirmaciones del sistema\n\ -agentlib:[=]\n\ cargar biblioteca de agente nativo, por ejemplo -agentlib:hprof\n\ consulte tambi\u00e9n, -agentlib:jdwp=help y -agentlib:hprof=help\n\ -agentpath:[=]\n\ cargar biblioteca de agente nativo por ruta completa\n\ -javaagent:[=]\n\ cargar agente del lenguaje de programaci\u00f3n Java, consulte java.lang.instrument\n\ -splash:\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 \n\ -classpath \n\ Una {0} lista de directorios, archivos JAR,\n\ y archivos ZIP en los que buscar los archivos de clase.\n\ -D=\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:\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[:...|:]\n\ -enableassertions[:...|:]\n\ permitir afirmaciones con granularidad especificada\n\ -da[:...|:]\n\ -disableassertions[:...|:]\n\ desactivar afirmaciones con granularidad especificada\n\ -esa | -enablesystemassertions\n\ permitir afirmaciones del sistema\n\ -dsa | -disablesystemassertions\n\ desactivar afirmaciones del sistema\n\ -agentlib:[=]\n\ cargar biblioteca de agente nativo, por ejemplo -agentlib:hprof\n\ consulte tambi\u00e9n, -agentlib:jdwp=help y -agentlib:hprof=help\n\ -agentpath:[=]\n\ cargar biblioteca de agente nativo por ruta completa\n\ -javaagent:[=]\n\ cargar agente del lenguaje de programaci\u00f3n Java, consulte java.lang.instrument\n\ -splash:\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:\n\ definir ruta de b\u00fasqueda para clases y recursos de la rutina de carga\n\ -Xbootclasspath/a:\n\ a\u00f1adir al final de la ruta de clase de la rutina de carga\n\ -Xbootclasspath/p:\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: registrar estado de GC en un archivo con marcas de tiempo\n\ -Xbatch desactivar recopilaci\u00f3n de fondos\n\ -Xms definir tama\u00f1o del mont\u00f3n de Java inicial\n\ -Xmx definir tama\u00f1o m\u00e1ximo del mont\u00f3n de Java\n\ -Xss 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 diff --git a/src/share/classes/sun/launcher/resources/launcher_fr.properties b/src/share/classes/sun/launcher/resources/launcher_fr.properties index c4e5f47a090ecb96bdd25bc9566ab26493c6a832..ace15ee3529c7dd5c06b44834b34d8c0e387a921 100644 --- a/src/share/classes/sun/launcher/resources/launcher_fr.properties +++ b/src/share/classes/sun/launcher/resources/launcher_fr.properties @@ -34,7 +34,7 @@ java.launcher.ergo.message1 =\ La machine virtuelle par d\u00e 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 \n\ -classpath \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=\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:\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[:...|:]\n\ -enableassertions[:...|:]\n\ activer les assertions avec la granularit\u00e9 sp\u00e9cifi\u00e9e\n\ -da[:...|:]\n\ -disableassertions[:...|:]\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:[=]\n\ charger la biblioth\u00e8que d''agents natifs, par exemple -agentlib:hprof\n\ voir \u00e9galement, -agentlib:jdwp=help et -agentlib:hprof=help\n\ -agentpath:[=]\n\ charger la biblioth\u00e8que d''agents natifs en indiquant le chemin complet\n\ -javaagent:[=]\n\ charger l''agent de langage de programmation Java, voir java.lang.instrument\n\ -splash:\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 \n\ -classpath \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=\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:\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[:...|:]\n\ -enableassertions[:...|:]\n\ activer les assertions avec la granularit\u00e9 sp\u00e9cifi\u00e9e\n\ -da[:...|:]\n\ -disableassertions[:...|:]\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:[=]\n\ charger la biblioth\u00e8que d''agents natifs, par exemple -agentlib:hprof\n\ voir \u00e9galement, -agentlib:jdwp=help et -agentlib:hprof=help\n\ -agentpath:[=]\n\ charger la biblioth\u00e8que d''agents natifs en indiquant le chemin complet\n\ -javaagent:[=]\n\ charger l''agent de langage de programmation Java, voir java.lang.instrument\n\ -splash:\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:\n\ d\u00e9finir le chemin de recherche pour les classes et ressources bootstrap\n\ -Xbootclasspath/a:\n\ ajouter \u00e0 la fin du chemin de la classe bootstrap\n\ -Xbootclasspath/p:\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: enregistrer le statut GC dans un fichier horodat\u00e9\n\ -Xbatch d\u00e9sactiver la compilation d''arri\u00e8re-plans\n\ -Xms d\u00e9finir la taille initiale des tas Java\n\ -Xmx d\u00e9finir la taille maximale des tas Java\n\ -Xss 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 diff --git a/src/share/classes/sun/launcher/resources/launcher_it.properties b/src/share/classes/sun/launcher/resources/launcher_it.properties index e73987e57e54a5d4fb43e8ee35b1e1dafabdbcf2..267283288a8c83e9a8308df6e72c95d0a670935b 100644 --- a/src/share/classes/sun/launcher/resources/launcher_it.properties +++ b/src/share/classes/sun/launcher/resources/launcher_it.properties @@ -34,7 +34,7 @@ java.launcher.ergo.message1 =\ La macchina virtuale predefinit 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 \n\ -classpath \n\ Elenco separato da {0} di directory, archivi JAR\n\ e archivi ZIP in cui cercare i file di classe.\n\ -D=\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:\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[:...|:]\n\ -enableassertions[:...|:]\n\ attiva le asserzioni con la granularit\u00e0 specificata\n\ -da[:...|:]\n\ -disableassertions[:...|:]\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:[=]\n\ carica la libreria agente nativa , ad es. -agentlib:hprof\n\ vedere anche, -agentlib:jdwp=help e -agentlib:hprof=help\n\ -agentpath:[=]\n\ carica la libreria agente nativa in base al percorso completo\n\ -javaagent:[=]\n\ carica l''agente del linguaggio di programmazione Java, vedere java.lang.instrument\n\ -splash:\n\ mostra la schermata iniziale con l''immagine specificata\nPer ulteriori informazioni, visitare http://java.sun.com/javase/reference. +java.launcher.opt.footer =\ -cp \n\ -classpath \n\ Elenco separato da {0} di directory, archivi JAR\n\ e archivi ZIP in cui cercare i file di classe.\n\ -D=\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:\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[:...|:]\n\ -enableassertions[:...|:]\n\ attiva le asserzioni con la granularit\u00e0 specificata\n\ -da[:...|:]\n\ -disableassertions[:...|:]\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:[=]\n\ carica la libreria agente nativa , ad es. -agentlib:hprof\n\ vedere anche, -agentlib:jdwp=help e -agentlib:hprof=help\n\ -agentpath:[=]\n\ carica la libreria agente nativa in base al percorso completo\n\ -javaagent:[=]\n\ carica l''agente del linguaggio di programmazione Java, vedere java.lang.instrument\n\ -splash:\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:\n\ imposta il percorso di ricerca per classi e risorse di bootstrap\n\ -Xbootclasspath/a:\n\ accoda alla fine del percorso della classe di bootstrap\n\ -Xbootclasspath/p:\n\ antepone al percorso della classe di bootsrap\n\ -Xnoclassgc disattiva Garbage Collection per la classe\n\ -Xincgc attiva Garbage Collection incrementale\n\ -Xloggc: registra lo stato GC in un file con timestamp\n\ -Xbatch disattiva la compilazione in background\n\ -Xms imposta la dimensione heap Java iniziale\n\ -Xmx imposta la dimensione heap Java massima\n\ -Xss 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 diff --git a/src/share/classes/sun/launcher/resources/launcher_ja.properties b/src/share/classes/sun/launcher/resources/launcher_ja.properties index ada07d76a5901e56bc506f182343e82c236126c6..2da74b850cadc0963856e9da6bd12e3c78b80665 100644 --- a/src/share/classes/sun/launcher/resources/launcher_ja.properties +++ b/src/share/classes/sun/launcher/resources/launcher_ja.properties @@ -34,7 +34,7 @@ java.launcher.ergo.message1 =\ \u30c7\u30d5\u30a9\u30eb\u30c8 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=\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:\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[:...|:]\n\ -enableassertions[:...|:]\n\ \u6307\u5b9a\u3057\u305f\u7c92\u5ea6\u3067\u30a2\u30b5\u30fc\u30b7\u30e7\u30f3\u3092\u6709\u52b9\u5316\n\ -da[:...|:]\n\ -disableassertions[:...|:]\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:[=]\n\ \u30cd\u30a4\u30c6\u30a3\u30d6\u30a8\u30fc\u30b8\u30a7\u30f3\u30c8\u30e9\u30a4\u30d6\u30e9\u30ea (\u4f8b: -agentlib:hprof) \u3092\u30ed\u30fc\u30c9\n\ \u95a2\u9023\u9805\u76ee\u3001 -agentlib:jdwp=help and -agentlib:hprof=help\n\ -agentpath:[=]\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:[=]\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:\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=\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:\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[:...|:]\n\ -enableassertions[:...|:]\n\ \u6307\u5b9a\u3057\u305f\u7c92\u5ea6\u3067\u30a2\u30b5\u30fc\u30b7\u30e7\u30f3\u3092\u6709\u52b9\u5316\n\ -da[:...|:]\n\ -disableassertions[:...|:]\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:[=]\n\ \u30cd\u30a4\u30c6\u30a3\u30d6\u30a8\u30fc\u30b8\u30a7\u30f3\u30c8\u30e9\u30a4\u30d6\u30e9\u30ea (\u4f8b: -agentlib:hprof) \u3092\u30ed\u30fc\u30c9\n\ \u95a2\u9023\u9805\u76ee\u3001 -agentlib:jdwp=help and -agentlib:hprof=help\n\ -agentpath:[=]\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:[=]\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:\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:\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:\n\ \u30d6\u30fc\u30c8\u30b9\u30c8\u30e9\u30c3\u30d7\u30af\u30e9\u30b9\u306e\u30d1\u30b9\u306e\u672b\u5c3e\u306b\u8ffd\u52a0\n\ -Xbootclasspath/p:\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: \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 \u521d\u671f Java \u30d2\u30fc\u30d7\u30b5\u30a4\u30ba\u3092\u8a2d\u5b9a\n\ -Xmx \u6700\u5927 Java \u30d2\u30fc\u30d7\u30b5\u30a4\u30ba\u3092\u8a2d\u5b9a\n\ -Xss 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 diff --git a/src/share/classes/sun/launcher/resources/launcher_ko.properties b/src/share/classes/sun/launcher/resources/launcher_ko.properties index 2c56f83cca61d45db95dc4ba3c7575a5213425fc..ef3ae358639ba58c3ea5f754605b6bf47e794aec 100644 --- a/src/share/classes/sun/launcher/resources/launcher_ko.properties +++ b/src/share/classes/sun/launcher/resources/launcher_ko.properties @@ -34,7 +34,7 @@ java.launcher.ergo.message1 =\ \uae30\ubcf8 VM\uc740 {0}\uc784 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=\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:\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[:...|:]\n\ -enableassertions[:...|:]\n\ \uc9c0\uc815\ud55c \uc815\ubc00\ub3c4\uc758 \uba85\uc81c \uc0ac\uc6a9\n\ -da[:...|:]\n\ -disableassertions[:...|:]\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:[=]\n\ \uc6d0\uc2dc \uc5d0\uc774\uc804\ud2b8 \ub77c\uc774\ube0c\ub7ec\ub9ac \ub85c\ub4dc, \uc608: -agentlib:hprof\n\ \ucc38\uc870: -agentlib:jdwp=help \ubc0f -agentlib:hprof=help\n\ -agentpath:[=]\n\ \uc804\uccb4 \uacbd\ub85c \uc774\ub984\uc73c\ub85c \uc6d0\uc2dc \uc5d0\uc774\uc804\ud2b8 \ub77c\uc774\ube0c\ub7ec\ub9ac \ub85c\ub4dc\n\ -javaagent:[=]\n\ Java \ud504\ub85c\uadf8\ub798\ubc0d \uc5b8\uc5b4 \uc5d0\uc774\uc804\ud2b8 \ub85c\ub4dc, java.lang.instrument \ucc38\uc870\n\ -splash:\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=\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:\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[:...|:]\n\ -enableassertions[:...|:]\n\ \uc9c0\uc815\ud55c \uc815\ubc00\ub3c4\uc758 \uba85\uc81c \uc0ac\uc6a9\n\ -da[:...|:]\n\ -disableassertions[:...|:]\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:[=]\n\ \uc6d0\uc2dc \uc5d0\uc774\uc804\ud2b8 \ub77c\uc774\ube0c\ub7ec\ub9ac \ub85c\ub4dc, \uc608: -agentlib:hprof\n\ \ucc38\uc870: -agentlib:jdwp=help \ubc0f -agentlib:hprof=help\n\ -agentpath:[=]\n\ \uc804\uccb4 \uacbd\ub85c \uc774\ub984\uc73c\ub85c \uc6d0\uc2dc \uc5d0\uc774\uc804\ud2b8 \ub77c\uc774\ube0c\ub7ec\ub9ac \ub85c\ub4dc\n\ -javaagent:[=]\n\ Java \ud504\ub85c\uadf8\ub798\ubc0d \uc5b8\uc5b4 \uc5d0\uc774\uc804\ud2b8 \ub85c\ub4dc, java.lang.instrument \ucc38\uc870\n\ -splash:\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:\n\ \ubd80\ud2b8\uc2a4\ud2b8\ub7a9 \ud074\ub798\uc2a4\uc640 \uc790\uc6d0\uc758 \uac80\uc0c9 \uacbd\ub85c \uc124\uc815\n\ -Xbootclasspath/a:\n\ \ubd80\ud2b8\uc2a4\ud2b8\ub7a9 \ud074\ub798\uc2a4 \uacbd\ub85c \ub05d\uc5d0 \ucd94\uac00\n\ -Xbootclasspath/p:\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: 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 \ucd08\uae30 Java \ud799 \ud06c\uae30 \uc124\uc815\n\ -Xmx \ucd5c\ub300 Java \ud799 \ud06c\uae30 \uc124\uc815\n\ -Xss 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 diff --git a/src/share/classes/sun/launcher/resources/launcher_sv.properties b/src/share/classes/sun/launcher/resources/launcher_sv.properties index 21f20ad1f0ee554385801d88076340c1b6c0c2af..95b3ba28db4d10c6a9638d1c94d1721a751e2a15 100644 --- a/src/share/classes/sun/launcher/resources/launcher_sv.properties +++ b/src/share/classes/sun/launcher/resources/launcher_sv.properties @@ -34,7 +34,7 @@ java.launcher.ergo.message1 =\ Standard-VM \u00e4r {0} 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 \n\ -classpath \n\ en med {0} avgr\u00e4nsad lista \u00f6ver kataloger, JAR-arkiv\n\ och ZIP-arkiv f\u00f6r s\u00f6kning efter klassfiler.\n\ -D=\n\ ange en systemegenskap\n\ -verbose[:klass|gc|jni]\n\ visa mer text\n\ -version skriv ut produktversionen och avsluta\n\ -version:\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[:...|:]\n\ -enableassertions[:...|:]\n\ aktivera bekr\u00e4ftelser med angiven precision\n\ -da[:...|:]\n\ -disableassertions[:...|:]\n\ inaktivera bekr\u00e4ftelser med angiven precision\n\ -esa | -enablesystemassertions\n\ aktivera systembekr\u00e4ftelser\n\ -dsa | -disablesystemassertions\n\ inaktivera systembekr\u00e4ftelser\n\ -agentlib:[=]\n\ l\u00e4s in det interna agentbiblioteket , t.ex. -agentlib:hprof\n\ se \u00e4ven, -agentlib:jdwp=help och -agentlib:hprof=help\n\ -agentpath:[=]\n\ l\u00e4s in internt agentbibliotek utifr\u00e5n fullst\u00e4ndig s\u00f6kv\u00e4g\n\ -javaagent:[=]\n\ l\u00e4s in agenten f\u00f6r programmeringsspr\u00e5ket Java, se java.lang.instrument\n\ -splash:\n\ visa v\u00e4lkomstf\u00f6nster med angiven bild\nMer information finns p\u00e5 http://java.sun.com/javase/reference. +java.launcher.opt.footer =\ -cp \n\ -classpath \n\ en med {0} avgr\u00e4nsad lista \u00f6ver kataloger, JAR-arkiv\n\ och ZIP-arkiv f\u00f6r s\u00f6kning efter klassfiler.\n\ -D=\n\ ange en systemegenskap\n\ -verbose[:klass|gc|jni]\n\ visa mer text\n\ -version skriv ut produktversionen och avsluta\n\ -version:\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[:...|:]\n\ -enableassertions[:...|:]\n\ aktivera bekr\u00e4ftelser med angiven precision\n\ -da[:...|:]\n\ -disableassertions[:...|:]\n\ inaktivera bekr\u00e4ftelser med angiven precision\n\ -esa | -enablesystemassertions\n\ aktivera systembekr\u00e4ftelser\n\ -dsa | -disablesystemassertions\n\ inaktivera systembekr\u00e4ftelser\n\ -agentlib:[=]\n\ l\u00e4s in det interna agentbiblioteket , t.ex. -agentlib:hprof\n\ se \u00e4ven, -agentlib:jdwp=help och -agentlib:hprof=help\n\ -agentpath:[=]\n\ l\u00e4s in internt agentbibliotek utifr\u00e5n fullst\u00e4ndig s\u00f6kv\u00e4g\n\ -javaagent:[=]\n\ l\u00e4s in agenten f\u00f6r programmeringsspr\u00e5ket Java, se java.lang.instrument\n\ -splash:\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:\n\ ange s\u00f6kv\u00e4g f\u00f6r bootstrap-klasser och -resurser\n\ -Xbootclasspath/a:\n\ l\u00e4gg till p\u00e5 slutet av s\u00f6kv\u00e4gen till bootstrap-klassen\n\ -Xbootclasspath/p:\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: logga GC-status till en fil med tidsst\u00e4mpel\n\ -Xbatch inaktivera kompilering i bakgrunden\n\ -Xms st\u00e4ll in ursprunglig heapstorlek f\u00f6r Java\n\ -Xmx st\u00e4ll in st\u00f6rsta heapstorlek f\u00f6r Java\n\ -Xss 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 diff --git a/src/share/classes/sun/launcher/resources/launcher_zh_CN.properties b/src/share/classes/sun/launcher/resources/launcher_zh_CN.properties index e7b0352d0d7990cbdc523765374f32ab10a3a853..55b5a06feb54479d122c629231ddce3d2ac387cd 100644 --- a/src/share/classes/sun/launcher/resources/launcher_zh_CN.properties +++ b/src/share/classes/sun/launcher/resources/launcher_zh_CN.properties @@ -34,7 +34,7 @@ java.launcher.ergo.message1 =\ \u9ed8\u8ba4\u7684 VM \u4e3a {0 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=\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:\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[:...|:]\n\ -enableassertions[:...|:]\n\ \u542f\u7528\u6307\u5b9a\u7c92\u5ea6\u7684\u65ad\u8a00\n\ -da[:...|:]\n\ -disableassertions[:...|:]\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:[=]\n\ \u88c5\u5165\u672c\u673a\u4ee3\u7406\u5e93 \uff0c\u4f8b\u5982\uff1a-agentlib:hprof\n\ \u53e6\u8bf7\u53c2\u89c1 -agentlib:jdwp=help \u548c -agentlib:hprof=help\n\ -agentpath:[=]\n\ \u4ee5\u5168\u8def\u5f84\u540d\u88c5\u5165\u672c\u673a\u4ee3\u7406\u5e93\n\ -javaagent:[=]\n\ \u88c5\u5165 Java \u7f16\u7a0b\u8bed\u8a00\u4ee3\u7406\uff0c\u8bf7\u53c2\u89c1 java.lang.instrument\n\ -splash:\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=\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:\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[:...|:]\n\ -enableassertions[:...|:]\n\ \u542f\u7528\u6307\u5b9a\u7c92\u5ea6\u7684\u65ad\u8a00\n\ -da[:...|:]\n\ -disableassertions[:...|:]\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:[=]\n\ \u88c5\u5165\u672c\u673a\u4ee3\u7406\u5e93 \uff0c\u4f8b\u5982\uff1a-agentlib:hprof\n\ \u53e6\u8bf7\u53c2\u89c1 -agentlib:jdwp=help \u548c -agentlib:hprof=help\n\ -agentpath:[=]\n\ \u4ee5\u5168\u8def\u5f84\u540d\u88c5\u5165\u672c\u673a\u4ee3\u7406\u5e93\n\ -javaagent:[=]\n\ \u88c5\u5165 Java \u7f16\u7a0b\u8bed\u8a00\u4ee3\u7406\uff0c\u8bf7\u53c2\u89c1 java.lang.instrument\n\ -splash:\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 diff --git a/src/share/classes/sun/launcher/resources/launcher_zh_TW.properties b/src/share/classes/sun/launcher/resources/launcher_zh_TW.properties index a04cbe71a7a7003620031011ae9d3c79a7672055..e5b87470ede958c99b283109c59e0078af34301a 100644 --- a/src/share/classes/sun/launcher/resources/launcher_zh_TW.properties +++ b/src/share/classes/sun/launcher/resources/launcher_zh_TW.properties @@ -34,7 +34,7 @@ java.launcher.ergo.message1 =\ \u9810\u8a2d VM \u70ba {0} 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=\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:\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[:...|:]\n\ -enableassertions[:...|:]\n\ \u555f\u7528\u5177\u6709\u6307\u5b9a\u9846\u7c92\u6027\u7684\u5ba3\u544a\n\ -da[:...|:]\n\ -disableassertions[:...|:]\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:[=]\n\ \u8f09\u5165\u539f\u751f\u4ee3\u7406\u7a0b\u5f0f\u7a0b\u5f0f\u5eab \uff0c\u4f8b\u5982 -agentlib:hprof\n\ \u53e6\u8acb\u53c3\u95b1 -agentlib:jdwp=help \u548c -agentlib:hprof=help\n\ -agentpath:[=]\n\ \u4f9d\u64da\u5b8c\u6574\u8def\u5f91\u540d\u7a31\u8f09\u5165\u539f\u751f\u4ee3\u7406\u7a0b\u5f0f\n\ -javaagent:[=]\n\ \u8f09\u5165 Java \u7a0b\u5f0f\u8a2d\u8a08\u8a9e\u8a00\u4ee3\u7406\u7a0b\u5f0f\uff0c\u8acb\u53c3\u95b1 java.lang.instrument\n\ -splash:\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=\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:\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[:...|:]\n\ -enableassertions[:...|:]\n\ \u555f\u7528\u5177\u6709\u6307\u5b9a\u9846\u7c92\u6027\u7684\u5ba3\u544a\n\ -da[:...|:]\n\ -disableassertions[:...|:]\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:[=]\n\ \u8f09\u5165\u539f\u751f\u4ee3\u7406\u7a0b\u5f0f\u7a0b\u5f0f\u5eab \uff0c\u4f8b\u5982 -agentlib:hprof\n\ \u53e6\u8acb\u53c3\u95b1 -agentlib:jdwp=help \u548c -agentlib:hprof=help\n\ -agentpath:[=]\n\ \u4f9d\u64da\u5b8c\u6574\u8def\u5f91\u540d\u7a31\u8f09\u5165\u539f\u751f\u4ee3\u7406\u7a0b\u5f0f\n\ -javaagent:[=]\n\ \u8f09\u5165 Java \u7a0b\u5f0f\u8a2d\u8a08\u8a9e\u8a00\u4ee3\u7406\u7a0b\u5f0f\uff0c\u8acb\u53c3\u95b1 java.lang.instrument\n\ -splash:\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 diff --git a/src/share/classes/sun/misc/BootClassLoaderHook.java b/src/share/classes/sun/misc/BootClassLoaderHook.java index a4c5e231dd7b9b4407d7fd8ddaba8f3c2ca8d88e..970ad5ceacc93eb899ecb9f9082c9829b9ec12c4 100644 --- a/src/share/classes/sun/misc/BootClassLoaderHook.java +++ b/src/share/classes/sun/misc/BootClassLoaderHook.java @@ -27,6 +27,8 @@ package sun.misc; 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 @@ public abstract class BootClassLoaderHook { } } - 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 class BootClassLoaderHook { 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 diff --git a/src/share/classes/sun/misc/Launcher.java b/src/share/classes/sun/misc/Launcher.java index 2a8397d4886ed00cd1e9f92cf2e10069bf163de3..3d7c5e3cc69146e253856169926e77e434777528 100644 --- a/src/share/classes/sun/misc/Launcher.java +++ b/src/share/classes/sun/misc/Launcher.java @@ -47,7 +47,6 @@ import java.security.Permissions; 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 @@ Launcher */ 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 @@ public class Launcher { 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 @@ public class Launcher { } } - 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() { public URL[] run() { - File[] classPath = getClassPath(path); + File[] classPath = getClassPath(bootClassPath); int len = classPath.length; Set seenDirs = new HashSet(); for (int i = 0; i < len; i++) { @@ -410,25 +408,16 @@ public class Launcher { } 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 -1) - directMemory = l; - } - } - - 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,28 +201,89 @@ public class VM { 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() { - if (!booted) { - String s - = System.getProperty("sun.lang.ClassLoader.allowArraySyntax"); - allowArraySyntax = (s == null - ? defaultAllowArraySyntax - : Boolean.parseBoolean(s)); - } 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. + // + // 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=. + // 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; + } + } + + // 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 // set for the class libraries. // diff --git a/src/share/classes/sun/net/www/MessageHeader.java b/src/share/classes/sun/net/www/MessageHeader.java index a9f9f9dc1ff51a0ce0cc9bcccc5804bf2fc7eb51..2493290d8241fe1750fd20b1deb34b66963f213d 100644 --- a/src/share/classes/sun/net/www/MessageHeader.java +++ b/src/share/classes/sun/net/www/MessageHeader.java @@ -196,6 +196,10 @@ class MessageHeader { } public synchronized Map> getHeaders(String[] excludeList) { + return filterAndAddHeaders(excludeList, null); + } + + public synchronized Map> filterAndAddHeaders(String[] excludeList, Map> include) { boolean skipIt = false; Map> m = new HashMap>(); for (int i = nkeys; --i >= 0;) { @@ -223,6 +227,19 @@ class MessageHeader { } } + 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))); } diff --git a/src/share/classes/sun/net/www/MimeTable.java b/src/share/classes/sun/net/www/MimeTable.java index 6d21fa0fd4ef81ab81b30a7aad67e5040aed7754..085b97505d887454e3cb1653ec4361421d8c0b92 100644 --- a/src/share/classes/sun/net/www/MimeTable.java +++ b/src/share/classes/sun/net/www/MimeTable.java @@ -73,29 +73,32 @@ public class MimeTable implements FileNameMap { 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() { + 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() { - public Void run() { - defaultInstance = new MimeTable(); - URLConnection.setFileNameMap(defaultInstance); - return null; - } - }); - } - - return defaultInstance; + return DefaultInstanceHolder.defaultInstance; } /** diff --git a/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java b/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java index ad45c983f29a1adcf5ad702faac021476a9b5b1c..56ed6a40fa34fd03b04ac0fa938fd9537851dee8 100644 --- a/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java +++ b/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java @@ -51,6 +51,9 @@ import java.util.List; 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 @@ public class HttpURLConnection extends java.net.HttpURLConnection { */ 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 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 @@ public class HttpURLConnection extends java.net.HttpURLConnection { 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(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 @@ public class HttpURLConnection extends java.net.HttpURLConnection { "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 @@ public class HttpURLConnection extends java.net.HttpURLConnection { /* 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 @@ public class HttpURLConnection extends java.net.HttpURLConnection { }); } + 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 @@ public class HttpURLConnection extends java.net.HttpURLConnection { "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 @@ public class HttpURLConnection extends java.net.HttpURLConnection { } } + 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 @@ public class HttpURLConnection extends java.net.HttpURLConnection { // 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 @@ public class HttpURLConnection extends java.net.HttpURLConnection { 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 @@ public class HttpURLConnection extends java.net.HttpURLConnection { 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 @@ public class HttpURLConnection extends java.net.HttpURLConnection { 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 @@ public class HttpURLConnection extends java.net.HttpURLConnection { } @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 @@ public class HttpURLConnection extends java.net.HttpURLConnection { * @since 1.4 */ @Override - public Map> getRequestProperties() { + public synchronized Map> 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 diff --git a/src/share/classes/sun/security/jca/Providers.java b/src/share/classes/sun/security/jca/Providers.java index 732c9f37ee4a5927ee9a6f84eb2b0a914aa16566..9e2ad0e9fa9e2eb0216300a84c4238c50e05256a 100644 --- a/src/share/classes/sun/security/jca/Providers.java +++ b/src/share/classes/sun/security/jca/Providers.java @@ -159,15 +159,18 @@ public class Providers { * 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(); diff --git a/src/share/classes/sun/security/jgss/krb5/InitialToken.java b/src/share/classes/sun/security/jgss/krb5/InitialToken.java index 36e0d517b3c4943935c52389dac6610c4b770ebe..e889fcc42a86025968f252f18115bd0c583c12a1 100644 --- a/src/share/classes/sun/security/jgss/krb5/InitialToken.java +++ b/src/share/classes/sun/security/jgss/krb5/InitialToken.java @@ -35,7 +35,6 @@ import java.security.MessageDigest; 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 @@ abstract class InitialToken extends Krb5Token { 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]) || diff --git a/src/share/classes/sun/security/ssl/Alerts.java b/src/share/classes/sun/security/ssl/Alerts.java index 2704628dd003bcc3a30a5298d95a8a2ef52e919e..672d9b719d77b7d29793c7d65097099aa671390b 100644 --- a/src/share/classes/sun/security/ssl/Alerts.java +++ b/src/share/classes/sun/security/ssl/Alerts.java @@ -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 @@ final class Alerts { 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 @@ final class Alerts { 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 @@ final class Alerts { 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; diff --git a/src/share/classes/sun/security/ssl/CipherSuite.java b/src/share/classes/sun/security/ssl/CipherSuite.java index 6844e9defa9188081158afcf9f4db94eb1679018..b6619a952a8d6a2091000d5454247968c254206d 100644 --- a/src/share/classes/sun/security/ssl/CipherSuite.java +++ b/src/share/classes/sun/security/ssl/CipherSuite.java @@ -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 @@ final class CipherSuite implements Comparable { 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 @@ final class CipherSuite implements Comparable { 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 @@ final class CipherSuite implements Comparable { // 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 @@ final class CipherSuite implements Comparable { 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 @@ final class CipherSuite implements Comparable { * * @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 @@ final class CipherSuite implements Comparable { 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 @@ final class CipherSuite implements Comparable { } // 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 @@ final class CipherSuite implements Comparable { // 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("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_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_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_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_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("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); + + // 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); - -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("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); - -// 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); - + // 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("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("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); // Register the names of a few additional CipherSuites. // Makes them show up as names instead of numbers in @@ -618,4 +706,6 @@ add("TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5", 0x0029, --p, K_KRB5_EXPORT, B_DES_4 // 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); } diff --git a/src/share/classes/sun/security/ssl/CipherSuiteList.java b/src/share/classes/sun/security/ssl/CipherSuiteList.java index fb3ff162e7e09d33289240622a1158e5b7ddb863..93bfb15a02feede4d0da166e95cdd1ab430eb8ad 100644 --- a/src/share/classes/sun/security/ssl/CipherSuiteList.java +++ b/src/share/classes/sun/security/ssl/CipherSuiteList.java @@ -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 @@ final class CipherSuiteList { // null if not yet checked. private volatile Boolean containsEC; - // for use by buildAvailableCache() only - private CipherSuiteList(Collection cipherSuites) { + // for use by buildAvailableCache() and + // Handshaker.getKickstartMessage() only + CipherSuiteList(Collection cipherSuites) { this.cipherSuites = cipherSuites; } @@ -221,15 +222,18 @@ final class CipherSuiteList { // SortedSet automatically arranges ciphersuites in default // preference order Set cipherSuites = new TreeSet(); - Collection allowedCipherSuites = CipherSuite.allowedCipherSuites(); + Collection 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); } diff --git a/src/share/classes/sun/security/ssl/ClientHandshaker.java b/src/share/classes/sun/security/ssl/ClientHandshaker.java index 32013610d9b32e2471116f8f0cac31b500cc5ef0..0e9960e11fc635083831705e751182ce3b9b945c 100644 --- a/src/share/classes/sun/security/ssl/ClientHandshaker.java +++ b/src/share/classes/sun/security/ssl/ClientHandshaker.java @@ -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 @@ final class ClientHandshaker extends Handshaker { */ 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 @@ final class ClientHandshaker extends Handshaker { // 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 @@ final class ClientHandshaker extends Handshaker { // 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 @@ final class ClientHandshaker extends Handshaker { // 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 @@ final class ClientHandshaker extends Handshaker { // 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 @@ final class ClientHandshaker extends Handshaker { 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); } @@ -868,6 +939,13 @@ final class ClientHandshaker extends Handshaker { // NOTREACHED } + /* + * 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 @@ -920,6 +998,13 @@ final class ClientHandshaker extends Handshaker { */ 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 @@ -933,11 +1018,14 @@ final class ClientHandshaker extends Handshaker { * Returns a ClientHello message to kickstart renegotiations */ HandshakeMessage getKickstartMessage() throws SSLException { - ClientHello mesg = new ClientHello(sslContext.getSecureRandom(), - protocolVersion); - maxProtocolVersion = protocolVersion; + // session ID of the ClientHello message + SessionId sessionId = SSLSessionImpl.nullSession.getSessionId(); + + // a list of cipher suites sent by the client + CipherSuiteList cipherSuites = enabledCipherSuites; - clnt_random = mesg.clnt_random; + // set the max protocol version this client is supporting. + maxProtocolVersion = protocolVersion; // // Try to resume an existing session. This might be mandatory, @@ -962,9 +1050,9 @@ final class ClientHandshaker extends Handshaker { 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 @@ final class ClientHandshaker extends Handshaker { + " 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 @@ final class ClientHandshaker extends Handshaker { 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; + + Collection cipherList = + new ArrayList(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); } } - if (session == null) { - if (enableNewSession) { - mesg.sessionId = SSLSessionImpl.nullSession.getSessionId(); - } else { - throw new SSLException("No existing session to resume."); + + 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 cipherList = + new ArrayList(cipherSuites.size() - 1); + for (CipherSuite suite : cipherSuites.collection()) { + if (suite != CipherSuite.C_SCSV) { + cipherList.add(suite); + } } + + 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); + // 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 mesg; + return clientHelloMessage; } /* diff --git a/src/share/classes/sun/security/ssl/HandshakeMessage.java b/src/share/classes/sun/security/ssl/HandshakeMessage.java index 3bb60877034fa2f4fd42230ac89a84847177ef4e..126ad310345dedab5d36b9fe482e578947ffd725 100644 --- a/src/share/classes/sun/security/ssl/HandshakeMessage.java +++ b/src/share/classes/sun/security/ssl/HandshakeMessage.java @@ -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 @@ public abstract class HandshakeMessage { * 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 @@ class HelloRequest extends HandshakeMessage * 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,27 +220,48 @@ class ClientHello extends HandshakeMessage private final static byte[] NULL_COMPRESSION = new byte[] {0}; - ClientHello(SecureRandom generator, ProtocolVersion protocolVersion) { + ClientHello(SecureRandom generator, ProtocolVersion protocolVersion, + SessionId sessionId, CipherSuiteList cipherSuites) { + this.protocolVersion = protocolVersion; + this.sessionId = sessionId; + this.cipherSuites = cipherSuites; + + if (cipherSuites.containsEC()) { + extensions.add(SupportedEllipticCurvesExtension.DEFAULT); + extensions.add(SupportedEllipticPointFormatsExtension.DEFAULT); + } + clnt_random = new RandomCookie(generator); compression_methods = NULL_COMPRESSION; - // sessionId, cipher_suites TBS later + } + + ClientHello(HandshakeInStream s, int messageLength) throws IOException { + protocolVersion = ProtocolVersion.valueOf(s.getInt8(), s.getInt8()); + clnt_random = new RandomCookie(s); + sessionId = new SessionId(s.getBytes8()); + cipherSuites = new CipherSuiteList(s); + compression_methods = s.getBytes8(); + if (messageLength() != messageLength) { + extensions = new HelloExtensions(s); + } } CipherSuiteList getCipherSuites() { return 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); - } + // 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... @@ -258,17 +274,7 @@ class ClientHello extends HandshakeMessage + extensions.length(); } - ClientHello(HandshakeInStream s, int messageLength) throws IOException { - protocolVersion = ProtocolVersion.valueOf(s.getInt8(), s.getInt8()); - clnt_random = new RandomCookie(s); - sessionId = new SessionId(s.getBytes8()); - cipherSuites = new CipherSuiteList(s); - compression_methods = s.getBytes8(); - if (messageLength() != messageLength) { - extensions = new HelloExtensions(s); - } - } - + @Override void send(HandshakeOutStream s) throws IOException { s.putInt8(protocolVersion.major); s.putInt8(protocolVersion.minor); @@ -279,6 +285,7 @@ class ClientHello extends HandshakeMessage extensions.send(s); } + @Override void print(PrintStream s) throws IOException { s.println("*** ClientHello, " + protocolVersion); @@ -315,7 +322,6 @@ class ServerHello extends HandshakeMessage CipherSuite cipherSuite; byte compression_method; HelloExtensions extensions = new HelloExtensions(); - int extensionLength; ServerHello() { // empty @@ -1425,8 +1431,6 @@ static final class CertificateVerify extends HandshakeMessage { */ 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 @@ static final class Finished extends HandshakeMessage { * 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 @@ static final class Finished extends HandshakeMessage { 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 @@ static final class Finished extends HandshakeMessage { s.println("***"); } } - } // diff --git a/src/share/classes/sun/security/ssl/Handshaker.java b/src/share/classes/sun/security/ssl/Handshaker.java index 2f55fbdfa359943e298752bf0586a27475936db0..ddef8fc221a31d899f87ff55a5c0af914c3ec6a1 100644 --- a/src/share/classes/sun/security/ssl/Handshaker.java +++ b/src/share/classes/sun/security/ssl/Handshaker.java @@ -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 @@ abstract class Handshaker { // 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 @@ abstract class Handshaker { 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 @@ abstract class Handshaker { * 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(); } /** @@ -458,6 +501,27 @@ abstract class Handshaker { return session; } + /* + * 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. diff --git a/src/share/classes/sun/security/ssl/HelloExtensions.java b/src/share/classes/sun/security/ssl/HelloExtensions.java index a59037fe35df8ef5e4452381e214dc2377a627c6..8b2764494ea82bc2d92b84a0393fe549cc1f7006 100644 --- a/src/share/classes/sun/security/ssl/HelloExtensions.java +++ b/src/share/classes/sun/security/ssl/HelloExtensions.java @@ -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 @@ final class HelloExtensions { } 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 @@ final class HelloExtensions { 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 @@ final class ExtensionType { return name; } - static List knownExtensions = new ArrayList(8); + static List knownExtensions = + new ArrayList(9); static ExtensionType get(int id) { for (ExtensionType ext : knownExtensions) { @@ -180,17 +185,44 @@ final class ExtensionType { } // 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 @@ final class UnknownExtension extends HelloExtension { } } -// 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 class ServerNameExtension extends HelloExtension { 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 @@ final class SupportedEllipticPointFormatsExtension extends HelloExtension { 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 ? "" : + Debug.toString(renegotiated_connection)); + } + +} diff --git a/src/share/classes/sun/security/ssl/OutputRecord.java b/src/share/classes/sun/security/ssl/OutputRecord.java index 67fb344a939d9a9244b9cd5ee7d1118fb082e447..e5c7a6def78b6e3c494f4e751ce05b08c58a7261 100644 --- a/src/share/classes/sun/security/ssl/OutputRecord.java +++ b/src/share/classes/sun/security/ssl/OutputRecord.java @@ -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 @@ class OutputRecord extends ByteArrayOutputStream implements Record { * 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 @@ class OutputRecord extends ByteArrayOutputStream implements Record { 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); } /* diff --git a/src/share/classes/sun/security/ssl/SSLEngineImpl.java b/src/share/classes/sun/security/ssl/SSLEngineImpl.java index 654bd248ff5cd18da711ccbcde198976df615040..cd7122aec19ada99f241d83f8ad1b8d657fa1f48 100644 --- a/src/share/classes/sun/security/ssl/SSLEngineImpl.java +++ b/src/share/classes/sun/security/ssl/SSLEngineImpl.java @@ -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 @@ final public class SSLEngineImpl extends SSLEngine { 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 @@ final public class SSLEngineImpl extends SSLEngine { 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 @@ final public class SSLEngineImpl extends SSLEngine { } 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 @@ final public class SSLEngineImpl extends SSLEngine { 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 @@ final public class SSLEngineImpl extends SSLEngine { 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; diff --git a/src/share/classes/sun/security/ssl/SSLServerSocketImpl.java b/src/share/classes/sun/security/ssl/SSLServerSocketImpl.java index a2870ddaa0be37bfe922e7a4a665467fe429981e..914406b2e4281d1672c8ca8a663801b8e74b4297 100644 --- a/src/share/classes/sun/security/ssl/SSLServerSocketImpl.java +++ b/src/share/classes/sun/security/ssl/SSLServerSocketImpl.java @@ -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 @@ class SSLServerSocketImpl extends SSLServerSocket try { ServerHandshaker handshaker = tmp.getServerHandshaker(); - for (Iterator t = enabledCipherSuites.iterator(); t.hasNext(); ) { - CipherSuite suite = (CipherSuite)t.next(); + for (Iterator t = enabledCipherSuites.iterator(); + t.hasNext();) { + CipherSuite suite = t.next(); if (handshaker.trySetCipherSuite(suite)) { checkedEnabled = true; return; diff --git a/src/share/classes/sun/security/ssl/SSLSocketImpl.java b/src/share/classes/sun/security/ssl/SSLSocketImpl.java index d9bfecfb31978d8fd86cebd8286fc6eedd28410f..a360fe7a2aaae4a1f0afde1200e664c57850d4ec 100644 --- a/src/share/classes/sun/security/ssl/SSLSocketImpl.java +++ b/src/share/classes/sun/security/ssl/SSLSocketImpl.java @@ -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 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl { * 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; @@ -288,6 +288,13 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl { 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; + /* * The authentication context holds all information used to establish * who this end of the connection is (certificate chains, private keys, @@ -528,11 +535,13 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl { 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 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl { 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 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl { } 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 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl { 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 diff --git a/src/share/classes/sun/security/ssl/ServerHandshaker.java b/src/share/classes/sun/security/ssl/ServerHandshaker.java index 84f0b8888b971b9c35c4288e91e5d3f64503cbc5..5d70c7492273f19a3d6aab84bb2020c1ca485ddb 100644 --- a/src/share/classes/sun/security/ssl/ServerHandshaker.java +++ b/src/share/classes/sun/security/ssl/ServerHandshaker.java @@ -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 @@ final class ServerHandshaker extends Handshaker { // 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 @@ final class ServerHandshaker extends Handshaker { */ 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 @@ final class ServerHandshaker extends Handshaker { */ 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 @@ final class ServerHandshaker extends Handshaker { 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); - - // invalidate the handshake so that the caller can - // dispose this object. - invalidated = true; + // Does the message include security renegotiation indication? + boolean renegotiationIndicated = false; - // 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 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"); + } + } + } + // 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"); } - return; + secureRenegotiation = true; } 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"); + 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"); + } + + // 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 @@ final class ServerHandshaker extends Handshaker { // 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 @@ final class ServerHandshaker extends Handshaker { 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 @@ final class ServerHandshaker extends Handshaker { 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 @@ final class ServerHandshaker extends Handshaker { */ 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 @@ final class ServerHandshaker extends Handshaker { return true; } - if (suite.isAvailable() == false) { + if (suite.isNegotiable() == false) { return false; } @@ -1135,6 +1234,13 @@ final class ServerHandshaker extends Handshaker { // NOTREACHED } + /* + * 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 @@ -1184,6 +1290,13 @@ final class ServerHandshaker extends Handshaker { */ 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 diff --git a/src/share/classes/sun/tools/jar/CommandLine.java b/src/share/classes/sun/tools/jar/CommandLine.java index bf53dd3ffd7155c1d98e807bf1fb4aa121a1dd22..acb13082f7bb5ff80102b97baf6c5aa161e5beee 100644 --- a/src/share/classes/sun/tools/jar/CommandLine.java +++ b/src/share/classes/sun/tools/jar/CommandLine.java @@ -36,7 +36,7 @@ import java.util.ArrayList; /** * Various utility methods for processing Java tool command line arguments. * - *

This is NOT part of any API suppored by Sun Microsystems. If + *

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. diff --git a/src/share/native/common/check_code.c b/src/share/native/common/check_code.c index 0a2cb1433b4ca190c2f3c602903a704f0676a931..980480edfecda722a2542dd0b0e0604d0c32db6a 100644 --- a/src/share/native/common/check_code.c +++ b/src/share/native/common/check_code.c @@ -2940,7 +2940,7 @@ merge_into_successors(context_type *context, unsigned int inumber, 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 @@ merge_into_one_successor(context_type *context, 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 diff --git a/src/share/native/common/jdk_util.c b/src/share/native/common/jdk_util.c index 616909eee46ce6c2065db95fa45e1ce5aba40c3d..8c7c8a1da1c31664bf4e43441e87a5d5324fbe1e 100644 --- a/src/share/native/common/jdk_util.c +++ b/src/share/native/common/jdk_util.c @@ -76,7 +76,7 @@ JDK_GetVersionInfo0(jdk_version_info* info, size_t info_size) { } - 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) | diff --git a/src/share/native/common/jni_util.c b/src/share/native/common/jni_util.c index bc5c3039719197d3c20830fccc437ffb27d459b2..fb903bbdcce02fd866457ef61870fe22d7503e72 100644 --- a/src/share/native/common/jni_util.c +++ b/src/share/native/common/jni_util.c @@ -433,7 +433,7 @@ getString8859_1Chars(JNIEnv *env, jstring jstr) for (i=0; iGetStringUTFLength(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); diff --git a/src/share/native/java/lang/ClassLoader.c b/src/share/native/java/lang/ClassLoader.c index 63c85813801cf5d9a17bf1c01af8b532dcf675ab..7e87af176ce0b5aa42167c62a078d7df4a91553a 100644 --- a/src/share/native/java/lang/ClassLoader.c +++ b/src/share/native/java/lang/ClassLoader.c @@ -331,7 +331,7 @@ Java_java_lang_ClassLoader_00024NativeLibrary_load 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 @@ Java_java_lang_ClassLoader_00024NativeLibrary_load 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 @@ Java_java_lang_ClassLoader_00024NativeLibrary_unload const char *onUnloadSymbols[] = JNI_ONUNLOAD_SYMBOLS; void *handle; JNI_OnUnload_t JNI_OnUnload; - int i; + unsigned int i; if (!initIDs(env)) return; diff --git a/src/share/native/java/lang/System.c b/src/share/native/java/lang/System.c index 96dfa20c81c0bb6c46cddd8c6ff7831b18528523..245b1bc535625fbc73e2e99933f5f170b1b25819 100644 --- a/src/share/native/java/lang/System.c +++ b/src/share/native/java/lang/System.c @@ -109,7 +109,7 @@ Java_java_lang_System_identityHashCode(JNIEnv *env, jobject this, jobject x) #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, diff --git a/src/share/native/java/lang/fdlibm/include/fdlibm.h b/src/share/native/java/lang/fdlibm/include/fdlibm.h index a2433fdb91298a63134a82fede30fc94f3149967..7a11f52a3ed42c33c51d86cffb45dcfaf2199cc8 100644 --- a/src/share/native/java/lang/fdlibm/include/fdlibm.h +++ b/src/share/native/java/lang/fdlibm/include/fdlibm.h @@ -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 diff --git a/src/share/native/java/lang/reflect/Proxy.c b/src/share/native/java/lang/reflect/Proxy.c index ec6f013934bb1cf89be12619ef64c8e358320814..3f023a423a68c4e4b0fb0557cef28f099c4fbef2 100644 --- a/src/share/native/java/lang/reflect/Proxy.c +++ b/src/share/native/java/lang/reflect/Proxy.c @@ -82,9 +82,9 @@ Java_java_lang_reflect_Proxy_defineClass0(JNIEnv *env, 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); diff --git a/src/share/native/java/nio/Bits.c b/src/share/native/java/nio/Bits.c index 12e2aff117949ef805054734b759081ca0343fd7..838a764da56128773dbfdec75ebf2ac7e2944c9f 100644 --- a/src/share/native/java/nio/Bits.c +++ b/src/share/native/java/nio/Bits.c @@ -72,7 +72,7 @@ Java_java_nio_Bits_copyFromShortArray(JNIEnv *env, jobject this, jobject src, 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 @@ Java_java_nio_Bits_copyFromShortArray(JNIEnv *env, jobject this, jobject src, if (length > MBYTE) size = MBYTE; else - size = length; + size = (size_t)length; GETCRITICAL(bytes, env, src); @@ -107,7 +107,7 @@ Java_java_nio_Bits_copyToShortArray(JNIEnv *env, jobject this, jlong srcAddr, 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 @@ Java_java_nio_Bits_copyToShortArray(JNIEnv *env, jobject this, jlong srcAddr, if (length > MBYTE) size = MBYTE; else - size = length; + size = (size_t)length; GETCRITICAL(bytes, env, dst); @@ -142,7 +142,7 @@ Java_java_nio_Bits_copyFromIntArray(JNIEnv *env, jobject this, jobject src, 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 @@ Java_java_nio_Bits_copyFromIntArray(JNIEnv *env, jobject this, jobject src, if (length > MBYTE) size = MBYTE; else - size = length; + size = (size_t)length; GETCRITICAL(bytes, env, src); @@ -177,7 +177,7 @@ Java_java_nio_Bits_copyToIntArray(JNIEnv *env, jobject this, jlong srcAddr, 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 @@ Java_java_nio_Bits_copyToIntArray(JNIEnv *env, jobject this, jlong srcAddr, if (length > MBYTE) size = MBYTE; else - size = length; + size = (size_t)length; GETCRITICAL(bytes, env, dst); @@ -212,7 +212,7 @@ Java_java_nio_Bits_copyFromLongArray(JNIEnv *env, jobject this, jobject src, 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 @@ Java_java_nio_Bits_copyFromLongArray(JNIEnv *env, jobject this, jobject src, if (length > MBYTE) size = MBYTE; else - size = length; + size = (size_t)length; GETCRITICAL(bytes, env, src); @@ -247,7 +247,7 @@ Java_java_nio_Bits_copyToLongArray(JNIEnv *env, jobject this, jlong srcAddr, 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 @@ Java_java_nio_Bits_copyToLongArray(JNIEnv *env, jobject this, jlong srcAddr, if (length > MBYTE) size = MBYTE; else - size = length; + size = (size_t)length; GETCRITICAL(bytes, env, dst); diff --git a/src/share/native/java/util/zip/Inflater.c b/src/share/native/java/util/zip/Inflater.c index 5c199fca143e92a945721c125ae094b96e060672..78619f4ac0f0d7f9f1bd4ef9c2922251ae511f60 100644 --- a/src/share/native/java/util/zip/Inflater.c +++ b/src/share/native/java/util/zip/Inflater.c @@ -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 @@ Java_java_util_zip_Inflater_inflateBytes(JNIEnv *env, jobject this, jlong addr, jbyte *in_buf; jbyte *out_buf; int ret; - - in_buf = (jbyte *) malloc(this_len); + /* + * 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(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 @@ Java_java_util_zip_Inflater_inflateBytes(JNIEnv *env, jobject this, jlong addr, 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 @@ Java_java_util_zip_Inflater_inflateBytes(JNIEnv *env, jobject this, jlong addr, (*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; diff --git a/src/share/native/sun/awt/image/BufImgSurfaceData.c b/src/share/native/sun/awt/image/BufImgSurfaceData.c index d2b3b33a02f34ca36caa3e7a17e81ae940bba910..f8ebd3ad4b703198ab1eefa479d8a8f55f31132f 100644 --- a/src/share/native/sun/awt/image/BufImgSurfaceData.c +++ b/src/share/native/sun/awt/image/BufImgSurfaceData.c @@ -48,9 +48,12 @@ static ColorData *BufImg_SetupICM(JNIEnv *env, BufImgSDOps *bisdo); 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 @@ static jfieldID allGrayID; */ 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, "", "(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 @@ Java_sun_awt_image_BufImgSurfaceData_initIDs */ 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 void BufImg_Release(JNIEnv *env, 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); } } diff --git a/src/share/native/sun/awt/image/jpeg/imageioJPEG.c b/src/share/native/sun/awt/image/jpeg/imageioJPEG.c index 2475166fc0d6bbd0590037ff070006159f7bc74b..6495db28fc58c445302696280ad85d845235f23a 100644 --- a/src/share/native/sun/awt/image/jpeg/imageioJPEG.c +++ b/src/share/native/sun/awt/image/jpeg/imageioJPEG.c @@ -2614,7 +2614,8 @@ Java_com_sun_imageio_plugins_jpeg_JPEGImageWriter_writeImage 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 @@ Java_com_sun_imageio_plugins_jpeg_JPEGImageWriter_writeImage } + 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 @@ Java_com_sun_imageio_plugins_jpeg_JPEGImageWriter_writeImage } // 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 @@ Java_com_sun_imageio_plugins_jpeg_JPEGImageWriter_writeImage "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 @@ Java_com_sun_imageio_plugins_jpeg_JPEGImageWriter_writeImage } targetLine = 0; + pixelBufferSize = srcWidth * numBands; + pixelStride = numBands * stepX; // for each line in destHeight while ((data->abortFlag == JNI_FALSE) @@ -2886,9 +2896,9 @@ Java_com_sun_imageio_plugins_jpeg_JPEGImageWriter_writeImage 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)]; diff --git a/src/share/native/sun/management/Flag.c b/src/share/native/sun/management/Flag.c index ac8dd708b2d2949717593549907d6286a3bd2baa..7a1fab59721ef4c9ee4c21280b9b5319a057472f 100644 --- a/src/share/native/sun/management/Flag.c +++ b/src/share/native/sun/management/Flag.c @@ -25,6 +25,7 @@ #include #include +#include #include #include "management.h" #include "sun_management_Flag.h" @@ -80,8 +81,6 @@ JNIEXPORT jint JNICALL 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; diff --git a/src/share/native/sun/misc/VM.c b/src/share/native/sun/misc/VM.c index 5d736e39070dc40b736b310e071253835939209a..28b378cce8337028a8baf7b5689c302bdf803f6c 100644 --- a/src/share/native/sun/misc/VM.c +++ b/src/share/native/sun/misc/VM.c @@ -23,6 +23,8 @@ * questions. */ +#include + #include "jni.h" #include "jni_util.h" #include "jlong.h" @@ -113,7 +115,6 @@ typedef void (JNICALL *GetJvmVersionInfo_fp)(JNIEnv*, jvm_version_info*, size_t) 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 @@ Java_sun_misc_VM_initialize(JNIEnv *env, jclass cls) { 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)); diff --git a/src/share/native/sun/misc/VMSupport.c b/src/share/native/sun/misc/VMSupport.c index c25986a6de1f7ad61b5ffef3ba10923500064312..e37ff93603225cc3ca236e006c631b63b0e2f246 100644 --- a/src/share/native/sun/misc/VMSupport.c +++ b/src/share/native/sun/misc/VMSupport.c @@ -38,8 +38,6 @@ static INIT_AGENT_PROPERTIES_FN InitAgentProperties_fp = NULL; 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, diff --git a/src/share/native/sun/security/pkcs11/wrapper/p11_crypt.c b/src/share/native/sun/security/pkcs11/wrapper/p11_crypt.c index 7466b94cb1245618249c1c2fd6d633abbf8eab4d..dc8f65fd5c564fc25da56616902814b7d29a52ae 100644 --- a/src/share/native/sun/security/pkcs11/wrapper/p11_crypt.c +++ b/src/share/native/sun/security/pkcs11/wrapper/p11_crypt.c @@ -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 @@ Java_sun_security_pkcs11_wrapper_PKCS11_C_1Encrypt { 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 @@ Java_sun_security_pkcs11_wrapper_PKCS11_C_1Encrypt 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 @@ Java_sun_security_pkcs11_wrapper_PKCS11_C_1EncryptUpdate { 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 @@ Java_sun_security_pkcs11_wrapper_PKCS11_C_1EncryptUpdate 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); - 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; - } + inBufP = (*env)->GetPrimitiveArrayCritical(env, jIn, NULL); + if (inBufP == NULL) { return 0; } } - ckEncryptedPartLen = jOutLen; if (directOut != 0) { - outBufP = (CK_BYTE_PTR)(directOut + jOutOfs); + outBufP = (CK_BYTE_PTR) directOut; } 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); + outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL); + if (outBufP == NULL) { + // Make sure to release inBufP + (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT); return 0; - } - } else { - outBufP = OBUF; } } + ckEncryptedPartLen = jOutLen; + //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 && outBufP != OBUF) { - free(outBufP); + if (directOut == 0) { + (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_ABORT); } + + ckAssertReturnValueOK(env, rv); + return ckEncryptedPartLen; } #endif @@ -284,7 +240,6 @@ Java_sun_security_pkcs11_wrapper_PKCS11_C_1EncryptFinal { 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 @@ Java_sun_security_pkcs11_wrapper_PKCS11_C_1EncryptFinal 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 @@ Java_sun_security_pkcs11_wrapper_PKCS11_C_1Decrypt { 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 @@ Java_sun_security_pkcs11_wrapper_PKCS11_C_1Decrypt 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 @@ Java_sun_security_pkcs11_wrapper_PKCS11_C_1DecryptUpdate { 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 @@ Java_sun_security_pkcs11_wrapper_PKCS11_C_1DecryptUpdate 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); - 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; - } + inBufP = (*env)->GetPrimitiveArrayCritical(env, jIn, NULL); + if (inBufP == NULL) { return 0; } } - ckDecryptedPartLen = jOutLen; if (directOut != 0) { - outBufP = (CK_BYTE_PTR)(directOut + jOutOfs); + outBufP = (CK_BYTE_PTR) directOut; } 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); + outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL); + if (outBufP == NULL) { + // Make sure to release inBufP + (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT); return 0; } - } else { - outBufP = OBUF; - } } - rv = (*ckpFunctions->C_DecryptUpdate)(ckSessionHandle, inBufP, jInLen, - outBufP, &ckDecryptedPartLen); + ckDecryptedPartLen = jOutLen; - if (directIn == 0 && inBufP != IBUF) { - free(inBufP); + 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); } - if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) { - if (directOut == 0 && ckDecryptedPartLen > 0) { - (*env)->SetByteArrayRegion(env, jOut, jOutOfs, ckDecryptedPartLen, - (jbyte *)outBufP); - } + if (directOut == 0) { + (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_ABORT); } - if (directOut == 0 && outBufP != OBUF) { - free(outBufP); - } + ckAssertReturnValueOK(env, rv); + return ckDecryptedPartLen; } @@ -547,7 +456,6 @@ Java_sun_security_pkcs11_wrapper_PKCS11_C_1DecryptFinal { 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 @@ Java_sun_security_pkcs11_wrapper_PKCS11_C_1DecryptFinal 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 diff --git a/src/solaris/native/java/io/UnixFileSystem_md.c b/src/solaris/native/java/io/UnixFileSystem_md.c index 8eebc6b597769c63a69264af8b71d100abeb0408..4dc9ee865e000fd0baf5307cd95b99e5e136670d 100644 --- a/src/solaris/native/java/io/UnixFileSystem_md.c +++ b/src/solaris/native/java/io/UnixFileSystem_md.c @@ -119,7 +119,7 @@ Java_java_io_UnixFileSystem_checkAccess(JNIEnv *env, jobject this, 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 @@ Java_java_io_UnixFileSystem_setPermission(JNIEnv *env, jobject this, 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) diff --git a/src/solaris/native/java/io/canonicalize_md.c b/src/solaris/native/java/io/canonicalize_md.c index a333cc7b2e69726b2331c9b2f0d0ffd6b55d21e9..45e1f9ce26e7407606a09c0c2cef12eb94a3109a 100644 --- a/src/solaris/native/java/io/canonicalize_md.c +++ b/src/solaris/native/java/io/canonicalize_md.c @@ -246,7 +246,7 @@ canonicalize(char *original, char *resolved, int len) 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; diff --git a/src/solaris/native/java/lang/java_props_md.c b/src/solaris/native/java/lang/java_props_md.c index 979a73ce23c2055c523093dce38a02d4f539d7bb..de6faf8c5b49217a39a937c74a3f578ced5998da 100644 --- a/src/solaris/native/java/lang/java_props_md.c +++ b/src/solaris/native/java/lang/java_props_md.c @@ -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 @@ static int ParseLocale(int cat, char ** std_language, char ** std_country, char 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) { diff --git a/src/solaris/native/java/net/PlainDatagramSocketImpl.c b/src/solaris/native/java/net/PlainDatagramSocketImpl.c index 48d0d8ecfa85b0d788868fed2d6179738245d12f..cde085a9473844062791f273ab64419488c43043 100644 --- a/src/solaris/native/java/net/PlainDatagramSocketImpl.c +++ b/src/solaris/native/java/net/PlainDatagramSocketImpl.c @@ -2255,7 +2255,7 @@ static void mcast_join_leave(JNIEnv *env, jobject this, { 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; diff --git a/src/solaris/native/sun/net/sdp/SdpSupport.c b/src/solaris/native/sun/net/sdp/SdpSupport.c index dd2750be5f77af134e28ed4ebcf1f1da82e2f568..65fce3ebeff95fb01513fd6860b7428b2c0df6c6 100644 --- a/src/solaris/native/sun/net/sdp/SdpSupport.c +++ b/src/solaris/native/sun/net/sdp/SdpSupport.c @@ -68,7 +68,7 @@ static int create(JNIEnv* env) */ if (ipv6_available()) { JNU_ThrowIOException(env, "IPv6 not supported"); - return; + return -1; } s = socket(AF_INET_SDP, SOCK_STREAM, 0); #else diff --git a/src/solaris/native/sun/net/spi/DefaultProxySelector.c b/src/solaris/native/sun/net/spi/DefaultProxySelector.c index 12770fdf78cefc5514c9412941fa528fcf631242..6c22e231602b14cd4f97311f8bf1814bfa912ce5 100644 --- a/src/solaris/native/sun/net/spi/DefaultProxySelector.c +++ b/src/solaris/native/sun/net/spi/DefaultProxySelector.c @@ -158,7 +158,7 @@ Java_sun_net_spi_DefaultProxySelector_getSystemProxy(JNIEnv *env, 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; diff --git a/src/solaris/native/sun/nio/ch/Net.c b/src/solaris/native/sun/nio/ch/Net.c index dc3d7c4ac349a01ef2d2d51b89e23219c401012a..05811a3162fb1ebfe324a0a13a30246131d99fea 100644 --- a/src/solaris/native/sun/nio/ch/Net.c +++ b/src/solaris/native/sun/nio/ch/Net.c @@ -298,7 +298,8 @@ Java_sun_nio_ch_Net_getIntOption0(JNIEnv *env, jclass clazz, jobject fdo, 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 @@ Java_sun_nio_ch_Net_getIntOption0(JNIEnv *env, jclass clazz, jobject fdo, } 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 @@ JNIEXPORT jint JNICALL 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 @@ JNIEXPORT jint JNICALL 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); diff --git a/src/solaris/native/sun/nio/ch/SctpNet.c b/src/solaris/native/sun/nio/ch/SctpNet.c index a39cc9e33e13d925942553895521334ed75062cc..f462ae3445ddf9629708e7eb1843dd35a3596603 100644 --- a/src/solaris/native/sun/nio/ch/SctpNet.c +++ b/src/solaris/native/sun/nio/ch/SctpNet.c @@ -537,7 +537,7 @@ JNIEXPORT int JNICALL Java_sun_nio_ch_SctpNet_getIntOption0 int result; struct linger linger; void *arg; - unsigned int arglen; + int arglen; if (mapSocketOption(opt, &klevel, &kopt) < 0) { JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", diff --git a/src/solaris/native/sun/nio/ch/UnixAsynchronousSocketChannelImpl.c b/src/solaris/native/sun/nio/ch/UnixAsynchronousSocketChannelImpl.c index 4ff6259c508d007bee9b722511949444552a4ec1..4106d0277fa57f3eae239b681732d540dc6dcfbf 100644 --- a/src/solaris/native/sun/nio/ch/UnixAsynchronousSocketChannelImpl.c +++ b/src/solaris/native/sun/nio/ch/UnixAsynchronousSocketChannelImpl.c @@ -40,10 +40,10 @@ Java_sun_nio_ch_UnixAsynchronousSocketChannelImpl_checkConnect(JNIEnv *env, 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 { diff --git a/src/windows/native/common/jni_util_md.c b/src/windows/native/common/jni_util_md.c index 96ca60d7df83b46a6bf5da8ce38069a0564e26d9..4f22836d0b27b0156ada3a67e3df1bc0afe84021 100644 --- a/src/windows/native/common/jni_util_md.c +++ b/src/windows/native/common/jni_util_md.c @@ -79,7 +79,7 @@ BOOL useNativeConverter(JNIEnv *env) { } 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 diff --git a/src/windows/native/java/io/WinNTFileSystem_md.c b/src/windows/native/java/io/WinNTFileSystem_md.c index d57047a64d185653a8f149e18e634531fb4db598..633d20e578aaec8e9bdce7e1d48221a295c9a23a 100644 --- a/src/windows/native/java/io/WinNTFileSystem_md.c +++ b/src/windows/native/java/io/WinNTFileSystem_md.c @@ -434,7 +434,9 @@ Java_java_io_WinNTFileSystem_setPermission(JNIEnv *env, jobject this, 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 @@ Java_java_io_WinNTFileSystem_setReadOnly(JNIEnv *env, jobject this, } } - 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 @@ Java_java_io_WinNTFileSystem_getDriveDirectory(JNIEnv *env, jobject this, 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; diff --git a/src/windows/native/java/io/io_util_md.c b/src/windows/native/java/io/io_util_md.c index f5b9723a743f0011a00047d6a1f4ea04e731bee9..722913f775a3a2491bdc8382ac1165cc831d05ee 100644 --- a/src/windows/native/java/io/io_util_md.c +++ b/src/windows/native/java/io/io_util_md.c @@ -66,6 +66,25 @@ fileToNTPath(JNIEnv *env, jobject file, jfieldID id) { 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 @@ currentDirLength(const WCHAR* ps, int pathlen) { 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); diff --git a/src/windows/native/java/io/io_util_md.h b/src/windows/native/java/io/io_util_md.h index c937adfbfb85595e2661df2691f04ad5e16cd572..6b6b89b6397a998eb28b335dcc553df5c79ffae0 100644 --- a/src/windows/native/java/io/io_util_md.h +++ b/src/windows/native/java/io/io_util_md.h @@ -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); diff --git a/src/windows/native/java/lang/java_props_md.c b/src/windows/native/java/lang/java_props_md.c index 300ab224498c2d4e44fc98eb6a88b13974c17e27..50835ee6e28d9994a1fc905d0a477477775e58e6 100644 --- a/src/windows/native/java/lang/java_props_md.c +++ b/src/windows/native/java/lang/java_props_md.c @@ -489,7 +489,7 @@ GetJavaProperties(JNIEnv* env) 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 @@ GetJavaProperties(JNIEnv* env) sprops.os_arch = "unknown"; #endif - sprops.patch_level = strdup(ver.szCSDVersion); + sprops.patch_level = _strdup(ver.szCSDVersion); sprops.desktop = "windows"; } diff --git a/src/windows/native/java/util/TimeZone_md.c b/src/windows/native/java/util/TimeZone_md.c index eb859efcf3721c887c0433ed395b453a98ffb93b..8bd269f76f47c337bbd834d8e9a7d573bc03b7ee 100644 --- a/src/windows/native/java/util/TimeZone_md.c +++ b/src/windows/native/java/util/TimeZone_md.c @@ -26,6 +26,7 @@ #include #include #include +#include "jvm.h" #include "TimeZone_md.h" #define VALUE_UNKNOWN 0 @@ -463,7 +464,7 @@ static char *matchJavaTZ(const char *java_home_dir, int value_type, char *tzName /* * 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 @@ static char *matchJavaTZ(const char *java_home_dir, int value_type, char *tzName 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 @@ static char *matchJavaTZ(const char *java_home_dir, int value_type, char *tzName fclose(fp); if (javaTZName == NULL && bestMatch[0] != '\0') { - javaTZName = strdup(bestMatch); + javaTZName = _strdup(bestMatch); } return javaTZName; @@ -515,7 +516,7 @@ char *findJavaTZ_md(const char *java_home_dir, const char *country) 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); diff --git a/src/windows/native/sun/nio/ch/ServerSocketChannelImpl.c b/src/windows/native/sun/nio/ch/ServerSocketChannelImpl.c index 6026671f4bbf9129e7f80f602e5412adeaca4464..770cd3d736020a756798dc4e019b7c3b1b2c0a38 100644 --- a/src/windows/native/sun/nio/ch/ServerSocketChannelImpl.c +++ b/src/windows/native/sun/nio/ch/ServerSocketChannelImpl.c @@ -84,7 +84,6 @@ Java_sun_nio_ch_ServerSocketChannelImpl_accept0(JNIEnv *env, jobject this, jobject remote_ia; int remote_port; jobject isa; - jobject ia; int addrlen = sizeof(sa); memset((char *)&sa, 0, sizeof(sa)); diff --git a/src/windows/native/sun/nio/ch/WindowsSelectorImpl.c b/src/windows/native/sun/nio/ch/WindowsSelectorImpl.c index 2a83f02f9d62ec05a4e6781f1bfc606303372b03..7b28f27dab41da6a07c9b8f81160ec26d8bce8b6 100644 --- a/src/windows/native/sun/nio/ch/WindowsSelectorImpl.c +++ b/src/windows/native/sun/nio/ch/WindowsSelectorImpl.c @@ -223,7 +223,7 @@ Java_sun_nio_ch_WindowsSelectorImpl_discardUrgentData(JNIEnv* env, jobject this, 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; } diff --git a/test/com/sun/org/apache/xml/internal/security/utils/UnsyncByteArrayOutputStream/BufferOverflowTest.java b/test/com/sun/org/apache/xml/internal/security/utils/UnsyncByteArrayOutputStream/BufferOverflowTest.java new file mode 100644 index 0000000000000000000000000000000000000000..ffb3c9e963d290415c39e81304bce85dc5e79a40 --- /dev/null +++ b/test/com/sun/org/apache/xml/internal/security/utils/UnsyncByteArrayOutputStream/BufferOverflowTest.java @@ -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); + } + } +} diff --git a/test/java/io/File/SetAccess.java b/test/java/io/File/SetAccess.java index 0b6c1724a5a6f5a99069b565c2919aaef3d6ce50..355740934b8fe53f449a6b7c9b3c62d15d06c11c 100644 --- a/test/java/io/File/SetAccess.java +++ b/test/java/io/File/SetAccess.java @@ -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 class SetAccess { } 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 @@ public class SetAccess { 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 @@ public class SetAccess { } 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()); } } diff --git a/test/java/io/File/SetReadOnly.java b/test/java/io/File/SetReadOnly.java index 2d348edf7a5b82517e7ddaa5bde515e732371504..1c1301bf7b5f88ad22cca829489cc9159a9aa6dc 100644 --- a/test/java/io/File/SetReadOnly.java +++ b/test/java/io/File/SetReadOnly.java @@ -22,7 +22,7 @@ */ /* @test - @bug 4091757 4939819 + @bug 4091757 4939819 6728842 @summary Basic test for setReadOnly method */ @@ -57,17 +57,8 @@ public class SetReadOnly { } 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"); diff --git a/test/java/io/pathNames/GeneralWin32.java b/test/java/io/pathNames/GeneralWin32.java index a43a8cd42f17f50661a67128520e6953fd4bb777..90802eee49f72a01d4d56764348c3b7a735900ac 100644 --- a/test/java/io/pathNames/GeneralWin32.java +++ b/test/java/io/pathNames/GeneralWin32.java @@ -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 diff --git a/test/java/lang/ClassLoader/deadlock/GetResource.java b/test/java/lang/ClassLoader/deadlock/GetResource.java new file mode 100644 index 0000000000000000000000000000000000000000..a1a1b4e1730899125bbea04806d84d7d5d9c610c --- /dev/null +++ b/test/java/lang/ClassLoader/deadlock/GetResource.java @@ -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(); + } +} diff --git a/test/java/lang/ProcessBuilder/Basic.java b/test/java/lang/ProcessBuilder/Basic.java index d0bbc1b4a3bb40dd53a1b430adb3436f7c37ad06..21ff40695ea7201d6cf389badbe79ef27b6193c0 100644 --- a/test/java/lang/ProcessBuilder/Basic.java +++ b/test/java/lang/ProcessBuilder/Basic.java @@ -1843,9 +1843,11 @@ public class Basic { 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); }}}; diff --git a/test/java/nio/Buffer/LimitDirectMemory.java b/test/java/nio/Buffer/LimitDirectMemory.java new file mode 100644 index 0000000000000000000000000000000000000000..597e4d9c093a612191dbac2f828867ecc5a13fe0 --- /dev/null +++ b/test/java/nio/Buffer/LimitDirectMemory.java @@ -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; + } +} diff --git a/test/java/nio/Buffer/LimitDirectMemory.sh b/test/java/nio/Buffer/LimitDirectMemory.sh new file mode 100644 index 0000000000000000000000000000000000000000..38e8c0c05fa3438c0d9c1073d9d26d8ebcc6317f --- /dev/null +++ b/test/java/nio/Buffer/LimitDirectMemory.sh @@ -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} diff --git a/test/java/nio/channels/Selector/TemporarySelector.java b/test/java/nio/channels/Selector/TemporarySelector.java new file mode 100644 index 0000000000000000000000000000000000000000..c131c327fa7c9cc2f30b7969f93c7670baad17a2 --- /dev/null +++ b/test/java/nio/channels/Selector/TemporarySelector.java @@ -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; + } + } +} diff --git a/test/java/nio/channels/SocketChannel/VectorIO.java b/test/java/nio/channels/SocketChannel/VectorIO.java index 0dfd2d66f8a0a418bad2ff9e2f53da3899944ae0..58215c024bb297c2a68430cb00547d6dbc995e7e 100644 --- a/test/java/nio/channels/SocketChannel/VectorIO.java +++ b/test/java/nio/channels/SocketChannel/VectorIO.java @@ -60,6 +60,7 @@ public class VectorIO { static void bufferTest(int port) throws Exception { ByteBuffer[] bufs = new ByteBuffer[testSize]; + long total = 0L; for(int i=0; i 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 @@ public class VectorIO { } void bufferTest() throws Exception { + long total = 0L; ByteBuffer[] bufs = new ByteBuffer[testSize]; for(int i=0; i 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 0 && args[0].equals("-shortrun"); @@ -81,6 +81,11 @@ public class Sorting { for (long random : randoms) { reset(random); + for (int length : lengths) { + testAndCheckWithInsertionSort(length, random); + } + reset(random); + for (int length : lengths) { testAndCheckWithCheckSum(length, random); } @@ -268,9 +273,7 @@ public class Sorting { " 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 @@ public class Sorting { 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 @@ public class Sorting { 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 @@ public class Sorting { 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 @@ public class Sorting { 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 @@ public class Sorting { 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 @@ public class Sorting { 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 @@ public class Sorting { 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 @@ public class Sorting { 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 @@ public class Sorting { } } + 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,56 +992,10 @@ public class Sorting { } } - 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 failed(int index, String value1, String value2) { - failed("Array is not sorted at " + index + "-th position: " + - value1 + " and " + value2); - } - - private static void checkSorted(Object object) { - if (object instanceof int[]) { - checkSorted((int[]) object); - } else if (object instanceof long[]) { - checkSorted((long[]) object); - } else if (object instanceof short[]) { - checkSorted((short[]) object); - } else if (object instanceof byte[]) { - checkSorted((byte[]) object); - } else if (object instanceof char[]) { - checkSorted((char[]) object); - } else if (object instanceof float[]) { - checkSorted((float[]) object); - } else if (object instanceof double[]) { - checkSorted((double[]) object); - } else if (object instanceof Integer[]) { - checkSorted((Integer[]) object); - } else { - failed("Unknow type of array: " + object + " of class " + - object.getClass().getName()); - } - } - - private static void compare(Integer[] a, Integer[] b) { - for (int i = 0; i < a.length; i++) { - if (a[i].intValue() != b[i].intValue()) { - failed(i, "" + a[i], "" + b[i]); - } - } - } - private static void compare(int[] a, int[] b) { for (int i = 0; i < a.length; i++) { if (a[i] != b[i]) { - failed(i, "" + a[i], "" + b[i]); + failedCompare(i, "" + a[i], "" + b[i]); } } } @@ -1002,7 +1003,7 @@ public class Sorting { private static void compare(long[] a, long[] b) { for (int i = 0; i < a.length; i++) { if (a[i] != b[i]) { - failed(i, "" + a[i], "" + b[i]); + failedCompare(i, "" + a[i], "" + b[i]); } } } @@ -1010,7 +1011,7 @@ public class Sorting { private static void compare(short[] a, short[] b) { for (int i = 0; i < a.length; i++) { if (a[i] != b[i]) { - failed(i, "" + a[i], "" + b[i]); + failedCompare(i, "" + a[i], "" + b[i]); } } } @@ -1018,7 +1019,7 @@ public class Sorting { private static void compare(byte[] a, byte[] b) { for (int i = 0; i < a.length; i++) { if (a[i] != b[i]) { - failed(i, "" + a[i], "" + b[i]); + failedCompare(i, "" + a[i], "" + b[i]); } } } @@ -1026,7 +1027,7 @@ public class Sorting { private static void compare(char[] a, char[] b) { for (int i = 0; i < a.length; i++) { if (a[i] != b[i]) { - failed(i, "" + a[i], "" + b[i]); + failedCompare(i, "" + a[i], "" + b[i]); } } } @@ -1034,7 +1035,7 @@ public class Sorting { private static void compare(float[] a, float[] b) { for (int i = 0; i < a.length; i++) { if (a[i] != b[i]) { - failed(i, "" + a[i], "" + b[i]); + failedCompare(i, "" + a[i], "" + b[i]); } } } @@ -1042,23 +1043,46 @@ public class Sorting { private static void compare(double[] a, double[] b) { for (int i = 0; i < a.length; i++) { if (a[i] != b[i]) { - failed(i, "" + a[i], "" + b[i]); + failedCompare(i, "" + a[i], "" + b[i]); } } } - private static void checkSorted(Integer[] a) { - for (int i = 0; i < a.length - 1; i++) { - if (a[i].intValue() > a[i + 1].intValue()) { - failed(i, "" + a[i], "" + a[i + 1]); + private static void compare(Integer[] a, Integer[] b) { + for (int i = 0; i < a.length; i++) { + if (a[i].compareTo(b[i]) != 0) { + failedCompare(i, "" + a[i], "" + b[i]); } } } + private static void checkSorted(Object object) { + if (object instanceof int[]) { + checkSorted((int[]) object); + } else if (object instanceof long[]) { + checkSorted((long[]) object); + } else if (object instanceof short[]) { + checkSorted((short[]) object); + } else if (object instanceof byte[]) { + checkSorted((byte[]) object); + } else if (object instanceof char[]) { + checkSorted((char[]) object); + } else if (object instanceof float[]) { + checkSorted((float[]) object); + } else if (object instanceof double[]) { + checkSorted((double[]) object); + } else if (object instanceof Integer[]) { + checkSorted((Integer[]) object); + } else { + failed("Unknow type of array: " + object + " of class " + + object.getClass().getName()); + } + } + private static void checkSorted(int[] a) { for (int i = 0; i < a.length - 1; i++) { if (a[i] > a[i + 1]) { - failed(i, "" + a[i], "" + a[i + 1]); + failedSort(i, "" + a[i], "" + a[i + 1]); } } } @@ -1066,7 +1090,7 @@ public class Sorting { private static void checkSorted(long[] a) { for (int i = 0; i < a.length - 1; i++) { if (a[i] > a[i + 1]) { - failed(i, "" + a[i], "" + a[i + 1]); + failedSort(i, "" + a[i], "" + a[i + 1]); } } } @@ -1074,7 +1098,7 @@ public class Sorting { private static void checkSorted(short[] a) { for (int i = 0; i < a.length - 1; i++) { if (a[i] > a[i + 1]) { - failed(i, "" + a[i], "" + a[i + 1]); + failedSort(i, "" + a[i], "" + a[i + 1]); } } } @@ -1082,7 +1106,7 @@ public class Sorting { private static void checkSorted(byte[] a) { for (int i = 0; i < a.length - 1; i++) { if (a[i] > a[i + 1]) { - failed(i, "" + a[i], "" + a[i + 1]); + failedSort(i, "" + a[i], "" + a[i + 1]); } } } @@ -1090,7 +1114,7 @@ public class Sorting { private static void checkSorted(char[] a) { for (int i = 0; i < a.length - 1; i++) { if (a[i] > a[i + 1]) { - failed(i, "" + a[i], "" + a[i + 1]); + failedSort(i, "" + a[i], "" + a[i + 1]); } } } @@ -1098,7 +1122,7 @@ public class Sorting { private static void checkSorted(float[] a) { for (int i = 0; i < a.length - 1; i++) { if (a[i] > a[i + 1]) { - failed(i, "" + a[i], "" + a[i + 1]); + failedSort(i, "" + a[i], "" + a[i + 1]); } } } @@ -1106,34 +1130,45 @@ public class Sorting { private static void checkSorted(double[] a) { for (int i = 0; i < a.length - 1; i++) { if (a[i] > a[i + 1]) { - failed(i, "" + a[i], "" + a[i + 1]); + failedSort(i, "" + a[i], "" + a[i + 1]); + } + } + } + + private static void checkSorted(Integer[] a) { + for (int i = 0; i < a.length - 1; i++) { + if (a[i].intValue() > a[i + 1].intValue()) { + failedSort(i, "" + a[i], "" + a[i + 1]); } } } private static void checkCheckSum(Object test, Object golden) { - if (checkSum(test) != checkSum(golden)) { - failed("It seems that original and sorted arrays are not identical"); + if (checkSumXor(test) != checkSumXor(golden)) { + failed("Original and sorted arrays are not identical [xor]"); + } + if (checkSumPlus(test) != checkSumPlus(golden)) { + failed("Original and sorted arrays are not identical [plus]"); } } - private static int checkSum(Object object) { + private static int checkSumXor(Object object) { if (object instanceof int[]) { - return checkSum((int[]) object); + return checkSumXor((int[]) object); } else if (object instanceof long[]) { - return checkSum((long[]) object); + return checkSumXor((long[]) object); } else if (object instanceof short[]) { - return checkSum((short[]) object); + return checkSumXor((short[]) object); } else if (object instanceof byte[]) { - return checkSum((byte[]) object); + return checkSumXor((byte[]) object); } else if (object instanceof char[]) { - return checkSum((char[]) object); + return checkSumXor((char[]) object); } else if (object instanceof float[]) { - return checkSum((float[]) object); + return checkSumXor((float[]) object); } else if (object instanceof double[]) { - return checkSum((double[]) object); + return checkSumXor((double[]) object); } else if (object instanceof Integer[]) { - return checkSum((Integer[]) object); + return checkSumXor((Integer[]) object); } else { failed("Unknow type of array: " + object + " of class " + object.getClass().getName()); @@ -1141,76 +1176,275 @@ public class Sorting { } } - private static int checkSum(Integer[] a) { - int checkXorSum = 0; + private static int checkSumXor(Integer[] a) { + int checkSum = 0; for (Integer e : a) { - checkXorSum ^= e.intValue(); + checkSum ^= e.intValue(); } - return checkXorSum; + return checkSum; } - private static int checkSum(int[] a) { - int checkXorSum = 0; + private static int checkSumXor(int[] a) { + int checkSum = 0; for (int e : a) { - checkXorSum ^= e; + checkSum ^= e; } - return checkXorSum; + return checkSum; } - private static int checkSum(long[] a) { - long checkXorSum = 0; + private static int checkSumXor(long[] a) { + long checkSum = 0; for (long e : a) { - checkXorSum ^= e; + checkSum ^= e; } - return (int) checkXorSum; + return (int) checkSum; } - private static int checkSum(short[] a) { - short checkXorSum = 0; + private static int checkSumXor(short[] a) { + short checkSum = 0; for (short e : a) { - checkXorSum ^= e; + checkSum ^= e; } - return (int) checkXorSum; + return (int) checkSum; } - private static int checkSum(byte[] a) { - byte checkXorSum = 0; + private static int checkSumXor(byte[] a) { + byte checkSum = 0; for (byte e : a) { - checkXorSum ^= e; + checkSum ^= e; } - return (int) checkXorSum; + return (int) checkSum; } - private static int checkSum(char[] a) { - char checkXorSum = 0; + private static int checkSumXor(char[] a) { + char checkSum = 0; for (char e : a) { - checkXorSum ^= e; + checkSum ^= e; } - return (int) checkXorSum; + return (int) checkSum; } - private static int checkSum(float[] a) { - int checkXorSum = 0; + private static int checkSumXor(float[] a) { + int checkSum = 0; for (float e : a) { - checkXorSum ^= (int) e; + checkSum ^= (int) e; } - return checkXorSum; + return checkSum; } - private static int checkSum(double[] a) { - int checkXorSum = 0; + private static int checkSumXor(double[] a) { + int checkSum = 0; for (double e : a) { - checkXorSum ^= (int) e; + checkSum ^= (int) e; + } + return checkSum; + } + + private static int checkSumPlus(Object object) { + if (object instanceof int[]) { + return checkSumPlus((int[]) object); + } else if (object instanceof long[]) { + return checkSumPlus((long[]) object); + } else if (object instanceof short[]) { + return checkSumPlus((short[]) object); + } else if (object instanceof byte[]) { + return checkSumPlus((byte[]) object); + } else if (object instanceof char[]) { + return checkSumPlus((char[]) object); + } else if (object instanceof float[]) { + return checkSumPlus((float[]) object); + } else if (object instanceof double[]) { + return checkSumPlus((double[]) object); + } else if (object instanceof Integer[]) { + return checkSumPlus((Integer[]) object); + } else { + failed("Unknow type of array: " + object + " of class " + + object.getClass().getName()); + return -1; + } + } + + private static int checkSumPlus(int[] a) { + int checkSum = 0; + + for (int e : a) { + checkSum += e; + } + return checkSum; + } + + private static int checkSumPlus(long[] a) { + long checkSum = 0; + + for (long e : a) { + checkSum += e; + } + return (int) checkSum; + } + + private static int checkSumPlus(short[] a) { + short checkSum = 0; + + for (short e : a) { + checkSum += e; + } + return (int) checkSum; + } + + private static int checkSumPlus(byte[] a) { + byte checkSum = 0; + + for (byte e : a) { + checkSum += e; + } + return (int) checkSum; + } + + private static int checkSumPlus(char[] a) { + char checkSum = 0; + + for (char e : a) { + checkSum += e; + } + return (int) checkSum; + } + + private static int checkSumPlus(float[] a) { + int checkSum = 0; + + for (float e : a) { + checkSum += (int) e; + } + return checkSum; + } + + private static int checkSumPlus(double[] a) { + int checkSum = 0; + + for (double e : a) { + checkSum += (int) e; + } + return checkSum; + } + + private static int checkSumPlus(Integer[] a) { + int checkSum = 0; + + for (Integer e : a) { + checkSum += e.intValue(); + } + return checkSum; + } + + private static void sortByInsertionSort(Object object) { + if (object instanceof int[]) { + sortByInsertionSort((int[]) object); + } else if (object instanceof long[]) { + sortByInsertionSort((long[]) object); + } else if (object instanceof short[]) { + sortByInsertionSort((short[]) object); + } else if (object instanceof byte[]) { + sortByInsertionSort((byte[]) object); + } else if (object instanceof char[]) { + sortByInsertionSort((char[]) object); + } else if (object instanceof float[]) { + sortByInsertionSort((float[]) object); + } else if (object instanceof double[]) { + sortByInsertionSort((double[]) object); + } else if (object instanceof Integer[]) { + sortByInsertionSort((Integer[]) object); + } else { + failed("Unknow type of array: " + object + " of class " + + object.getClass().getName()); + } + } + + private static void sortByInsertionSort(int[] a) { + for (int j, i = 1; i < a.length; i++) { + int ai = a[i]; + for (j = i - 1; j >= 0 && ai < a[j]; j--) { + a[j + 1] = a[j]; + } + a[j + 1] = ai; + } + } + + private static void sortByInsertionSort(long[] a) { + for (int j, i = 1; i < a.length; i++) { + long ai = a[i]; + for (j = i - 1; j >= 0 && ai < a[j]; j--) { + a[j + 1] = a[j]; + } + a[j + 1] = ai; + } + } + + private static void sortByInsertionSort(short[] a) { + for (int j, i = 1; i < a.length; i++) { + short ai = a[i]; + for (j = i - 1; j >= 0 && ai < a[j]; j--) { + a[j + 1] = a[j]; + } + a[j + 1] = ai; + } + } + + private static void sortByInsertionSort(byte[] a) { + for (int j, i = 1; i < a.length; i++) { + byte ai = a[i]; + for (j = i - 1; j >= 0 && ai < a[j]; j--) { + a[j + 1] = a[j]; + } + a[j + 1] = ai; + } + } + + private static void sortByInsertionSort(char[] a) { + for (int j, i = 1; i < a.length; i++) { + char ai = a[i]; + for (j = i - 1; j >= 0 && ai < a[j]; j--) { + a[j + 1] = a[j]; + } + a[j + 1] = ai; + } + } + + private static void sortByInsertionSort(float[] a) { + for (int j, i = 1; i < a.length; i++) { + float ai = a[i]; + for (j = i - 1; j >= 0 && ai < a[j]; j--) { + a[j + 1] = a[j]; + } + a[j + 1] = ai; + } + } + + private static void sortByInsertionSort(double[] a) { + for (int j, i = 1; i < a.length; i++) { + double ai = a[i]; + for (j = i - 1; j >= 0 && ai < a[j]; j--) { + a[j + 1] = a[j]; + } + a[j + 1] = ai; + } + } + + private static void sortByInsertionSort(Integer[] a) { + for (int j, i = 1; i < a.length; i++) { + Integer ai = a[i]; + for (j = i - 1; j >= 0 && ai < a[j]; j--) { + a[j + 1] = a[j]; + } + a[j + 1] = ai; } - return checkXorSum; } private static void sort(Object object) { @@ -1292,7 +1526,7 @@ public class Sorting { for (int i = fromIndex; i < toIndex - 1; i++) { if (a[i].intValue() > a[i + 1].intValue()) { - failed(i, "" + a[i], "" + a[i + 1]); + failedSort(i, "" + a[i], "" + a[i + 1]); } } @@ -1314,7 +1548,7 @@ public class Sorting { for (int i = fromIndex; i < toIndex - 1; i++) { if (a[i] > a[i + 1]) { - failed(i, "" + a[i], "" + a[i + 1]); + failedSort(i, "" + a[i], "" + a[i + 1]); } } @@ -1336,7 +1570,7 @@ public class Sorting { for (int i = fromIndex; i < toIndex - 1; i++) { if (a[i] > a[i + 1]) { - failed(i, "" + a[i], "" + a[i + 1]); + failedSort(i, "" + a[i], "" + a[i + 1]); } } @@ -1358,7 +1592,7 @@ public class Sorting { for (int i = fromIndex; i < toIndex - 1; i++) { if (a[i] > a[i + 1]) { - failed(i, "" + a[i], "" + a[i + 1]); + failedSort(i, "" + a[i], "" + a[i + 1]); } } @@ -1380,7 +1614,7 @@ public class Sorting { for (int i = fromIndex; i < toIndex - 1; i++) { if (a[i] > a[i + 1]) { - failed(i, "" + a[i], "" + a[i + 1]); + failedSort(i, "" + a[i], "" + a[i + 1]); } } @@ -1402,7 +1636,7 @@ public class Sorting { for (int i = fromIndex; i < toIndex - 1; i++) { if (a[i] > a[i + 1]) { - failed(i, "" + a[i], "" + a[i + 1]); + failedSort(i, "" + a[i], "" + a[i + 1]); } } @@ -1424,7 +1658,7 @@ public class Sorting { for (int i = fromIndex; i < toIndex - 1; i++) { if (a[i] > a[i + 1]) { - failed(i, "" + a[i], "" + a[i + 1]); + failedSort(i, "" + a[i], "" + a[i + 1]); } } @@ -1446,7 +1680,7 @@ public class Sorting { for (int i = fromIndex; i < toIndex - 1; i++) { if (a[i] > a[i + 1]) { - failed(i, "" + a[i], "" + a[i + 1]); + failedSort(i, "" + a[i], "" + a[i + 1]); } } diff --git a/test/javax/swing/Security/6938813/bug6938813.java b/test/javax/swing/Security/6938813/bug6938813.java new file mode 100644 index 0000000000000000000000000000000000000000..5bedf95e1403036d2040d4c20d342bdefa892e67 --- /dev/null +++ b/test/javax/swing/Security/6938813/bug6938813.java @@ -0,0 +1,125 @@ +/* + * 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 6938813 + * @summary Swing mutable statics + * @author Pavel Porvatov + */ + +import sun.awt.AppContext; +import sun.awt.SunToolkit; + +import javax.swing.text.html.HTMLEditorKit; +import javax.swing.text.html.StyleSheet; +import javax.swing.text.html.parser.DTD; +import javax.swing.text.html.parser.ParserDelegator; +import java.lang.reflect.Field; + +public class bug6938813 { + public static final String DTD_KEY = "dtd_key"; + + private static volatile StyleSheet styleSheet; + + public static void main(String[] args) throws Exception { + // Run validation and init values for this AppContext + validate(); + + Thread thread = new ThreadInAnotherAppContext(); + + thread.start(); + thread.join(); + } + + private static void validate() throws Exception { + AppContext appContext = AppContext.getAppContext(); + + assertTrue(DTD.getDTD(DTD_KEY).getName().equals(DTD_KEY), "DTD.getDTD() mixed AppContexts"); + + // Spoil hash value + DTD invalidDtd = DTD.getDTD("invalid DTD"); + + DTD.putDTDHash(DTD_KEY, invalidDtd); + + assertTrue(DTD.getDTD(DTD_KEY) == invalidDtd, "Something wrong with DTD.getDTD()"); + + Object dtdKey = getParserDelegator_DTD_KEY(); + + assertTrue(appContext.get(dtdKey) == null, "ParserDelegator mixed AppContexts"); + + // Init default DTD + new ParserDelegator(); + + Object dtdValue = appContext.get(dtdKey); + + assertTrue(dtdValue != null, "ParserDelegator.defaultDTD isn't initialized"); + + // Try reinit default DTD + new ParserDelegator(); + + assertTrue(dtdValue == appContext.get(dtdKey), "ParserDelegator.defaultDTD created a duplicate"); + + HTMLEditorKit htmlEditorKit = new HTMLEditorKit(); + + if (styleSheet == null) { + // First AppContext + styleSheet = htmlEditorKit.getStyleSheet(); + + assertTrue(styleSheet != null, "htmlEditorKit.getStyleSheet() returns null"); + assertTrue(htmlEditorKit.getStyleSheet() == styleSheet, "Something wrong with htmlEditorKit.getStyleSheet()"); + } else { + assertTrue(htmlEditorKit.getStyleSheet() != styleSheet, "HtmlEditorKit.getStyleSheet() mixed AppContexts"); + } + } + + private static void assertTrue(boolean b, String msg) { + if (!b) { + throw new RuntimeException("Test failed: " + msg); + } + } + + private static Object getParserDelegator_DTD_KEY() throws Exception { + Field field = ParserDelegator.class.getDeclaredField("DTD_KEY"); + + field.setAccessible(true); + + return field.get(null); + } + + private static class ThreadInAnotherAppContext extends Thread { + public ThreadInAnotherAppContext() { + super(new ThreadGroup("6938813"), "ThreadInAnotherAppContext"); + } + + public void run() { + SunToolkit.createNewAppContext(); + + try { + validate(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + } +} diff --git a/test/javax/swing/UIDefaults/6622002/bug6622002.java b/test/javax/swing/UIDefaults/6622002/bug6622002.java new file mode 100644 index 0000000000000000000000000000000000000000..afd883b1e6566123452887d9e1ff36d447ff6735 --- /dev/null +++ b/test/javax/swing/UIDefaults/6622002/bug6622002.java @@ -0,0 +1,64 @@ +/* + * 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 6622002 + * @author Alexander Potochkin + * @summary UIDefault.ProxyLazyValue has unsafe reflection usage + */ + +import javax.swing.*; + +public class bug6622002 { + public static void main(String[] args) { + + if (createPrivateValue() == null) { + throw new RuntimeException("The private value unexpectedly wasn't created"); + } + + if (createPublicValue() == null) { + throw new RuntimeException("The public value unexpectedly wasn't created"); + } + + System.setSecurityManager(new SecurityManager()); + + if (createPrivateValue() != null) { + throw new RuntimeException("The private value was unexpectedly created"); + } + + if (createPublicValue() == null) { + throw new RuntimeException("The public value unexpectedly wasn't created"); + } + } + + private static Object createPrivateValue() { + return new UIDefaults.ProxyLazyValue( + "javax.swing.MultiUIDefaults").createValue(null); + } + + private static Object createPublicValue() { + return new UIDefaults.ProxyLazyValue( + "javax.swing.UIDefaults").createValue(null); + } +} diff --git a/test/sun/misc/BootClassLoaderHook/TestHook.java b/test/sun/misc/BootClassLoaderHook/TestHook.java index 7dca5e87dc09e296dca6238278816e41b65c03be..5a620b1a6f590ddfdd2b2c74fdb61574e8e9faa3 100644 --- a/test/sun/misc/BootClassLoaderHook/TestHook.java +++ b/test/sun/misc/BootClassLoaderHook/TestHook.java @@ -24,7 +24,10 @@ import java.io.File; import java.util.TreeSet; import java.util.Set; +import java.net.URLStreamHandlerFactory; import sun.misc.BootClassLoaderHook; +import sun.misc.URLClassPath; + /* @test * @bug 6888802 @@ -68,10 +71,6 @@ public class TestHook extends BootClassLoaderHook { for (String s : copy) { System.out.println(" Loaded " + s); } - - if (BootClassLoaderHook.getBootstrapPaths().length > 0) { - throw new RuntimeException("Unexpected returned value from getBootstrapPaths()"); - } } private static void testHook() throws Exception { @@ -98,8 +97,9 @@ public class TestHook extends BootClassLoaderHook { return false; } - public File[] getAdditionalBootstrapPaths() { - return new File[0]; + public URLClassPath getBootstrapClassPath(URLClassPath bcp, + URLStreamHandlerFactory factory) { + return bcp; } public boolean isCurrentThreadPrefetching() { diff --git a/test/sun/security/pkcs11/fips/CipherTest.java b/test/sun/security/pkcs11/fips/CipherTest.java index e0558958210cbcafca4e9b90b2719172be0525f4..ea99884a4c7fec2ea68980900130187501a2c369 100644 --- a/test/sun/security/pkcs11/fips/CipherTest.java +++ b/test/sun/security/pkcs11/fips/CipherTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2005, 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 @@ -114,10 +114,11 @@ public class CipherTest { } boolean isEnabled() { -// return cipherSuite.equals("SSL_RSA_WITH_RC4_128_MD5") && -// (clientAuth != null); -// return cipherSuite.indexOf("_RSA_") != -1; -// return cipherSuite.indexOf("DH_anon") != -1; + // ignore SCSV + if (cipherSuite.equals("TLS_EMPTY_RENEGOTIATION_INFO_SCSV")) { + return false; + } + return true; } diff --git a/test/sun/security/pkcs11/sslecc/CipherTest.java b/test/sun/security/pkcs11/sslecc/CipherTest.java index 9d29e56c7995a8e14b04625045ac0a395db37964..34ed0eeb9d74403da16b4968b1484200aa2ef359 100644 --- a/test/sun/security/pkcs11/sslecc/CipherTest.java +++ b/test/sun/security/pkcs11/sslecc/CipherTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2006, 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 @@ -114,12 +114,11 @@ public class CipherTest { } boolean isEnabled() { -// if (true) return cipherSuite.contains("_ECDH_"); -// return cipherSuite.equals("SSL_RSA_WITH_RC4_128_MD5") && -// (clientAuth != null); -// return cipherSuite.indexOf("_RSA_") != -1; -// return cipherSuite.indexOf("DH_anon") != -1; -// return cipherSuite.contains("ECDSA") == false; + // ignore SCSV + if (cipherSuite.equals("TLS_EMPTY_RENEGOTIATION_INFO_SCSV")) { + return false; + } + return true; } diff --git a/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/InvalidateServerSessionRenegotiate.java b/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/InvalidateServerSessionRenegotiate.java index 5410ec46d40322d9ce1d01ae1c1b1e828dc94ce4..6954f84bc7d662a6b02c6e34fe963ddaee38897f 100644 --- a/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/InvalidateServerSessionRenegotiate.java +++ b/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/InvalidateServerSessionRenegotiate.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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,8 +25,6 @@ * @test * @bug 4403428 * @summary Invalidating JSSE session on server causes SSLProtocolException - * @ignore incompatible with disabled unsafe renegotiation (6898739), please - * reenable when safe renegotiation is implemented. * @author Brad Wetmore */ diff --git a/test/sun/security/ssl/javax/net/ssl/NewAPIs/JSSERenegotiate.java b/test/sun/security/ssl/javax/net/ssl/NewAPIs/JSSERenegotiate.java index e2809cb9370fb248c7b1c5f676c7641aba95ce77..8bf2f027053e4cd18091cbd33e216b06ad0f2ee9 100644 --- a/test/sun/security/ssl/javax/net/ssl/NewAPIs/JSSERenegotiate.java +++ b/test/sun/security/ssl/javax/net/ssl/NewAPIs/JSSERenegotiate.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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,8 +26,6 @@ * @bug 4280338 * @summary "Unsupported SSL message version" SSLProtocolException * w/SSL_RSA_WITH_NULL_MD5 - * @ignore incompatible with disabled unsafe renegotiation (6898739), please - * reenable when safe renegotiation is implemented. * * @author Ram Marti * @author Brad Wetmore diff --git a/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/CheckStatus.java b/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/CheckStatus.java index a8bb12129d04db27d0ba8148f1565c6457545dae..c29f55a04b9f80dd22097f5e8c4c9f7e38b757d2 100644 --- a/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/CheckStatus.java +++ b/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/CheckStatus.java @@ -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 @@ -25,8 +25,6 @@ * @test * @bug 4948079 * @summary SSLEngineResult needs updating [none yet] - * @ignore incompatible with disabled unsafe renegotiation (6898739), please - * reenable when safe renegotiation is implemented. * * This is a simple hack to test a bunch of conditions and check * their return codes. diff --git a/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/ConnectionTest.java b/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/ConnectionTest.java index 2befa4a0eec560d7edbba05b8097ac16ca3ede45..546a7865668018040236da857146bc4692bbe364 100644 --- a/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/ConnectionTest.java +++ b/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/ConnectionTest.java @@ -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 @@ -26,8 +26,6 @@ * @bug 4495742 * @summary Add non-blocking SSL/TLS functionality, usable with any * I/O abstraction - * @ignore incompatible with disabled unsafe renegotiation (6898739), please - * reenable when safe renegotiation is implemented. * * This is a bit hacky, meant to test various conditions. The main * thing I wanted to do with this was to do buffer reads/writes diff --git a/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/NoAuthClientAuth.java b/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/NoAuthClientAuth.java index 972c7ea51d3aaa5425fb9fb186d9b62844fdeece..44a34372b3cbc028decd2d09005991e630a40c81 100644 --- a/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/NoAuthClientAuth.java +++ b/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/NoAuthClientAuth.java @@ -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 @@ -25,8 +25,6 @@ * @test * @bug 4495742 * @summary Demonstrate SSLEngine switch from no client auth to client auth. - * @ignore incompatible with disabled unsafe renegotiation (6898739), please - * reenable when safe renegotiation is implemented. * * @author Brad R. Wetmore */ diff --git a/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/TestAllSuites.java b/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/TestAllSuites.java index b7a0dd56b0941bff3ee0416cc8b96b1382e9d3a0..6b477a2bf2003eac16ad82d5ce20ae966ed5598e 100644 --- a/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/TestAllSuites.java +++ b/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/TestAllSuites.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2005, 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 @@ -119,6 +119,15 @@ public class TestAllSuites { return; } + /* + * Don't run the SCSV suite + */ + if (suite.equals("TLS_EMPTY_RENEGOTIATION_INFO_SCSV")) { + System.out.println("Ignoring SCSV suite"); + return; + } + + if (!suite.contains("DH_anon")) { ssle2.setNeedClientAuth(true); } diff --git a/test/sun/security/ssl/sanity/ciphersuites/CheckCipherSuites.java b/test/sun/security/ssl/sanity/ciphersuites/CheckCipherSuites.java index 8f58e3d2b8ab23971432276b5b6d5f328b7f1acb..e1ff7e6464eee590623e05ccf05d0b51d996adde 100644 --- a/test/sun/security/ssl/sanity/ciphersuites/CheckCipherSuites.java +++ b/test/sun/security/ssl/sanity/ciphersuites/CheckCipherSuites.java @@ -64,6 +64,8 @@ public class CheckCipherSuites { "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA", "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA", "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA", + "TLS_EMPTY_RENEGOTIATION_INFO_SCSV", + }; private final static String[] ENABLED_UNLIMITED = { @@ -101,6 +103,8 @@ public class CheckCipherSuites { "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA", "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA", "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA", + "TLS_EMPTY_RENEGOTIATION_INFO_SCSV", + }; // supported ciphersuites using default JCE policy jurisdiction files @@ -133,6 +137,7 @@ public class CheckCipherSuites { "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA", "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA", "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA", + "TLS_EMPTY_RENEGOTIATION_INFO_SCSV", "SSL_RSA_WITH_NULL_MD5", "SSL_RSA_WITH_NULL_SHA", @@ -160,6 +165,7 @@ public class CheckCipherSuites { "TLS_KRB5_EXPORT_WITH_RC4_40_MD5", "TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA", "TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5", + }; // supported ciphersuites using unlimited JCE policy jurisdiction files @@ -199,6 +205,7 @@ public class CheckCipherSuites { "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA", "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA", "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA", + "TLS_EMPTY_RENEGOTIATION_INFO_SCSV", "SSL_RSA_WITH_NULL_MD5", "SSL_RSA_WITH_NULL_SHA", @@ -228,6 +235,7 @@ public class CheckCipherSuites { "TLS_KRB5_EXPORT_WITH_RC4_40_MD5", "TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA", "TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5", + }; private static void showSuites(String[] suites) { diff --git a/test/sun/security/ssl/sanity/interop/CipherTest.java b/test/sun/security/ssl/sanity/interop/CipherTest.java index b1b3de61ce79c30f73605a7575ed353455885470..975bbe833e71fa20cedbc8003d3a5c7a1dfa8e31 100644 --- a/test/sun/security/ssl/sanity/interop/CipherTest.java +++ b/test/sun/security/ssl/sanity/interop/CipherTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2005, 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 @@ -115,10 +115,11 @@ public class CipherTest { } boolean isEnabled() { -// return cipherSuite.equals("SSL_RSA_WITH_RC4_128_MD5") && -// (clientAuth != null); -// return cipherSuite.indexOf("_RSA_") != -1; -// return cipherSuite.indexOf("DH_anon") != -1; + // ignore SCSV + if (cipherSuite.equals("TLS_EMPTY_RENEGOTIATION_INFO_SCSV")) { + return false; + } + return true; } diff --git a/test/tools/jar/UpdateManifest.java b/test/tools/jar/UpdateManifest.java index 2bcd25081ea7238a4ce8f84d87f45d0db88b1fd8..64897183b571df074191c0e40bc9fa1106a17e54 100644 --- a/test/tools/jar/UpdateManifest.java +++ b/test/tools/jar/UpdateManifest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 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 @@ -23,7 +23,7 @@ /** * @test - * @bug 6434207 6442687 + * @bug 6434207 6442687 6984046 * @summary Ensure that jar ufm actually updates the * existing jar file's manifest with contents of the * manifest file. @@ -87,7 +87,7 @@ public class UpdateManifest { if (!debug) manifestOrig.deleteOnExit(); PrintWriter pw = new PrintWriter(manifestOrig); pw.println("Manifest-Version: 1.0"); - pw.println("Created-By: 1.6.0-internal (Sun Microsystems Inc.)"); + pw.println("Created-By: 1.7.0-internal (Oracle Corporation)"); pw.println(""); pw.println(animal); pw.println(specTitle); @@ -109,7 +109,7 @@ public class UpdateManifest { if (!debug) manifestUpdate.deleteOnExit(); pw = new PrintWriter(manifestUpdate); final String createdBy = - "Created-By: 1.5.0-special (Sun Microsystems Inc.)"; + "Created-By: 1.7.0-special (Oracle Corporation)"; final String specVersion = "Specification-Version: 1.0.0.0"; pw.println(createdBy); // replaces line in the original diff --git a/test/tools/launcher/Arrrghs.java b/test/tools/launcher/Arrrghs.java index f5730ba3532ae411ad8199bb0cd93d6c9ec2891f..de3dbe20112ce827ed34f416471b8d3a99397ca8 100644 --- a/test/tools/launcher/Arrrghs.java +++ b/test/tools/launcher/Arrrghs.java @@ -24,6 +24,7 @@ /** * @test * @bug 5030233 6214916 6356475 6571029 6684582 6742159 4459600 6758881 6753938 + * 6894719 * @summary Argument parsing validation. * @compile -XDignore.symbol.file Arrrghs.java TestHelper.java * @run main Arrrghs @@ -326,20 +327,36 @@ public class Arrrghs { System.out.println(tr); } + static void test6894719() { + // test both arguments to ensure they exist + TestHelper.TestResult tr = null; + tr = TestHelper.doExec(TestHelper.javaCmd, + "-no-jre-restrict-search", "-version"); + tr.checkPositive(); + System.out.println(tr); + + tr = TestHelper.doExec(TestHelper.javaCmd, + "-jre-restrict-search", "-version"); + tr.checkPositive(); + System.out.println(tr); + } /** * @param args the command line arguments * @throws java.io.FileNotFoundException */ public static void main(String[] args) throws FileNotFoundException { - if (TestHelper.debug) System.out.println("Starting Arrrghs tests"); - quoteParsingTests(); - runBasicErrorMessageTests(); - runMainMethodTests(); - if (TestHelper.testExitValue > 0) { - System.out.println("Total of " + TestHelper.testExitValue + " failed"); - System.exit(1); - } else { - System.out.println("All tests pass"); - } + if (TestHelper.debug) { + System.out.println("Starting Arrrghs tests"); + } + quoteParsingTests(); + runBasicErrorMessageTests(); + runMainMethodTests(); + test6894719(); + if (TestHelper.testExitValue > 0) { + System.out.println("Total of " + TestHelper.testExitValue + " failed"); + System.exit(1); + } else { + System.out.println("All tests pass"); } } +} diff --git a/test/tools/pack200/AttributeTests.java b/test/tools/pack200/AttributeTests.java new file mode 100644 index 0000000000000000000000000000000000000000..e7107996cc8b28caef2a85cbaffbc82d04214e34 --- /dev/null +++ b/test/tools/pack200/AttributeTests.java @@ -0,0 +1,131 @@ +/* + * 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.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +/* + * @test + * @bug 6982312 + * @summary tests various classfile format and attribute handling by pack200 + * @compile -XDignore.symbol.file Utils.java AttributeTests.java + * @run main AttributeTests + * @author ksrini + */ +public class AttributeTests { + + public static void main(String... args) throws Exception { + test6982312(); + test6746111(); + } + /* + * This is an interim test, which ensures pack200 handles JSR-292 related + * classfile changes seamlessly, until all the classfile changes in jdk7 + * and jdk8 are fully supported. At that time this test should be jettisoned, + * along with the associated jar file. + * + * The jar file contains sources and classes noting the classes were + * derived by using the javac from the lambda project, + * see http://openjdk.java.net/projects/lambda/. + * Therefore the classes contained in the jar cannot be compiled, using + * the standard jdk7's javac compiler. + */ + static void test6982312() throws IOException { + String pack200Cmd = Utils.getPack200Cmd(); + File dynJar = new File(".", "dyn.jar"); + Utils.copyFile(new File(Utils.TEST_SRC_DIR, "dyn.jar"), dynJar); + File testJar = new File(".", "test.jar"); + List cmds = new ArrayList(); + cmds.add(pack200Cmd); + cmds.add("--repack"); + cmds.add(testJar.getAbsolutePath()); + cmds.add(dynJar.getAbsolutePath()); + Utils.runExec(cmds); + /* + * compare the repacked jar bit-wise, as all the files + * should be transmitted "as-is". + */ + Utils.doCompareBitWise(dynJar.getAbsoluteFile(), testJar.getAbsoluteFile()); + testJar.delete(); + dynJar.delete(); + } + + /* + * this test checks to see if we get the expected strings for output + */ + static void test6746111() throws Exception { + String pack200Cmd = Utils.getPack200Cmd(); + File badAttrJar = new File(".", "badattr.jar"); + Utils.copyFile(new File(Utils.TEST_SRC_DIR, "badattr.jar"), badAttrJar); + File testJar = new File(".", "test.jar"); + List cmds = new ArrayList(); + cmds.add(pack200Cmd); + cmds.add("--repack"); + cmds.add("-v"); + cmds.add(testJar.getAbsolutePath()); + cmds.add(badAttrJar.getAbsolutePath()); + List output = Utils.runExec(cmds); + /* + * compare the repacked jar bit-wise, as all the files + * should be transmitted "as-is". + */ + Utils.doCompareBitWise(badAttrJar.getAbsoluteFile(), testJar.getAbsoluteFile()); + String[] expectedStrings = { + "WARNING: Passing class file uncompressed due to unrecognized" + + " attribute: Foo.class", + "INFO: com.sun.java.util.jar.pack.Attribute$FormatException: " + + "class attribute \"XourceFile\": is unknown attribute " + + "in class Foo", + "INFO: com.sun.java.util.jar.pack.ClassReader$ClassFormatException: " + + "AnnotationDefault: attribute length cannot be zero, in Test.message()", + "WARNING: Passing class file uncompressed due to unknown class format: Test.class" + }; + List notfoundList = new ArrayList(); + notfoundList.addAll(Arrays.asList(expectedStrings)); + // make sure the expected messages are emitted + for (String x : output) { + findString(x, notfoundList, expectedStrings); + } + if (!notfoundList.isEmpty()) { + System.out.println("Not found:"); + for (String x : notfoundList) { + System.out.println(x); + } + throw new Exception("Test fails: " + notfoundList.size() + + " expected strings not found"); + } + testJar.delete(); + badAttrJar.delete(); + } + + private static void findString(String outputStr, List notfoundList, + String[] expectedStrings) { + for (String y : expectedStrings) { + if (outputStr.contains(y)) { + notfoundList.remove(y); + return; + } + } + } +} diff --git a/test/tools/pack200/PackageVersionTest.java b/test/tools/pack200/PackageVersionTest.java index 344aadd6b6178aabb871a785d01c2ff0ede97915..538b92ecafc7bd043e3be5b8a4af1374a06d9650 100644 --- a/test/tools/pack200/PackageVersionTest.java +++ b/test/tools/pack200/PackageVersionTest.java @@ -24,7 +24,7 @@ /* * @test - * @bug 6712743 + * @bug 6712743 6991164 * @summary verify package versions * @compile -XDignore.symbol.file Utils.java PackageVersionTest.java * @run main PackageVersionTest @@ -40,6 +40,7 @@ import java.io.PrintStream; import java.util.jar.JarFile; import java.util.jar.Pack200; import java.util.jar.Pack200.Packer; +import java.util.jar.Pack200.Unpacker; public class PackageVersionTest { private static final File javaHome = new File(System.getProperty("java.home")); @@ -60,6 +61,7 @@ public class PackageVersionTest { createClassFile("Test6"); createClassFile("Test7"); + verify6991164(); verifyPack("Test5.class", JAVA5_PACKAGE_MAJOR_VERSION, JAVA5_PACKAGE_MINOR_VERSION); @@ -75,6 +77,18 @@ public class PackageVersionTest { JAVA5_PACKAGE_MINOR_VERSION); } + static void verify6991164() { + Unpacker unpacker = Pack200.newUnpacker(); + String versionStr = unpacker.toString(); + String expected = "Pack200, Vendor: " + + System.getProperty("java.vendor") + ", Version: " + + JAVA6_PACKAGE_MAJOR_VERSION + "." + JAVA6_PACKAGE_MINOR_VERSION; + if (!versionStr.equals(expected)) { + System.out.println("Expected: " + expected); + System.out.println("Obtained: " + versionStr); + throw new RuntimeException("did not get expected string " + expected); + } + } static void createClassFile(String name) { createJavaFile(name); diff --git a/test/tools/pack200/badattr.jar b/test/tools/pack200/badattr.jar new file mode 100644 index 0000000000000000000000000000000000000000..330be6147c1da7b15da65df3eb331da064fc39f2 Binary files /dev/null and b/test/tools/pack200/badattr.jar differ diff --git a/test/tools/pack200/dyn.jar b/test/tools/pack200/dyn.jar new file mode 100644 index 0000000000000000000000000000000000000000..b04c2a9e825b1201cbdcd2f863478587356ce7ec Binary files /dev/null and b/test/tools/pack200/dyn.jar differ